diff --git a/zebra/interface.c b/zebra/interface.c index d5f2dc4c9a..7eb98faeb1 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -155,48 +155,8 @@ static int if_zebra_new_hook(struct interface *ifp) zebra_ptm_if_init(zebra_if); ifp->ptm_enable = zebra_ptm_get_enable_state(); -#if defined(HAVE_RTADV) - { - /* Set default router advertise values. */ - struct rtadvconf *rtadv; - rtadv = &zebra_if->rtadv; - - rtadv->AdvSendAdvertisements = 0; - rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; - rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; - rtadv->AdvIntervalTimer = 0; - rtadv->AdvManagedFlag = 0; - rtadv->AdvOtherConfigFlag = 0; - rtadv->AdvHomeAgentFlag = 0; - rtadv->AdvLinkMTU = 0; - rtadv->AdvReachableTime = 0; - rtadv->AdvRetransTimer = 0; - rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT; - memset(&rtadv->lastadvcurhoplimit, 0, - sizeof(rtadv->lastadvcurhoplimit)); - memset(&rtadv->lastadvmanagedflag, 0, - sizeof(rtadv->lastadvmanagedflag)); - memset(&rtadv->lastadvotherconfigflag, 0, - sizeof(rtadv->lastadvotherconfigflag)); - memset(&rtadv->lastadvreachabletime, 0, - sizeof(rtadv->lastadvreachabletime)); - memset(&rtadv->lastadvretranstimer, 0, - sizeof(rtadv->lastadvretranstimer)); - rtadv->AdvDefaultLifetime = - -1; /* derive from MaxRtrAdvInterval */ - rtadv->HomeAgentPreference = 0; - rtadv->HomeAgentLifetime = - -1; /* derive from AdvDefaultLifetime */ - rtadv->AdvIntervalOption = 0; - rtadv->UseFastRexmit = true; - rtadv->DefaultPreference = RTADV_PREF_MEDIUM; - - rtadv->AdvPrefixList = list_new(); - rtadv->AdvRDNSSList = list_new(); - rtadv->AdvDNSSLList = list_new(); - } -#endif /* HAVE_RTADV */ + rtadv_if_init(zebra_if); memset(&zebra_if->neigh_mac[0], 0, 6); @@ -271,15 +231,8 @@ static int if_zebra_delete_hook(struct interface *ifp) /* Free installed address chains tree. */ if (zebra_if->ipv4_subnets) route_table_finish(zebra_if->ipv4_subnets); -#if defined(HAVE_RTADV) - struct rtadvconf *rtadv; - - rtadv = &zebra_if->rtadv; - list_delete(&rtadv->AdvPrefixList); - list_delete(&rtadv->AdvRDNSSList); - list_delete(&rtadv->AdvDNSSLList); -#endif /* HAVE_RTADV */ + rtadv_if_fini(zebra_if); zebra_evpn_if_cleanup(zebra_if); zebra_evpn_mac_ifp_del(ifp); @@ -1078,15 +1031,7 @@ void if_up(struct interface *ifp, bool install_connected) if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp); -#if defined(HAVE_RTADV) - /* Enable fast tx of RA if enabled && RA interval is not in msecs */ - if (zif->rtadv.AdvSendAdvertisements - && (zif->rtadv.MaxRtrAdvInterval >= 1000) - && zif->rtadv.UseFastRexmit) { - zif->rtadv.inFastRexmit = 1; - zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS; - } -#endif + rtadv_if_up(zif); /* Install connected routes to the kernel. */ if (install_connected) diff --git a/zebra/interface.h b/zebra/interface.h index c6930ce816..5569711aa7 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -30,6 +30,7 @@ #include "zebra/zebra_l2.h" #include "zebra/zebra_nhg_private.h" #include "zebra/zebra_router.h" +#include "zebra/rtadv.h" #ifdef __cplusplus extern "C" { @@ -46,218 +47,6 @@ extern "C" { #define IF_VLAN_BITMAP_MAX 4096 -#if defined(HAVE_RTADV) -/* Router advertisement parameter. From RFC4861, RFC6275 and RFC4191. */ -struct rtadvconf { - /* A flag indicating whether or not the router sends periodic Router - Advertisements and responds to Router Solicitations. - Default: false */ - int AdvSendAdvertisements; - - /* The maximum time allowed between sending unsolicited multicast - Router Advertisements from the interface, in milliseconds. - MUST be no less than 70 ms [RFC6275 7.5] and no greater - than 1800000 ms [RFC4861 6.2.1]. - - Default: 600000 milliseconds */ - int MaxRtrAdvInterval; -#define RTADV_MAX_RTR_ADV_INTERVAL 600000 - - /* The minimum time allowed between sending unsolicited multicast - Router Advertisements from the interface, in milliseconds. - MUST be no less than 30 ms [RFC6275 7.5]. - MUST be no greater than .75 * MaxRtrAdvInterval. - - Default: 0.33 * MaxRtrAdvInterval */ - int MinRtrAdvInterval; /* This field is currently unused. */ -#define RTADV_MIN_RTR_ADV_INTERVAL (0.33 * RTADV_MAX_RTR_ADV_INTERVAL) - - /* Unsolicited Router Advertisements' interval timer. */ - int AdvIntervalTimer; - - /* The true/false value to be placed in the "Managed address - configuration" flag field in the Router Advertisement. See - [ADDRCONF]. - - Default: false */ - int AdvManagedFlag; - struct timeval lastadvmanagedflag; - - - /* The true/false value to be placed in the "Other stateful - configuration" flag field in the Router Advertisement. See - [ADDRCONF]. - - Default: false */ - int AdvOtherConfigFlag; - struct timeval lastadvotherconfigflag; - - /* The value to be placed in MTU options sent by the router. A - value of zero indicates that no MTU options are sent. - - Default: 0 */ - int AdvLinkMTU; - - - /* The value to be placed in the Reachable Time field in the Router - Advertisement messages sent by the router. The value zero means - unspecified (by this router). MUST be no greater than 3,600,000 - milliseconds (1 hour). - - Default: 0 */ - uint32_t AdvReachableTime; -#define RTADV_MAX_REACHABLE_TIME 3600000 - struct timeval lastadvreachabletime; - - /* The value to be placed in the Retrans Timer field in the Router - Advertisement messages sent by the router. The value zero means - unspecified (by this router). - - Default: 0 */ - int AdvRetransTimer; - struct timeval lastadvretranstimer; - - /* The default value to be placed in the Cur Hop Limit field in the - Router Advertisement messages sent by the router. The value - should be set to that current diameter of the Internet. The - value zero means unspecified (by this router). - - Default: The value specified in the "Assigned Numbers" RFC - [ASSIGNED] that was in effect at the time of implementation. */ - int AdvCurHopLimit; - struct timeval lastadvcurhoplimit; - -#define RTADV_DEFAULT_HOPLIMIT 64 /* 64 hops */ - - /* The value to be placed in the Router Lifetime field of Router - Advertisements sent from the interface, in seconds. MUST be - either zero or between MaxRtrAdvInterval and 9000 seconds. A - value of zero indicates that the router is not to be used as a - default router. - - Default: 3 * MaxRtrAdvInterval */ - int AdvDefaultLifetime; -#define RTADV_MAX_RTRLIFETIME 9000 /* 2.5 hours */ - - /* A list of prefixes to be placed in Prefix Information options in - Router Advertisement messages sent from the interface. - - Default: all prefixes that the router advertises via routing - protocols as being on-link for the interface from which the - advertisement is sent. The link-local prefix SHOULD NOT be - included in the list of advertised prefixes. */ - struct list *AdvPrefixList; - - /* The true/false value to be placed in the "Home agent" - flag field in the Router Advertisement. See [RFC6275 7.1]. - - Default: false */ - int AdvHomeAgentFlag; -#ifndef ND_RA_FLAG_HOME_AGENT -#define ND_RA_FLAG_HOME_AGENT 0x20 -#endif - - /* The value to be placed in Home Agent Information option if Home - Flag is set. - Default: 0 */ - int HomeAgentPreference; - - /* The value to be placed in Home Agent Information option if Home - Flag is set. Lifetime (seconds) MUST not be greater than 18.2 - hours. - The value 0 has special meaning: use of AdvDefaultLifetime value. - - Default: 0 */ - int HomeAgentLifetime; -#define RTADV_MAX_HALIFETIME 65520 /* 18.2 hours */ - - /* The true/false value to insert or not an Advertisement Interval - option. See [RFC 6275 7.3] - - Default: false */ - int AdvIntervalOption; - - /* The value to be placed in the Default Router Preference field of - a router advertisement. See [RFC 4191 2.1 & 2.2] - - Default: 0 (medium) */ - int DefaultPreference; -#define RTADV_PREF_MEDIUM 0x0 /* Per RFC4191. */ - - /* - * List of recursive DNS servers to include in the RDNSS option. - * See [RFC8106 5.1] - * - * Default: empty list; do not emit RDNSS option - */ - struct list *AdvRDNSSList; - - /* - * List of DNS search domains to include in the DNSSL option. - * See [RFC8106 5.2] - * - * Default: empty list; do not emit DNSSL option - */ - struct list *AdvDNSSLList; - - /* - * rfc4861 states RAs must be sent at least 3 seconds apart. - * We allow faster retransmits to speed up convergence but can - * turn that capability off to meet the rfc if needed. - */ - bool UseFastRexmit; /* True if fast rexmits are enabled */ - - uint8_t inFastRexmit; /* True if we're rexmits faster than usual */ - - /* Track if RA was configured by BGP or by the Operator or both */ - uint8_t ra_configured; /* Was RA configured? */ -#define BGP_RA_CONFIGURED (1<<0) /* BGP configured RA? */ -#define VTY_RA_CONFIGURED (1<<1) /* Operator configured RA? */ -#define VTY_RA_INTERVAL_CONFIGURED (1<<2) /* Operator configured RA interval */ - int NumFastReXmitsRemain; /* Loaded first with number of fast - rexmits to do */ - -#define RTADV_FAST_REXMIT_PERIOD 1 /* 1 sec */ -#define RTADV_NUM_FAST_REXMITS 4 /* Fast Rexmit RA 4 times on certain events */ -}; - -struct rtadv_rdnss { - /* Address of recursive DNS server to advertise */ - struct in6_addr addr; - - /* - * Lifetime in seconds; all-ones means infinity, zero - * stop using it. - */ - uint32_t lifetime; - - /* If lifetime not set, use a default of 3*MaxRtrAdvInterval */ - int lifetime_set; -}; - -/* - * [RFC1035 2.3.4] sets the maximum length of a domain name (a sequence of - * labels, each prefixed by a length octet) at 255 octets. - */ -#define RTADV_MAX_ENCODED_DOMAIN_NAME 255 - -struct rtadv_dnssl { - /* Domain name without trailing root zone dot (NUL-terminated) */ - char name[RTADV_MAX_ENCODED_DOMAIN_NAME - 1]; - - /* Name encoded as in [RFC1035 3.1] */ - uint8_t encoded_name[RTADV_MAX_ENCODED_DOMAIN_NAME]; - - /* Actual length of encoded_name */ - size_t encoded_len; - - /* Lifetime as for RDNSS */ - uint32_t lifetime; - int lifetime_set; -}; - -#endif /* HAVE_RTADV */ - /* Zebra interface type - ones of interest. */ enum zebra_iftype { ZEBRA_IF_OTHER = 0, /* Anything else */ @@ -361,10 +150,8 @@ struct zebra_if { unsigned int down_count; char down_last[FRR_TIMESTAMP_LEN]; -#if defined(HAVE_RTADV) struct rtadvconf rtadv; unsigned int ra_sent, ra_rcvd; -#endif /* HAVE_RTADV */ struct irdp_interface *irdp; diff --git a/zebra/main.c b/zebra/main.c index 3ae20361be..87f3de2d97 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -408,9 +408,7 @@ int main(int argc, char **argv) zebra_vty_init(); access_list_init(); prefix_list_init(); -#if defined(HAVE_RTADV) rtadv_cmd_init(); -#endif /* PTM socket */ #ifdef ZEBRA_PTM_SUPPORT zebra_ptm_init(); diff --git a/zebra/rib.h b/zebra/rib.h index 6b41952050..60092c9632 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -288,33 +288,6 @@ DECLARE_LIST(re_list, struct route_entry, next); #define RNODE_NEXT_RE(rn, re) RE_DEST_NEXT_ROUTE(rib_dest_from_rnode(rn), re) -#if defined(HAVE_RTADV) -PREDECL_SORTLIST_UNIQ(adv_if_list); -/* Structure which hold status of router advertisement. */ -struct rtadv { - int sock; - - struct adv_if_list_head adv_if; - struct adv_if_list_head adv_msec_if; - - struct thread *ra_read; - struct thread *ra_timer; -}; - -/* adv list node */ -struct adv_if { - char name[INTERFACE_NAMSIZ]; - struct adv_if_list_item list_item; -}; - -static int adv_if_cmp(const struct adv_if *a, const struct adv_if *b) -{ - return if_cmp_name_func(a->name, b->name); -} - -DECLARE_SORTLIST_UNIQ(adv_if_list, struct adv_if, list_item, adv_if_cmp); -#endif /* HAVE_RTADV */ - /* * rib_table_info_t * diff --git a/zebra/rtadv.c b/zebra/rtadv.c index e1d2016e66..b24dc89a68 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -73,6 +73,28 @@ DEFINE_MTYPE_STATIC(ZEBRA, ADV_IF, "Advertised Interface"); #define ALLNODE "ff02::1" #define ALLROUTER "ff02::2" +/* adv list node */ +struct adv_if { + char name[INTERFACE_NAMSIZ]; + struct adv_if_list_item list_item; +}; + +static int adv_if_cmp(const struct adv_if *a, const struct adv_if *b) +{ + return if_cmp_name_func(a->name, b->name); +} + +DECLARE_SORTLIST_UNIQ(adv_if_list, struct adv_if, list_item, adv_if_cmp); + +static int rtadv_prefix_cmp(const struct rtadv_prefix *a, + const struct rtadv_prefix *b) +{ + return prefix_cmp(&a->prefix, &b->prefix); +} + +DECLARE_RBTREE_UNIQ(rtadv_prefixes, struct rtadv_prefix, item, + rtadv_prefix_cmp); + DEFINE_MTYPE_STATIC(ZEBRA, RTADV_RDNSS, "Router Advertisement RDNSS"); DEFINE_MTYPE_STATIC(ZEBRA, RTADV_DNSSL, "Router Advertisement DNSSL"); @@ -315,7 +337,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp, } /* Fill in prefix. */ - for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) { + frr_each (rtadv_prefixes, zif->rtadv.prefixes, rprefix) { struct nd_opt_prefix_info *pinfo; pinfo = (struct nd_opt_prefix_info *)(buf + len); @@ -1065,31 +1087,20 @@ static void rtadv_prefix_free(struct rtadv_prefix *rtadv_prefix) XFREE(MTYPE_RTADV_PREFIX, rtadv_prefix); } -static struct rtadv_prefix *rtadv_prefix_lookup(struct list *rplist, - struct prefix_ipv6 *p) -{ - struct listnode *node; - struct rtadv_prefix *rprefix; - - for (ALL_LIST_ELEMENTS_RO(rplist, node, rprefix)) - if (prefix_same((struct prefix *)&rprefix->prefix, - (struct prefix *)p)) - return rprefix; - return NULL; -} - -static struct rtadv_prefix *rtadv_prefix_get(struct list *rplist, +static struct rtadv_prefix *rtadv_prefix_get(struct rtadv_prefixes_head *list, struct prefix_ipv6 *p) { - struct rtadv_prefix *rprefix; + struct rtadv_prefix *rprefix, ref; - rprefix = rtadv_prefix_lookup(rplist, p); + ref.prefix = *p; + + rprefix = rtadv_prefixes_find(list, &ref); if (rprefix) return rprefix; rprefix = rtadv_prefix_new(); memcpy(&rprefix->prefix, p, sizeof(struct prefix_ipv6)); - listnode_add(rplist, rprefix); + rtadv_prefixes_add(list, rprefix); return rprefix; } @@ -1107,7 +1118,7 @@ static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp) { struct rtadv_prefix *rprefix; - rprefix = rtadv_prefix_get(zif->rtadv.AdvPrefixList, &rp->prefix); + rprefix = rtadv_prefix_get(zif->rtadv.prefixes, &rp->prefix); /* * Set parameters based on where the prefix is created. @@ -1142,7 +1153,7 @@ static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp) { struct rtadv_prefix *rprefix; - rprefix = rtadv_prefix_lookup(zif->rtadv.AdvPrefixList, &rp->prefix); + rprefix = rtadv_prefixes_find(zif->rtadv.prefixes, rp); if (rprefix != NULL) { /* @@ -1165,7 +1176,7 @@ static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp) } } - listnode_delete(zif->rtadv.AdvPrefixList, (void *)rprefix); + rtadv_prefixes_del(zif->rtadv.prefixes, rprefix); rtadv_prefix_free(rprefix); return 1; } else @@ -1358,7 +1369,6 @@ void rtadv_stop_ra_all(void) { struct vrf *vrf; struct interface *ifp; - struct listnode *node, *nnode; struct zebra_if *zif; struct rtadv_prefix *rprefix; @@ -1366,8 +1376,8 @@ void rtadv_stop_ra_all(void) FOR_ALL_INTERFACES (vrf, ifp) { zif = ifp->info; - for (ALL_LIST_ELEMENTS(zif->rtadv.AdvPrefixList, - node, nnode, rprefix)) + frr_each_safe (rtadv_prefixes, zif->rtadv.prefixes, + rprefix) rtadv_prefix_reset(zif, rprefix); rtadv_stop_ra(ifp); @@ -2671,7 +2681,7 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp) if (zif->rtadv.AdvLinkMTU) vty_out(vty, " ipv6 nd mtu %d\n", zif->rtadv.AdvLinkMTU); - for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) { + frr_each (rtadv_prefixes, zif->rtadv.prefixes, rprefix) { if ((rprefix->AdvPrefixCreate == PREFIX_SRC_MANUAL) || (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH)) { vty_out(vty, " ipv6 nd prefix %pFX", &rprefix->prefix); @@ -2768,6 +2778,72 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val) return; } +void rtadv_if_up(struct zebra_if *zif) +{ + /* Enable fast tx of RA if enabled && RA interval is not in msecs */ + if (zif->rtadv.AdvSendAdvertisements && + (zif->rtadv.MaxRtrAdvInterval >= 1000) && + zif->rtadv.UseFastRexmit) { + zif->rtadv.inFastRexmit = 1; + zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS; + } +} + +void rtadv_if_init(struct zebra_if *zif) +{ + /* Set default router advertise values. */ + struct rtadvconf *rtadv; + + rtadv = &zif->rtadv; + + rtadv->AdvSendAdvertisements = 0; + rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; + rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; + rtadv->AdvIntervalTimer = 0; + rtadv->AdvManagedFlag = 0; + rtadv->AdvOtherConfigFlag = 0; + rtadv->AdvHomeAgentFlag = 0; + rtadv->AdvLinkMTU = 0; + rtadv->AdvReachableTime = 0; + rtadv->AdvRetransTimer = 0; + rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT; + memset(&rtadv->lastadvcurhoplimit, 0, + sizeof(rtadv->lastadvcurhoplimit)); + memset(&rtadv->lastadvmanagedflag, 0, + sizeof(rtadv->lastadvmanagedflag)); + memset(&rtadv->lastadvotherconfigflag, 0, + sizeof(rtadv->lastadvotherconfigflag)); + memset(&rtadv->lastadvreachabletime, 0, + sizeof(rtadv->lastadvreachabletime)); + memset(&rtadv->lastadvretranstimer, 0, + sizeof(rtadv->lastadvretranstimer)); + rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */ + rtadv->HomeAgentPreference = 0; + rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */ + rtadv->AdvIntervalOption = 0; + rtadv->UseFastRexmit = true; + rtadv->DefaultPreference = RTADV_PREF_MEDIUM; + + rtadv_prefixes_init(rtadv->prefixes); + + rtadv->AdvRDNSSList = list_new(); + rtadv->AdvDNSSLList = list_new(); +} + +void rtadv_if_fini(struct zebra_if *zif) +{ + struct rtadvconf *rtadv; + struct rtadv_prefix *rp; + + rtadv = &zif->rtadv; + + while ((rp = rtadv_prefixes_pop(rtadv->prefixes))) + rtadv_prefix_free(rp); + + list_delete(&rtadv->AdvRDNSSList); + list_delete(&rtadv->AdvDNSSLList); +} + void rtadv_vrf_init(struct zebra_vrf *zvrf) { if (!vrf_is_backend_netns() && (zvrf_id(zvrf) != VRF_DEFAULT)) @@ -2899,37 +2975,7 @@ bool rtadv_compiled_in(void) return true; } -#else -void rtadv_vrf_init(struct zebra_vrf *zvrf) -{ - /* Empty.*/; -} - -void rtadv_cmd_init(void) -{ - /* Empty.*/; -} - -void rtadv_add_prefix(struct zebra_if *zif, const struct prefix_ipv6 *p) -{ - /* Empty.*/; -} - -void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p) -{ - /* Empty.*/; -} - -void rtadv_stop_ra(struct interface *ifp) -{ - /* Empty.*/; -} - -void rtadv_stop_ra_all(void) -{ - /* Empty.*/; -} - +#else /* !HAVE_RTADV */ /* * If the end user does not have RADV enabled we should * handle this better diff --git a/zebra/rtadv.h b/zebra/rtadv.h index a95174b22b..26c7823747 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -24,17 +24,248 @@ #include "zebra.h" #include "vty.h" -#include "zebra/interface.h" +#include "typesafe.h" + +#include "zebra/zserv.h" #ifdef __cplusplus extern "C" { #endif -/* NB: RTADV is defined in zebra/interface.h above */ +struct interface; +struct zebra_if; + #if defined(HAVE_RTADV) +PREDECL_SORTLIST_UNIQ(adv_if_list); +/* Structure which hold status of router advertisement. */ +struct rtadv { + int sock; + + struct adv_if_list_head adv_if; + struct adv_if_list_head adv_msec_if; + + struct thread *ra_read; + struct thread *ra_timer; +}; + +PREDECL_RBTREE_UNIQ(rtadv_prefixes); + +/* Router advertisement parameter. From RFC4861, RFC6275 and RFC4191. */ +struct rtadvconf { + /* A flag indicating whether or not the router sends periodic Router + Advertisements and responds to Router Solicitations. + Default: false */ + int AdvSendAdvertisements; + + /* The maximum time allowed between sending unsolicited multicast + Router Advertisements from the interface, in milliseconds. + MUST be no less than 70 ms [RFC6275 7.5] and no greater + than 1800000 ms [RFC4861 6.2.1]. + + Default: 600000 milliseconds */ + int MaxRtrAdvInterval; +#define RTADV_MAX_RTR_ADV_INTERVAL 600000 + + /* The minimum time allowed between sending unsolicited multicast + Router Advertisements from the interface, in milliseconds. + MUST be no less than 30 ms [RFC6275 7.5]. + MUST be no greater than .75 * MaxRtrAdvInterval. + + Default: 0.33 * MaxRtrAdvInterval */ + int MinRtrAdvInterval; /* This field is currently unused. */ +#define RTADV_MIN_RTR_ADV_INTERVAL (0.33 * RTADV_MAX_RTR_ADV_INTERVAL) + + /* Unsolicited Router Advertisements' interval timer. */ + int AdvIntervalTimer; + + /* The true/false value to be placed in the "Managed address + configuration" flag field in the Router Advertisement. See + [ADDRCONF]. + + Default: false */ + int AdvManagedFlag; + struct timeval lastadvmanagedflag; + + + /* The true/false value to be placed in the "Other stateful + configuration" flag field in the Router Advertisement. See + [ADDRCONF]. + + Default: false */ + int AdvOtherConfigFlag; + struct timeval lastadvotherconfigflag; + + /* The value to be placed in MTU options sent by the router. A + value of zero indicates that no MTU options are sent. + + Default: 0 */ + int AdvLinkMTU; + + + /* The value to be placed in the Reachable Time field in the Router + Advertisement messages sent by the router. The value zero means + unspecified (by this router). MUST be no greater than 3,600,000 + milliseconds (1 hour). + + Default: 0 */ + uint32_t AdvReachableTime; +#define RTADV_MAX_REACHABLE_TIME 3600000 + struct timeval lastadvreachabletime; + + /* The value to be placed in the Retrans Timer field in the Router + Advertisement messages sent by the router. The value zero means + unspecified (by this router). + + Default: 0 */ + int AdvRetransTimer; + struct timeval lastadvretranstimer; + + /* The default value to be placed in the Cur Hop Limit field in the + Router Advertisement messages sent by the router. The value + should be set to that current diameter of the Internet. The + value zero means unspecified (by this router). + + Default: The value specified in the "Assigned Numbers" RFC + [ASSIGNED] that was in effect at the time of implementation. */ + int AdvCurHopLimit; + struct timeval lastadvcurhoplimit; + +#define RTADV_DEFAULT_HOPLIMIT 64 /* 64 hops */ + + /* The value to be placed in the Router Lifetime field of Router + Advertisements sent from the interface, in seconds. MUST be + either zero or between MaxRtrAdvInterval and 9000 seconds. A + value of zero indicates that the router is not to be used as a + default router. + + Default: 3 * MaxRtrAdvInterval */ + int AdvDefaultLifetime; +#define RTADV_MAX_RTRLIFETIME 9000 /* 2.5 hours */ + + /* A list of prefixes to be placed in Prefix Information options in + Router Advertisement messages sent from the interface. + + Default: all prefixes that the router advertises via routing + protocols as being on-link for the interface from which the + advertisement is sent. The link-local prefix SHOULD NOT be + included in the list of advertised prefixes. */ + struct rtadv_prefixes_head prefixes[1]; + + /* The true/false value to be placed in the "Home agent" + flag field in the Router Advertisement. See [RFC6275 7.1]. + + Default: false */ + int AdvHomeAgentFlag; +#ifndef ND_RA_FLAG_HOME_AGENT +#define ND_RA_FLAG_HOME_AGENT 0x20 +#endif + + /* The value to be placed in Home Agent Information option if Home + Flag is set. + Default: 0 */ + int HomeAgentPreference; + + /* The value to be placed in Home Agent Information option if Home + Flag is set. Lifetime (seconds) MUST not be greater than 18.2 + hours. + The value 0 has special meaning: use of AdvDefaultLifetime value. + + Default: 0 */ + int HomeAgentLifetime; +#define RTADV_MAX_HALIFETIME 65520 /* 18.2 hours */ + + /* The true/false value to insert or not an Advertisement Interval + option. See [RFC 6275 7.3] + + Default: false */ + int AdvIntervalOption; + + /* The value to be placed in the Default Router Preference field of + a router advertisement. See [RFC 4191 2.1 & 2.2] + + Default: 0 (medium) */ + int DefaultPreference; +#define RTADV_PREF_MEDIUM 0x0 /* Per RFC4191. */ + + /* + * List of recursive DNS servers to include in the RDNSS option. + * See [RFC8106 5.1] + * + * Default: empty list; do not emit RDNSS option + */ + struct list *AdvRDNSSList; + + /* + * List of DNS search domains to include in the DNSSL option. + * See [RFC8106 5.2] + * + * Default: empty list; do not emit DNSSL option + */ + struct list *AdvDNSSLList; + + /* + * rfc4861 states RAs must be sent at least 3 seconds apart. + * We allow faster retransmits to speed up convergence but can + * turn that capability off to meet the rfc if needed. + */ + bool UseFastRexmit; /* True if fast rexmits are enabled */ + + uint8_t inFastRexmit; /* True if we're rexmits faster than usual */ + + /* Track if RA was configured by BGP or by the Operator or both */ + uint8_t ra_configured; /* Was RA configured? */ +#define BGP_RA_CONFIGURED (1 << 0) /* BGP configured RA? */ +#define VTY_RA_CONFIGURED (1 << 1) /* Operator configured RA? */ +#define VTY_RA_INTERVAL_CONFIGURED \ + (1 << 2) /* Operator configured RA interval */ + int NumFastReXmitsRemain; /* Loaded first with number of fast + rexmits to do */ + +#define RTADV_FAST_REXMIT_PERIOD 1 /* 1 sec */ +#define RTADV_NUM_FAST_REXMITS 4 /* Fast Rexmit RA 4 times on certain events \ + */ +}; + +struct rtadv_rdnss { + /* Address of recursive DNS server to advertise */ + struct in6_addr addr; + + /* + * Lifetime in seconds; all-ones means infinity, zero + * stop using it. + */ + uint32_t lifetime; + + /* If lifetime not set, use a default of 3*MaxRtrAdvInterval */ + int lifetime_set; +}; + +/* + * [RFC1035 2.3.4] sets the maximum length of a domain name (a sequence of + * labels, each prefixed by a length octet) at 255 octets. + */ +#define RTADV_MAX_ENCODED_DOMAIN_NAME 255 + +struct rtadv_dnssl { + /* Domain name without trailing root zone dot (NUL-terminated) */ + char name[RTADV_MAX_ENCODED_DOMAIN_NAME - 1]; + + /* Name encoded as in [RFC1035 3.1] */ + uint8_t encoded_name[RTADV_MAX_ENCODED_DOMAIN_NAME]; + + /* Actual length of encoded_name */ + size_t encoded_len; + + /* Lifetime as for RDNSS */ + uint32_t lifetime; + int lifetime_set; +}; + /* Router advertisement prefix. */ struct rtadv_prefix { + struct rtadv_prefixes_item item; + /* Prefix to be advertised. */ struct prefix_ipv6 prefix; @@ -135,8 +366,6 @@ struct nd_opt_dnssl { /* DNS search list option [RFC8106 5.2] */ } __attribute__((__packed__)); #endif -#endif /* HAVE_RTADV */ - /* * ipv6 nd prefixes can be manually defined, derived from the kernel interface * configs or both. If both, manual flag/timer settings are used. @@ -158,10 +387,60 @@ extern void rtadv_vrf_terminate(struct zebra_vrf *zvrf); extern void rtadv_stop_ra(struct interface *ifp); extern void rtadv_stop_ra_all(void); extern void rtadv_cmd_init(void); -extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS); -extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS); +extern void rtadv_if_init(struct zebra_if *zif); +extern void rtadv_if_up(struct zebra_if *zif); +extern void rtadv_if_fini(struct zebra_if *zif); extern void rtadv_add_prefix(struct zebra_if *zif, const struct prefix_ipv6 *p); extern void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p); + +#else /* !HAVE_RTADV */ +struct rtadv { + /* empty structs aren't valid ISO C */ + char dummy; +}; + +struct rtadvconf { + /* same again, empty structs aren't valid ISO C */ + char dummy; +}; + +static inline void rtadv_vrf_init(struct zebra_vrf *zvrf) +{ +} +static inline void rtadv_vrf_terminate(struct zebra_vrf *zvrf) +{ +} +static inline void rtadv_cmd_init(void) +{ +} +static inline void rtadv_if_init(struct zebra_if *zif) +{ +} +static inline void rtadv_if_up(struct zebra_if *zif) +{ +} +static inline void rtadv_if_fini(struct zebra_if *zif) +{ +} +static inline void rtadv_add_prefix(struct zebra_if *zif, + const struct prefix_ipv6 *p) +{ +} +static inline void rtadv_delete_prefix(struct zebra_if *zif, + const struct prefix *p) +{ +} +static inline void rtadv_stop_ra(struct interface *ifp) +{ +} +static inline void rtadv_stop_ra_all(void) +{ +} +#endif + +extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS); +extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS); + extern uint32_t rtadv_get_interfaces_configured_from_bgp(void); extern bool rtadv_compiled_in(void); diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h index 98744f3c1f..1c3e98158d 100644 --- a/zebra/zebra_l2.h +++ b/zebra/zebra_l2.h @@ -28,6 +28,7 @@ #include "if.h" #include "vlan.h" #include "vxlan.h" +#include "zebra/zebra_vrf.h" #ifdef __cplusplus extern "C" { diff --git a/zebra/zebra_opaque.c b/zebra/zebra_opaque.c index 0a98194acb..3d757566e0 100644 --- a/zebra/zebra_opaque.c +++ b/zebra/zebra_opaque.c @@ -25,6 +25,7 @@ #include "zebra/debug.h" #include "zebra/zserv.h" #include "zebra/zebra_opaque.h" +#include "zebra/rib.h" /* Mem type */ DEFINE_MTYPE_STATIC(ZEBRA, OPQ, "ZAPI Opaque Information"); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index f88a65d952..553864d089 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -141,9 +141,8 @@ static int zebra_vrf_enable(struct vrf *vrf) zvrf->zns = zebra_ns_lookup((ns_id_t)vrf->vrf_id); else zvrf->zns = zebra_ns_lookup(NS_DEFAULT); -#if defined(HAVE_RTADV) + rtadv_vrf_init(zvrf); -#endif /* Inform clients that the VRF is now active. This is an * add for the clients. @@ -186,9 +185,7 @@ static int zebra_vrf_disable(struct vrf *vrf) /* Stop any VxLAN-EVPN processing. */ zebra_vxlan_vrf_disable(zvrf); -#if defined(HAVE_RTADV) rtadv_vrf_terminate(zvrf); -#endif /* Inform clients that the VRF is now inactive. This is a * delete for the clients. diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 21e7f286f3..02e3c197c9 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -26,6 +26,7 @@ #include #include +#include #include #ifdef __cplusplus @@ -177,9 +178,7 @@ struct zebra_vrf { struct table_manager *tbl_mgr; -#if defined(HAVE_RTADV) struct rtadv rtadv; -#endif /* HAVE_RTADV */ bool zebra_rnh_ip_default_route; bool zebra_rnh_ipv6_default_route; diff --git a/zebra/zserv.h b/zebra/zserv.h index 7a5be001be..9986cc9f7e 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -36,14 +36,14 @@ #include "lib/linklist.h" /* for list */ #include "lib/workqueue.h" /* for work_queue */ #include "lib/hook.h" /* for DECLARE_HOOK, DECLARE_KOOH */ - -#include "zebra/zebra_vrf.h" /* for zebra_vrf */ /* clang-format on */ #ifdef __cplusplus extern "C" { #endif +struct zebra_vrf; + /* Default port information. */ #define ZEBRA_VTY_PORT 2601