iof-bird-daemon / proto / ospf / ospf.h @ a7a7372a
History | View | Annotate | Download (26.6 KB)
1 |
/*
|
---|---|
2 |
* BIRD -- OSPF
|
3 |
*
|
4 |
* (c) 1999--2005 Ondrej Filip <feela@network.cz>
|
5 |
* (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
|
6 |
* (c) 2009--2014 CZ.NIC z.s.p.o.
|
7 |
*
|
8 |
* Can be freely distributed and used under the terms of the GNU GPL.
|
9 |
*/
|
10 |
|
11 |
#ifndef _BIRD_OSPF_H_
|
12 |
#define _BIRD_OSPF_H_
|
13 |
|
14 |
#include "nest/bird.h" |
15 |
|
16 |
#include "lib/checksum.h" |
17 |
#include "lib/ip.h" |
18 |
#include "lib/lists.h" |
19 |
#include "lib/slists.h" |
20 |
#include "lib/socket.h" |
21 |
#include "lib/timer.h" |
22 |
#include "lib/resource.h" |
23 |
#include "nest/protocol.h" |
24 |
#include "nest/iface.h" |
25 |
#include "nest/route.h" |
26 |
#include "nest/cli.h" |
27 |
#include "nest/locks.h" |
28 |
#include "nest/bfd.h" |
29 |
#include "conf/conf.h" |
30 |
#include "lib/string.h" |
31 |
|
32 |
|
33 |
#ifdef LOCAL_DEBUG
|
34 |
#define OSPF_FORCE_DEBUG 1 |
35 |
#else
|
36 |
#define OSPF_FORCE_DEBUG 0 |
37 |
#endif
|
38 |
|
39 |
|
40 |
#define IP4_MIN_MTU 576 |
41 |
#define IP6_MIN_MTU 1280 |
42 |
|
43 |
#define IP4_OSPF_ALL_ROUTERS ipa_build4(224, 0, 0, 5) |
44 |
#define IP4_OSPF_DES_ROUTERS ipa_build4(224, 0, 0, 6) |
45 |
|
46 |
#define IP6_OSPF_ALL_ROUTERS ipa_build6(0xFF020000, 0, 0, 5) |
47 |
#define IP6_OSPF_DES_ROUTERS ipa_build6(0xFF020000, 0, 0, 6) |
48 |
|
49 |
#ifdef IPV6
|
50 |
#define ip4_addr u32
|
51 |
#define ip6_addr ip_addr
|
52 |
#define _MI6(x1,x2,x3,x4) _MI(x1, x2, x3, x4)
|
53 |
#define ipa_is_link_local(x) ipa_has_link_scope(x)
|
54 |
#define ipa_from_u32(x) _MI6(0,0,0xffff,x) |
55 |
#define ipa_to_u32(x) _I3(x)
|
56 |
#define ipa_build4(a,b,c,d) IPA_NONE
|
57 |
#define ipa_build6(a,b,c,d) _MI6(a,b,c,d)
|
58 |
#define OSPF_IS_V2 0 |
59 |
#else
|
60 |
#define ip4_addr u32
|
61 |
#define ip6_addr ip_addr
|
62 |
#define _I0(X) 0 |
63 |
#define _I1(X) 0 |
64 |
#define _I2(X) 0 |
65 |
#define _I3(X) 0 |
66 |
#define _MI6(x1,x2,x3,x4) IPA_NONE
|
67 |
#define ipa_is_link_local(x) 0 |
68 |
#define ipa_build4(a,b,c,d) _MI(((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) |
69 |
#define ipa_build6(a,b,c,d) IPA_NONE
|
70 |
#define OSPF_IS_V2 1 |
71 |
#endif
|
72 |
|
73 |
// FIXME: MAX_PREFIX_LENGTH
|
74 |
|
75 |
#define OSPF_TRACE(flags, msg, args...) \
|
76 |
do { if ((p->p.debug & flags) || OSPF_FORCE_DEBUG) \ |
77 |
log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0) |
78 |
|
79 |
#define OSPF_PACKET(dumpfn, buffer, msg, args...) \
|
80 |
do { if ((p->p.debug & D_PACKETS) || OSPF_FORCE_DEBUG) \ |
81 |
{ log(L_TRACE "%s: " msg, p->p.name, ## args ); dumpfn(p, buffer); } } while(0) |
82 |
|
83 |
|
84 |
#define OSPF_PROTO 89 |
85 |
|
86 |
#define LSREFRESHTIME 1800 /* 30 minutes */ |
87 |
#define MINLSINTERVAL 5 |
88 |
#define MINLSARRIVAL 1 |
89 |
#define LSINFINITY 0xffffff |
90 |
|
91 |
#define OSPF_DEFAULT_TICK 1 |
92 |
#define OSPF_DEFAULT_STUB_COST 1000 |
93 |
#define OSPF_DEFAULT_ECMP_LIMIT 16 |
94 |
#define OSPF_DEFAULT_TRANSINT 40 |
95 |
|
96 |
#define OSPF_MIN_PKT_SIZE 256 |
97 |
#define OSPF_MAX_PKT_SIZE 65535 |
98 |
|
99 |
#define OSPF_VLINK_ID_OFFSET 0x80000000 |
100 |
|
101 |
|
102 |
struct ospf_config
|
103 |
{ |
104 |
struct proto_config c;
|
105 |
uint tick; |
106 |
byte ospf2; |
107 |
byte rfc1583; |
108 |
byte stub_router; |
109 |
byte merge_external; |
110 |
byte abr; |
111 |
byte asbr; |
112 |
int ecmp;
|
113 |
list area_list; /* list of area configs (struct ospf_area_config) */
|
114 |
list vlink_list; /* list of configured vlinks (struct ospf_iface_patt) */
|
115 |
}; |
116 |
|
117 |
struct ospf_area_config
|
118 |
{ |
119 |
node n; |
120 |
u32 areaid; |
121 |
u32 default_cost; /* Cost of default route for stub areas
|
122 |
(With possible LSA_EXT3_EBIT for NSSA areas) */
|
123 |
u8 type; /* Area type (standard, stub, NSSA), represented
|
124 |
by option flags (OPT_E, OPT_N) */
|
125 |
u8 summary; /* Import summaries to this stub/NSSA area, valid for ABR */
|
126 |
u8 default_nssa; /* Generate default NSSA route for NSSA+summary area */
|
127 |
u8 translator; /* Translator role, for NSSA ABR */
|
128 |
u32 transint; /* Translator stability interval */
|
129 |
list patt_list; /* List of iface configs (struct ospf_iface_patt) */
|
130 |
list net_list; /* List of aggregate networks for that area */
|
131 |
list enet_list; /* List of aggregate external (NSSA) networks */
|
132 |
list stubnet_list; /* List of stub networks added to Router LSA */
|
133 |
}; |
134 |
|
135 |
struct area_net_config
|
136 |
{ |
137 |
node n; |
138 |
struct prefix px;
|
139 |
u32 tag; |
140 |
u8 hidden; |
141 |
}; |
142 |
|
143 |
struct area_net
|
144 |
{ |
145 |
struct fib_node fn;
|
146 |
u32 metric; /* With possible LSA_EXT3_EBIT for NSSA area nets */
|
147 |
u32 tag; |
148 |
u8 hidden; |
149 |
u8 active; |
150 |
}; |
151 |
|
152 |
struct ospf_stubnet_config
|
153 |
{ |
154 |
node n; |
155 |
struct prefix px;
|
156 |
u32 cost; |
157 |
u8 hidden; |
158 |
u8 summary; |
159 |
}; |
160 |
|
161 |
struct nbma_node
|
162 |
{ |
163 |
node n; |
164 |
ip_addr ip; |
165 |
byte eligible; |
166 |
byte found; |
167 |
}; |
168 |
|
169 |
struct ospf_iface_patt
|
170 |
{ |
171 |
struct iface_patt i;
|
172 |
u32 type; |
173 |
u32 stub; |
174 |
u32 cost; |
175 |
u32 helloint; |
176 |
u32 rxmtint; |
177 |
u32 pollint; |
178 |
u32 waitint; |
179 |
u32 deadc; |
180 |
u32 deadint; |
181 |
u32 inftransdelay; |
182 |
list nbma_list; |
183 |
u32 priority; |
184 |
u32 voa; |
185 |
u32 vid; |
186 |
int tx_tos;
|
187 |
int tx_priority;
|
188 |
u16 tx_length; |
189 |
u16 rx_buffer; |
190 |
|
191 |
#define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ |
192 |
u8 instance_id; |
193 |
u8 autype; /* Not really used in OSPFv3 */
|
194 |
#define OSPF_AUTH_NONE 0 |
195 |
#define OSPF_AUTH_SIMPLE 1 |
196 |
#define OSPF_AUTH_CRYPT 2 |
197 |
#define OSPF_AUTH_CRYPT_SIZE 16 |
198 |
u8 strictnbma; |
199 |
u8 check_link; |
200 |
u8 ecmp_weight; |
201 |
u8 link_lsa_suppression; |
202 |
u8 real_bcast; /* Not really used in OSPFv3 */
|
203 |
u8 ptp_netmask; /* bool + 2 for unspecified */
|
204 |
u8 ttl_security; /* bool + 2 for TX only */
|
205 |
u8 bfd; |
206 |
u8 bsd_secondary; |
207 |
list *passwords; |
208 |
}; |
209 |
|
210 |
/* Default values for interface parameters */
|
211 |
#define COST_D 10 |
212 |
#define RXMTINT_D 5 |
213 |
#define INFTRANSDELAY_D 1 |
214 |
#define PRIORITY_D 1 |
215 |
#define HELLOINT_D 10 |
216 |
#define POLLINT_D 20 |
217 |
#define DEADC_D 4 |
218 |
#define WAIT_DMH 4 |
219 |
/* Value of Wait timer - not found it in RFC * - using 4*HELLO */
|
220 |
|
221 |
|
222 |
|
223 |
struct ospf_proto
|
224 |
{ |
225 |
struct proto p;
|
226 |
timer *disp_timer; /* OSPF proto dispatcher */
|
227 |
uint tick; |
228 |
struct top_graph *gr; /* LSA graph */ |
229 |
slist lsal; /* List of all LSA's */
|
230 |
int calcrt; /* Routing table calculation scheduled? |
231 |
0=no, 1=normal, 2=forced reload */
|
232 |
list iface_list; /* List of OSPF interfaces (struct ospf_iface) */
|
233 |
list area_list; /* List of OSPF areas (struct ospf_area) */
|
234 |
int areano; /* Number of area I belong to */ |
235 |
int padj; /* Number of neighbors in Exchange or Loading state */ |
236 |
struct fib rtf; /* Routing table */ |
237 |
byte ospf2; /* OSPF v2 or v3 */
|
238 |
byte rfc1583; /* RFC1583 compatibility */
|
239 |
byte stub_router; /* Do not forward transit traffic */
|
240 |
byte merge_external; /* Should i merge external routes? */
|
241 |
byte asbr; /* May i originate any ext/NSSA lsa? */
|
242 |
byte ecmp; /* Maximal number of nexthops in ECMP route, or 0 */
|
243 |
struct ospf_area *backbone; /* If exists */ |
244 |
void *lsab; /* LSA buffer used when originating router LSAs */ |
245 |
int lsab_size, lsab_used;
|
246 |
linpool *nhpool; /* Linpool used for next hops computed in SPF */
|
247 |
sock *vlink_sk; /* IP socket used for vlink TX */
|
248 |
u32 router_id; |
249 |
u32 last_vlink_id; /* Interface IDs for vlinks (starts at 0x80000000) */
|
250 |
}; |
251 |
|
252 |
struct ospf_area
|
253 |
{ |
254 |
node n; |
255 |
u32 areaid; |
256 |
struct ospf_area_config *ac; /* Related area config */ |
257 |
struct top_hash_entry *rt; /* My own router LSA */ |
258 |
struct top_hash_entry *pxr_lsa; /* Originated prefix LSA */ |
259 |
list cand; /* List of candidates for RT calc. */
|
260 |
struct fib net_fib; /* Networks to advertise or not */ |
261 |
struct fib enet_fib; /* External networks for NSSAs */ |
262 |
u32 options; /* Optional features */
|
263 |
u8 update_rt_lsa; /* Rt lsa origination scheduled? */
|
264 |
u8 trcap; /* Transit capability? */
|
265 |
u8 marked; /* Used in OSPF reconfigure */
|
266 |
u8 translate; /* Translator state (TRANS_*), for NSSA ABR */
|
267 |
timer *translator_timer; /* For NSSA translator switch */
|
268 |
struct ospf_proto *po;
|
269 |
struct fib rtr; /* Routing tables for routers */ |
270 |
}; |
271 |
|
272 |
|
273 |
|
274 |
struct ospf_iface
|
275 |
{ |
276 |
node n; |
277 |
struct iface *iface; /* Nest's iface (NULL for vlinks) */ |
278 |
struct ifa *addr; /* IP prefix associated with that OSPF iface */ |
279 |
struct ospf_area *oa;
|
280 |
struct ospf_iface_patt *cf;
|
281 |
char *ifname; /* Interface name (iface->name), new one for vlinks */ |
282 |
|
283 |
pool *pool; |
284 |
sock *sk; /* IP socket */
|
285 |
list neigh_list; /* List of neigbours (struct ospf_neighbor) */
|
286 |
u32 cost; /* Cost of iface */
|
287 |
u32 waitint; /* number of sec before changing state from wait */
|
288 |
u32 rxmtint; /* number of seconds between LSA retransmissions */
|
289 |
u32 pollint; /* Poll interval */
|
290 |
u32 deadint; /* after "deadint" missing hellos is router dead */
|
291 |
u32 iface_id; /* Interface ID (iface->index or new value for vlinks) */
|
292 |
u32 vid; /* ID of peer of virtual link */
|
293 |
ip_addr vip; /* IP of peer of virtual link */
|
294 |
struct ospf_iface *vifa; /* OSPF iface which the vlink goes through */ |
295 |
struct ospf_area *voa; /* OSPF area which the vlink goes through */ |
296 |
u16 inftransdelay; /* The estimated number of seconds it takes to
|
297 |
transmit a Link State Update Packet over this
|
298 |
interface. LSAs contained in the update */
|
299 |
u16 helloint; /* number of seconds between hello sending */
|
300 |
list *passwords; |
301 |
u32 csn; /* Last used crypt seq number */
|
302 |
bird_clock_t csn_use; /* Last time when packet with that CSN was sent */
|
303 |
ip_addr all_routers; /* Multicast (or broadcast) address for all routers */
|
304 |
ip_addr des_routers; /* Multicast (or NULL) address for designated routers */
|
305 |
ip_addr drip; /* Designated router IP */
|
306 |
ip_addr bdrip; /* Backup DR IP */
|
307 |
u32 drid; /* DR Router ID */
|
308 |
u32 bdrid; /* BDR Router ID */
|
309 |
s16 rt_pos_beg; /* Position of iface in Router-LSA, begin, inclusive */
|
310 |
s16 rt_pos_end; /* Position of iface in Router-LSA, end, exclusive */
|
311 |
s16 px_pos_beg; /* Position of iface in Rt Prefix-LSA, begin, inclusive */
|
312 |
s16 px_pos_end; /* Position of iface in Rt Prefix-LSA, end, exclusive */
|
313 |
u32 dr_iface_id; /* if drid is valid, this is iface_id of DR (for connecting network) */
|
314 |
u8 instance_id; /* Used to differentiate between more OSPF
|
315 |
instances on one interface */
|
316 |
u8 autype; /* Authentication type (OSPF_AUTH_*) */
|
317 |
u8 type; /* OSPF view of type (OSPF_IT_*) */
|
318 |
u8 strictnbma; /* Can I talk with unknown neighbors? */
|
319 |
u8 stub; /* Inactive interface */
|
320 |
u8 state; /* Interface state machine (OSPF_IS_*) */
|
321 |
timer *wait_timer; /* WAIT timer */
|
322 |
timer *hello_timer; /* HELLOINT timer */
|
323 |
timer *poll_timer; /* Poll Interval - for NBMA */
|
324 |
|
325 |
struct top_hash_entry *link_lsa; /* Originated link LSA */ |
326 |
struct top_hash_entry *net_lsa; /* Originated network LSA */ |
327 |
struct top_hash_entry *pxn_lsa; /* Originated prefix LSA */ |
328 |
u8 update_link_lsa; |
329 |
u8 update_net_lsa; |
330 |
int fadj; /* Number of fully adjacent neighbors */ |
331 |
list nbma_list; |
332 |
u8 priority; /* A router priority for DR election */
|
333 |
u8 ioprob; |
334 |
#define OSPF_I_OK 0 /* Everything OK */ |
335 |
#define OSPF_I_SK 1 /* Socket open failed */ |
336 |
#define OSPF_I_LL 2 /* Missing link-local address (OSPFv3) */ |
337 |
u8 sk_dr; /* Socket is a member of designated routers group */
|
338 |
u8 marked; /* Used in OSPF reconfigure, 2 for force restart */
|
339 |
u16 rxbuf; /* Buffer size */
|
340 |
u16 tx_length; /* Soft TX packet length limit, usually MTU */
|
341 |
u8 check_link; /* Whether iface link change is used */
|
342 |
u8 ecmp_weight; /* Weight used for ECMP */
|
343 |
u8 link_lsa_suppression; /* Suppression of Link-LSA origination */
|
344 |
u8 ptp_netmask; /* Send real netmask for P2P */
|
345 |
u8 check_ttl; /* Check incoming packets for TTL 255 */
|
346 |
u8 bfd; /* Use BFD on iface */
|
347 |
}; |
348 |
|
349 |
struct ospf_neighbor
|
350 |
{ |
351 |
node n; |
352 |
pool *pool; |
353 |
struct ospf_iface *ifa;
|
354 |
u8 state; |
355 |
timer *inactim; /* Inactivity timer */
|
356 |
u8 imms; /* I, M, Master/slave received */
|
357 |
u8 myimms; /* I, M Master/slave */
|
358 |
u32 dds; /* DD Sequence number being sent */
|
359 |
u32 ddr; /* last Dat Des packet received */
|
360 |
|
361 |
u32 rid; /* Router ID */
|
362 |
ip_addr ip; /* IP of it's interface */
|
363 |
u8 priority; /* Priority */
|
364 |
u8 adj; /* built adjacency? */
|
365 |
u8 want_lsreq; /* Set to 1 when lsrql was shortened during LSUPD */
|
366 |
u32 options; /* Options received */
|
367 |
|
368 |
/* Entries dr and bdr store IP addresses in OSPFv2 and router IDs in
|
369 |
OSPFv3, we use the same type to simplify handling */
|
370 |
u32 dr; /* Neigbour's idea of DR */
|
371 |
u32 bdr; /* Neigbour's idea of BDR */
|
372 |
u32 iface_id; /* ID of Neighbour's iface connected to common network */
|
373 |
|
374 |
/* Database summary list iterator, controls initial dbdes exchange.
|
375 |
* Advances in the LSA list as dbdes packets are sent.
|
376 |
*/
|
377 |
siterator dbsi; /* iterator of po->lsal */
|
378 |
|
379 |
/* Link state request list, controls initial LSA exchange.
|
380 |
* Entries added when received in dbdes packets, removed as sent in lsreq packets.
|
381 |
*/
|
382 |
slist lsrql; /* slist of struct top_hash_entry from n->lsrqh */
|
383 |
struct top_graph *lsrqh;
|
384 |
|
385 |
/* Link state retransmission list, controls LSA retransmission during flood.
|
386 |
* Entries added as sent in lsupd packets, removed when received in lsack packets.
|
387 |
* These entries hold ret_count in appropriate LSA entries.
|
388 |
*/
|
389 |
slist lsrtl; /* slist of struct top_hash_entry from n->lsrth */
|
390 |
struct top_graph *lsrth;
|
391 |
timer *rxmt_timer; /* RXMT timer */
|
392 |
list ackl[2];
|
393 |
#define ACKL_DIRECT 0 |
394 |
#define ACKL_DELAY 1 |
395 |
timer *ackd_timer; /* Delayed ack timer */
|
396 |
struct bfd_request *bfd_req; /* BFD request, if BFD is used */ |
397 |
void *ldd_buffer; /* Last database description packet */ |
398 |
u32 ldd_bsize; /* Buffer size for ldd_buffer */
|
399 |
u32 csn; /* Last received crypt seq number (for MD5) */
|
400 |
}; |
401 |
|
402 |
|
403 |
/* OSPF interface types */
|
404 |
#define OSPF_IT_BCAST 0 |
405 |
#define OSPF_IT_NBMA 1 |
406 |
#define OSPF_IT_PTP 2 |
407 |
#define OSPF_IT_PTMP 3 |
408 |
#define OSPF_IT_VLINK 4 |
409 |
#define OSPF_IT_UNDEF 5 |
410 |
|
411 |
/* OSPF interface states */
|
412 |
#define OSPF_IS_DOWN 0 /* Not active */ |
413 |
#define OSPF_IS_LOOP 1 /* Iface with no link */ |
414 |
#define OSPF_IS_WAITING 2 /* Waiting for Wait timer */ |
415 |
#define OSPF_IS_PTP 3 /* PTP operational */ |
416 |
#define OSPF_IS_DROTHER 4 /* I'm on BCAST or NBMA and I'm not DR */ |
417 |
#define OSPF_IS_BACKUP 5 /* I'm BDR */ |
418 |
#define OSPF_IS_DR 6 /* I'm DR */ |
419 |
|
420 |
/* Definitions for interface state machine */
|
421 |
#define ISM_UP 0 /* Interface Up */ |
422 |
#define ISM_WAITF 1 /* Wait timer fired */ |
423 |
#define ISM_BACKS 2 /* Backup seen */ |
424 |
#define ISM_NEICH 3 /* Neighbor change */ |
425 |
#define ISM_LOOP 4 /* Link down */ |
426 |
#define ISM_UNLOOP 5 /* Link up */ |
427 |
#define ISM_DOWN 6 /* Interface down */ |
428 |
|
429 |
|
430 |
/* OSPF neighbor states */
|
431 |
#define NEIGHBOR_DOWN 0 |
432 |
#define NEIGHBOR_ATTEMPT 1 |
433 |
#define NEIGHBOR_INIT 2 |
434 |
#define NEIGHBOR_2WAY 3 |
435 |
#define NEIGHBOR_EXSTART 4 |
436 |
#define NEIGHBOR_EXCHANGE 5 |
437 |
#define NEIGHBOR_LOADING 6 |
438 |
#define NEIGHBOR_FULL 7 |
439 |
|
440 |
/* Definitions for neighbor state machine */
|
441 |
#define INM_HELLOREC 0 /* Hello Received */ |
442 |
#define INM_START 1 /* Neighbor start - for NBMA */ |
443 |
#define INM_2WAYREC 2 /* 2-Way received */ |
444 |
#define INM_NEGDONE 3 /* Negotiation done */ |
445 |
#define INM_EXDONE 4 /* Exchange done */ |
446 |
#define INM_BADLSREQ 5 /* Bad LS Request */ |
447 |
#define INM_LOADDONE 6 /* Load done */ |
448 |
#define INM_ADJOK 7 /* AdjOK? */ |
449 |
#define INM_SEQMIS 8 /* Sequence number mismatch */ |
450 |
#define INM_1WAYREC 9 /* 1-Way */ |
451 |
#define INM_KILLNBR 10 /* Kill Neighbor */ |
452 |
#define INM_INACTTIM 11 /* Inactivity timer */ |
453 |
#define INM_LLDOWN 12 /* Line down */ |
454 |
|
455 |
#define TRANS_OFF 0 |
456 |
#define TRANS_ON 1 |
457 |
#define TRANS_WAIT 2 /* Waiting before the end of translation */ |
458 |
|
459 |
|
460 |
|
461 |
/* Generic option flags */
|
462 |
#define OPT_V6 0x01 /* OSPFv3, LSA relevant for IPv6 routing calculation */ |
463 |
#define OPT_E 0x02 /* Related to AS-external LSAs */ |
464 |
#define OPT_MC 0x04 /* Related to MOSPF, not used and obsolete */ |
465 |
#define OPT_N 0x08 /* Related to NSSA */ |
466 |
#define OPT_P 0x08 /* OSPFv2, flags P and N share position, see NSSA RFC */ |
467 |
#define OPT_EA 0x10 /* OSPFv2, external attributes, not used and obsolete */ |
468 |
#define OPT_R 0x10 /* OSPFv3, originator is active router */ |
469 |
#define OPT_DC 0x20 /* Related to demand circuits, not used */ |
470 |
|
471 |
/* Router-LSA VEB flags are are stored together with links (OSPFv2) or options (OSPFv3) */
|
472 |
#define OPT_RT_B (0x01 << 24) |
473 |
#define OPT_RT_E (0x02 << 24) |
474 |
#define OPT_RT_V (0x04 << 24) |
475 |
#define OPT_RT_NT (0x10 << 24) |
476 |
|
477 |
/* Prefix flags, specific for OSPFv3 */
|
478 |
#define OPT_PX_NU 0x01 |
479 |
#define OPT_PX_LA 0x02 |
480 |
#define OPT_PX_P 0x08 |
481 |
#define OPT_PX_DN 0x10 |
482 |
|
483 |
|
484 |
struct ospf_packet
|
485 |
{ |
486 |
u8 version; |
487 |
u8 type; |
488 |
u16 length; |
489 |
u32 routerid; |
490 |
u32 areaid; |
491 |
u16 checksum; |
492 |
u8 instance_id; /* See RFC 6549 */
|
493 |
u8 autype; /* Undefined for OSPFv3 */
|
494 |
}; |
495 |
|
496 |
struct ospf_md5
|
497 |
{ |
498 |
u16 zero; |
499 |
u8 keyid; |
500 |
u8 len; |
501 |
u32 csn; |
502 |
}; |
503 |
|
504 |
union ospf_auth
|
505 |
{ |
506 |
u8 password[8];
|
507 |
struct ospf_md5 md5;
|
508 |
}; |
509 |
|
510 |
/* Packet types */
|
511 |
#define HELLO_P 1 /* Hello */ |
512 |
#define DBDES_P 2 /* Database description */ |
513 |
#define LSREQ_P 3 /* Link state request */ |
514 |
#define LSUPD_P 4 /* Link state update */ |
515 |
#define LSACK_P 5 /* Link state acknowledgement */ |
516 |
|
517 |
|
518 |
#define DBDES_I 4 /* Init bit */ |
519 |
#define DBDES_M 2 /* More bit */ |
520 |
#define DBDES_MS 1 /* Master/Slave bit */ |
521 |
#define DBDES_IMMS (DBDES_I | DBDES_M | DBDES_MS)
|
522 |
|
523 |
|
524 |
#define LSA_T_RT 0x2001 |
525 |
#define LSA_T_NET 0x2002 |
526 |
#define LSA_T_SUM_NET 0x2003 |
527 |
#define LSA_T_SUM_RT 0x2004 |
528 |
#define LSA_T_EXT 0x4005 |
529 |
#define LSA_T_NSSA 0x2007 |
530 |
#define LSA_T_LINK 0x0008 |
531 |
#define LSA_T_PREFIX 0x2009 |
532 |
|
533 |
#define LSA_T_V2_MASK 0x00ff |
534 |
|
535 |
#define LSA_UBIT 0x8000 |
536 |
|
537 |
#define LSA_SCOPE_LINK 0x0000 |
538 |
#define LSA_SCOPE_AREA 0x2000 |
539 |
#define LSA_SCOPE_AS 0x4000 |
540 |
#define LSA_SCOPE_RES 0x6000 |
541 |
#define LSA_SCOPE_MASK 0x6000 |
542 |
#define LSA_SCOPE(type) ((type) & LSA_SCOPE_MASK)
|
543 |
|
544 |
|
545 |
#define LSA_MAXAGE 3600 /* 1 hour */ |
546 |
#define LSA_CHECKAGE 300 /* 5 minutes */ |
547 |
#define LSA_MAXAGEDIFF 900 /* 15 minutes */ |
548 |
|
549 |
#define LSA_ZEROSEQNO ((s32) 0x80000000) |
550 |
#define LSA_INITSEQNO ((s32) 0x80000001) |
551 |
#define LSA_MAXSEQNO ((s32) 0x7fffffff) |
552 |
|
553 |
#define LSA_METRIC_MASK 0x00FFFFFF |
554 |
#define LSA_OPTIONS_MASK 0x00FFFFFF |
555 |
|
556 |
|
557 |
#define LSART_PTP 1 |
558 |
#define LSART_NET 2 |
559 |
#define LSART_STUB 3 |
560 |
#define LSART_VLNK 4 |
561 |
|
562 |
#define LSA_RT2_LINKS 0x0000FFFF |
563 |
|
564 |
#define LSA_SUM2_TOS 0xFF000000 |
565 |
|
566 |
#define LSA_EXT2_TOS 0x7F000000 |
567 |
#define LSA_EXT2_EBIT 0x80000000 |
568 |
|
569 |
#define LSA_EXT3_EBIT 0x4000000 |
570 |
#define LSA_EXT3_FBIT 0x2000000 |
571 |
#define LSA_EXT3_TBIT 0x1000000 |
572 |
|
573 |
|
574 |
struct ospf_lsa_header
|
575 |
{ |
576 |
u16 age; /* LS Age */
|
577 |
u16 type_raw; /* Type, mixed with options on OSPFv2 */
|
578 |
|
579 |
u32 id; |
580 |
u32 rt; /* Advertising router */
|
581 |
s32 sn; /* LS Sequence number */
|
582 |
u16 checksum; |
583 |
u16 length; |
584 |
}; |
585 |
|
586 |
|
587 |
/* In OSPFv2, options are embedded in higher half of type_raw */
|
588 |
static inline u8 lsa_get_options(struct ospf_lsa_header *lsa) |
589 |
{ return lsa->type_raw >> 8; } |
590 |
|
591 |
static inline void lsa_set_options(struct ospf_lsa_header *lsa, u16 options) |
592 |
{ lsa->type_raw = (lsa->type_raw & 0xff) | (options << 8); } |
593 |
|
594 |
|
595 |
struct ospf_lsa_rt
|
596 |
{ |
597 |
u32 options; /* VEB flags, mixed with link count for OSPFv2 and options for OSPFv3 */
|
598 |
}; |
599 |
|
600 |
struct ospf_lsa_rt2_link
|
601 |
{ |
602 |
u32 id; |
603 |
u32 data; |
604 |
#ifdef CPU_BIG_ENDIAN
|
605 |
u8 type; |
606 |
u8 no_tos; |
607 |
u16 metric; |
608 |
#else
|
609 |
u16 metric; |
610 |
u8 no_tos; |
611 |
u8 type; |
612 |
#endif
|
613 |
}; |
614 |
|
615 |
struct ospf_lsa_rt2_tos
|
616 |
{ |
617 |
#ifdef CPU_BIG_ENDIAN
|
618 |
u8 tos; |
619 |
u8 padding; |
620 |
u16 metric; |
621 |
#else
|
622 |
u16 metric; |
623 |
u8 padding; |
624 |
u8 tos; |
625 |
#endif
|
626 |
}; |
627 |
|
628 |
struct ospf_lsa_rt3_link
|
629 |
{ |
630 |
#ifdef CPU_BIG_ENDIAN
|
631 |
u8 type; |
632 |
u8 padding; |
633 |
u16 metric; |
634 |
#else
|
635 |
u16 metric; |
636 |
u8 padding; |
637 |
u8 type; |
638 |
#endif
|
639 |
u32 lif; /* Local interface ID */
|
640 |
u32 nif; /* Neighbor interface ID */
|
641 |
u32 id; /* Neighbor router ID */
|
642 |
}; |
643 |
|
644 |
|
645 |
struct ospf_lsa_net
|
646 |
{ |
647 |
u32 optx; /* Netmask for OSPFv2, options for OSPFv3 */
|
648 |
u32 routers[]; |
649 |
}; |
650 |
|
651 |
struct ospf_lsa_sum2
|
652 |
{ |
653 |
u32 netmask; |
654 |
u32 metric; |
655 |
}; |
656 |
|
657 |
struct ospf_lsa_sum3_net
|
658 |
{ |
659 |
u32 metric; |
660 |
u32 prefix[]; |
661 |
}; |
662 |
|
663 |
struct ospf_lsa_sum3_rt
|
664 |
{ |
665 |
u32 options; |
666 |
u32 metric; |
667 |
u32 drid; |
668 |
}; |
669 |
|
670 |
struct ospf_lsa_ext2
|
671 |
{ |
672 |
u32 netmask; |
673 |
u32 metric; |
674 |
u32 fwaddr; |
675 |
u32 tag; |
676 |
}; |
677 |
|
678 |
struct ospf_lsa_ext3
|
679 |
{ |
680 |
u32 metric; |
681 |
u32 rest[]; |
682 |
}; |
683 |
|
684 |
struct ospf_lsa_ext_local
|
685 |
{ |
686 |
ip_addr ip, fwaddr; |
687 |
int pxlen;
|
688 |
u32 metric, ebit, fbit, tag, propagate; |
689 |
u8 pxopts; |
690 |
}; |
691 |
|
692 |
struct ospf_lsa_link
|
693 |
{ |
694 |
u32 options; |
695 |
ip6_addr lladdr; |
696 |
u32 pxcount; |
697 |
u32 rest[]; |
698 |
}; |
699 |
|
700 |
struct ospf_lsa_prefix
|
701 |
{ |
702 |
#ifdef CPU_BIG_ENDIAN
|
703 |
u16 pxcount; |
704 |
u16 ref_type; |
705 |
#else
|
706 |
u16 ref_type; |
707 |
u16 pxcount; |
708 |
#endif
|
709 |
u32 ref_id; |
710 |
u32 ref_rt; |
711 |
u32 rest[]; |
712 |
}; |
713 |
|
714 |
|
715 |
static inline uint |
716 |
lsa_net_count(struct ospf_lsa_header *lsa)
|
717 |
{ |
718 |
return (lsa->length - sizeof(struct ospf_lsa_header) - sizeof(struct ospf_lsa_net)) |
719 |
/ sizeof(u32);
|
720 |
} |
721 |
|
722 |
/* In ospf_area->rtr we store paths to routers, but we use RID (and not IP address)
|
723 |
as index, so we need to encapsulate RID to IP address */
|
724 |
|
725 |
#define ipa_from_rid(x) ipa_from_u32(x)
|
726 |
#define ipa_to_rid(x) ipa_to_u32(x)
|
727 |
|
728 |
|
729 |
#define IPV6_PREFIX_SPACE(x) ((((x) + 63) / 32) * 4) |
730 |
#define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32) |
731 |
|
732 |
static inline u32 * |
733 |
lsa_get_ipv6_prefix(u32 *buf, ip_addr *addr, int *pxlen, u8 *pxopts, u16 *rest)
|
734 |
{ |
735 |
u8 pxl = (*buf >> 24);
|
736 |
*pxopts = (*buf >> 16);
|
737 |
*rest = *buf; |
738 |
*pxlen = pxl; |
739 |
buf++; |
740 |
|
741 |
*addr = IPA_NONE; |
742 |
|
743 |
#ifdef IPV6
|
744 |
if (pxl > 0) |
745 |
_I0(*addr) = *buf++; |
746 |
if (pxl > 32) |
747 |
_I1(*addr) = *buf++; |
748 |
if (pxl > 64) |
749 |
_I2(*addr) = *buf++; |
750 |
if (pxl > 96) |
751 |
_I3(*addr) = *buf++; |
752 |
|
753 |
/* Clean up remaining bits */
|
754 |
if (pxl < 128) |
755 |
addr->addr[pxl / 32] &= u32_mkmask(pxl % 32); |
756 |
#endif
|
757 |
|
758 |
return buf;
|
759 |
} |
760 |
|
761 |
static inline u32 * |
762 |
lsa_get_ipv6_addr(u32 *buf, ip_addr *addr) |
763 |
{ |
764 |
*addr = *(ip_addr *) buf; |
765 |
return buf + 4; |
766 |
} |
767 |
|
768 |
static inline u32 * |
769 |
put_ipv6_prefix(u32 *buf, ip_addr addr, u8 pxlen, u8 pxopts, u16 lh) |
770 |
{ |
771 |
*buf++ = ((pxlen << 24) | (pxopts << 16) | lh); |
772 |
|
773 |
if (pxlen > 0) |
774 |
*buf++ = _I0(addr); |
775 |
if (pxlen > 32) |
776 |
*buf++ = _I1(addr); |
777 |
if (pxlen > 64) |
778 |
*buf++ = _I2(addr); |
779 |
if (pxlen > 96) |
780 |
*buf++ = _I3(addr); |
781 |
return buf;
|
782 |
} |
783 |
|
784 |
static inline u32 * |
785 |
put_ipv6_addr(u32 *buf, ip_addr addr) |
786 |
{ |
787 |
*(ip_addr *) buf = addr; |
788 |
return buf + 4; |
789 |
} |
790 |
|
791 |
|
792 |
struct ospf_lsreq_header
|
793 |
{ |
794 |
u32 type; |
795 |
u32 id; |
796 |
u32 rt; |
797 |
}; |
798 |
|
799 |
|
800 |
|
801 |
#define SH_ROUTER_SELF 0xffffffff |
802 |
|
803 |
struct lsadb_show_data {
|
804 |
struct symbol *name; /* Protocol to request data from */ |
805 |
u16 type; /* LSA Type, 0 -> all */
|
806 |
u16 scope; /* Scope, 0 -> all, hack to handle link scope as 1 */
|
807 |
u32 area; /* Specified for area scope */
|
808 |
u32 lsid; /* LSA ID, 0 -> all */
|
809 |
u32 router; /* Advertising router, 0 -> all */
|
810 |
}; |
811 |
|
812 |
|
813 |
#define EA_OSPF_METRIC1 EA_CODE(EAP_OSPF, 0) |
814 |
#define EA_OSPF_METRIC2 EA_CODE(EAP_OSPF, 1) |
815 |
#define EA_OSPF_TAG EA_CODE(EAP_OSPF, 2) |
816 |
#define EA_OSPF_ROUTER_ID EA_CODE(EAP_OSPF, 3) |
817 |
|
818 |
|
819 |
/* ospf.c */
|
820 |
void ospf_schedule_rtcalc(struct ospf_proto *p); |
821 |
|
822 |
static inline void ospf_notify_rt_lsa(struct ospf_area *oa) |
823 |
{ oa->update_rt_lsa = 1; }
|
824 |
|
825 |
static inline void ospf_notify_net_lsa(struct ospf_iface *ifa) |
826 |
{ ifa->update_net_lsa = 1; }
|
827 |
|
828 |
static inline void ospf_notify_link_lsa(struct ospf_iface *ifa) |
829 |
{ ifa->update_link_lsa = 1; }
|
830 |
|
831 |
|
832 |
#define ospf_is_v2(X) OSPF_IS_V2
|
833 |
#define ospf_is_v3(X) (!OSPF_IS_V2)
|
834 |
/*
|
835 |
static inline int ospf_is_v2(struct ospf_proto *p)
|
836 |
{ return p->ospf2; }
|
837 |
|
838 |
static inline int ospf_is_v3(struct ospf_proto *p)
|
839 |
{ return ! p->ospf2; }
|
840 |
*/
|
841 |
static inline int ospf_get_version(struct ospf_proto *p) |
842 |
{ return ospf_is_v2(p) ? 2 : 3; } |
843 |
|
844 |
struct ospf_area *ospf_find_area(struct ospf_proto *p, u32 aid); |
845 |
|
846 |
static inline struct ospf_area *ospf_main_area(struct ospf_proto *p) |
847 |
{ return (p->areano == 1) ? HEAD(p->area_list) : p->backbone; } |
848 |
|
849 |
static inline int oa_is_stub(struct ospf_area *oa) |
850 |
{ return (oa->options & (OPT_E | OPT_N)) == 0; } |
851 |
|
852 |
static inline int oa_is_ext(struct ospf_area *oa) |
853 |
{ return oa->options & OPT_E; }
|
854 |
|
855 |
static inline int oa_is_nssa(struct ospf_area *oa) |
856 |
{ return oa->options & OPT_N; }
|
857 |
|
858 |
void ospf_sh_neigh(struct proto *P, char *iff); |
859 |
void ospf_sh(struct proto *P); |
860 |
void ospf_sh_iface(struct proto *P, char *iff); |
861 |
void ospf_sh_state(struct proto *P, int verbose, int reachable); |
862 |
|
863 |
void ospf_sh_lsadb(struct lsadb_show_data *ld); |
864 |
|
865 |
/* iface.c */
|
866 |
void ospf_iface_chstate(struct ospf_iface *ifa, u8 state); |
867 |
void ospf_iface_sm(struct ospf_iface *ifa, int event); |
868 |
struct ospf_iface *ospf_iface_find(struct ospf_proto *p, struct iface *what); |
869 |
void ospf_if_notify(struct proto *P, uint flags, struct iface *iface); |
870 |
void ospf_ifa_notify2(struct proto *P, uint flags, struct ifa *a); |
871 |
void ospf_ifa_notify3(struct proto *P, uint flags, struct ifa *a); |
872 |
void ospf_iface_info(struct ospf_iface *ifa); |
873 |
void ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *ip); |
874 |
void ospf_iface_new_vlink(struct ospf_proto *p, struct ospf_iface_patt *ip); |
875 |
void ospf_iface_remove(struct ospf_iface *ifa); |
876 |
void ospf_iface_shutdown(struct ospf_iface *ifa); |
877 |
int ospf_iface_assure_bufsize(struct ospf_iface *ifa, uint plen); |
878 |
int ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new); |
879 |
void ospf_reconfigure_ifaces(struct ospf_proto *p); |
880 |
void ospf_open_vlink_sk(struct ospf_proto *p); |
881 |
struct nbma_node *find_nbma_node_(list *nnl, ip_addr ip);
|
882 |
|
883 |
static inline struct nbma_node * find_nbma_node(struct ospf_iface *ifa, ip_addr ip) |
884 |
{ return find_nbma_node_(&ifa->nbma_list, ip); }
|
885 |
|
886 |
/* neighbor.c */
|
887 |
struct ospf_neighbor *ospf_neighbor_new(struct ospf_iface *ifa); |
888 |
void ospf_neigh_sm(struct ospf_neighbor *n, int event); |
889 |
void ospf_dr_election(struct ospf_iface *ifa); |
890 |
struct ospf_neighbor *find_neigh(struct ospf_iface *ifa, u32 rid); |
891 |
struct ospf_neighbor *find_neigh_by_ip(struct ospf_iface *ifa, ip_addr ip); |
892 |
void ospf_neigh_remove(struct ospf_neighbor *n); |
893 |
void ospf_neigh_update_bfd(struct ospf_neighbor *n, int use_bfd); |
894 |
void ospf_sh_neigh_info(struct ospf_neighbor *n); |
895 |
|
896 |
/* packet.c */
|
897 |
void ospf_pkt_fill_hdr(struct ospf_iface *ifa, void *buf, u8 h_type); |
898 |
uint ospf_pkt_maxsize(struct ospf_iface *ifa);
|
899 |
int ospf_rx_hook(sock * sk, int size); |
900 |
// void ospf_tx_hook(sock * sk);
|
901 |
void ospf_err_hook(sock * sk, int err); |
902 |
void ospf_verr_hook(sock *sk, int err); |
903 |
void ospf_send_to(struct ospf_iface *ifa, ip_addr ip); |
904 |
void ospf_send_to_agt(struct ospf_iface *ifa, u8 state); |
905 |
void ospf_send_to_bdr(struct ospf_iface *ifa); |
906 |
|
907 |
static inline void ospf_send_to_all(struct ospf_iface *ifa) |
908 |
{ ospf_send_to(ifa, ifa->all_routers); } |
909 |
|
910 |
static inline void ospf_send_to_des(struct ospf_iface *ifa) |
911 |
{ |
912 |
if (ipa_nonzero(ifa->des_routers))
|
913 |
ospf_send_to(ifa, ifa->des_routers); |
914 |
else
|
915 |
ospf_send_to_bdr(ifa); |
916 |
} |
917 |
|
918 |
static inline uint ospf_pkt_hdrlen(struct ospf_proto *p) |
919 |
{ return ospf_is_v2(p) ? (sizeof(struct ospf_packet) + sizeof(union ospf_auth)) : sizeof(struct ospf_packet); } |
920 |
|
921 |
static inline void * ospf_tx_buffer(struct ospf_iface *ifa) |
922 |
{ return ifa->sk->tbuf; }
|
923 |
|
924 |
/* hello.c */
|
925 |
#define OHS_HELLO 0 |
926 |
#define OHS_POLL 1 |
927 |
#define OHS_SHUTDOWN 2 |
928 |
|
929 |
void ospf_send_hello(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn); |
930 |
void ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa, struct ospf_neighbor *n, ip_addr faddr); |
931 |
|
932 |
/* dbdes.c */
|
933 |
void ospf_send_dbdes(struct ospf_proto *p, struct ospf_neighbor *n, int next); |
934 |
void ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa, struct ospf_neighbor *n); |
935 |
|
936 |
/* lsreq.c */
|
937 |
void ospf_send_lsreq(struct ospf_proto *p, struct ospf_neighbor *n); |
938 |
void ospf_receive_lsreq(struct ospf_packet *pkt, struct ospf_iface *ifa, struct ospf_neighbor *n); |
939 |
|
940 |
/* lsupd.c */
|
941 |
void ospf_dump_lsahdr(struct ospf_proto *p, struct ospf_lsa_header *lsa_n); |
942 |
void ospf_dump_common(struct ospf_proto *p, struct ospf_packet *pkt); |
943 |
void ospf_add_flushed_to_lsrt(struct ospf_proto *p, struct ospf_neighbor *n); |
944 |
int ospf_flood_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from); |
945 |
int ospf_send_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, struct ospf_neighbor *n); |
946 |
void ospf_rxmt_lsupd(struct ospf_proto *p, struct ospf_neighbor *n); |
947 |
void ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa, struct ospf_neighbor *n); |
948 |
|
949 |
/* lsack.c */
|
950 |
void ospf_enqueue_lsack(struct ospf_neighbor *n, struct ospf_lsa_header *h_n, int queue); |
951 |
void ospf_reset_lsack_queue(struct ospf_neighbor *n); |
952 |
void ospf_send_lsack(struct ospf_proto *p, struct ospf_neighbor *n, int queue); |
953 |
void ospf_receive_lsack(struct ospf_packet *pkt, struct ospf_iface *ifa, struct ospf_neighbor *n); |
954 |
|
955 |
|
956 |
#include "proto/ospf/rt.h" |
957 |
#include "proto/ospf/topology.h" |
958 |
#include "proto/ospf/lsalib.h" |
959 |
|
960 |
#endif /* _BIRD_OSPF_H_ */ |