]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Zebra: Restrict IPv6 RA to valid interfaces
authorvivek <vivek@cumulusnetworks.com>
Tue, 22 Mar 2016 16:52:35 +0000 (16:52 +0000)
committervivek <vivek@cumulusnetworks.com>
Tue, 22 Mar 2016 16:52:35 +0000 (16:52 +0000)
Restrict interfaces on which IPv6 Router Advertisements are allowed. The list
excludes loopback interfaces including the VRF device interface; specific to
Cumulus, it also includes "switch0" and "ethX" interfaces.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
Ticket: CM-9849
Reviewed By: CCR-4334
Testing Done: Manual

lib/if.h
zebra/rt_netlink.c
zebra/rtadv.c
zebra/rtadv.h

index a8e674765f1a307c92d4fc512229488ae38ce654..797a68bf8281e37bbd753a6b155955096df75f57 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -91,6 +91,7 @@ struct interface
 #define ZEBRA_INTERFACE_ACTIVE     (1 << 0)
 #define ZEBRA_INTERFACE_SUB        (1 << 1)
 #define ZEBRA_INTERFACE_LINKDETECTION (1 << 2)
+#define ZEBRA_INTERFACE_VRF_LOOPBACK (1 << 3)
 
   /* Interface flags. */
   uint64_t flags;
index 0ec44982761f842b18fce5dd20f5b8adb136aa64..6258c4bf65365ad9590c5f96968224df3c8685a5 100644 (file)
@@ -599,6 +599,7 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
   char *name = NULL;
   char *kind = NULL;
   char *slave_kind = NULL;
+  int vrf_device = 0;
 
   ifi = NLMSG_DATA (h);
 
@@ -643,6 +644,7 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
 
       if (kind && strcmp(kind, "vrf") == 0)
         {
+          vrf_device = 1;
           netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
           vrf_id = (vrf_id_t)ifi->ifi_index;
         }
@@ -661,6 +663,8 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
   ifp = if_get_by_name_vrf (name, vrf_id);
   set_ifindex(ifp, ifi->ifi_index);
   ifp->flags = ifi->ifi_flags & 0x0000fffff;
+  if (vrf_device)
+    SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
   ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
   ifp->metric = 0;
 
@@ -1219,6 +1223,7 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
   char *name = NULL;
   char *kind = NULL;
   char *slave_kind = NULL;
+  int vrf_device = 0;
 
   vrf_id_t vrf_id = ns_id;
 
@@ -1271,6 +1276,7 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
 
       if (kind && strcmp(kind, "vrf") == 0)
         {
+          vrf_device = 1;
           netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
           vrf_id = (vrf_id_t)ifi->ifi_index;
         }
@@ -1319,6 +1325,8 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
           /* Update interface information. */
           set_ifindex(ifp, ifi->ifi_index);
           ifp->flags = ifi->ifi_flags & 0x0000fffff;
+          if (vrf_device)
+            SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
           ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
           ifp->metric = 0;
 
@@ -1381,6 +1389,7 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
       if (IS_ZEBRA_DEBUG_KERNEL)
         zlog_debug ("RTM_DELLINK for %s(%u)", name, ifp->ifindex);
 
+      UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
       if_delete_update (ifp);
     }
 
index 23e3c3a6ef4552de742e731867a990975a9ba10d..1d81b1e1093c8347c89429a9593e11bc4206d0e7 100644 (file)
@@ -393,7 +393,9 @@ rtadv_timer (struct thread *thread)
   for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
     for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp))
       {
-        if (if_is_loopback (ifp) || ! if_is_operative (ifp))
+        if (if_is_loopback (ifp) ||
+            CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) ||
+            ! if_is_operative (ifp))
           continue;
 
         zif = ifp->info;
@@ -520,7 +522,8 @@ rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int h
     zlog_debug ("%s(%u): Rx RA/RS len %d from %s",
                 ifp->name, ifp->ifindex, len, addr_str);
 
-  if (if_is_loopback (ifp))
+  if (if_is_loopback (ifp) ||
+      CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
     return;
 
   /* Check interface configuration. */
@@ -770,9 +773,10 @@ DEFUN (ipv6_nd_suppress_ra,
 
   ifp = vty->index;
 
-  if (if_is_loopback (ifp))
+  if (if_is_loopback (ifp) ||
+      CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
     {
-      vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
+      vty_out (vty, "Cannot configure IPv6 Router Advertisements on this  interface%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
 
@@ -792,9 +796,10 @@ DEFUN (no_ipv6_nd_suppress_ra,
 
   ifp = vty->index;
 
-  if (if_is_loopback (ifp))
+  if (if_is_loopback (ifp) ||
+      CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
     {
-      vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
+      vty_out (vty, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE);
       return CMD_WARNING;
     }
 
@@ -1786,7 +1791,8 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
 
   zif = ifp->info;
 
-  if (! if_is_loopback (ifp))
+  if (!(if_is_loopback (ifp) ||
+        CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)))
     {
       if (ipv6_address_configured(ifp))
         {
index e8d84f9dee8887c53b94ad800d31e139c93c4bbd..a3ea4259314dc0f7eb60e450059460b3f4860bc0 100644 (file)
@@ -116,9 +116,11 @@ 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, "lo", strlen("lo")) == 0) ||
       (strncmp (ifp->name, "switch", strlen("switch")) == 0))
     return 0;
 #endif