Revision 2c971094 proto/ospf/lsupd.c

View differences:

proto/ospf/lsupd.c
14 14
  /* FIXME Go on! */
15 15
}
16 16

  
17
void
18
flood_lsa(struct ospf_neighbor *n, struct ospf_lsa_header *hn,
19
  struct ospf_lsa_header *hh, struct proto_ospf *po, struct ospf_iface *iff)
20
{
21
  struct ospf_iface *ifa;
22
  struct ospf_neighbor *nn;
23
  struct top_hash_entry *en;
24
  int ret;
25

  
26
  /* pg 148 */
27
  WALK_LIST(NODE ifa,po->iface_list)
28
  {
29
    if(hh->type==LSA_T_EXT)
30
    {
31
      if(ifa->type==OSPF_IT_VLINK) continue;
32
      if(ifa->oa->stub) continue;
33
    }
34
    else
35
    {
36
      if(iff->oa->areaid==BACKBONE)
37
      {
38
        if((ifa->type!=OSPF_IT_VLINK)&&(ifa->oa!=iff->oa)) continue;
39
      }
40
      else
41
      {
42
        if(ifa->oa!=iff->oa) continue;
43
      }
44
    }
45
    ret=0;
46
    WALK_LIST(NODE nn, ifa->neigh_list)
47
    {
48
      if(nn->state<NEIGHBOR_EXCHANGE) continue;
49
      if(nn->state<NEIGHBOR_FULL)
50
      {
51

  
52
        if((en=ospf_hash_find_header(nn->lsrqh,hh))!=NULL)
53
	{
54
	  switch(lsa_comp(hh,&en->lsa))
55
	  {
56
            case CMP_OLDER:
57
              continue;
58
	      break;
59
	    case CMP_SAME:
60
              s_rem_node(SNODE en);
61
	      DBG("Removing from lsreq list for neigh %u\n", nn->rid);
62
	      ospf_hash_delete(nn->lsrqh,en);
63
	      if(EMPTY_SLIST(nn->lsrql)) ospf_neigh_sm(nn, INM_LOADDONE);
64
	      continue;
65
	      break;
66
	    case CMP_NEWER:
67
              s_rem_node(SNODE en);
68
	      DBG("Removing from lsreq list for neigh %u\n", nn->rid);
69
	      ospf_hash_delete(nn->lsrqh,en);
70
	      if(EMPTY_SLIST(nn->lsrql)) ospf_neigh_sm(nn, INM_LOADDONE);
71
	      break;
72
	    default: bug("Bug in lsa_comp?\n");
73
	  }
74
	}
75
      }
76
      if(nn==n) continue;
77
      en=ospf_hash_get_header(nn->lsrth, hh);
78
      s_add_tail(&nn->lsrtl, SNODE en);
79
      ret=1;
80
    }
81
    if(ret==0) continue;
82
    if(ifa==iff)
83
    {
84
      if((n->rid==iff->drid)||n->rid==iff->bdrid) continue;
85
      if(iff->state=OSPF_IS_BACKUP) continue;
86
    }
87
    /* FIXME directly flood */
88
    {
89
      sock *sk;
90
      ip_addr to;
91
      u16 len;
92
      struct ospf_lsupd_packet *pk;
93
      struct ospf_packet *op;
94

  
95
      if(ifa->type==OSPF_IT_NBMA)  sk=iff->ip_sk;
96
      else sk=iff->hello_sk;	/* FIXME is this tru for PTP? */
97

  
98
      pk=(struct ospf_lsupd_packet *)sk->tbuf;
99
      op=(struct ospf_packet *)sk->tbuf;
100

  
101
      fill_ospf_pkt_hdr(ifa, pk, LSUPD);
102
      pk->lsano=htonl(1);
103
      memcpy(pk+1,hn,ntohs(hn->length));
104
      len=sizeof(struct ospf_lsupd_packet)+ntohs(hn->length);
105
      op->length=htons(len);
106
      ospf_pkt_finalize(ifa, op);
107

  
108
      if(ifa->type==OSPF_IT_NBMA)
109
      {
110
	struct ospf_neighbor *nnn;
111
        WALK_LIST(NODE nnn,ifa->neigh_list)
112
	{
113
          if(nnn->state>NEIGHBOR_EXSTART)
114
            sk_send_to(sk,len, nnn->ip, OSPF_PROTO);
115
	}
116
      }
117
      else
118
      {
119
        if((ifa->state==OSPF_IS_BACKUP)||(ifa->state==OSPF_IS_DR))
120
          sk_send_to(sk,len, AllSPFRouters, OSPF_PROTO);
121
	else sk_send_to(sk,len, AllDRouters, OSPF_PROTO);
122
      }
123
    }
124
  }
125
}
126

  
17 127
void		/* I send all I received in LSREQ */
18 128
ospf_lsupd_tx_list(struct ospf_neighbor *n, list *l)
19 129
{
......
116 226
  {
117 227
    struct ospf_lsa_header lsatmp;
118 228
    struct top_hash_entry *lsadb;
229
    /* pg 143 (1) */
119 230
    if(lsa->checksum!=lsasum_check(lsa,NULL,po))
120 231
    {
121 232
      log("Received bad lsa checksum from %u\n",n->rid);
122 233
      continue;
123 234
    }
235
    /* pg 143 (2) */
124 236
    if((lsa->type<LSA_T_RT)||(lsa->type>LSA_T_EXT))
125 237
    {
126 238
      log("Unknown LSA type from %u\n",n->rid);
127 239
      continue;
128 240
    }
241
    /* pg 143 (3) */
129 242
    if((lsa->type==LSA_T_EXT)&&oa->stub)
130 243
    {
131 244
      log("Received External LSA in stub area from %u\n",n->rid);
......
136 249
        lsatmp.id, lsatmp.rt);
137 250
    lsadb=ospf_hash_find_header(oa->gr, &lsatmp);
138 251

  
139
    /* Remove it from link state request list */
140
    WALK_LIST(NODE ifa,po->iface_list)
141
      WALK_LIST(NODE ntmp,ifa->neigh_list)
142
      {
143
        struct top_hash_entry *en;
144
	if(ntmp->state>NEIGHBOR_EXSTART)
145
          if((en=ospf_hash_find_header(ntmp->lsrqh,&lsatmp))!=NULL)
146
	  {
147
	    s_rem_node(SNODE en);
148
	    DBG("Removing from lsreq list for neigh %u\n", ntmp->rid);
149
	    ospf_hash_delete(ntmp->lsrqh,en);
150
	    if(EMPTY_SLIST(ntmp->lsrql)) ospf_neigh_sm(ntmp, INM_LOADDONE);
151
	  }
152
      }
153

  
252
    /* pg 143 (4) */
154 253
    if((lsatmp.age==LSA_MAXAGE)&&(lsadb==NULL))
155 254
    {
156 255
      struct ospf_neighbor *n=NULL;
......
169 268
	continue;
170 269
      }
171 270
    }
271
    /* pg 144 (5) */
172 272
    if((lsadb==NULL)||(lsa_comp(&lsatmp,&lsadb->lsa)==CMP_NEWER))
173 273
    {
174
       struct ospf_neighbor *n=NULL;
175
       struct ospf_iface *ifa=NULL;
274
       struct ospf_iface *ift=NULL;
176 275
       void *body;
177 276

  
178
       /* FIXME self originated? */
179 277

  
278
      /* pg 144 (5a) */
180 279
      if(lsadb && ((lsadb->inst_t-now)<MINLSARRIVAL)) continue;
181 280

  
281
      flood_lsa(n,lsa,&lsatmp,po,ifa);
282

  
182 283
      /* Remove old from all ret lists */
284
      /* pg 144 (5c) */
183 285
      if(lsadb)
184
        WALK_LIST(NODE ifa,po->iface_list)
185
          WALK_LIST(NODE ntmp,ifa->neigh_list)
286
        WALK_LIST(NODE ift,po->iface_list)
287
          WALK_LIST(NODE ntmp,ift->neigh_list)
186 288
	  {
187 289
	    struct top_hash_entry *en;
188 290
	    if(ntmp->state>NEIGHBOR_EXSTART)
......
193 295
	      }
194 296
	  }
195 297

  
196
      /* Install new */
298
      /* pg 144 (5d) */
197 299
      body=mb_alloc(p->pool,lsatmp.length-sizeof(struct ospf_lsa_header));
198
      ntohlsab(lsa+1,body,lsatmp.type,lsatmp.length-sizeof(struct ospf_lsa_header));
300
      ntohlsab(lsa+1,body,lsatmp.type,
301
        lsatmp.length-sizeof(struct ospf_lsa_header));
199 302
      lsadb=lsa_install_new(&lsatmp,body, oa);
200 303
      DBG("New LSA installed in DB\n");
201 304

  
305
      /* FIXME 144 (5e) ack */
306
      /* FIXME 145 (5f) self originated? */
307

  
202 308
      continue;
203 309
    }
204 310

  
205
    /* FIXME pg144 (6)?? */
311
    /* FIXME pg145 (6)?? */
206 312

  
313
    /* pg145 (7) */
207 314
    if(lsa_comp(&lsatmp,&lsadb->lsa)==CMP_SAME)
208 315
    {
209 316
	struct top_hash_entry *en;
......
213 320
	continue;
214 321
    }
215 322

  
323
    /* pg145 (8) */
216 324
    if((lsadb->lsa.age==LSA_MAXAGE)&&(lsadb->lsa.sn==LSA_MAXSEQNO)) continue;
217 325

  
218
    /* FIXME lsa_send(n,lsa) */
326
    {
327
      list l;
328
      struct l_lsr_head llsh;
329
      init_list(&l);
330
      memcpy(&llsh.lsh,&lsadb->lsa,sizeof(struct ospf_lsa_header));
331
      add_tail(&l, NODE &llsh);
332
      ospf_lsupd_tx_list(n, &l);
333
    }
219 334
  }
220 335
}
221 336

  

Also available in: Unified diff