]> git.puffer.fish Git - mirror/frr.git/commitdiff
BGP: Trigger IPv6 router advertisements upon config of unnumbered neighbor
authorvivek <vivek@cumulusnetworks.com>
Mon, 2 May 2016 20:53:38 +0000 (13:53 -0700)
committervivek <vivek@cumulusnetworks.com>
Mon, 2 May 2016 20:53:38 +0000 (13:53 -0700)
Instead of turning on IPv6 RA on every interface as soon as it has an IPv6
address, only enable it upon configuration of BGP neighbor. When the BGP
neighbor is deleted, signal that RAs can be turned off.

To support this, introduce new message interaction between BGP and Zebra.
Also, take appropriate actions in BGP upon interface add/del since the
unnumbered neighbor could exist prior to interface creation etc.

Only unnumbered IPv6 neighbors require RA, the /30 or /31 based neighbors
don't. However, to keep the interaction simple and not have to deal with
too many dynamic conditions (e.g., address deletes or neighbor change to/from
'v6only'), RAs on the interface are triggered upon any unnumbered neighbor
configuration.

BGP-triggered RAs will cause RAs to be initiated on the interface; however,
if BGP asks that RAs be stopped (upon delete of unnumbered neighbor), RAs
will continue to be exchanged if the operator has explicitly enabled.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-10640
Reviewed By: CCR-4589
Testing Done: Various manual and automated (refer to defect)

17 files changed:
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgp_zebra.h
bgpd/bgpd.c
bgpd/bgpd.h
lib/log.c
lib/zclient.c
lib/zclient.h
lib/zebra.h
zebra/connected.c
zebra/interface.c
zebra/interface.h
zebra/rt_netlink.c
zebra/rtadv.c
zebra/rtadv.h
zebra/rtadv_null.c
zebra/zserv.c

index 768abcdf25c4a28e69fb90a28cbefc0fb782aa35..bdc57769ebe731ebd76124ba401052f46e9c8855 100644 (file)
@@ -2712,6 +2712,14 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
 
       if (peer && v6only)
         SET_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
