Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsreq.c @ 035f6acb

History | View | Annotate | Download (3.92 KB)

1
/*
2
 *        BIRD -- OSPF
3
 *
4
 *        (c) 2000 Ondrej Filip <feela@network.cz>
5
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

    
9
#include "ospf.h"
10

    
11
void
12
ospf_lsreq_tx(struct ospf_neighbor *n)
13
{
14
  snode *sn;
15
  struct top_hash_entry *en;
16
  struct ospf_lsreq_packet *pk;
17
  struct ospf_packet *op;
18
  struct ospf_lsreq_header *lsh;
19
  u16 length;
20
  int i,j;
21
  struct proto *p=&n->ifa->proto->proto;
22

    
23
  pk=(struct ospf_lsreq_packet *)n->ifa->ip_sk->tbuf;
24
  op=(struct ospf_packet *)n->ifa->ip_sk->tbuf;
25

    
26
  fill_ospf_pkt_hdr(n->ifa, pk, LSREQ_P);
27

    
28
  sn=SHEAD(n->lsrql);
29
  if(EMPTY_SLIST(n->lsrql))
30
  {
31
    if(n->state==NEIGHBOR_LOADING) ospf_neigh_sm(n, INM_LOADDONE);
32
    return;
33
  }
34
 
35
  i=j=(n->ifa->iface->mtu-SIPH-sizeof(struct ospf_lsreq_packet))/
36
    sizeof(struct ospf_lsreq_header);
37
  lsh=(struct ospf_lsreq_header *)(pk+1);
38
  
39
  for(;i>0;i--)
40
  {
41
    en=(struct top_hash_entry *)sn;
42
    lsh->padd1=0; lsh->padd2=0;
43
    lsh->type=en->lsa.type;
44
    lsh->rt=htonl(en->lsa.rt);
45
    lsh->id=htonl(en->lsa.id);
46
    DBG("Requesting %uth LSA: Type: %u, Id: %I, RT: %I\n",i, en->lsa.type,
47
                    en->lsa.id, en->lsa.rt);
48
    lsh++;
49
    if(sn==STAIL(n->lsrql)) break;
50
    sn=sn->next;
51
  }
52
  if(i!=0) i--;
53

    
54
  length=sizeof(struct ospf_lsreq_packet)+(j-i)*sizeof(struct ospf_lsreq_header);
55
  op->length=htons(length);
56
  ospf_pkt_finalize(n->ifa, op);
57
  sk_send_to(n->ifa->ip_sk,length, n->ip, OSPF_PROTO);
58
  OSPF_TRACE(D_PACKETS, "LS request sent to: %I", n->rid);
59
}
60

    
61
void
62
lsrr_timer_hook(timer *timer)
63
{
64
  struct ospf_iface *ifa;
65
  struct proto *p;
66
  struct ospf_neighbor *n;
67
  struct top_hash_entry *en;
68

    
69
  n=(struct ospf_neighbor *)timer->data;
70
  ifa=n->ifa;
71
  p=(struct proto *)(ifa->proto);
72

    
73
  DBG("%s: LSRR timer fired on interface %s for neigh: %I.\n",
74
    p->name, ifa->iface->name, n->rid);
75
  if(n->state<NEIGHBOR_FULL) ospf_lsreq_tx(n);
76
  else
77
  {
78
    if(!EMPTY_SLIST(n->lsrtl))
79
    {
80
      list uplist;
81
      slab *upslab;
82
      struct l_lsr_head *llsh;
83

    
84
      init_list(&uplist);
85
      upslab=sl_new(n->pool,sizeof(struct l_lsr_head));
86

    
87
      WALK_SLIST(SNODE en,n->lsrtl)
88
      {
89
        if((SNODE en)->next==(SNODE en)) bug("RTList is cycled");
90
        llsh=sl_alloc(upslab);
91
        llsh->lsh.id=en->lsa.id;
92
        llsh->lsh.rt=en->lsa.rt;
93
        llsh->lsh.type=en->lsa.type;
94
        DBG("Working on ID: %I, RT: %I, Type: %u\n",
95
          en->lsa.id, en->lsa.rt, en->lsa.type);
96
        add_tail(&uplist, NODE llsh);
97
      }
98
      ospf_lsupd_tx_list(n, &uplist);
99
      rfree(upslab);
100
    }
101
  }
102
}
103

    
104
void
105
ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p,
106
  struct ospf_iface *ifa, u16 size)
107
{
108
  u32 nrid, myrid;
109
  struct ospf_neighbor *n;
110
  struct ospf_lsreq_header *lsh;
111
  struct l_lsr_head *llsh;
112
  list uplist;
113
  slab *upslab;
114
  int length;
115
  int i,lsano;
116

    
117
  nrid=ntohl(ps->ospf_packet.routerid);
118

    
119
  myrid=p->cf->global->router_id;
120

    
121
  if((n=find_neigh(ifa, nrid))==NULL)
122
  {
123
    OSPF_TRACE(D_PACKETS, "Received lsreq from unknown neighbor! (%I)",
124
      nrid);
125
    return ;
126
  }
127
  if(n->state<NEIGHBOR_EXCHANGE) return;
128

    
129
  OSPF_TRACE(D_EVENTS, "Received LS req from neighbor: %I", n->ip);
130
  ospf_neigh_sm(n, INM_HELLOREC);
131

    
132
  length=ntohs(ps->ospf_packet.length);
133
  lsh=(void *)(ps+1);
134
  init_list(&uplist);
135
  upslab=sl_new(n->pool,sizeof(struct l_lsr_head));
136

    
137
  lsano=(length-sizeof(struct ospf_lsreq_packet))/
138
    sizeof(struct ospf_lsreq_header);
139
  for(i=0;i<lsano;lsh++,i++)
140
  {
141
    DBG("Processing LSA: ID=%I, Type=%u, Router=%I\n", ntohl(lsh->id),
142
    lsh->type, ntohl(lsh->rt));
143
    llsh=sl_alloc(upslab);
144
    llsh->lsh.id=ntohl(lsh->id);
145
    llsh->lsh.rt=ntohl(lsh->rt);
146
    llsh->lsh.type=lsh->type;
147
    add_tail(&uplist, NODE llsh);
148
    if(ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
149
      llsh->lsh.type)==NULL)
150
    {
151
      log("Received bad LS req from: %I looking: RT: %I, ID: %I, Type: %u",
152
        n->ip, lsh->rt, lsh->id, lsh->type);
153
      ospf_neigh_sm(n,INM_BADLSREQ);
154
      rfree(upslab);
155
      return;
156
    }
157
  }
158
  ospf_lsupd_tx_list(n, &uplist);
159
  rfree(upslab);
160
}
161