ospf.h 18.3 KB
Newer Older
1 2 3
/*
 *	BIRD -- OSPF
 *
4
 *	(c) 1999--2005 Ondrej Filip <feela@network.cz>
5 6 7 8 9 10 11
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#ifndef _BIRD_OSPF_H_
#define _BIRD_OSPF_H_

12
#define MAXNETS 10
13 14 15 16 17 18 19 20 21
#define OSPF_MAX_PKT_SIZE 65535
/*
 * RFC 2328 says, maximum packet size is 65535 (IP packet size
 * limit). Really a bit less for OSPF, because this contains also IP
 * header. This could be too much for small systems, so I normally
 * allocate 2*mtu (i found one cisco sending packets mtu+16). OSPF
 * packets are almost always sent small enough to not be fragmented.
 */

Ondřej Filip's avatar
Ondřej Filip committed
22 23 24 25 26 27 28
#ifdef LOCAL_DEBUG
#define OSPF_FORCE_DEBUG 1
#else
#define OSPF_FORCE_DEBUG 0
#endif
#define OSPF_TRACE(flags, msg, args...) do { if ((p->debug & flags) || OSPF_FORCE_DEBUG) \
  log(L_TRACE "%s: " msg, p->name , ## args ); } while(0)
Ondřej Filip's avatar
Ondřej Filip committed
29

30 31 32 33 34
#define OSPF_PACKET(dumpfn, buffer, msg, args...) \
do { if ((p->debug & D_PACKETS) || OSPF_FORCE_DEBUG) \
{ log(L_TRACE "%s: " msg, p->name, ## args ); dumpfn(p, buffer); } } while(0)


35 36 37
#include "nest/bird.h"

#include "lib/checksum.h"
38 39
#include "lib/ip.h"
#include "lib/lists.h"
40
#include "lib/slists.h"
41 42 43 44 45
#include "lib/socket.h"
#include "lib/timer.h"
#include "lib/resource.h"
#include "nest/protocol.h"
#include "nest/iface.h"
46
#include "nest/route.h"
47
#include "nest/cli.h"
Ondřej Filip's avatar
Ondřej Filip committed
48
#include "nest/locks.h"
49
#include "conf/conf.h"
50
#include "lib/string.h"
51

52
#define OSPF_PROTO 89
53

Ondřej Filip's avatar
Ondřej Filip committed
54
#ifndef IPV6
55
#define OSPFv2 1
56
#define OSPF_VERSION 2
57
#define OSPF_VLINK_MTU 576			/* RFC 2328 A.1 */
58 59
#define AllSPFRouters ipa_from_u32(0xe0000005)	/* 224.0.0.5 */
#define AllDRouters ipa_from_u32(0xe0000006)	/* 224.0.0.6 */
Ondřej Filip's avatar
Ondřej Filip committed
60
#else
61 62
#define OSPFv3 1
#define OSPF_VERSION 3
63
#define OSPF_VLINK_MTU 1280			/* RFC 5340 A.1 */
64 65
#define AllSPFRouters _MI(0xFF020000, 0, 0, 5)	/* FF02::5 */
#define AllDRouters   _MI(0xFF020000, 0, 0, 6)	/* FF02::6 */
Ondřej Filip's avatar
Ondřej Filip committed
66 67
#endif

68

Ondřej Filip's avatar
Ondřej Filip committed
69
#define LSREFRESHTIME 1800	/* 30 minutes */
70 71
#define MINLSINTERVAL 5
#define MINLSARRIVAL 1
Ondřej Filip's avatar
Ondřej Filip committed
72
#define LSINFINITY 0xffffff
Ondřej Filip's avatar
Ondřej Filip committed
73

74
#define DEFAULT_OSPFTICK 1
75
#define DEFAULT_RFC1583 0	/* compatibility with rfc1583 */
Ondřej Filip's avatar
Ondřej Filip committed
76
#define DEFAULT_STUB_COST 1000
77
#define DEFAULT_ECMP_LIMIT 16
Ondřej Filip's avatar
Ondřej Filip committed
78

79

Ondřej Filip's avatar
Ondřej Filip committed
80 81
struct ospf_config
{
82
  struct proto_config c;
83
  unsigned tick;
84
  int rfc1583;
85
  int ecmp;
Ondřej Filip's avatar
Ondřej Filip committed
86 87 88
  list area_list;
};

Ondřej Filip's avatar
Ondřej Filip committed
89 90
struct nbma_node
{
91 92
  node n;
  ip_addr ip;
93
  int eligible;
94 95
};

Ondřej Filip's avatar
Ondřej Filip committed
96
struct area_net_config
Ondřej Filip's avatar
Ondřej Filip committed
97
{
98
  node n;
Ondřej Filip's avatar
Ondřej Filip committed
99
  struct prefix px;
100
  int hidden;
Ondřej Filip's avatar
Ondřej Filip committed
101 102 103 104 105 106
};

struct area_net
{
  struct fib_node fn;
  int hidden;
Ondřej Filip's avatar
Ondřej Filip committed
107
  int active;
108
  u32 metric;
109 110
};

111 112 113 114 115 116 117 118
struct ospf_stubnet_config
{
  node n;
  struct prefix px;
  int hidden, summary;
  u32 cost;
};

Ondřej Filip's avatar
Ondřej Filip committed
119 120
struct ospf_area_config
{
Ondřej Filip's avatar
Ondřej Filip committed
121 122 123
  node n;
  u32 areaid;
  int stub;
Ondřej Filip's avatar
Ondřej Filip committed
124
  list patt_list;
125
  list vlink_list;
126
  list net_list;
127
  list stubnet_list;
128 129
};

130 131 132 133 134 135 136 137 138 139 140 141 142 143

/* Option flags */

#define OPT_E	0x02
#define OPT_N	0x08
#define OPT_DC	0x20

#ifdef OSPFv2
#define OPT_EA	0x10

/* VEB flags are are stored independently in 'u16 options' */
#define OPT_RT_B  (0x01 << 8)
#define OPT_RT_E  (0x02 << 8)
#define OPT_RT_V  (0x04 << 8)
144 145
#endif

146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
#ifdef OSPFv3
#define OPT_V6	0x01
#define OPT_R	0x10

/* VEB flags are are stored together with options in 'u32 options' */
#define OPT_RT_B  (0x01 << 24)
#define OPT_RT_E  (0x02 << 24)
#define OPT_RT_V  (0x04 << 24)
#define OPT_RT_NT (0x10 << 24)

#define OPT_PX_NU 0x01
#define OPT_PX_LA 0x02
#define OPT_PX_P  0x08
#define OPT_PX_DN 0x10
#endif
161 162


Ondřej Filip's avatar
Ondřej Filip committed
163 164
struct ospf_iface
{
165
  node n;
Ondřej Filip's avatar
Ondřej Filip committed
166
  struct iface *iface;		/* Nest's iface */
Ondřej Zajíček's avatar
Ondřej Zajíček committed
167
  struct ifa *addr;		/* IP prefix associated with that OSPF iface */
168
  struct ospf_area *oa;
169
  pool *pool;
170
  sock *sk;			/* IP socket (for DD ...) */
Ondřej Filip's avatar
Ondřej Filip committed
171
  list neigh_list;		/* List of neigbours */
172
  u32 cost;			/* Cost of iface */
173 174 175
  u32 waitint;			/* number of sec before changing state from wait */
  u32 rxmtint;			/* number of seconds between LSA retransmissions */
  u32 pollint;			/* Poll interval */
176
  u32 dead;			/* after "deadint" missing hellos is router dead */
Ondřej Filip's avatar
Ondřej Filip committed
177 178
  u32 vid;			/* Id of peer of virtual link */
  ip_addr vip;			/* IP of peer of virtual link */
179 180
  struct ospf_iface *vifa;	/* OSPF iface which the vlink goes through */
  struct ospf_area *voa;	/* OSPF area which the vlink goes through */
181 182 183
  u16 inftransdelay;		/* The estimated number of seconds it takes to
				   transmit a Link State Update Packet over this
				   interface.  LSAs contained in the update */
184
  u16 helloint;			/* number of seconds between hello sending */
185 186

#ifdef OSPFv2
187
  list *passwords;
188
  u16 autype;
189 190
  u32 csn;                      /* Last used crypt seq number */
  bird_clock_t csn_use;         /* Last time when packet with that CSN was sent */
191 192
#endif

Ondřej Filip's avatar
Ondřej Filip committed
193 194
  ip_addr drip;			/* Designated router */
  ip_addr bdrip;		/* Backup DR */
195
  u32 drid;
Ondřej Filip's avatar
Ondřej Filip committed
196
  u32 bdrid;
197 198 199 200 201 202 203

#ifdef OSPFv3
  u32 dr_iface_id;		/* if drid is valid, this is iface_id of DR (for connecting network) */
  u8 instance_id;		/* Used to differentiate between more OSPF
				   instances on one interface */
#endif

Ondřej Filip's avatar
Ondřej Filip committed
204
  u8 type;			/* OSPF view of type */
205
#define OSPF_IT_BCAST 0
206 207
#define OSPF_IT_NBMA 1
#define OSPF_IT_PTP 2
208
#define OSPF_IT_VLINK 3
Ondřej Filip's avatar
Ondřej Filip committed
209
#define OSPF_IT_UNDEF 4
Ondřej Filip's avatar
Ondřej Filip committed
210 211 212
  u8 strictnbma;		/* Can I talk with unknown neighbors? */
  u8 stub;			/* Inactive interface */
  u8 state;			/* Interface state machine */
213
#define OSPF_IS_DOWN 0		/* Not working */
214
#define OSPF_IS_LOOP 1		/* Iface with no link */
215 216 217 218 219
#define OSPF_IS_WAITING 2	/* Waiting for Wait timer */
#define OSPF_IS_PTP 3		/* PTP operational */
#define OSPF_IS_DROTHER 4	/* I'm on BCAST or NBMA and I'm not DR */
#define OSPF_IS_BACKUP 5	/* I'm BDR */
#define OSPF_IS_DR 6		/* I'm DR */
220 221
  timer *wait_timer;		/* WAIT timer */
  timer *hello_timer;		/* HELLOINT timer */
222
  timer *poll_timer;		/* Poll Interval - for NBMA */
223 224 225
/* Default values for interface parameters */
#define COST_D 10
#define RXMTINT_D 5
226
#define INFTRANSDELAY_D 1
227
#define PRIORITY_D 1
228
#define HELLOINT_D 10
229
#define POLLINT_D 20
Ondřej Filip's avatar
Ondřej Filip committed
230
#define DEADC_D 4
231 232 233 234 235 236 237
#define WAIT_DMH 4		
  /* Value of Wait timer - not found it in RFC * - using 4*HELLO */

  struct top_hash_entry *net_lsa;	/* Originated network LSA */
  int orignet;				/* Schedule network LSA origination */
#ifdef OSPFv3
  int origlink;				/* Schedule link LSA origination */
238
  struct top_hash_entry *link_lsa;	/* Originated link LSA */
239 240 241
  struct top_hash_entry *pxn_lsa;	/* Originated prefix LSA */
#endif
  int fadj;				/* Number of full adjacent neigh */
242
  list nbma_list;
243
  u8 priority;			/* A router priority for DR election */
244
  u8 ioprob;
245 246 247
#define OSPF_I_OK 0		/* Everything OK */
#define OSPF_I_SK 1		/* Socket open failed */
#define OSPF_I_LL 2		/* Missing link-local address (OSPFv3) */
248 249
  u8 sk_spf;			/* Socket is a member of SPFRouters group */
  u8 sk_dr; 			/* Socket is a member of DRouters group */
250
  u16 rxbuf;			/* Buffer size */
251
  u8 check_link;		/* Whether iface link change is used */
252
  u8 ecmp_weight;		/* Weight used for ECMP */
253 254
};

255 256 257 258 259 260 261 262 263 264 265 266 267 268
struct ospf_md5
{
  u16 zero;
  u8 keyid;
  u8 len;
  u32 csn;
};

union ospf_auth
{
  u8 password[8];
  struct ospf_md5 md5;
};

269 270

/* Packet types */
Ondřej Filip's avatar
Ondřej Filip committed
271 272 273 274 275
#define HELLO_P 1		/* Hello */
#define DBDES_P 2		/* Database description */
#define LSREQ_P 3		/* Link state request */
#define LSUPD_P 4		/* Link state update */
#define LSACK_P 5		/* Link state acknowledgement */
276 277

/* Area IDs */
Ondřej Filip's avatar
Ondřej Filip committed
278
#define BACKBONE 0
279 280


Ondřej Filip's avatar
Ondřej Filip committed
281 282
struct immsb
{
283
#ifdef CPU_BIG_ENDIAN
284 285 286 287 288
  u8 padding:5;
  u8 i:1;
  u8 m:1;
  u8 ms:1;
#else
289 290 291 292
  u8 ms:1;
  u8 m:1;
  u8 i:1;
  u8 padding:5;
293
#endif
294 295
};

Ondřej Filip's avatar
Ondřej Filip committed
296 297
union imms
{
298 299 300
  u8 byte;
  struct immsb bit;
};
301 302 303
#define DBDES_MS 1
#define DBDES_M 2
#define DBDES_I 4
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332


#ifdef OSPFv2

struct ospf_packet
{
  u8 version;
  u8 type;
  u16 length;
  u32 routerid;
  u32 areaid;
  u16 checksum;
  u16 autype;
  union ospf_auth u;
};


#else /* OSPFv3 packet descriptions */

struct ospf_packet
{
  u8 version;
  u8 type;
  u16 length;
  u32 routerid;
  u32 areaid;
  u16 checksum;
  u8 instance_id;
  u8 zero;
333 334
};

335

336 337 338 339 340
#endif




Ondřej Filip's avatar
Ondřej Filip committed
341 342 343 344 345 346
struct ospf_lsa_header
{
  u16 age;			/* LS Age */
#define LSA_MAXAGE 3600		/* 1 hour */
#define LSA_CHECKAGE 300	/* 5 minutes */
#define LSA_MAXAGEDIFF 900	/* 15 minutes */
347 348

#ifdef OSPFv2
349
  u8 options;
350
  u8 type;
351 352 353 354 355 356 357

#define LSA_T_RT	1
#define LSA_T_NET	2
#define LSA_T_SUM_NET	3
#define LSA_T_SUM_RT	4
#define LSA_T_EXT	5

358 359 360 361 362
#define LSA_SCOPE_AREA	0x2000
#define LSA_SCOPE_AS	0x4000

#define LSA_SCOPE(lsa)	(((lsa)->type == LSA_T_EXT) ? LSA_SCOPE_AS : LSA_SCOPE_AREA)

363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
#else /* OSPFv3 */
  u16 type;

#define LSA_T_RT	0x2001
#define LSA_T_NET	0x2002
#define LSA_T_SUM_NET	0x2003
#define LSA_T_SUM_RT	0x2004
#define LSA_T_EXT	0x4005
#define LSA_T_LINK	0x0008
#define LSA_T_PREFIX	0x2009

#define LSA_UBIT	0x8000

#define LSA_SCOPE_LINK	0x0000
#define LSA_SCOPE_AREA	0x2000
#define LSA_SCOPE_AS	0x4000
#define LSA_SCOPE_RES	0x6000
#define LSA_SCOPE_MASK	0x6000

#define LSA_SCOPE(lsa)	((lsa)->type & LSA_SCOPE_MASK)
#endif

385
  u32 id;
Ondřej Filip's avatar
Ondřej Filip committed
386 387
  u32 rt;			/* Advertising router */
  s32 sn;			/* LS Sequence number */
388 389
#define LSA_INITSEQNO ((s32) 0x80000001)
#define LSA_MAXSEQNO ((s32) 0x7fffffff)
390
  u16 checksum;
Ondřej Filip's avatar
Ondřej Filip committed
391
  u16 length;
392 393
};

394

395 396 397 398 399 400 401
#define LSART_PTP 1
#define LSART_NET 2
#define LSART_STUB 3
#define LSART_VLNK 4


#ifdef OSPFv2
402

Ondřej Filip's avatar
Ondřej Filip committed
403 404
struct ospf_lsa_rt
{
405
#ifdef CPU_BIG_ENDIAN
406
  u16 options;	/* VEB flags only */
407
  u16 links;
408 409 410 411
#else
  u16 links;
  u16 options;	/* VEB flags only */
#endif
412 413
};

Ondřej Filip's avatar
Ondřej Filip committed
414 415
struct ospf_lsa_rt_link
{
416 417
  u32 id;
  u32 data;
418
#ifdef CPU_BIG_ENDIAN
419
  u8 type;
420
  u8 padding;
421
  u16 metric;
422 423 424 425 426
#else
  u16 metric;
  u8 padding;
  u8 type;
#endif
427 428
};

429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
struct ospf_lsa_net
{
  ip_addr netmask;
  u32 routers[];
};

struct ospf_lsa_sum
{
  ip_addr netmask;
  u32 metric;
};

struct ospf_lsa_ext
{
  ip_addr netmask;
  u32 metric;
  ip_addr fwaddr;
  u32 tag;
};

449 450
#define LSA_SUM_TOS  0xFF000000
#define LSA_EXT_TOS  0x7F000000
451 452
#define LSA_EXT_EBIT 0x80000000

453 454 455 456
/* Endianity swap for lsa->type */
#define ntoht(x) x
#define htont(x) x

457 458 459 460 461 462 463 464 465 466

#else  /* OSPFv3 */

struct ospf_lsa_rt
{
  u32 options;
};

struct ospf_lsa_rt_link
{
467
#ifdef CPU_BIG_ENDIAN
468
  u8 type;
469 470
  u8 padding;
  u16 metric;
471 472 473 474 475
#else
  u16 metric;
  u8 padding;
  u8 type;
#endif
476 477 478
  u32 lif;	/* Local interface ID */
  u32 nif;	/* Neighbor interface ID */
  u32 id;	/* Neighbor router ID */
479 480
};

Ondřej Filip's avatar
Ondřej Filip committed
481 482
struct ospf_lsa_net
{
483 484
  u32 options;
  u32 routers[];
485 486
};

487
struct ospf_lsa_sum_net
Ondřej Filip's avatar
Ondřej Filip committed
488
{
489 490
  u32 metric;
  u32 prefix[];
491 492
};

493 494 495 496 497 498
struct ospf_lsa_sum_rt
{
  u32 options;
  u32 metric;
  u32 drid;
};
Ondřej Filip's avatar
Ondřej Filip committed
499 500

struct ospf_lsa_ext
Ondřej Filip's avatar
Ondřej Filip committed
501
{
502 503 504 505 506 507 508 509 510 511 512 513 514 515
  u32 metric;
  u32 rest[];
};

struct ospf_lsa_link
{
  u32 options;
  ip_addr lladdr;
  u32 pxcount;
  u32 rest[];
};

struct ospf_lsa_prefix
{
516
#ifdef CPU_BIG_ENDIAN
517 518
  u16 pxcount;
  u16 ref_type;
519 520 521 522
#else
  u16 ref_type;
  u16 pxcount;
#endif
523 524 525
  u32 ref_id;
  u32 ref_rt;
  u32 rest[];
Ondřej Filip's avatar
Ondřej Filip committed
526 527
};

528 529 530 531
#define LSA_EXT_EBIT 0x4000000
#define LSA_EXT_FBIT 0x2000000
#define LSA_EXT_TBIT 0x1000000

532 533 534 535
/* Endianity swap for lsa->type */
#define ntoht(x) ntohs(x)
#define htont(x) htons(x)

536 537 538 539 540
#endif

#define METRIC_MASK  0x00FFFFFF
#define OPTIONS_MASK 0x00FFFFFF

541 542
static inline unsigned
lsa_rt_count(struct ospf_lsa_header *lsa)
543 544 545 546 547
{
  return (lsa->length - sizeof(struct ospf_lsa_header) - sizeof(struct ospf_lsa_rt))
    / sizeof(struct ospf_lsa_rt_link);
}

548 549
static inline unsigned
lsa_net_count(struct ospf_lsa_header *lsa)
550 551 552 553 554 555
{
  return (lsa->length - sizeof(struct ospf_lsa_header) - sizeof(struct ospf_lsa_net))
    / sizeof(u32);
}


556 557
#ifdef OSPFv3

558 559 560
#define IPV6_PREFIX_SPACE(x) ((((x) + 63) / 32) * 4)
#define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32)

561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
static inline u32 *
lsa_get_ipv6_prefix(u32 *buf, ip_addr *addr, int *pxlen, u8 *pxopts, u16 *rest)
{
  u8 pxl = (*buf >> 24);
  *pxopts = (*buf >> 16);
  *rest = *buf;
  *pxlen = pxl;
  buf++;

  *addr = IPA_NONE;

  if (pxl > 0)
    _I0(*addr) = *buf++;
  if (pxl > 32)
    _I1(*addr) = *buf++;
  if (pxl > 64)
    _I2(*addr) = *buf++;
  if (pxl > 96)
    _I3(*addr) = *buf++;

  return buf;
}

static inline u32 *
lsa_get_ipv6_addr(u32 *buf, ip_addr *addr)
{
  *addr = *(ip_addr *) buf;
  return buf + 4;
}

591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
static inline u32 *
put_ipv6_prefix(u32 *buf, ip_addr addr, u8 pxlen, u8 pxopts, u16 lh)
{
  *buf++ = ((pxlen << 24) | (pxopts << 16) | lh);

  if (pxlen > 0)
    *buf++ = _I0(addr);
  if (pxlen > 32)
    *buf++ = _I1(addr);
  if (pxlen > 64)
    *buf++ = _I2(addr);
  if (pxlen > 96)
    *buf++ = _I3(addr);
  return buf;
}

static inline u32 *
put_ipv6_addr(u32 *buf, ip_addr addr)
{
  *(ip_addr *) buf = addr;
  return buf + 4;
}

614 615 616 617
#endif



Ondřej Filip's avatar
Ondřej Filip committed
618 619
struct ospf_lsreq_header
{
620
  u32 type;
Ondřej Filip's avatar
Ondřej Filip committed
621
  u32 id;
Ondřej Filip's avatar
Ondřej Filip committed
622
  u32 rt;			/* Advertising router */
Ondřej Filip's avatar
Ondřej Filip committed
623 624
};

Ondřej Filip's avatar
Ondřej Filip committed
625 626
struct l_lsr_head
{
627 628 629 630
  node n;
  struct ospf_lsreq_header lsh;
};

631

632 633
struct ospf_neighbor
{
634
  node n;
635
  pool *pool;
636
  struct ospf_iface *ifa;
637
  u8 state;
638
#define NEIGHBOR_DOWN 0
639 640 641
#define NEIGHBOR_ATTEMPT 1
#define NEIGHBOR_INIT 2
#define NEIGHBOR_2WAY 3
642
#define NEIGHBOR_EXSTART 4
643 644 645
#define NEIGHBOR_EXCHANGE 5
#define NEIGHBOR_LOADING 6
#define NEIGHBOR_FULL 7
Ondřej Filip's avatar
Ondřej Filip committed
646
  timer *inactim;		/* Inactivity timer */
647
  union imms imms;		/* I, M, Master/slave received */
Ondřej Filip's avatar
Ondřej Filip committed
648 649
  u32 dds;			/* DD Sequence number being sent */
  u32 ddr;			/* last Dat Des packet received */
650
  union imms myimms;		/* I, M Master/slave */
Ondřej Filip's avatar
Ondřej Filip committed
651 652 653 654
  u32 rid;			/* Router ID */
  ip_addr ip;			/* IP of it's interface */
  u8 priority;			/* Priority */
  u8 adj;			/* built adjacency? */
655 656 657 658 659 660 661 662 663 664 665
  u32 options;			/* Options received */

  /* dr and bdr store IP address in OSPFv2 and router ID in OSPFv3,
     we use the same type to simplify handling */
  u32 dr;			/* Neigbour's idea of DR */
  u32 bdr;			/* Neigbour's idea of BDR */

#ifdef OSPFv3
  u32 iface_id;			/* ID of Neighbour's iface connected to common network */
#endif

Ondřej Filip's avatar
Ondřej Filip committed
666 667 668
  siterator dbsi;		/* Database summary list iterator */
  slist lsrql;			/* Link state request */
  struct top_graph *lsrqh;	/* LSA graph */
669
  siterator lsrqi;
Ondřej Filip's avatar
Ondřej Filip committed
670
  slist lsrtl;			/* Link state retransmission list */
671
  siterator lsrti;
Ondřej Filip's avatar
Ondřej Filip committed
672
  struct top_graph *lsrth;
Ondřej Filip's avatar
Ondřej Filip committed
673 674
  void *ldbdes;			/* Last database description packet */
  timer *rxmt_timer;		/* RXMT timer */
675 676 677
  list ackl[2];
#define ACKL_DIRECT 0
#define ACKL_DELAY 1
Ondřej Filip's avatar
Ondřej Filip committed
678
  timer *ackd_timer;		/* Delayed ack timer */
679
  u32 csn;                      /* Last received crypt seq number (for MD5) */
680 681
};

682
/* Definitions for interface state machine */
Ondřej Filip's avatar
Ondřej Filip committed
683 684 685 686
#define ISM_UP 0		/* Interface Up */
#define ISM_WAITF 1		/* Wait timer fired */
#define ISM_BACKS 2		/* Backup seen */
#define ISM_NEICH 3		/* Neighbor change */
687 688
#define ISM_LOOP 4		/* Link down */
#define ISM_UNLOOP 5		/* Link up */
Ondřej Filip's avatar
Ondřej Filip committed
689
#define ISM_DOWN 6		/* Interface down */
690 691

/* Definitions for neighbor state machine */
Ondřej Filip's avatar
Ondřej Filip committed
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
#define INM_HELLOREC 0		/* Hello Received */
#define INM_START 1		/* Neighbor start - for NBMA */
#define INM_2WAYREC 2		/* 2-Way received */
#define INM_NEGDONE 3		/* Negotiation done */
#define INM_EXDONE 4		/* Exchange done */
#define INM_BADLSREQ 5		/* Bad LS Request */
#define INM_LOADDONE 6		/* Load done */
#define INM_ADJOK 7		/* AdjOK? */
#define INM_SEQMIS 8		/* Sequence number mismatch */
#define INM_1WAYREC 9		/* 1-Way */
#define INM_KILLNBR 10		/* Kill Neighbor */
#define INM_INACTTIM 11		/* Inactivity timer */
#define INM_LLDOWN 12		/* Line down */

struct ospf_area
{
708
  node n;
709
  u32 areaid;
710
  struct ospf_area_config *ac;	/* Related area config, might be NULL */
711
  int origrt;			/* Rt lsa origination scheduled? */
Ondřej Filip's avatar
Ondřej Filip committed
712
  struct top_hash_entry *rt;	/* My own router LSA */
713
  struct top_hash_entry *pxr_lsa; /* Originated prefix LSA */
714
  list cand;			/* List of candidates for RT calc. */
Ondřej Filip's avatar
Ondřej Filip committed
715
  struct fib net_fib;		/* Networks to advertise or not */
716
  unsigned stub;
Ondřej Filip's avatar
Ondřej Filip committed
717
  int trcap;			/* Transit capability? */
718
  u32 options;			/* Optional features */
Ondřej Filip's avatar
Ondřej Filip committed
719
  struct proto_ospf *po;
Ondřej Filip's avatar
Ondřej Filip committed
720
  struct fib rtr;		/* Routing tables for routers */
721 722
};

Ondřej Filip's avatar
Ondřej Filip committed
723 724
struct proto_ospf
{
725
  struct proto proto;
726 727
  timer *disp_timer;		/* OSPF proto dispatcher */
  unsigned tick;
728 729
  struct top_graph *gr;		/* LSA graph */
  slist lsal;			/* List of all LSA's */
730 731
  int calcrt;			/* Routing table calculation scheduled?
				   0=no, 1=normal, 2=forced reload */
732
  list iface_list;		/* Interfaces we really use */
733
  list area_list;
734
  int areano;			/* Number of area I belong to */
Ondřej Filip's avatar
Ondřej Filip committed
735
  struct fib rtf;		/* Routing table */
736 737 738
  byte rfc1583;			/* RFC1583 compatibility */
  byte ebit;			/* Did I originate any ext lsa? */
  byte ecmp;			/* Maximal number of nexthops in ECMP route, or 0 */
Ondřej Filip's avatar
Ondřej Filip committed
739
  struct ospf_area *backbone;	/* If exists */
740 741
  void *lsab;			/* LSA buffer used when originating router LSAs */
  int lsab_size, lsab_used;
742
  linpool *nhpool;		/* Linpool used for next hops computed in SPF */
743
  u32 router_id;
744 745
};

Ondřej Filip's avatar
Ondřej Filip committed
746 747
struct ospf_iface_patt
{
Ondřej Filip's avatar
Ondřej Filip committed
748
  struct iface_patt i;
749 750 751 752 753 754 755 756
  u32 cost;
  u32 helloint;
  u32 rxmtint;
  u32 pollint;
  u32 inftransdelay;
  u32 priority;
  u32 waitint;
  u32 deadc;
757
  u32 dead;
758 759 760
  u32 type;
  u32 strictnbma;
  u32 stub;
Ondřej Filip's avatar
Ondřej Filip committed
761
  u32 vid;
762
  u16 rxbuf;
763
  u8 check_link;
764
  u8 ecmp_weight;
765 766 767
#define OSPF_RXBUF_NORMAL 0
#define OSPF_RXBUF_LARGE 1
#define OSPF_RXBUF_MINSIZE 256	/* Minimal allowed size */
768
  list nbma_list;
769 770 771 772 773 774 775 776 777 778 779 780 781 782

  u32 autype;			  /* Not really used in OSPFv3 */
#define OSPF_AUTH_NONE 0
#define OSPF_AUTH_SIMPLE 1
#define OSPF_AUTH_CRYPT 2
#define OSPF_AUTH_CRYPT_SIZE 16

#ifdef OSPFv2
  list *passwords;
#endif

#ifdef OSPFv3
  u8 instance_id;
#endif
Ondřej Filip's avatar
Ondřej Filip committed
783 784
};

785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
#if defined(OSPFv2) && !defined(CONFIG_MC_PROPER_SRC)
static inline int
ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr)
{
  /*
   * We cannot properly support multiple OSPF ifaces on real iface
   * with multiple prefixes, therefore we force OSPF ifaces with
   * non-primary IP prefixes to be stub.
   */
  return ip->stub || !(addr->flags & IA_PRIMARY);
}
#else
static inline int
ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr UNUSED)
{
  return ip->stub;
}
#endif

804
int ospf_import_control(struct proto *p, rte **new, ea_list **attrs,
Ondřej Filip's avatar
Ondřej Filip committed
805
			struct linpool *pool);
Martin Mareš's avatar
Martin Mareš committed
806 807
struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool);
void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs);
808
void schedule_rt_lsa(struct ospf_area *oa);
809
void schedule_rtcalc(struct proto_ospf *po);
Ondřej Filip's avatar
Ondřej Filip committed
810
void schedule_net_lsa(struct ospf_iface *ifa);
811 812 813 814

