diff options
Diffstat (limited to 'proto/ospf/ospf.h')
-rw-r--r-- | proto/ospf/ospf.h | 207 |
1 files changed, 119 insertions, 88 deletions
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 81c610d5..54eeb74c 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -14,7 +14,7 @@ #include "nest/bird.h" #include "lib/checksum.h" -#include "lib/ip.h" +#include "lib/idm.h" #include "lib/lists.h" #include "lib/slists.h" #include "lib/socket.h" @@ -37,14 +37,6 @@ #endif -#ifdef IPV6 -#define OSPF_IS_V2 0 -#else -#define OSPF_IS_V2 1 -#endif - -// FIXME: MAX_PREFIX_LENGTH - #define OSPF_TRACE(flags, msg, args...) \ do { if ((p->p.debug & flags) || OSPF_FORCE_DEBUG) \ log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0) @@ -66,16 +58,16 @@ log_rl(&p->log_lsa_tbf, L_REMOTE "%s: " msg, p->p.name, args) #define LOG_LSA2(msg, args...) \ - do { if (! p->log_lsa_tbf.mark) \ + do { if (! p->log_lsa_tbf.drop) \ log(L_REMOTE "%s: " msg, p->p.name, args); } while(0) #define OSPF_PROTO 89 -#define LSREFRESHTIME 1800 /* 30 minutes */ -#define MINLSINTERVAL 5 -#define MINLSARRIVAL 1 -#define LSINFINITY 0xffffff +#define LSREFRESHTIME 1800 /* 30 minutes */ +#define MINLSINTERVAL (5 S_) +#define MINLSARRIVAL (1 S_) +#define LSINFINITY 0xffffff #define OSPF_DEFAULT_TICK 1 #define OSPF_DEFAULT_STUB_COST 1000 @@ -87,16 +79,18 @@ #define OSPF_VLINK_ID_OFFSET 0x80000000 - struct ospf_config { struct proto_config c; uint tick; u8 ospf2; + u8 af_ext; + u8 af_mc; u8 rfc1583; u8 stub_router; u8 merge_external; u8 instance_id; + u8 instance_id_set; u8 abr; u8 asbr; int ecmp; @@ -125,24 +119,24 @@ struct ospf_area_config struct area_net_config { node n; - struct prefix px; + net_addr prefix; u32 tag; u8 hidden; }; struct area_net { - struct fib_node fn; u32 metric; /* With possible LSA_EXT3_EBIT for NSSA area nets */ u32 tag; u8 hidden; u8 active; + struct fib_node fn; }; struct ospf_stubnet_config { node n; - struct prefix px; + net_addr prefix; u32 cost; u8 hidden; u8 summary; @@ -177,9 +171,9 @@ struct ospf_iface_patt int tx_priority; u16 tx_length; u16 rx_buffer; - #define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ u8 instance_id; + u8 instance_id_set; u8 autype; /* OSPF_AUTH_*, not really used in OSPFv3 */ u8 strictnbma; u8 check_link; @@ -189,7 +183,6 @@ struct ospf_iface_patt u8 ptp_netmask; /* bool + 2 for unspecified */ u8 ttl_security; /* bool + 2 for TX only */ u8 bfd; - u8 bsd_secondary; list *passwords; }; @@ -220,12 +213,15 @@ struct ospf_proto int areano; /* Number of area I belong to */ int padj; /* Number of neighbors in Exchange or Loading state */ struct fib rtf; /* Routing table */ - byte ospf2; /* OSPF v2 or v3 */ - byte rfc1583; /* RFC1583 compatibility */ - byte stub_router; /* Do not forward transit traffic */ - byte merge_external; /* Should i merge external routes? */ - byte asbr; /* May i originate any ext/NSSA lsa? */ - byte ecmp; /* Maximal number of nexthops in ECMP route, or 0 */ + struct idm idm; /* OSPFv3 LSA ID map */ + u8 ospf2; /* OSPF v2 or v3 */ + u8 af_ext; /* OSPFv3-AF extension */ + u8 af_mc; /* OSPFv3-AF multicast */ + u8 rfc1583; /* RFC1583 compatibility */ + u8 stub_router; /* Do not forward transit traffic */ + u8 merge_external; /* Should i merge external routes? */ + u8 asbr; /* May i originate any ext/NSSA lsa? */ + u8 ecmp; /* Maximal number of nexthops in ECMP route, or 0 */ struct ospf_area *backbone; /* If exists */ event *flood_event; /* Event for flooding LS updates */ void *lsab; /* LSA buffer used when originating router LSAs */ @@ -273,10 +269,10 @@ struct ospf_iface sock *sk; /* IP socket */ list neigh_list; /* List of neighbors (struct ospf_neighbor) */ u32 cost; /* Cost of iface */ - u32 waitint; /* number of sec before changing state from wait */ - u32 rxmtint; /* number of seconds between LSA retransmissions */ - u32 pollint; /* Poll interval */ - u32 deadint; /* after "deadint" missing hellos is router dead */ + u32 waitint; /* Number of seconds before changing state from wait */ + u32 rxmtint; /* Number of seconds between LSA retransmissions */ + u32 pollint; /* Poll interval in seconds */ + u32 deadint; /* After deadint seconds without hellos is router dead */ u32 iface_id; /* Interface ID (iface->index or new value for vlinks) */ u32 vid; /* ID of peer of virtual link */ ip_addr vip; /* IP of peer of virtual link */ @@ -287,8 +283,8 @@ struct ospf_iface interface. LSAs contained in the update */ u16 helloint; /* number of seconds between hello sending */ list *passwords; - u32 csn; /* Last used crypt seq number */ - bird_clock_t csn_use; /* Last time when packet with that CSN was sent */ + u32 csn; /* Last used crypt seq number */ + btime csn_use; /* Last time when packet with that CSN was sent */ ip_addr all_routers; /* Multicast (or broadcast) address for all routers */ ip_addr des_routers; /* Multicast (or NULL) address for designated routers */ ip_addr drip; /* Designated router IP */ @@ -458,14 +454,15 @@ struct ospf_neighbor /* Generic option flags */ -#define OPT_V6 0x01 /* OSPFv3, LSA relevant for IPv6 routing calculation */ -#define OPT_E 0x02 /* Related to AS-external LSAs */ -#define OPT_MC 0x04 /* Related to MOSPF, not used and obsolete */ -#define OPT_N 0x08 /* Related to NSSA */ -#define OPT_P 0x08 /* OSPFv2, flags P and N share position, see NSSA RFC */ -#define OPT_EA 0x10 /* OSPFv2, external attributes, not used and obsolete */ -#define OPT_R 0x10 /* OSPFv3, originator is active router */ -#define OPT_DC 0x20 /* Related to demand circuits, not used */ +#define OPT_V6 0x0001 /* OSPFv3, LSA relevant for IPv6 routing calculation */ +#define OPT_E 0x0002 /* Related to AS-external LSAs */ +#define OPT_MC 0x0004 /* Related to MOSPF, not used and obsolete */ +#define OPT_N 0x0008 /* Related to NSSA */ +#define OPT_P 0x0008 /* OSPFv2, flags P and N share position, see NSSA RFC */ +#define OPT_EA 0x0010 /* OSPFv2, external attributes, not used and obsolete */ +#define OPT_R 0x0010 /* OSPFv3, originator is active router */ +#define OPT_DC 0x0020 /* Related to demand circuits, not used */ +#define OPT_AF 0x0100 /* OSPFv3 Address Families (RFC 5838) */ /* Router-LSA VEB flags are are stored together with links (OSPFv2) or options (OSPFv3) */ #define OPT_RT_B (0x01 << 24) @@ -682,8 +679,8 @@ struct ospf_lsa_ext3 struct ospf_lsa_ext_local { - ip_addr ip, fwaddr; - int pxlen; + net_addr net; + ip_addr fwaddr; u32 metric, ebit, fbit, tag, propagate; u8 pxopts; }; @@ -721,73 +718,102 @@ lsa_net_count(struct ospf_lsa_header *lsa) /* In ospf_area->rtr we store paths to routers, but we use RID (and not IP address) as index, so we need to encapsulate RID to IP address */ -#define ipa_from_rid(x) ipa_from_u32(x) -#define ipa_to_rid(x) ipa_to_u32(x) +#define net_from_rid(x) NET_ADDR_IP4(ip4_from_u32(x), IP4_MAX_PREFIX_LENGTH) +#define rid_from_net(x) ip4_to_u32(((net_addr_ip4 *) x)->prefix) #define IPV6_PREFIX_SPACE(x) ((((x) + 63) / 32) * 4) #define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32) -/* FIXME: these four functions should be significantly redesigned w.r.t. integration, - also should be named as ospf3_* instead of *_ipv6_* */ + +static inline int +ospf_valid_prefix(net_addr *n) +{ + /* + * In OSPFv2, prefix is stored as netmask; ip4_masklen() returns 255 for + * invalid one. But OSPFv3-AF may receive IPv4 net with 32 < pxlen < 128. + */ + uint max = (n->type == NET_IP4) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH; + return n->pxlen <= max; +} + +/* + * In OSPFv3-AF (RFC 5835), IPv4 address is encoded by just placing it in the + * first 32 bits of IPv6 address and setting remaining bits to zero. Likewise + * for IPv4 prefix, where remaining bits do not matter. We use following + * functions to convert between IPv4 and IPv4-in-IPv6 representations: + */ + +static inline ip4_addr ospf3_6to4(ip6_addr a) +{ return _MI4(_I0(a)); } + +static inline ip6_addr ospf3_4to6(ip4_addr a) +{ return _MI6(_I(a), 0, 0, 0); } + static inline u32 * -lsa_get_ipv6_prefix(u32 *buf, ip_addr *addr, int *pxlen, u8 *pxopts, u16 *rest) +ospf3_get_prefix(u32 *buf, int af, net_addr *n, u8 *pxopts, u16 *rest) { - u8 pxl = (*buf >> 24); - *pxopts = (*buf >> 16); - *rest = *buf; - *pxlen = pxl; + ip6_addr px = IP6_NONE; + uint pxlen = (*buf >> 24); + *pxopts = (*buf >> 16) & 0xff; + if (rest) *rest = *buf & 0xffff; buf++; - *addr = IPA_NONE; - -#ifdef IPV6 - if (pxl > 0) - _I0(*addr) = *buf++; - if (pxl > 32) - _I1(*addr) = *buf++; - if (pxl > 64) - _I2(*addr) = *buf++; - if (pxl > 96) - _I3(*addr) = *buf++; + if (pxlen > 0) + _I0(px) = *buf++; + if (pxlen > 32) + _I1(px) = *buf++; + if (pxlen > 64) + _I2(px) = *buf++; + if (pxlen > 96) + _I3(px) = *buf++; /* Clean up remaining bits */ - if (pxl < 128) - addr->addr[pxl / 32] &= u32_mkmask(pxl % 32); -#endif + if (pxlen < 128) + px.addr[pxlen / 32] &= u32_mkmask(pxlen % 32); + + if (af == NET_IP4) + net_fill_ip4(n, ospf3_6to4(px), pxlen); + else + net_fill_ip6(n, px, pxlen); return buf; } static inline u32 * -lsa_get_ipv6_addr(u32 *buf, ip_addr *addr) +ospf3_put_prefix(u32 *buf, net_addr *n, u8 pxopts, u16 rest) { - *addr = *(ip_addr *) buf; - return buf + 4; -} + ip6_addr px = (n->type == NET_IP4) ? ospf3_4to6(net4_prefix(n)) : net6_prefix(n); + uint pxlen = n->pxlen; -static inline u32 * -put_ipv6_prefix(u32 *buf, ip_addr addr UNUSED4, u8 pxlen UNUSED4, u8 pxopts UNUSED4, u16 lh UNUSED4) -{ -#ifdef IPV6 - *buf++ = ((pxlen << 24) | (pxopts << 16) | lh); + *buf++ = ((pxlen << 24) | (pxopts << 16) | rest); if (pxlen > 0) - *buf++ = _I0(addr); + *buf++ = _I0(px); if (pxlen > 32) - *buf++ = _I1(addr); + *buf++ = _I1(px); if (pxlen > 64) - *buf++ = _I2(addr); + *buf++ = _I2(px); if (pxlen > 96) - *buf++ = _I3(addr); -#endif + *buf++ = _I3(px); + return buf; } static inline u32 * -put_ipv6_addr(u32 *buf, ip_addr addr) +ospf3_get_addr(u32 *buf, int af, ip_addr *addr) { - *(ip_addr *) buf = addr; + ip6_addr a; + memcpy(&a, buf, 16); + *addr = (af == NET_IP4) ? ipa_from_ip4(ospf3_6to4(a)) : ipa_from_ip6(a); + return buf + 4; +} + +static inline u32 * +ospf3_put_addr(u32 *buf, ip_addr addr) +{ + ip6_addr a = ipa_is_ip4(addr) ? ospf3_4to6(ipa_to_ip4(addr)) : ipa_to_ip6(addr); + memcpy(buf, &a, 16); return buf + 4; } @@ -831,19 +857,24 @@ static inline void ospf_notify_net_lsa(struct ospf_iface *ifa) static inline void ospf_notify_link_lsa(struct ospf_iface *ifa) { ifa->update_link_lsa = 1; } - -#define ospf_is_v2(X) OSPF_IS_V2 -#define ospf_is_v3(X) (!OSPF_IS_V2) -/* static inline int ospf_is_v2(struct ospf_proto *p) { return p->ospf2; } static inline int ospf_is_v3(struct ospf_proto *p) { return ! p->ospf2; } -*/ -static inline int ospf_get_version(struct ospf_proto *p UNUSED4 UNUSED6) + +static inline int ospf_get_version(struct ospf_proto *p) { return ospf_is_v2(p) ? 2 : 3; } +static inline int ospf_is_ip4(struct ospf_proto *p) +{ return p->p.net_type == NET_IP4; } + +static inline int ospf_is_ip6(struct ospf_proto *p) +{ return p->p.net_type == NET_IP6; } + +static inline int ospf_get_af(struct ospf_proto *p) +{ return p->p.net_type; } + struct ospf_area *ospf_find_area(struct ospf_proto *p, u32 aid); static inline struct ospf_area *ospf_main_area(struct ospf_proto *p) @@ -925,7 +956,7 @@ static inline void ospf_send_to_des(struct ospf_iface *ifa) #define SKIP(DSC) do { err_dsc = DSC; goto skip; } while(0) #endif -static inline uint ospf_pkt_hdrlen(struct ospf_proto *p UNUSED4 UNUSED6) +static inline uint ospf_pkt_hdrlen(struct ospf_proto *p) { return ospf_is_v2(p) ? (sizeof(struct ospf_packet) + sizeof(union ospf_auth)) : sizeof(struct ospf_packet); } static inline void * ospf_tx_buffer(struct ospf_iface *ifa) |