From: vivek Date: Tue, 22 Mar 2016 16:52:35 +0000 (+0000) Subject: Zebra: Restrict IPv6 RA to valid interfaces X-Git-Tag: frr-2.0-rc1~1048 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=c23af4d3e6ea864774f0bedfccc9ed1acb2cfab2;p=mirror%2Ffrr.git Zebra: Restrict IPv6 RA to valid interfaces 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 Reviewed-by: Don Slice Ticket: CM-9849 Reviewed By: CCR-4334 Testing Done: Manual --- diff --git a/lib/if.h b/lib/if.h index a8e674765f..797a68bf82 100644 --- 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; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 0ec4498276..6258c4bf65 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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); } diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 23e3c3a6ef..1d81b1e109 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -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)) { diff --git a/zebra/rtadv.h b/zebra/rtadv.h index e8d84f9dee..a3ea425931 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -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