+
+      /* Request zebra to initiate IPv6 RAs on this interface. We do this
+       * any unnumbered peer in order to not worry about run-time transitions
+       * (e.g., peering is initially IPv4, but the IPv4 /30 or /31 address
+       * gets deleted later etc.)
+       */
+      if (peer->ifp)
+        bgp_zebra_initiate_radv (bgp, peer);
     }
   else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
            (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
@@ -2842,6 +2850,9 @@ DEFUN (no_neighbor,
       peer = peer_lookup_by_conf_if (vty->index, argv[0]);
       if (peer)
         {
+          /* Request zebra to terminate IPv6 RAs on this interface. */
+          if (peer->ifp)
+            bgp_zebra_terminate_radv (peer->bgp, peer);
           peer_delete (peer);
           return CMD_SUCCESS;
         }
@@ -2900,6 +2911,9 @@ DEFUN (no_neighbor_interface_config,
   peer = peer_lookup_by_conf_if (vty->index, argv[0]);
   if (peer)
     {
+      /* Request zebra to terminate IPv6 RAs on this interface. */
+      if (peer->ifp)
+        bgp_zebra_terminate_radv (peer->bgp, peer);
       peer_delete (peer);
     }
   else
index 43653a36f845f06308c85f640f62e2f094513ca4..7f5f47e062aff0d3330dcb561dce3949f4582d82 100644 (file)
@@ -167,6 +167,31 @@ bgp_read_import_check_update(int command, struct zclient *zclient,
   return 0;
 }
 
+/* Set or clear interface on which unnumbered neighbor is configured. This
+ * would in turn cause BGP to initiate or turn off IPv6 RAs on this
+ * interface.
+ */
+static void
+bgp_update_interface_nbrs (struct bgp *bgp, struct interface *ifp,
+                           struct interface *upd_ifp)
+{
+  struct listnode *node, *nnode;
+  struct peer *peer;
+
+  for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
+    {
+      if (peer->conf_if &&
+          (strcmp (peer->conf_if, ifp->name) == 0))
+        {
+          peer->ifp = upd_ifp;
+          if (upd_ifp)
+            bgp_zebra_initiate_radv (bgp, peer);
+          else
+            bgp_zebra_terminate_radv (bgp, peer);
+        }
+    }
+}
+
 static void
 bgp_start_interface_nbrs (struct bgp *bgp, struct interface *ifp)
 {
@@ -241,12 +266,20 @@ bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length,
     vrf_id_t vrf_id)
 {
   struct interface *ifp;
+  struct bgp *bgp;
 
   ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
+  if (!ifp) // unexpected
+    return 0;
 
   if (BGP_DEBUG (zebra, ZEBRA) && ifp)
     zlog_debug("Rx Intf add VRF %u IF %s", vrf_id, ifp->name);
 
+  bgp = bgp_lookup_by_vrf_id (vrf_id);
+  if (!bgp)
+    return 0;
+
+  bgp_update_interface_nbrs (bgp, ifp, ifp);
   return 0;
 }
 
@@ -256,10 +289,11 @@ bgp_interface_delete (int command, struct zclient *zclient,
 {
   struct stream *s;
   struct interface *ifp;
+  struct bgp *bgp;
 
   s = zclient->ibuf;
   ifp = zebra_interface_state_read (s, vrf_id);
-  if (! ifp) /* This may happen if we've just unregistered for a VRF. */
+  if (!ifp) /* This may happen if we've just unregistered for a VRF. */
     return 0;
 
   ifp->ifindex = IFINDEX_DELETED;
@@ -267,6 +301,11 @@ bgp_interface_delete (int command, struct zclient *zclient,
   if (BGP_DEBUG (zebra, ZEBRA))
     zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name);
 
+  bgp = bgp_lookup_by_vrf_id (vrf_id);
+  if (!bgp)
+    return 0;
+
+  bgp_update_interface_nbrs (bgp, ifp, NULL);
   return 0;
 }
 
@@ -1965,6 +2004,32 @@ bgp_zebra_instance_deregister (struct bgp *bgp)
   zclient_send_dereg_requests (zclient, bgp->vrf_id);
 }
 
+void
+bgp_zebra_initiate_radv (struct bgp *bgp, struct peer *peer)
+{
+  /* Don't try to initiate if we're not connected to Zebra */
+  if (zclient->sock < 0)
+    return;
+
+  if (BGP_DEBUG (zebra, ZEBRA))
+    zlog_debug("%u: Initiating RA for peer %s", bgp->vrf_id, peer->host);
+
+  zclient_send_interface_radv_req (zclient, bgp->vrf_id, peer->ifp, 1);
+}
+
+void
+bgp_zebra_terminate_radv (struct bgp *bgp, struct peer *peer)
+{
+  /* Don't try to terminate if we're not connected to Zebra */
+  if (zclient->sock < 0)
+    return;
+
+  if (BGP_DEBUG (zebra, ZEBRA))
+    zlog_debug("%u: Terminating RA for peer %s", bgp->vrf_id, peer->host);
+
+  zclient_send_interface_radv_req (zclient, bgp->vrf_id, peer->ifp, 0);
+}
+
 /* BGP has established connection with Zebra. */
 static void
 bgp_zebra_connected (struct zclient *zclient)
index 308834ce2bfbfa5281f01efa668bd69ed7f586e4..1770a2c0d5a453c26629a02cdb4029e5010016b9 100644 (file)
@@ -38,6 +38,9 @@ extern void bgp_zebra_announce (struct prefix *, struct bgp_info *, struct bgp *
 extern void bgp_zebra_announce_table (struct bgp *, afi_t, safi_t);
 extern void bgp_zebra_withdraw (struct prefix *, struct bgp_info *, safi_t);
 
+extern void bgp_zebra_initiate_radv (struct bgp *bgp, struct peer *peer);
+extern void bgp_zebra_terminate_radv (struct bgp *bgp, struct peer *peer);
+
 extern void bgp_zebra_instance_register (struct bgp *);
 extern void bgp_zebra_instance_deregister (struct bgp *);
 
index 26c8f48c4296699af625723264021aa566e33830..1a2c874c245dc19fcde04922e605d7de91c3f466 100644 (file)
@@ -1339,6 +1339,7 @@ bgp_peer_conf_if_to_su_update (struct peer *peer)
   prev_family = peer->su.sa.sa_family;
   if ((ifp = if_lookup_by_name_vrf (peer->conf_if, peer->bgp->vrf_id)))
     {
+      peer->ifp = ifp;
       /* If BGP unnumbered is not "v6only", we first see if we can derive the
        * peer's IPv4 address.
        */
index a07bd389f5924c6efa2d82e1a830c820b00821d7..d15a58ecd4796badb115a87618c306682f9a691b 100644 (file)
@@ -578,6 +578,7 @@ struct peer
   
   unsigned int ifindex;                /* ifindex of the BGP connection. */
   char *conf_if;                /* neighbor interface config name. */
+  struct interface *ifp;        /* corresponding interface */
   char *ifname;                        /* bind interface name. */
   char *update_if;
   union sockunion *update_source;
index b031206a21a669539201dd246078851c46c07d3d..a8577bf9a4c79441644502f75578036c5763ee4e 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -876,7 +876,9 @@ static const struct zebra_desc_table command_types[] = {
   DESC_ENTRY    (ZEBRA_REDISTRIBUTE_IPV6_ADD),
   DESC_ENTRY    (ZEBRA_REDISTRIBUTE_IPV6_DEL),
   DESC_ENTRY    (ZEBRA_INTERFACE_VRF_UPDATE),
-  DESC_ENTRY    (ZEBRA_BFD_CLIENT_REGISTER)
+  DESC_ENTRY    (ZEBRA_BFD_CLIENT_REGISTER),
+  DESC_ENTRY    (ZEBRA_INTERFACE_ENABLE_RADV),
+  DESC_ENTRY    (ZEBRA_INTERFACE_DISABLE_RADV)
 };
 #undef DESC_ENTRY
 
index 1aa1251bf5abb2b1366603b5527fe4beaee1c280..8cc6bd92a46b57a1da5bd35ff4ba92cdfca3f307 100644 (file)
@@ -481,6 +481,37 @@ zclient_send_dereg_requests (struct zclient *zclient, vrf_id_t vrf_id)
     zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, vrf_id);
 }
 
+/* Send request to zebra daemon to start or stop RA. */
+void
+zclient_send_interface_radv_req (struct zclient *zclient, vrf_id_t vrf_id,
+                                 struct interface *ifp, int enable)
+{
+  struct stream *s;
+
+  /* zclient is disabled. */
+  if (!zclient->enable)
+    return;
+
+  /* If not connected to the zebra yet. */
+  if (zclient->sock < 0)
+    return;
+
+  /* Form and send message. */
+  s = zclient->obuf;
+  stream_reset (s);
+
+  if (enable)
+    zclient_create_header (s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
+  else
+    zclient_create_header (s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
+
+  stream_putl (s, ifp->ifindex);
+
+  stream_putw_at (s, 0, stream_get_endp (s));
+
+  zclient_send_message(zclient);
+}
+
 /* Make connection to zebra daemon. */
 int
 zclient_start (struct zclient *zclient)
index d41196521777e1d4823089c04a16bee9edef3862..726f254a2ae08ca131fb497b49373e6df4a9803c 100644 (file)
@@ -175,6 +175,9 @@ extern void redist_del_instance (struct redist_proto *, u_short);
 extern void zclient_send_reg_requests (struct zclient *, vrf_id_t);
 extern void zclient_send_dereg_requests (struct zclient *, vrf_id_t);
 
+extern void zclient_send_interface_radv_req (struct zclient *zclient, vrf_id_t vrf_id,
+                                 struct interface *ifp, int enable);
+
 /* Send redistribute command to zebra daemon. Do not update zclient state. */
 extern int zebra_redistribute_send (int command, struct zclient *, afi_t, int type, u_short instance, vrf_id_t vrf_id);
 
index 751e8ce3df7d9b07f6e9ff5a93f5e77b02fa17e4..38a1889e722a0dc874f3da3ff3e57186b86ccfa5 100644 (file)
@@ -453,7 +453,9 @@ struct in_pktinfo
 #define ZEBRA_VRF_DELETE                  44
 #define ZEBRA_INTERFACE_VRF_UPDATE        45
 #define ZEBRA_BFD_CLIENT_REGISTER         46
-#define ZEBRA_MESSAGE_MAX                 47
+#define ZEBRA_INTERFACE_ENABLE_RADV       47
+#define ZEBRA_INTERFACE_DISABLE_RADV      48
+#define ZEBRA_MESSAGE_MAX                 49
 
 /* Marker value used in new Zserv, in the byte location corresponding
  * the command value in the old zserv header. To allow old and new
index 272689b5947b407e2b1f5fa1ddc89fea276a7eb0..7da40ce03ae3c917ec16637ddcbd050e6f5fb81e 100644 (file)
@@ -66,13 +66,6 @@ connected_withdraw (struct connected *ifc)
   /* The address is not in the kernel anymore, so clear the flag */
   UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
 
-  /* Enable RA suppression if there are no IPv6 addresses on this interface */
-  if (interface_ipv6_auto_ra_allowed (ifc->ifp))
-    {
-      if (! ipv6_address_configured(ifc->ifp))
-        ipv6_nd_suppress_ra_set (ifc->ifp, RA_SUPPRESS);
-    }
-
   if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
     {
       listnode_delete (ifc->ifp->connected, ifc);
@@ -100,12 +93,6 @@ connected_announce (struct interface *ifp, struct connected *ifc)
   if (ifc->address->family == AF_INET)
     if_subnet_add (ifp, ifc);
 
-  else if (ifc->address->family == AF_INET6)
-    {
-      if (interface_ipv6_auto_ra_allowed (ifp))
-        ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
-    }
-
   zebra_interface_address_add_update (ifp, ifc);
 
   if (if_is_operative(ifp))
index 66ab536cf61273b2ac7f5838251931860a44d835..91eb5c49ce5a292db384b726004a716adf9a40bc 100644 (file)
@@ -684,9 +684,6 @@ if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id)
   /* Delete all neighbor addresses learnt through IPv6 RA */
   if_down_del_nbr_connected (ifp);
 
-  /* Suppress RAs on this interface, if enabled. */
-  ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
-
   /* Send out notification on interface VRF change. */
   /* This is to issue an UPDATE or a DELETE, as appropriate. */
   zebra_interface_vrf_update_del (ifp, vrf_id);
@@ -701,10 +698,6 @@ if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id)
   /* Install connected routes (in new VRF). */
   if_install_connected (ifp);
 
-  /* Enable RAs on this interface, if IPv6 addresses are present. */
-  if (ipv6_address_configured(ifp))
-    ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
-
   /* Due to connected route change, schedule RIB processing for both old
    * and new VRF.
    */
@@ -1929,10 +1922,6 @@ ipv6_address_install (struct vty *vty, struct interface *ifp,
 
       /* Add to linked list. */
       listnode_add (ifp->connected, ifc);
-
-      /* Enable RA on this interface */
-      if (interface_ipv6_auto_ra_allowed (ifp))
-        ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
     }
 
   /* This address is configured from zebra. */
@@ -2031,13 +2020,6 @@ ipv6_address_uninstall (struct vty *vty, struct interface *ifp,
       return CMD_WARNING;
     }
 
-  /* Enable RA suppression if there are no IPv6 addresses on this interface */
-  if (interface_ipv6_auto_ra_allowed (ifp))
-    {
-      if (! ipv6_address_configured(ifp))
-        ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
-    }
-
   UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED);
   /* This information will be propagated to the zclients when the
    * kernel notification is received. */
index 2e88566e1a48b816f30c5c794fc3babc8dbba37d..3784253e6dd566ed3d8295a59a9287f27fd76efe 100644 (file)
@@ -172,6 +172,7 @@ struct rtadvconf
 #define RTADV_PREF_MEDIUM 0x0 /* Per RFC4191. */
 
   u_char inFastRexmit;          /* True if we're rexmits faster than usual */
+  u_char configured;            /* Has operator configured RA? */
   int NumFastReXmitsRemain;     /* Loaded first with number of fast rexmits to do */
 
 #define RTADV_FAST_REXMIT_PERIOD 1 /* 1 sec */
index 4102cc375d97a9303f411cba7d8472003caec9e8..0c7d72130aa06eb28fc1e845098012dd2425498d 100644 (file)
@@ -1350,13 +1350,6 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
               /* pre-configured interface, learnt now */
               if (ifp->vrf_id != vrf_id)
                 if_update_vrf (ifp, name, strlen(name), vrf_id);
-
-              /* Start IPv6 RA, if any IPv6 addresses on interface. */
-              if (interface_ipv6_auto_ra_allowed (ifp))
-                {
-                  if (ipv6_address_configured (ifp))
-                    ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
-                }
             }
 
           /* Update interface information. */
index e3e390d5655b9d50f8885e0e025da7332660adbe..9179701302d2734ace14f8538eeb997088855ef3 100644 (file)
@@ -26,6 +26,7 @@
 #include "sockopt.h"
 #include "thread.h"
 #include "if.h"
+#include "stream.h"
 #include "log.h"
 #include "prefix.h"
 #include "linklist.h"
@@ -734,7 +735,7 @@ rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
     return 0;
 }
 
-void
+static void
 ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status)
 {
   struct zebra_if *zif;
@@ -783,6 +784,58 @@ ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status statu
     }
 }
 
