]>
Commit | Line | Data |
---|---|---|
c1f8dc91 OF |
1 | /* |
2 | * BIRD -- OSPF | |
3 | * | |
e300066d | 4 | * (c) 1999--2005 Ondrej Filip <feela@network.cz> |
c1f8dc91 OF |
5 | * |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #ifndef _BIRD_OSPF_H_ | |
10 | #define _BIRD_OSPF_H_ | |
11 | ||
273fd2c1 | 12 | #define MAXNETS 10 |
94c42054 OF |
13 | #define OSPF_MAX_PKT_SIZE 65536 |
14 | /* | |
e300066d OF |
15 | * RFC 2328 says, maximum packet size is 65535 |
16 | * This could be too much for small systems, so I | |
17 | * normally allocate 2*mtu - (I found one cisco | |
18 | * sending packets mtu+16) | |
19 | */ | |
f14032ef OF |
20 | #ifdef LOCAL_DEBUG |
21 | #define OSPF_FORCE_DEBUG 1 | |
22 | #else | |
23 | #define OSPF_FORCE_DEBUG 0 | |
24 | #endif | |
25 | #define OSPF_TRACE(flags, msg, args...) do { if ((p->debug & flags) || OSPF_FORCE_DEBUG) \ | |
26 | log(L_TRACE "%s: " msg, p->name , ## args ); } while(0) | |
6d2b3211 | 27 | |
8298d780 OZ |
28 | #define OSPF_PACKET(dumpfn, buffer, msg, args...) \ |
29 | do { if ((p->debug & D_PACKETS) || OSPF_FORCE_DEBUG) \ | |
30 | { log(L_TRACE "%s: " msg, p->name, ## args ); dumpfn(p, buffer); } } while(0) | |
31 | ||
32 | ||
4364b47e OF |
33 | #include "nest/bird.h" |
34 | ||
35 | #include "lib/checksum.h" | |
6ba36f06 MM |
36 | #include "lib/ip.h" |
37 | #include "lib/lists.h" | |
30147b89 | 38 | #include "lib/slists.h" |
6ba36f06 MM |
39 | #include "lib/socket.h" |
40 | #include "lib/timer.h" | |
41 | #include "lib/resource.h" | |
42 | #include "nest/protocol.h" | |
43 | #include "nest/iface.h" | |
4364b47e | 44 | #include "nest/route.h" |
a783e259 | 45 | #include "nest/cli.h" |
f8f1e1f1 | 46 | #include "nest/locks.h" |
4364b47e | 47 | #include "conf/conf.h" |
d345cda5 | 48 | #include "lib/string.h" |
6ba36f06 | 49 | |
5b1a92e6 | 50 | #define OSPF_PROTO 89 |
c3226991 | 51 | |
aec76c6e | 52 | #ifndef IPV6 |
c3226991 | 53 | #define OSPFv2 1 |
296ecb56 | 54 | #define OSPF_VERSION 2 |
d5356072 | 55 | #define OSPF_VLINK_MTU 576 /* RFC 2328 A.1 */ |
5b1a92e6 OF |
56 | #define AllSPFRouters ipa_from_u32(0xe0000005) /* 224.0.0.5 */ |
57 | #define AllDRouters ipa_from_u32(0xe0000006) /* 224.0.0.6 */ | |
aec76c6e | 58 | #else |
c3226991 OZ |
59 | #define OSPFv3 1 |
60 | #define OSPF_VERSION 3 | |
d5356072 | 61 | #define OSPF_VLINK_MTU 1280 /* RFC 5340 A.1 */ |
c3226991 OZ |
62 | #define AllSPFRouters _MI(0xFF020000, 0, 0, 5) /* FF02::5 */ |
63 | #define AllDRouters _MI(0xFF020000, 0, 0, 6) /* FF02::6 */ | |
aec76c6e OF |
64 | #endif |
65 | ||
15087574 | 66 | |
921a93f2 | 67 | #define LSREFRESHTIME 1800 /* 30 minutes */ |
15087574 OF |
68 | #define MINLSINTERVAL 5 |
69 | #define MINLSARRIVAL 1 | |
98ac6176 | 70 | #define LSINFINITY 0xffffff |
d631698e | 71 | |
62eee823 | 72 | #define DEFAULT_OSPFTICK 1 |
3b16080c | 73 | #define DEFAULT_RFC1583 0 /* compatibility with rfc1583 */ |
8d94a524 | 74 | #define DEFAULT_STUB_COST 1000 |
d631698e | 75 | |
15087574 | 76 | |
2e10a170 OF |
77 | struct ospf_config |
78 | { | |
c1f8dc91 | 79 | struct proto_config c; |
b8f17cf1 | 80 | unsigned tick; |
3fa5722d | 81 | int rfc1583; |
b36a0a79 OF |
82 | list area_list; |
83 | }; | |
84 | ||
2e10a170 OF |
85 | struct nbma_node |
86 | { | |
e5b5d18c OF |
87 | node n; |
88 | ip_addr ip; | |
a190e720 | 89 | int eligible; |
e5b5d18c OF |
90 | }; |
91 | ||
98ac6176 | 92 | struct area_net_config |
2e10a170 | 93 | { |
c926eee7 | 94 | node n; |
66261211 | 95 | struct prefix px; |
c926eee7 | 96 | int hidden; |
98ac6176 OF |
97 | }; |
98 | ||
99 | struct area_net | |
100 | { | |
101 | struct fib_node fn; | |
102 | int hidden; | |
66261211 | 103 | int active; |
60e04f04 | 104 | u32 metric; |
c926eee7 OF |
105 | }; |
106 | ||
38675202 OZ |
107 | struct ospf_stubnet_config |
108 | { | |
109 | node n; | |
110 | struct prefix px; | |
111 | int hidden, summary; | |
112 | u32 cost; | |
113 | }; | |
114 | ||
2e10a170 OF |
115 | struct ospf_area_config |
116 | { | |
b36a0a79 OF |
117 | node n; |
118 | u32 areaid; | |
119 | int stub; | |
89d6782d | 120 | list patt_list; |
3b16080c | 121 | list vlink_list; |
c926eee7 | 122 | list net_list; |
38675202 | 123 | list stubnet_list; |
c1f8dc91 OF |
124 | }; |
125 | ||
c3226991 OZ |
126 | |
127 | /* Option flags */ | |
128 | ||
129 | #define OPT_E 0x02 | |
130 | #define OPT_N 0x08 | |
131 | #define OPT_DC 0x20 | |
132 | ||
133 | #ifdef OSPFv2 | |
134 | #define OPT_EA 0x10 | |
135 | ||
136 | /* VEB flags are are stored independently in 'u16 options' */ | |
137 | #define OPT_RT_B (0x01 << 8) | |
138 | #define OPT_RT_E (0x02 << 8) | |
139 | #define OPT_RT_V (0x04 << 8) | |
621ccdfe | 140 | #endif |
621ccdfe | 141 | |
c3226991 OZ |
142 | #ifdef OSPFv3 |
143 | #define OPT_V6 0x01 | |
144 | #define OPT_R 0x10 | |
145 | ||
146 | /* VEB flags are are stored together with options in 'u32 options' */ | |
147 | #define OPT_RT_B (0x01 << 24) | |
148 | #define OPT_RT_E (0x02 << 24) | |
149 | #define OPT_RT_V (0x04 << 24) | |
150 | #define OPT_RT_NT (0x10 << 24) | |
151 | ||
152 | #define OPT_PX_NU 0x01 | |
153 | #define OPT_PX_LA 0x02 | |
154 | #define OPT_PX_P 0x08 | |
155 | #define OPT_PX_DN 0x10 | |
156 | #endif | |
621ccdfe OF |
157 | |
158 | ||
2e10a170 OF |
159 | struct ospf_iface |
160 | { | |
b11d8a4f | 161 | node n; |
2e10a170 | 162 | struct iface *iface; /* Nest's iface */ |
48cff379 | 163 | struct ifa *addr; /* IP prefix associated with that OSPF iface */ |
30147b89 | 164 | struct ospf_area *oa; |
f8f1e1f1 | 165 | struct object_lock *lock; |
f9c799a0 | 166 | sock *sk; /* IP socket (for DD ...) */ |
2e10a170 | 167 | list neigh_list; /* List of neigbours */ |
9912fa51 | 168 | u32 cost; /* Cost of iface */ |
7df86c25 OF |
169 | u32 waitint; /* number of sec before changing state from wait */ |
170 | u32 rxmtint; /* number of seconds between LSA retransmissions */ | |
171 | u32 pollint; /* Poll interval */ | |
d8c7d9e8 | 172 | u32 dead; /* after "deadint" missing hellos is router dead */ |
98ac6176 OF |
173 | u32 vid; /* Id of peer of virtual link */ |
174 | ip_addr vip; /* IP of peer of virtual link */ | |
0aad2b92 OZ |
175 | struct ospf_iface *vifa; /* OSPF iface which the vlink goes through */ |
176 | struct ospf_area *voa; /* OSPF area which the vlink goes through */ | |
9912fa51 OF |
177 | u16 inftransdelay; /* The estimated number of seconds it takes to |
178 | transmit a Link State Update Packet over this | |
179 | interface. LSAs contained in the update */ | |
621ccdfe | 180 | u16 helloint; /* number of seconds between hello sending */ |
c3226991 OZ |
181 | |
182 | #ifdef OSPFv2 | |
3e2bd0f1 | 183 | list *passwords; |
c3226991 | 184 | u16 autype; |
024c310b OZ |
185 | u32 csn; /* Last used crypt seq number */ |
186 | bird_clock_t csn_use; /* Last time when packet with that CSN was sent */ | |
c3226991 OZ |
187 | #endif |
188 | ||
2e10a170 | 189 | ip_addr drip; /* Designated router */ |
aec76c6e | 190 | u32 drid; |
2e10a170 | 191 | ip_addr bdrip; /* Backup DR */ |
aec76c6e | 192 | u32 bdrid; |
c3226991 OZ |
193 | |
194 | #ifdef OSPFv3 | |
195 | u32 dr_iface_id; /* if drid is valid, this is iface_id of DR (for connecting network) */ | |
196 | u8 instance_id; /* Used to differentiate between more OSPF | |
197 | instances on one interface */ | |
198 | #endif | |
199 | ||
2e10a170 | 200 | u8 type; /* OSPF view of type */ |
96f1b8ba | 201 | #define OSPF_IT_BCAST 0 |
4c630a6d OF |
202 | #define OSPF_IT_NBMA 1 |
203 | #define OSPF_IT_PTP 2 | |
96f1b8ba | 204 | #define OSPF_IT_VLINK 3 |
aaaff776 | 205 | #define OSPF_IT_UNDEF 4 |
2e10a170 OF |
206 | u8 strictnbma; /* Can I talk with unknown neighbors? */ |
207 | u8 stub; /* Inactive interface */ | |
2e10a170 | 208 | u8 state; /* Interface state machine */ |
96f1b8ba OF |
209 | #define OSPF_IS_DOWN 0 /* Not working */ |
210 | #define OSPF_IS_LOOP 1 /* Should never happen */ | |
211 | #define OSPF_IS_WAITING 2 /* Waiting for Wait timer */ | |
212 | #define OSPF_IS_PTP 3 /* PTP operational */ | |
213 | #define OSPF_IS_DROTHER 4 /* I'm on BCAST or NBMA and I'm not DR */ | |
214 | #define OSPF_IS_BACKUP 5 /* I'm BDR */ | |
215 | #define OSPF_IS_DR 6 /* I'm DR */ | |
65112dd2 OF |
216 | timer *wait_timer; /* WAIT timer */ |
217 | timer *hello_timer; /* HELLOINT timer */ | |
a190e720 | 218 | timer *poll_timer; /* Poll Interval - for NBMA */ |
5b1a92e6 OF |
219 | /* Default values for interface parameters */ |
220 | #define COST_D 10 | |
221 | #define RXMTINT_D 5 | |
249fdef7 | 222 | #define INFTRANSDELAY_D 1 |
4c630a6d | 223 | #define PRIORITY_D 1 |
5b1a92e6 | 224 | #define HELLOINT_D 10 |
a190e720 | 225 | #define POLLINT_D 20 |
35ff423d | 226 | #define DEADC_D 4 |
c3226991 OZ |
227 | #define WAIT_DMH 4 |
228 | /* Value of Wait timer - not found it in RFC * - using 4*HELLO */ | |
229 | ||
230 | struct top_hash_entry *net_lsa; /* Originated network LSA */ | |
231 | int orignet; /* Schedule network LSA origination */ | |
232 | #ifdef OSPFv3 | |
c3226991 | 233 | int origlink; /* Schedule link LSA origination */ |
be862406 | 234 | struct top_hash_entry *link_lsa; /* Originated link LSA */ |
c3226991 OZ |
235 | struct top_hash_entry *pxn_lsa; /* Originated prefix LSA */ |
236 | #endif | |
237 | int fadj; /* Number of full adjacent neigh */ | |
e5b5d18c | 238 | list nbma_list; |
353729f5 | 239 | u8 priority; /* A router priority for DR election */ |
621ccdfe | 240 | u8 ioprob; |
0aad2b92 OZ |
241 | #define OSPF_I_OK 0 /* Everything OK */ |
242 | #define OSPF_I_SK 1 /* Socket open failed */ | |
243 | #define OSPF_I_LL 2 /* Missing link-local address (OSPFv3) */ | |
353729f5 OZ |
244 | u8 sk_spf; /* Socket is a member of SPFRouters group */ |
245 | u8 sk_dr; /* Socket is a member of DRouters group */ | |
94c42054 | 246 | u32 rxbuf; |
5b1a92e6 OF |
247 | }; |
248 | ||
3e2bd0f1 OF |
249 | struct ospf_md5 |
250 | { | |
251 | u16 zero; | |
252 | u8 keyid; | |
253 | u8 len; | |
254 | u32 csn; | |
255 | }; | |
256 | ||
257 | union ospf_auth | |
258 | { | |
259 | u8 password[8]; | |
260 | struct ospf_md5 md5; | |
261 | }; | |
262 | ||
c3226991 OZ |
263 | |
264 | /* Packet types */ | |
2e10a170 OF |
265 | #define HELLO_P 1 /* Hello */ |
266 | #define DBDES_P 2 /* Database description */ | |
267 | #define LSREQ_P 3 /* Link state request */ | |
268 | #define LSUPD_P 4 /* Link state update */ | |
269 | #define LSACK_P 5 /* Link state acknowledgement */ | |
c3226991 OZ |
270 | |
271 | /* Area IDs */ | |
2c971094 | 272 | #define BACKBONE 0 |
296ecb56 | 273 | |
296ecb56 | 274 | |
2e10a170 OF |
275 | struct immsb |
276 | { | |
b082c1bf | 277 | #ifdef CPU_BIG_ENDIAN |
c11007bc OF |
278 | u8 padding:5; |
279 | u8 i:1; | |
280 | u8 m:1; | |
281 | u8 ms:1; | |
282 | #else | |
04c6319a OF |
283 | u8 ms:1; |
284 | u8 m:1; | |
285 | u8 i:1; | |
286 | u8 padding:5; | |
c11007bc | 287 | #endif |
04c6319a OF |
288 | }; |
289 | ||
2e10a170 OF |
290 | union imms |
291 | { | |
04c6319a OF |
292 | u8 byte; |
293 | struct immsb bit; | |
294 | }; | |
2c1d1cc7 OF |
295 | #define DBDES_MS 1 |
296 | #define DBDES_M 2 | |
297 | #define DBDES_I 4 | |
c3226991 OZ |
298 | |
299 | ||
300 | #ifdef OSPFv2 | |
301 | ||
302 | struct ospf_packet | |
303 | { | |
304 | u8 version; | |
305 | u8 type; | |
306 | u16 length; | |
307 | u32 routerid; | |
308 | u32 areaid; | |
309 | u16 checksum; | |
310 | u16 autype; | |
311 | union ospf_auth u; | |
312 | }; | |
313 | ||
314 | ||
315 | #else /* OSPFv3 packet descriptions */ | |
316 | ||
317 | struct ospf_packet | |
318 | { | |
319 | u8 version; | |
320 | u8 type; | |
321 | u16 length; | |
322 | u32 routerid; | |
323 | u32 areaid; | |
324 | u16 checksum; | |
325 | u8 instance_id; | |
326 | u8 zero; | |
1af66415 OF |
327 | }; |
328 | ||
ce17d4c1 | 329 | |
c3226991 OZ |
330 | #endif |
331 | ||
332 | ||
333 | ||
334 | ||
2e10a170 OF |
335 | struct ospf_lsa_header |
336 | { | |
337 | u16 age; /* LS Age */ | |
338 | #define LSA_MAXAGE 3600 /* 1 hour */ | |
339 | #define LSA_CHECKAGE 300 /* 5 minutes */ | |
340 | #define LSA_MAXAGEDIFF 900 /* 15 minutes */ | |
c3226991 OZ |
341 | |
342 | #ifdef OSPFv2 | |
2c1d1cc7 | 343 | u8 options; |
ce17d4c1 | 344 | u8 type; |
c3226991 OZ |
345 | |
346 | #define LSA_T_RT 1 | |
347 | #define LSA_T_NET 2 | |
348 | #define LSA_T_SUM_NET 3 | |
349 | #define LSA_T_SUM_RT 4 | |
350 | #define LSA_T_EXT 5 | |
351 | ||
98899244 OZ |
352 | #define LSA_SCOPE_AREA 0x2000 |
353 | #define LSA_SCOPE_AS 0x4000 | |
354 | ||
355 | #define LSA_SCOPE(lsa) (((lsa)->type == LSA_T_EXT) ? LSA_SCOPE_AS : LSA_SCOPE_AREA) | |
356 | ||
c3226991 OZ |
357 | #else /* OSPFv3 */ |
358 | u16 type; | |
359 | ||
360 | #define LSA_T_RT 0x2001 | |
361 | #define LSA_T_NET 0x2002 | |
362 | #define LSA_T_SUM_NET 0x2003 | |
363 | #define LSA_T_SUM_RT 0x2004 | |
364 | #define LSA_T_EXT 0x4005 | |
365 | #define LSA_T_LINK 0x0008 | |
366 | #define LSA_T_PREFIX 0x2009 | |
367 | ||
368 | #define LSA_UBIT 0x8000 | |
369 | ||
370 | #define LSA_SCOPE_LINK 0x0000 | |
371 | #define LSA_SCOPE_AREA 0x2000 | |
372 | #define LSA_SCOPE_AS 0x4000 | |
373 | #define LSA_SCOPE_RES 0x6000 | |
374 | #define LSA_SCOPE_MASK 0x6000 | |
375 | ||
376 | #define LSA_SCOPE(lsa) ((lsa)->type & LSA_SCOPE_MASK) | |
377 | #endif | |
378 | ||
ce17d4c1 | 379 | u32 id; |
2e10a170 OF |
380 | u32 rt; /* Advertising router */ |
381 | s32 sn; /* LS Sequence number */ | |
b49e6f5a OZ |
382 | #define LSA_INITSEQNO ((s32) 0x80000001) |
383 | #define LSA_MAXSEQNO ((s32) 0x7fffffff) | |
2c1d1cc7 | 384 | u16 checksum; |
2e10a170 | 385 | u16 length; |
ce17d4c1 OF |
386 | }; |
387 | ||
fdb19982 | 388 | |
c3226991 OZ |
389 | #define LSART_PTP 1 |
390 | #define LSART_NET 2 | |
391 | #define LSART_STUB 3 | |
392 | #define LSART_VLNK 4 | |
393 | ||
394 | ||
395 | #ifdef OSPFv2 | |
fdb19982 | 396 | |
2e10a170 OF |
397 | struct ospf_lsa_rt |
398 | { | |
c15e5690 | 399 | #ifdef CPU_BIG_ENDIAN |
c3226991 | 400 | u16 options; /* VEB flags only */ |
ce17d4c1 | 401 | u16 links; |
c15e5690 OZ |
402 | #else |
403 | u16 links; | |
404 | u16 options; /* VEB flags only */ | |
405 | #endif | |
ce17d4c1 OF |
406 | }; |
407 | ||
2e10a170 OF |
408 | struct ospf_lsa_rt_link |
409 | { | |
ce17d4c1 OF |
410 | u32 id; |
411 | u32 data; | |
c15e5690 | 412 | #ifdef CPU_BIG_ENDIAN |
ce17d4c1 | 413 | u8 type; |
c15e5690 | 414 | u8 padding; |
ce17d4c1 | 415 | u16 metric; |
c15e5690 OZ |
416 | #else |
417 | u16 metric; | |
418 | u8 padding; | |
419 | u8 type; | |
420 | #endif | |
ce17d4c1 OF |
421 | }; |
422 | ||
c3226991 OZ |
423 | struct ospf_lsa_net |
424 | { | |
425 | ip_addr netmask; | |
426 | u32 routers[]; | |
427 | }; | |
428 | ||
429 | struct ospf_lsa_sum | |
430 | { | |
431 | ip_addr netmask; | |
432 | u32 metric; | |
433 | }; | |
434 | ||
435 | struct ospf_lsa_ext | |
436 | { | |
437 | ip_addr netmask; | |
438 | u32 metric; | |
439 | ip_addr fwaddr; | |
440 | u32 tag; | |
441 | }; | |
442 | ||
a6bc04d5 OZ |
443 | #define LSA_SUM_TOS 0xFF000000 |
444 | #define LSA_EXT_TOS 0x7F000000 | |
c3226991 OZ |
445 | #define LSA_EXT_EBIT 0x80000000 |
446 | ||
061ab802 OZ |
447 | /* Endianity swap for lsa->type */ |
448 | #define ntoht(x) x | |
449 | #define htont(x) x | |
450 | ||
c3226991 OZ |
451 | |
452 | #else /* OSPFv3 */ | |
453 | ||
454 | struct ospf_lsa_rt | |
455 | { | |
456 | u32 options; | |
457 | }; | |
458 | ||
459 | struct ospf_lsa_rt_link | |
460 | { | |
c15e5690 | 461 | #ifdef CPU_BIG_ENDIAN |
c3226991 | 462 | u8 type; |
ce17d4c1 OF |
463 | u8 padding; |
464 | u16 metric; | |
c15e5690 OZ |
465 | #else |
466 | u16 metric; | |
467 | u8 padding; | |
468 | u8 type; | |
469 | #endif | |
c3226991 OZ |
470 | u32 lif; /* Local interface ID */ |
471 | u32 nif; /* Neighbor interface ID */ | |
472 | u32 id; /* Neighbor router ID */ | |
2c1d1cc7 OF |
473 | }; |
474 | ||
2e10a170 OF |
475 | struct ospf_lsa_net |
476 | { | |
c3226991 OZ |
477 | u32 options; |
478 | u32 routers[]; | |
dfa9a53a OF |
479 | }; |
480 | ||
c3226991 | 481 | struct ospf_lsa_sum_net |
2e10a170 | 482 | { |
c3226991 OZ |
483 | u32 metric; |
484 | u32 prefix[]; | |
ce17d4c1 OF |
485 | }; |
486 | ||
c3226991 OZ |
487 | struct ospf_lsa_sum_rt |
488 | { | |
489 | u32 options; | |
490 | u32 metric; | |
491 | u32 drid; | |
492 | }; | |
98ac6176 OF |
493 | |
494 | struct ospf_lsa_ext | |
2e10a170 | 495 | { |
c3226991 OZ |
496 | u32 metric; |
497 | u32 rest[]; | |
498 | }; | |
499 | ||
500 | struct ospf_lsa_link | |
501 | { | |
502 | u32 options; | |
503 | ip_addr lladdr; | |
504 | u32 pxcount; | |
505 | u32 rest[]; | |
506 | }; | |
507 | ||
508 | struct ospf_lsa_prefix | |
509 | { | |
c15e5690 | 510 | #ifdef CPU_BIG_ENDIAN |
c3226991 OZ |
511 | u16 pxcount; |
512 | u16 ref_type; | |
c15e5690 OZ |
513 | #else |
514 | u16 ref_type; | |
515 | u16 pxcount; | |
516 | #endif | |
c3226991 OZ |
517 | u32 ref_id; |
518 | u32 ref_rt; | |
519 | u32 rest[]; | |
98ac6176 OF |
520 | }; |
521 | ||
c3226991 OZ |
522 | #define LSA_EXT_EBIT 0x4000000 |
523 | #define LSA_EXT_FBIT 0x2000000 | |
524 | #define LSA_EXT_TBIT 0x1000000 | |
525 | ||
061ab802 OZ |
526 | /* Endianity swap for lsa->type */ |
527 | #define ntoht(x) ntohs(x) | |
528 | #define htont(x) htons(x) | |
529 | ||
c3226991 OZ |
530 | #endif |
531 | ||
532 | #define METRIC_MASK 0x00FFFFFF | |
533 | #define OPTIONS_MASK 0x00FFFFFF | |
534 | ||
b66abe8e OZ |
535 | static inline unsigned |
536 | lsa_rt_count(struct ospf_lsa_header *lsa) | |
c3226991 OZ |
537 | { |
538 | return (lsa->length - sizeof(struct ospf_lsa_header) - sizeof(struct ospf_lsa_rt)) | |
539 | / sizeof(struct ospf_lsa_rt_link); | |
540 | } | |
541 | ||
b66abe8e OZ |
542 | static inline unsigned |
543 | lsa_net_count(struct ospf_lsa_header *lsa) | |
c3226991 OZ |
544 | { |
545 | return (lsa->length - sizeof(struct ospf_lsa_header) - sizeof(struct ospf_lsa_net)) | |
546 | / sizeof(u32); | |
547 | } | |
548 | ||
549 | ||
b66abe8e OZ |
550 | #ifdef OSPFv3 |
551 | ||
a6bc04d5 OZ |
552 | #define IPV6_PREFIX_SPACE(x) ((((x) + 63) / 32) * 4) |
553 | #define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32) | |
554 | ||
b66abe8e OZ |
555 | static inline u32 * |
556 | lsa_get_ipv6_prefix(u32 *buf, ip_addr *addr, int *pxlen, u8 *pxopts, u16 *rest) | |
557 | { | |
558 | u8 pxl = (*buf >> 24); | |
559 | *pxopts = (*buf >> 16); | |
560 | *rest = *buf; | |
561 | *pxlen = pxl; | |
562 | buf++; | |
563 | ||
564 | *addr = IPA_NONE; | |
565 | ||
566 | if (pxl > 0) | |
567 | _I0(*addr) = *buf++; | |
568 | if (pxl > 32) | |
569 | _I1(*addr) = *buf++; | |
570 | if (pxl > 64) | |
571 | _I2(*addr) = *buf++; | |
572 | if (pxl > 96) | |
573 | _I3(*addr) = *buf++; | |
574 | ||
575 | return buf; | |
576 | } | |
577 | ||
578 | static inline u32 * | |
579 | lsa_get_ipv6_addr(u32 *buf, ip_addr *addr) | |
580 | { | |
581 | *addr = *(ip_addr *) buf; | |
582 | return buf + 4; | |
583 | } | |
584 | ||
a6bc04d5 OZ |
585 | static inline u32 * |
586 | put_ipv6_prefix(u32 *buf, ip_addr addr, u8 pxlen, u8 pxopts, u16 lh) | |
587 | { | |
588 | *buf++ = ((pxlen << 24) | (pxopts << 16) | lh); | |
589 | ||
590 | if (pxlen > 0) | |
591 | *buf++ = _I0(addr); | |
592 | if (pxlen > 32) | |
593 | *buf++ = _I1(addr); | |
594 | if (pxlen > 64) | |
595 | *buf++ = _I2(addr); | |
596 | if (pxlen > 96) | |
597 | *buf++ = _I3(addr); | |
598 | return buf; | |
599 | } | |
600 | ||
601 | static inline u32 * | |
602 | put_ipv6_addr(u32 *buf, ip_addr addr) | |
603 | { | |
604 | *(ip_addr *) buf = addr; | |
605 | return buf + 4; | |
606 | } | |
607 | ||
b66abe8e OZ |
608 | #endif |
609 | ||
610 | ||
611 | ||
2e10a170 OF |
612 | struct ospf_lsreq_header |
613 | { | |
c3226991 | 614 | u32 type; |
6d2b3211 | 615 | u32 id; |
2e10a170 | 616 | u32 rt; /* Advertising router */ |
6d2b3211 OF |
617 | }; |
618 | ||
2e10a170 OF |
619 | struct l_lsr_head |
620 | { | |
f45fd316 OF |
621 | node n; |
622 | struct ospf_lsreq_header lsh; | |
623 | }; | |
624 | ||
de769e24 | 625 | |
c76674f0 OF |
626 | struct ospf_neighbor |
627 | { | |
e83dc0d7 | 628 | node n; |
035f6acb | 629 | pool *pool; |
903a3f39 | 630 | struct ospf_iface *ifa; |
2c1d1cc7 | 631 | u8 state; |
c76674f0 | 632 | #define NEIGHBOR_DOWN 0 |
cd70d934 OF |
633 | #define NEIGHBOR_ATTEMPT 1 |
634 | #define NEIGHBOR_INIT 2 | |
635 | #define NEIGHBOR_2WAY 3 | |
c76674f0 | 636 | #define NEIGHBOR_EXSTART 4 |
903a3f39 OF |
637 | #define NEIGHBOR_EXCHANGE 5 |
638 | #define NEIGHBOR_LOADING 6 | |
639 | #define NEIGHBOR_FULL 7 | |
2e10a170 | 640 | timer *inactim; /* Inactivity timer */ |
04c6319a | 641 | union imms imms; /* I, M, Master/slave received */ |
2e10a170 OF |
642 | u32 dds; /* DD Sequence number being sent */ |
643 | u32 ddr; /* last Dat Des packet received */ | |
04c6319a | 644 | union imms myimms; /* I, M Master/slave */ |
2e10a170 OF |
645 | u32 rid; /* Router ID */ |
646 | ip_addr ip; /* IP of it's interface */ | |
647 | u8 priority; /* Priority */ | |
2e10a170 | 648 | u8 adj; /* built adjacency? */ |
c3226991 OZ |
649 | u32 options; /* Options received */ |
650 | ||
651 | /* dr and bdr store IP address in OSPFv2 and router ID in OSPFv3, | |
652 | we use the same type to simplify handling */ | |
653 | u32 dr; /* Neigbour's idea of DR */ | |
654 | u32 bdr; /* Neigbour's idea of BDR */ | |
655 | ||
656 | #ifdef OSPFv3 | |
657 | u32 iface_id; /* ID of Neighbour's iface connected to common network */ | |
658 | #endif | |
659 | ||
2e10a170 OF |
660 | siterator dbsi; /* Database summary list iterator */ |
661 | slist lsrql; /* Link state request */ | |
662 | struct top_graph *lsrqh; /* LSA graph */ | |
30147b89 | 663 | siterator lsrqi; |
2e10a170 | 664 | slist lsrtl; /* Link state retransmission list */ |
30147b89 | 665 | siterator lsrti; |
921a93f2 | 666 | struct top_graph *lsrth; |
2e10a170 OF |
667 | void *ldbdes; /* Last database description packet */ |
668 | timer *rxmt_timer; /* RXMT timer */ | |
c76ba51a OF |
669 | list ackl[2]; |
670 | #define ACKL_DIRECT 0 | |
671 | #define ACKL_DELAY 1 | |
2e10a170 | 672 | timer *ackd_timer; /* Delayed ack timer */ |
3e2bd0f1 | 673 | u32 csn; /* Last received crypt seq number (for MD5) */ |
c76674f0 OF |
674 | }; |
675 | ||
96f1b8ba | 676 | /* Definitions for interface state machine */ |
2e10a170 OF |
677 | #define ISM_UP 0 /* Interface Up */ |
678 | #define ISM_WAITF 1 /* Wait timer fired */ | |
679 | #define ISM_BACKS 2 /* Backup seen */ | |
680 | #define ISM_NEICH 3 /* Neighbor change */ | |
353729f5 OZ |
681 | // #define ISM_LOOP 4 /* Loop indicated */ |
682 | // #define ISM_UNLOOP 5 /* Unloop indicated */ | |
2e10a170 | 683 | #define ISM_DOWN 6 /* Interface down */ |
96f1b8ba OF |
684 | |
685 | /* Definitions for neighbor state machine */ | |
2e10a170 OF |
686 | #define INM_HELLOREC 0 /* Hello Received */ |
687 | #define INM_START 1 /* Neighbor start - for NBMA */ | |
688 | #define INM_2WAYREC 2 /* 2-Way received */ | |
689 | #define INM_NEGDONE 3 /* Negotiation done */ | |
690 | #define INM_EXDONE 4 /* Exchange done */ | |
691 | #define INM_BADLSREQ 5 /* Bad LS Request */ | |
692 | #define INM_LOADDONE 6 /* Load done */ | |
693 | #define INM_ADJOK 7 /* AdjOK? */ | |
694 | #define INM_SEQMIS 8 /* Sequence number mismatch */ | |
695 | #define INM_1WAYREC 9 /* 1-Way */ | |
696 | #define INM_KILLNBR 10 /* Kill Neighbor */ | |
697 | #define INM_INACTTIM 11 /* Inactivity timer */ | |
698 | #define INM_LLDOWN 12 /* Line down */ | |
699 | ||
700 | struct ospf_area | |
701 | { | |
8496b2e4 | 702 | node n; |
15087574 | 703 | u32 areaid; |
38675202 | 704 | struct ospf_area_config *ac; /* Related area config */ |
70a38319 | 705 | int origrt; /* Rt lsa origination scheduled? */ |
de30342f | 706 | struct top_hash_entry *rt; /* My own router LSA */ |
c3226991 | 707 | struct top_hash_entry *pxr_lsa; /* Originated prefix LSA */ |
dfa9a53a | 708 | list cand; /* List of candidates for RT calc. */ |
98ac6176 | 709 | struct fib net_fib; /* Networks to advertise or not */ |
e81b440f | 710 | unsigned stub; |
b36a0a79 | 711 | int trcap; /* Transit capability? */ |
c3226991 | 712 | u32 options; /* Optional features */ |
c45f48fb | 713 | struct proto_ospf *po; |
98ac6176 | 714 | struct fib rtr; /* Routing tables for routers */ |
15087574 OF |
715 | }; |
716 | ||
2e10a170 OF |
717 | struct proto_ospf |
718 | { | |
4364b47e | 719 | struct proto proto; |
b8f17cf1 OF |
720 | timer *disp_timer; /* OSPF proto dispatcher */ |
721 | unsigned tick; | |
86c84d76 OF |
722 | struct top_graph *gr; /* LSA graph */ |
723 | slist lsal; /* List of all LSA's */ | |
f7574707 OZ |
724 | int calcrt; /* Routing table calculation scheduled? |
725 | 0=no, 1=normal, 2=forced reload */ | |
4364b47e | 726 | list iface_list; /* Interfaces we really use */ |
8496b2e4 | 727 | list area_list; |
15087574 | 728 | int areano; /* Number of area I belong to */ |
98ac6176 | 729 | struct fib rtf; /* Routing table */ |
fdb19982 OF |
730 | int rfc1583; /* RFC1583 compatibility */ |
731 | int ebit; /* Did I originate any ext lsa? */ | |
98ac6176 | 732 | struct ospf_area *backbone; /* If exists */ |
3d15dcdb OZ |
733 | void *lsab; /* LSA buffer used when originating router LSAs */ |
734 | int lsab_size, lsab_used; | |
8a70a13e | 735 | u32 router_id; |
6ba36f06 MM |
736 | }; |
737 | ||
2e10a170 OF |
738 | struct ospf_iface_patt |
739 | { | |
89d6782d | 740 | struct iface_patt i; |
7df86c25 OF |
741 | u32 cost; |
742 | u32 helloint; | |
743 | u32 rxmtint; | |
744 | u32 pollint; | |
745 | u32 inftransdelay; | |
746 | u32 priority; | |
747 | u32 waitint; | |
748 | u32 deadc; | |
d8c7d9e8 | 749 | u32 dead; |
7df86c25 | 750 | u32 type; |
7df86c25 OF |
751 | u32 strictnbma; |
752 | u32 stub; | |
98ac6176 | 753 | u32 vid; |
94c42054 OF |
754 | u32 rxbuf; |
755 | #define OSPF_RXBUF_NORMAL 0 | |
756 | #define OSPF_RXBUF_LARGE 1 | |
757 | #define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ | |
e5b5d18c | 758 | list nbma_list; |
c3226991 OZ |
759 | |
760 | u32 autype; /* Not really used in OSPFv3 */ | |
761 | #define OSPF_AUTH_NONE 0 | |
762 | #define OSPF_AUTH_SIMPLE 1 | |
763 | #define OSPF_AUTH_CRYPT 2 | |
764 | #define OSPF_AUTH_CRYPT_SIZE 16 | |
765 | ||
766 | #ifdef OSPFv2 | |
767 | list *passwords; | |
768 | #endif | |
769 | ||
770 | #ifdef OSPFv3 | |
771 | u8 instance_id; | |
772 | #endif | |
89d6782d OF |
773 | }; |
774 | ||
af157fa3 OZ |
775 | #if defined(OSPFv2) && !defined(CONFIG_MC_PROPER_SRC) |
776 | static inline int | |
777 | ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr) | |
778 | { | |
779 | /* | |
780 | * We cannot properly support multiple OSPF ifaces on real iface | |
781 | * with multiple prefixes, therefore we force OSPF ifaces with | |
782 | * non-primary IP prefixes to be stub. | |
783 | */ | |
784 | return ip->stub || !(addr->flags & IA_PRIMARY); | |
785 | } | |
786 | #else | |
787 | static inline int | |
788 | ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr UNUSED) | |
789 | { | |
790 | return ip->stub; | |
791 | } | |
792 | #endif | |
793 | ||
b8f17cf1 | 794 | int ospf_import_control(struct proto *p, rte **new, ea_list **attrs, |
2e10a170 | 795 | struct linpool *pool); |
5919c66e MM |
796 | struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool); |
797 | void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs); | |
70a38319 | 798 | void schedule_rt_lsa(struct ospf_area *oa); |
b8f17cf1 | 799 | void schedule_rtcalc(struct proto_ospf *po); |
b9ed99f7 | 800 | void schedule_net_lsa(struct ospf_iface *ifa); |
be862406 OZ |
801 | |
802 | #ifdef OSPFv3 | |
803 | void schedule_link_lsa(struct ospf_iface *ifa); | |
804 | #else | |
e81b440f | 805 | static inline void schedule_link_lsa(struct ospf_iface *ifa UNUSED) {} |
be862406 OZ |
806 | #endif |
807 | ||
c4f0f014 | 808 | void ospf_sh_neigh(struct proto *p, char *iff); |
4ab4e977 | 809 | void ospf_sh(struct proto *p); |
c4f0f014 | 810 | void ospf_sh_iface(struct proto *p, char *iff); |
0ea8fb4a | 811 | void ospf_sh_state(struct proto *p, int verbose, int reachable); |
e81b440f | 812 | void ospf_sh_lsadb(struct proto *p); |
05198c12 | 813 | |
4364b47e | 814 | |
5919c66e MM |
815 | #define EA_OSPF_METRIC1 EA_CODE(EAP_OSPF, 0) |
816 | #define EA_OSPF_METRIC2 EA_CODE(EAP_OSPF, 1) | |
817 | #define EA_OSPF_TAG EA_CODE(EAP_OSPF, 2) | |
c27b2449 | 818 | #define EA_OSPF_ROUTER_ID EA_CODE(EAP_OSPF, 3) |
5919c66e | 819 | |
98ac6176 | 820 | #include "proto/ospf/rt.h" |
4364b47e OF |
821 | #include "proto/ospf/hello.h" |
822 | #include "proto/ospf/packet.h" | |
823 | #include "proto/ospf/iface.h" | |
824 | #include "proto/ospf/neighbor.h" | |
825 | #include "proto/ospf/topology.h" | |
826 | #include "proto/ospf/dbdes.h" | |
6d2b3211 | 827 | #include "proto/ospf/lsreq.h" |
f45fd316 OF |
828 | #include "proto/ospf/lsupd.h" |
829 | #include "proto/ospf/lsack.h" | |
830 | #include "proto/ospf/lsalib.h" | |
6ba36f06 | 831 | |
c1f8dc91 | 832 | #endif /* _BIRD_OSPF_H_ */ |