#ifdef OSPFv3
void schedule_link_lsa(struct ospf_iface *ifa);
#else
815
static inline void schedule_link_lsa(struct ospf_iface *ifa UNUSED) {}
816 817
#endif

Ondřej Filip's avatar
Ondřej Filip committed
818
void ospf_sh_neigh(struct proto *p, char *iff);
Ondřej Filip's avatar
Ondřej Filip committed
819
void ospf_sh(struct proto *p);
Ondřej Filip's avatar
Ondřej Filip committed
820
void ospf_sh_iface(struct proto *p, char *iff);
821
void ospf_sh_state(struct proto *p, int verbose, int reachable);
822
void ospf_sh_lsadb(struct proto *p);
Ondřej Zajíček's avatar
Ondřej Zajíček committed
823

824

Martin Mareš's avatar
Martin Mareš committed
825 826 827
#define EA_OSPF_METRIC1	EA_CODE(EAP_OSPF, 0)
#define EA_OSPF_METRIC2	EA_CODE(EAP_OSPF, 1)
#define EA_OSPF_TAG	EA_CODE(EAP_OSPF, 2)
828
#define EA_OSPF_ROUTER_ID EA_CODE(EAP_OSPF, 3)
Martin Mareš's avatar
Martin Mareš committed
829

Ondřej Filip's avatar
Ondřej Filip committed
830
#include "proto/ospf/rt.h"
831 832 833 834 835 836
#include "proto/ospf/hello.h"
#include "proto/ospf/packet.h"
#include "proto/ospf/iface.h"
#include "proto/ospf/neighbor.h"
#include "proto/ospf/topology.h"
#include "proto/ospf/dbdes.h"
Ondřej Filip's avatar
Ondřej Filip committed
837
#include "proto/ospf/lsreq.h"
838 839 840
#include "proto/ospf/lsupd.h"
#include "proto/ospf/lsack.h"
#include "proto/ospf/lsalib.h"
841

842
#endif /* _BIRD_OSPF_H_ */