+/*
+ * Handle client (BGP) message to enable or disable IPv6 RA on an interface.
+ * Note that while the client could request RA on an interface on which the
+ * operator has not enabled RA, RA won't be disabled upon client request
+ * if the operator has explicitly enabled RA.
+ */
+void
+zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
+                          struct zebra_vrf *zvrf, int enable)
+{
+  struct stream *s;
+  unsigned int ifindex;
+  struct interface *ifp;
+  struct zebra_if *zif;
+
+  s = client->ibuf;
+
+  /* Get interface index. */
+  ifindex = stream_getl (s);
+
+  if (IS_ZEBRA_DEBUG_EVENT)
+    zlog_debug("%u: IF %u RA %s from client %s",
+               zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
+               zebra_route_string(client->proto));
+
+  /* Locate interface and check VRF match. */
+  ifp = if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT), ifindex);
+  if (!ifp)
+    {
+      zlog_warn("%u: IF %u RA %s client %s - interface unknown",
+               zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
+               zebra_route_string(client->proto));
+      return;
+    }
+  if (ifp->vrf_id != zvrf->vrf_id)
+    {
+      zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
+               zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
+               zebra_route_string(client->proto), ifp->vrf_id);
+      return;
+    }
+
+  zif = ifp->info;
+  if (enable)
+    ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
+  else
+    {
+      if (!zif->rtadv.configured)
+        ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
+    }
+}
+
 DEFUN (ipv6_nd_suppress_ra,
        ipv6_nd_suppress_ra_cmd,
        "ipv6 nd suppress-ra",
@@ -791,6 +844,7 @@ DEFUN (ipv6_nd_suppress_ra,
        "Suppress Router Advertisement\n")
 {
   struct interface *ifp;
+  struct zebra_if *zif;
 
   ifp = vty->index;
 
@@ -802,6 +856,8 @@ DEFUN (ipv6_nd_suppress_ra,
     }
 
   ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
+  zif = ifp->info;
+  zif->rtadv.configured = 0;
   return CMD_SUCCESS;
 }
 
@@ -814,6 +870,7 @@ DEFUN (no_ipv6_nd_suppress_ra,
        "Suppress Router Advertisement\n")
 {
   struct interface *ifp;
+  struct zebra_if *zif;
 
   ifp = vty->index;
 
@@ -825,6 +882,8 @@ DEFUN (no_ipv6_nd_suppress_ra,
     }
 
   ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
+  zif = ifp->info;
+  zif->rtadv.configured = 1;
   return CMD_SUCCESS;
 }
 
index a3ea4259314dc0f7eb60e450059460b3f4860bc0..3011505dbc3a1347cb20aca27a16378911f06e06 100644 (file)
@@ -108,26 +108,8 @@ typedef enum {
 extern void rtadv_init (struct zebra_ns *);
 extern void rtadv_terminate (struct zebra_ns *);
 extern void rtadv_cmd_init (void);
-extern void ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status);
+extern void zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
+                          struct zebra_vrf *zvrf, int enable);
 
 
-/* Can we turn on IPv6 RAs automatically on this interface? */
-static inline int
-interface_ipv6_auto_ra_allowed (struct interface *ifp)
-{
-#if defined (HAVE_RTADV)
-  if (if_is_loopback (ifp) ||
-      CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
-    return 0;
-#if defined (HAVE_CUMULUS)
-  if ((strncmp (ifp->name, "eth", strlen("eth")) == 0) ||
-      (strncmp (ifp->name, "switch", strlen("switch")) == 0))
-    return 0;
-#endif
-  return 1;
-#else
-  return 0;
-#endif
-}
-
 #endif /* _ZEBRA_RTADV_H */
index 851c8e0a645f05701e66ee6145fdad914e8dfe78..ee6eda6bdd84c4959a9dc82e7852667f4e803c7e 100644 (file)
@@ -24,7 +24,8 @@
 #include <rtadv.h>
 #include <zebra_ns.h>
 
-void ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status)
+void zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
+                          struct zebra_vrf *zvrf, int enable)
 { return; }
 
 void rtadv_init (struct zebra_ns *zns)
index 3872d17409c3f1b54f20400e55e53cb512232968..9491b39a91d0dc870c4255ae65600e3326d512bd 100644 (file)
@@ -50,6 +50,7 @@
 #include "zebra/rt_netlink.h"
 #include "zebra/interface.h"
 #include "zebra/zebra_ptm.h"
+#include "zebra/rtadv.h"
 
 /* Event list of zebra. */
 enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
@@ -2026,6 +2027,12 @@ zebra_client_read (struct thread *thread)
     case ZEBRA_BFD_CLIENT_REGISTER:
       zebra_ptm_bfd_client_register(client, sock, length);
       break;
+    case ZEBRA_INTERFACE_ENABLE_RADV:
+      zebra_interface_radv_set (client, sock, length, zvrf, 1);
+      break;
+    case ZEBRA_INTERFACE_DISABLE_RADV:
+      zebra_interface_radv_set (client, sock, length, zvrf, 0);
+      break;
     default:
       zlog_info ("Zebra received unknown command %d", command);
       break;