]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: clean up rtadv integration
authorDavid Lamparter <equinox@diac24.net>
Sun, 18 Apr 2021 10:11:14 +0000 (12:11 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Sat, 21 May 2022 12:14:01 +0000 (14:14 +0200)
Move a few things into places they actually belong, and reduce the
number of places we have `#ifdev HAVE_RTADV`.  Just overall code
prettification.

... I had actually done this quite a while ago while doing some other
random hacking and thought it more useful to not be sitting on it on my
disk...

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
zebra/interface.c
zebra/interface.h
zebra/main.c
zebra/rib.h
zebra/rtadv.c
zebra/rtadv.h
zebra/zebra_l2.h
zebra/zebra_opaque.c
zebra/zebra_vrf.c
zebra/zebra_vrf.h
zebra/zserv.h

index d5f2dc4c9af83c009eb13dbadfacfc0fa821542e..7eb98faeb11d0a896e0a04051f2ee29955b56e60 100644 (file)
@@ -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)
index c6930ce8168f50cf7c953d687e961847d7288dbd..5569711aa7837d06ac54179261a6ec0d9333e36a 100644 (file)
@@ -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;
 
index 3ae20361be87be0cc3ca3ff68f9b15d6c165988a..87f3de2d97ef871164e7fa4708402c9d3c0b14ab 100644 (file)
@@ -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();
index 6b41952050da9073b84f5d8545ba5bab779b6803..60092c9632e619ced30a6a36acfff35c6379fbc6 100644 (file)
@@ -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
  *
index e1d2016e66d5aebbca6a823c973882b90ccf07d8..b24dc89a68b873e9dee8782b99bfba1af25b663c 100644 (file)
@@ -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;
+
+       ref.prefix = *p;
 
-       rprefix = rtadv_prefix_lookup(rplist, 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
index a95174b22b0e58b7c16f7fb5d60136eef2578c1d..26c7823747dc8814fbcfc865960c6effbcb3f5ac 100644 (file)
 
 #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);
 
index 98744f3c1fbf390598d5c14eb7f977bed1abb7ad..1c3e98158d4765a6bd80404306ea03e6c628792f 100644 (file)
@@ -28,6 +28,7 @@
 #include "if.h"
 #include "vlan.h"
 #include "vxlan.h"
+#include "zebra/zebra_vrf.h"
 
 #ifdef __cplusplus
 extern "C" {
index 0a98194acbbed3c9ac4d2426e7f91bdfcd895ee4..3d757566e05db9d986f79ec06dcd3d9d7944e03c 100644 (file)
@@ -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");
index f88a65d9520806efdf70a6ca0f0bdc808387b1dc..553864d089e2c17cc32a4c2b20c2ca50fc568c97 100644 (file)
@@ -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.
index 21e7f286f36811a617e6dc9fa6953748536862e7..02e3c197c9bea70ee71c42984813875edd7696c7 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <zebra/zebra_ns.h>
 #include <zebra/zebra_pw.h>
+#include <zebra/rtadv.h>
 #include <lib/vxlan.h>
 
 #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;
index 7a5be001be3e42c31129961d1a754aad127f317d..9986cc9f7e3cf7f6e8963216f92b665290bf0260 100644 (file)
 #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