diff options
Diffstat (limited to 'proto/ospf/ospf.h')
-rw-r--r-- | proto/ospf/ospf.h | 506 |
1 files changed, 345 insertions, 161 deletions
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 7f0ee54..0930a06 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -18,6 +18,7 @@ * normally allocate 2*mtu - (I found one cisco * sending packets mtu+16) */ +#define LOCAL_DEBUG 1 #ifdef LOCAL_DEBUG #define OSPF_FORCE_DEBUG 1 #else @@ -49,13 +50,17 @@ do { if ((p->debug & D_PACKETS) || OSPF_FORCE_DEBUG) \ #include "lib/string.h" #define OSPF_PROTO 89 + #ifndef IPV6 +#define OSPFv2 1 #define OSPF_VERSION 2 #define AllSPFRouters ipa_from_u32(0xe0000005) /* 224.0.0.5 */ #define AllDRouters ipa_from_u32(0xe0000006) /* 224.0.0.6 */ -#define DEFAULTDES ipa_from_u32(0) #else -#error OSPF for IPv6 is not implemented (mail to Feela <feela@network.cz>) +#define OSPFv3 1 +#define OSPF_VERSION 3 +#define AllSPFRouters _MI(0xFF020000, 0, 0, 5) /* FF02::5 */ +#define AllDRouters _MI(0xFF020000, 0, 0, 6) /* FF02::6 */ #endif @@ -118,32 +123,37 @@ struct ospf_area_config list stubnet_list; }; -struct obits -{ -#ifdef CPU_BIG_ENDIAN - u8 unused2:2; - u8 dc:1; - u8 ea:1; - u8 np:1; - u8 mc:1; - u8 e:1; - u8 unused1:1; -#else - u8 unused1:1; - u8 e:1; - u8 mc:1; - u8 np:1; - u8 ea:1; - u8 dc:1; - u8 unused2:2; + +/* 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) #endif -}; -union options -{ - u8 byte; - struct obits bit; -}; +#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 struct ospf_iface @@ -152,9 +162,7 @@ struct ospf_iface struct iface *iface; /* Nest's iface */ struct ospf_area *oa; struct object_lock *lock; - sock *hello_sk; /* Hello socket */ - sock *dr_sk; /* For states DR or BACKUP */ - sock *ip_sk; /* IP socket (for DD ...) */ + sock *sk; /* IP socket (for DD ...) */ list neigh_list; /* List of neigbours */ u32 cost; /* Cost of iface */ u32 waitint; /* number of sec before changing state from wait */ @@ -167,15 +175,27 @@ struct ospf_iface u16 inftransdelay; /* The estimated number of seconds it takes to transmit a Link State Update Packet over this interface. LSAs contained in the update */ - u16 autype; u16 helloint; /* number of seconds between hello sending */ + +#ifdef OSPFv2 list *passwords; + u16 autype; u32 csn; /* Last used crypt seq number */ bird_clock_t csn_use; /* Last time when packet with that CSN was sent */ +#endif + ip_addr drip; /* Designated router */ u32 drid; ip_addr bdrip; /* Backup DR */ u32 bdrid; + +#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 */ + ip_addr lladdr; /* Used link-local addr */ +#endif + u8 type; /* OSPF view of type */ #define OSPF_IT_BCAST 0 #define OSPF_IT_NBMA 1 @@ -206,15 +226,21 @@ struct ospf_iface #define HELLOINT_D 10 #define POLLINT_D 20 #define DEADC_D 4 -#define WAIT_DMH 4 /* Value of Wait timer - not found it in RFC - * - using 4*HELLO - */ - struct top_hash_entry *nlsa; /* Originated net lsa */ - int orignet; /* Schedule network LSA origination */ - int fadj; /* Number of full adjacent neigh */ +#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 */ + struct top_hash_entry *link_lsa; /* Originated link LSA */ + struct top_hash_entry *pxn_lsa; /* Originated prefix LSA */ +#endif + int fadj; /* Number of full adjacent neigh */ list nbma_list; - u8 priority; /* A router priority for DR election */ + u8 priority; /* A router priority for DR election */ u8 ioprob; + u8 dr_up; /* Socket is a member of DRouters group */ u32 rxbuf; }; @@ -232,35 +258,17 @@ union ospf_auth struct ospf_md5 md5; }; -struct ospf_packet -{ - u8 version; - u8 type; + +/* Packet types */ #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 */ - u16 length; - u32 routerid; - u32 areaid; + +/* Area IDs */ #define BACKBONE 0 - u16 checksum; - u16 autype; - union ospf_auth u; -}; -struct ospf_hello_packet -{ - struct ospf_packet ospf_packet; - ip_addr netmask; - u16 helloint; - u8 options; - u8 priority; - u32 deadint; - ip_addr dr; - ip_addr bdr; -}; struct immsb { @@ -282,164 +290,326 @@ union imms u8 byte; struct immsb bit; }; - -struct ospf_dbdes_packet -{ - struct ospf_packet ospf_packet; - u16 iface_mtu; - u8 options; - union imms imms; /* I, M, MS bits */ #define DBDES_MS 1 #define DBDES_M 2 #define DBDES_I 4 - u32 ddseq; + + +#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; +}; + + +#endif + + + + 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 */ + +#ifdef OSPFv2 u8 options; u8 type; + +#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 + +#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) + +#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 + u32 id; -#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 u32 rt; /* Advertising router */ s32 sn; /* LS Sequence number */ -#define LSA_INITSEQNO 0x80000001 -#define LSA_MAXSEQNO 0x7fffffff +#define LSA_INITSEQNO ((s32) 0x80000001) +#define LSA_MAXSEQNO ((s32) 0x7fffffff) u16 checksum; u16 length; }; -struct vebb -{ -#ifdef CPU_BIG_ENDIAN - u8 padding:5; - u8 v:1; - u8 e:1; - u8 b:1; -#else - u8 b:1; - u8 e:1; - u8 v:1; - u8 padding:5; -#endif -}; -union veb -{ - u8 byte; - struct vebb bit; -}; +#define LSART_PTP 1 +#define LSART_NET 2 +#define LSART_STUB 3 +#define LSART_VLNK 4 + + +#ifdef OSPFv2 struct ospf_lsa_rt { - union veb veb; - u8 padding; +#ifdef CPU_BIG_ENDIAN + u16 options; /* VEB flags only */ + u16 links; +#else u16 links; + u16 options; /* VEB flags only */ +#endif }; struct ospf_lsa_rt_link { u32 id; u32 data; +#ifdef CPU_BIG_ENDIAN u8 type; -#define LSART_PTP 1 -#define LSART_NET 2 -#define LSART_STUB 3 -#define LSART_VLNK 4 - u8 notos; - u16 metric; -}; - -struct ospf_lsa_rt_link_tos -{ /* Actually we ignore TOS. This is useless */ - u8 tos; u8 padding; u16 metric; +#else + u16 metric; + u8 padding; + u8 type; +#endif }; 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; }; -struct ospf_lsa_ext_etos +#define LSA_SUM_TOS 0xFF000000 +#define LSA_EXT_TOS 0x7F000000 +#define LSA_EXT_EBIT 0x80000000 + +/* Endianity swap for lsa->type */ +#define ntoht(x) x +#define htont(x) x + + +#else /* OSPFv3 */ + +struct ospf_lsa_rt { -#ifdef CPU_BIG_ENDIAN - u8 ebit:1; - u8 tos:7; - u8 padding1; - u16 padding2; -#else - u16 padding2; - u8 padding1; - u8 tos:7; - u8 ebit:1; -#endif + u32 options; }; -#define METRIC_MASK 0x00FFFFFF -struct ospf_lsa_sum_tos +struct ospf_lsa_rt_link { #ifdef CPU_BIG_ENDIAN - u8 tos; - u8 padding1; - u16 padding2; + u8 type; + u8 padding; + u16 metric; #else - u16 padding2; - u8 padding1; - u8 tos; + u16 metric; + u8 padding; + u8 type; #endif + u32 lif; /* Local interface ID */ + u32 nif; /* Neighbor interface ID */ + u32 id; /* Neighbor router ID */ }; -union ospf_lsa_sum_tm +struct ospf_lsa_net +{ + u32 options; + u32 routers[]; +}; + +struct ospf_lsa_sum_net { - struct ospf_lsa_sum_tos tos; u32 metric; + u32 prefix[]; }; -union ospf_lsa_ext_etm +struct ospf_lsa_sum_rt { - struct ospf_lsa_ext_etos etos; + u32 options; u32 metric; + u32 drid; }; -struct ospf_lsa_ext_tos +struct ospf_lsa_ext { - union ospf_lsa_ext_etm etm; - ip_addr fwaddr; - u32 tag; + u32 metric; + u32 rest[]; +}; + +struct ospf_lsa_link +{ + u32 options; + ip_addr lladdr; + u32 pxcount; + u32 rest[]; }; -struct ospf_lsreq_packet +struct ospf_lsa_prefix { - struct ospf_packet ospf_packet; +#ifdef CPU_BIG_ENDIAN + u16 pxcount; + u16 ref_type; +#else + u16 ref_type; + u16 pxcount; +#endif + u32 ref_id; + u32 ref_rt; + u32 rest[]; }; +#define LSA_EXT_EBIT 0x4000000 +#define LSA_EXT_FBIT 0x2000000 +#define LSA_EXT_TBIT 0x1000000 + +/* Endianity swap for lsa->type */ +#define ntoht(x) ntohs(x) +#define htont(x) htons(x) + +#endif + +#define METRIC_MASK 0x00FFFFFF +#define OPTIONS_MASK 0x00FFFFFF + +static inline unsigned +lsa_rt_count(struct ospf_lsa_header *lsa) +{ + return (lsa->length - sizeof(struct ospf_lsa_header) - sizeof(struct ospf_lsa_rt)) + / sizeof(struct ospf_lsa_rt_link); +} + +static inline unsigned +lsa_net_count(struct ospf_lsa_header *lsa) +{ + return (lsa->length - sizeof(struct ospf_lsa_header) - sizeof(struct ospf_lsa_net)) + / sizeof(u32); +} + + +#ifdef OSPFv3 + +#define IPV6_PREFIX_SPACE(x) ((((x) + 63) / 32) * 4) +#define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32) + +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; +} + +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; +} + +#endif + + + struct ospf_lsreq_header { - u16 padd1; - u8 padd2; - u8 type; + u32 type; u32 id; u32 rt; /* Advertising router */ }; @@ -450,17 +620,6 @@ struct l_lsr_head struct ospf_lsreq_header lsh; }; -struct ospf_lsupd_packet -{ - struct ospf_packet ospf_packet; - u32 lsano; /* Number of LSA's */ -}; - -struct ospf_lsack_packet -{ - struct ospf_packet ospf_packet; -}; - struct ospf_neighbor { @@ -484,10 +643,18 @@ struct ospf_neighbor u32 rid; /* Router ID */ ip_addr ip; /* IP of it's interface */ u8 priority; /* Priority */ - u8 options; /* Options received */ - ip_addr dr; /* Neigbour's idea of DR */ - ip_addr bdr; /* Neigbour's idea of BDR */ u8 adj; /* built adjacency? */ + 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 + siterator dbsi; /* Database summary list iterator */ slist lsrql; /* Link state request */ struct top_graph *lsrqh; /* LSA graph */ @@ -535,13 +702,14 @@ struct ospf_area struct ospf_area_config *ac; /* Related area config */ int origrt; /* Rt lsa origination scheduled? */ struct top_hash_entry *rt; /* My own router LSA */ + struct top_hash_entry *pxr_lsa; /* Originated prefix LSA */ list cand; /* List of candidates for RT calc. */ struct fib net_fib; /* Networks to advertise or not */ int stub; int trcap; /* Transit capability? */ + u32 options; /* Optional features */ struct proto_ospf *po; struct fib rtr; /* Routing tables for routers */ - union options opt; /* RFC2328 - A.2 */ }; struct proto_ospf @@ -562,6 +730,7 @@ struct proto_ospf struct ospf_area *backbone; /* If exists */ void *lsab; /* LSA buffer used when originating router LSAs */ int lsab_size, lsab_used; + u32 router_id; }; struct ospf_iface_patt @@ -577,20 +746,28 @@ struct ospf_iface_patt u32 deadc; u32 dead; u32 type; - u32 autype; u32 strictnbma; u32 stub; u32 vid; -#define OSPF_AUTH_NONE 0 -#define OSPF_AUTH_SIMPLE 1 -#define OSPF_AUTH_CRYPT 2 -#define OSPF_AUTH_CRYPT_SIZE 16 u32 rxbuf; #define OSPF_RXBUF_NORMAL 0 #define OSPF_RXBUF_LARGE 1 #define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ - list *passwords; list nbma_list; + + 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 }; int ospf_import_control(struct proto *p, rte **new, ea_list **attrs, @@ -600,6 +777,13 @@ void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs); void schedule_rt_lsa(struct ospf_area *oa); void schedule_rtcalc(struct proto_ospf *po); void schedule_net_lsa(struct ospf_iface *ifa); + +#ifdef OSPFv3 +void schedule_link_lsa(struct ospf_iface *ifa); +#else +static inline void schedule_link_lsa(struct ospf_iface *ifa) {} +#endif + void ospf_sh_neigh(struct proto *p, char *iff); void ospf_sh(struct proto *p); void ospf_sh_iface(struct proto *p, char *iff); |