--- embedaddon/quagga/zebra/rib.h 2013/07/21 23:54:41 1.1.1.3 +++ embedaddon/quagga/zebra/rib.h 2016/11/02 10:09:10 1.1.1.4 @@ -23,6 +23,7 @@ #ifndef _ZEBRA_RIB_H #define _ZEBRA_RIB_H +#include "linklist.h" #include "prefix.h" #include "table.h" #include "queue.h" @@ -56,12 +57,19 @@ struct rib /* Type fo this route. */ int type; + /* VRF identifier. */ + vrf_id_t vrf_id; + /* Which routing table */ int table; /* Metric */ u_int32_t metric; + /* MTU */ + u_int32_t mtu; + u_int32_t nexthop_mtu; + /* Distance. */ u_char distance; @@ -74,6 +82,8 @@ struct rib /* RIB internal status */ u_char status; #define RIB_ENTRY_REMOVED (1 << 0) +#define RIB_ENTRY_CHANGED (1 << 1) +#define RIB_ENTRY_SELECTED_FIB (1 << 2) /* Nexthop information. */ u_char nexthop_num; @@ -164,55 +174,29 @@ typedef struct rib_dest_t_ RIB_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), rib, next) /* Static route information. */ -struct static_ipv4 +struct static_route { /* For linked list. */ - struct static_ipv4 *prev; - struct static_ipv4 *next; + struct static_route *prev; + struct static_route *next; - /* Administrative distance. */ - u_char distance; + /* VRF identifier. */ + vrf_id_t vrf_id; - /* Flag for this static route's type. */ - u_char type; -#define STATIC_IPV4_GATEWAY 1 -#define STATIC_IPV4_IFNAME 2 -#define STATIC_IPV4_BLACKHOLE 3 - - /* Nexthop value. */ - union - { - struct in_addr ipv4; - char *ifname; - } gate; - - /* bit flags */ - u_char flags; -/* - see ZEBRA_FLAG_REJECT - ZEBRA_FLAG_BLACKHOLE - */ -}; - -#ifdef HAVE_IPV6 -/* Static route information. */ -struct static_ipv6 -{ - /* For linked list. */ - struct static_ipv6 *prev; - struct static_ipv6 *next; - /* Administrative distance. */ u_char distance; /* Flag for this static route's type. */ u_char type; -#define STATIC_IPV6_GATEWAY 1 -#define STATIC_IPV6_GATEWAY_IFNAME 2 -#define STATIC_IPV6_IFNAME 3 +#define STATIC_IPV4_GATEWAY 1 +#define STATIC_IPV4_IFNAME 2 +#define STATIC_IPV4_BLACKHOLE 3 +#define STATIC_IPV6_GATEWAY 4 +#define STATIC_IPV6_GATEWAY_IFNAME 5 +#define STATIC_IPV6_IFNAME 6 /* Nexthop value. */ - struct in6_addr ipv6; + union g_addr addr; char *ifname; /* bit flags */ @@ -222,7 +206,6 @@ struct static_ipv6 ZEBRA_FLAG_BLACKHOLE */ }; -#endif /* HAVE_IPV6 */ enum nexthop_types_t { @@ -245,7 +228,7 @@ struct nexthop /* Interface index. */ char *ifname; - unsigned int ifindex; + ifindex_t ifindex; enum nexthop_types_t type; @@ -253,22 +236,106 @@ struct nexthop #define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */ #define NEXTHOP_FLAG_FIB (1 << 1) /* FIB nexthop. */ #define NEXTHOP_FLAG_RECURSIVE (1 << 2) /* Recursive nexthop. */ +#define NEXTHOP_FLAG_ONLINK (1 << 3) /* Nexthop should be installed onlink. */ - /* Nexthop address or interface name. */ + /* Nexthop address */ union g_addr gate; - - /* Recursive lookup nexthop. */ - u_char rtype; - unsigned int rifindex; - union g_addr rgate; union g_addr src; + + /* Nexthops obtained by recursive resolution. + * + * If the nexthop struct needs to be resolved recursively, + * NEXTHOP_FLAG_RECURSIVE will be set in flags and the nexthops + * obtained by recursive resolution will be added to `resolved'. + * Only one level of recursive resolution is currently supported. */ + struct nexthop *resolved; }; +/* The following for loop allows to iterate over the nexthop + * structure of routes. + * + * We have to maintain quite a bit of state: + * + * nexthop: The pointer to the current nexthop, either in the + * top-level chain or in the resolved chain of ni. + * tnexthop: The pointer to the current nexthop in the top-level + * nexthop chain. + * recursing: Information if nh currently is in the top-level chain + * (0) or in a resolved chain (1). + * + * Initialization: Set `nexthop' and `tnexthop' to the head of the + * top-level chain. As nexthop is in the top level chain, set recursing + * to 0. + * + * Iteration check: Check that the `nexthop' pointer is not NULL. + * + * Iteration step: This is the tricky part. Check if `nexthop' has + * NEXTHOP_FLAG_RECURSIVE set. If yes, this implies that `nexthop' is in + * the top level chain and has at least one nexthop attached to + * `nexthop->resolved'. As we want to descend into `nexthop->resolved', + * set `recursing' to 1 and set `nexthop' to `nexthop->resolved'. + * `tnexthop' is left alone in that case so we can remember which nexthop + * in the top level chain we are currently handling. + * + * If NEXTHOP_FLAG_RECURSIVE is not set, `nexthop' will progress in its + * current chain. If we are recursing, `nexthop' will be set to + * `nexthop->next' and `tnexthop' will be left alone. If we are not + * recursing, both `tnexthop' and `nexthop' will be set to `nexthop->next' + * as we are progressing in the top level chain. + * If we encounter `nexthop->next == NULL', we will clear the `recursing' + * flag as we arived either at the end of the resolved chain or at the end + * of the top level chain. In both cases, we set `tnexthop' and `nexthop' + * to `tnexthop->next', progressing to the next position in the top-level + * chain and possibly to its end marked by NULL. + */ +#define ALL_NEXTHOPS_RO(head, nexthop, tnexthop, recursing) \ + (tnexthop) = (nexthop) = (head), (recursing) = 0; \ + (nexthop); \ + (nexthop) = CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE) \ + ? (((recursing) = 1), (nexthop)->resolved) \ + : ((nexthop)->next ? ((recursing) ? (nexthop)->next \ + : ((tnexthop) = (nexthop)->next)) \ + : (((recursing) = 0),((tnexthop) = (tnexthop)->next))) + +/* Structure holding nexthop & VRF identifier, + * used for applying the route-map. */ +struct nexthop_vrfid +{ + struct nexthop *nexthop; + vrf_id_t vrf_id; +}; + + +#if defined (HAVE_RTADV) +/* Structure which hold status of router advertisement. */ +struct rtadv +{ + int sock; + + int adv_if_count; + int adv_msec_if_count; + + struct thread *ra_read; + struct thread *ra_timer; +}; +#endif /* HAVE_RTADV */ + +#ifdef HAVE_NETLINK +/* Socket interface to kernel */ +struct nlsock +{ + int sock; + int seq; + struct sockaddr_nl snl; + const char *name; +}; +#endif + /* Routing table instance. */ -struct vrf +struct zebra_vrf { - /* Identifier. This is same as routing table vector index. */ - u_int32_t id; + /* Identifier. */ + vrf_id_t vrf_id; /* Routing table name. */ char *name; @@ -284,6 +351,25 @@ struct vrf /* Static route configuration. */ struct route_table *stable[AFI_MAX][SAFI_MAX]; + +#ifdef HAVE_NETLINK + struct nlsock netlink; /* kernel messages */ + struct nlsock netlink_cmd; /* command channel */ + struct thread *t_netlink; +#endif + + /* 2nd pointer type used primarily to quell a warning on + * ALL_LIST_ELEMENTS_RO + */ + struct list _rid_all_sorted_list; + struct list _rid_lo_sorted_list; + struct list *rid_all_sorted_list; + struct list *rid_lo_sorted_list; + struct prefix rid_user_assigned; + +#if defined (HAVE_RTADV) + struct rtadv rtadv; +#endif /* HAVE_RTADV */ }; /* @@ -296,9 +382,9 @@ typedef struct rib_table_info_t_ { /* - * Back pointer to vrf. + * Back pointer to zebra_vrf. */ - struct vrf *vrf; + struct zebra_vrf *zvrf; afi_t afi; safi_t safi; @@ -317,14 +403,29 @@ typedef enum */ typedef struct rib_tables_iter_t_ { - uint32_t vrf_id; + vrf_id_t vrf_id; int afi_safi_ix; rib_tables_iter_state_t state; } rib_tables_iter_t; +/* RPF lookup behaviour */ +enum multicast_mode +{ + MCAST_NO_CONFIG = 0, /* MIX_MRIB_FIRST, but no show in config write */ + MCAST_MRIB_ONLY, /* MRIB only */ + MCAST_URIB_ONLY, /* URIB only */ + MCAST_MIX_MRIB_FIRST, /* MRIB, if nothing at all then URIB */ + MCAST_MIX_DISTANCE, /* MRIB & URIB, lower distance wins */ + MCAST_MIX_PFXLEN, /* MRIB & URIB, longer prefix wins */ + /* on equal value, MRIB wins for last 2 */ +}; + +extern void multicast_mode_ipv4_set (enum multicast_mode mode); +extern enum multicast_mode multicast_mode_ipv4_get (void); + extern const char *nexthop_type_to_str (enum nexthop_types_t nh_type); -extern struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int); +extern struct nexthop *nexthop_ifindex_add (struct rib *, ifindex_t); extern struct nexthop *nexthop_ifname_add (struct rib *, char *); extern struct nexthop *nexthop_blackhole_add (struct rib *); extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *, @@ -332,85 +433,91 @@ extern struct nexthop *nexthop_ipv4_add (struct rib *, extern struct nexthop *nexthop_ipv4_ifindex_add (struct rib *, struct in_addr *, struct in_addr *, - unsigned int); + ifindex_t); +extern int nexthop_has_fib_child(struct nexthop *); extern void rib_lookup_and_dump (struct prefix_ipv4 *); extern void rib_lookup_and_pushup (struct prefix_ipv4 *); -extern void rib_dump (const char *, const struct prefix_ipv4 *, const struct rib *); -extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *); +#define rib_dump(prefix ,rib) _rib_dump(__func__, prefix, rib) +extern void _rib_dump (const char *, + union prefix46constptr, const struct rib *); +extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *, + vrf_id_t); #define ZEBRA_RIB_LOOKUP_ERROR -1 #define ZEBRA_RIB_FOUND_EXACT 0 #define ZEBRA_RIB_FOUND_NOGATE 1 #define ZEBRA_RIB_FOUND_CONNECTED 2 #define ZEBRA_RIB_NOTFOUND 3 -#ifdef HAVE_IPV6 extern struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *); -#endif /* HAVE_IPV6 */ -extern struct vrf *vrf_lookup (u_int32_t); -extern struct route_table *vrf_table (afi_t afi, safi_t safi, u_int32_t id); -extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t id); +extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t); +extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); +extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, vrf_id_t); /* NOTE: * All rib_add_ipv[46]* functions will not just add prefix into RIB, but * also implicitly withdraw equal prefix of same type. */ extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, struct in_addr *gate, struct in_addr *src, - unsigned int ifindex, u_int32_t vrf_id, - u_int32_t, u_char, safi_t); + ifindex_t ifindex, vrf_id_t vrf_id, int table_id, + u_int32_t, u_int32_t, u_char, safi_t); extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *, safi_t); extern int rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p, - struct in_addr *gate, unsigned int ifindex, - u_int32_t, safi_t safi); + struct in_addr *gate, ifindex_t ifindex, + vrf_id_t, safi_t safi); -extern struct rib *rib_match_ipv4 (struct in_addr); +extern struct rib *rib_match_ipv4_safi (struct in_addr addr, safi_t safi, + int skip_bgp, struct route_node **rn_out, + vrf_id_t); +extern struct rib *rib_match_ipv4_multicast (struct in_addr addr, + struct route_node **rn_out, + vrf_id_t); -extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *); +extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *, vrf_id_t); -extern void rib_update (void); +extern void rib_update (vrf_id_t); extern void rib_weed_tables (void); extern void rib_sweep_route (void); +extern void rib_close_table (struct route_table *); extern void rib_close (void); extern void rib_init (void); extern unsigned long rib_score_proto (u_char proto); extern int -static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, - u_char flags, u_char distance, u_int32_t vrf_id); - +static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate, + const char *ifname, u_char flags, u_char distance, + vrf_id_t vrf_id); extern int -static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, - u_char distance, u_int32_t vrf_id); +static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate, + const char *ifname, u_char distance, vrf_id_t vrf_id); -#ifdef HAVE_IPV6 extern int rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p, - struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, - u_int32_t metric, u_char distance, safi_t safi); + struct in6_addr *gate, ifindex_t ifindex, vrf_id_t vrf_id, + int table_id, u_int32_t metric, u_int32_t mtu, + u_char distance, safi_t safi); extern int rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p, - struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi); + struct in6_addr *gate, ifindex_t ifindex, vrf_id_t vrf_id, safi_t safi); -extern struct rib *rib_lookup_ipv6 (struct in6_addr *); +extern struct rib *rib_lookup_ipv6 (struct in6_addr *, vrf_id_t); -extern struct rib *rib_match_ipv6 (struct in6_addr *); +extern struct rib *rib_match_ipv6 (struct in6_addr *, vrf_id_t); extern struct route_table *rib_table_ipv6; extern int static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, const char *ifname, u_char flags, u_char distance, - u_int32_t vrf_id); + vrf_id_t vrf_id); extern int static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, - const char *ifname, u_char distance, u_int32_t vrf_id); + const char *ifname, u_char distance, vrf_id_t vrf_id); -#endif /* HAVE_IPV6 */ - extern int rib_gc_dest (struct route_node *rn); extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter); @@ -486,10 +593,10 @@ rib_dest_table (rib_dest_t *dest) /* * rib_dest_vrf */ -static inline struct vrf * +static inline struct zebra_vrf * rib_dest_vrf (rib_dest_t *dest) { - return rib_table_info (rib_dest_table (dest))->vrf; + return rib_table_info (rib_dest_table (dest))->zvrf; } /*