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