From: vivek Date: Fri, 19 Feb 2016 02:47:32 +0000 (-0800) Subject: Zebra: Restrict automatic RA enable to relevant interfaces X-Git-Tag: frr-2.0-rc1~1121 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=30a3822f2bc1db2fa3fbee8bec42898996ecbb07;p=matthieu%2Ffrr.git Zebra: Restrict automatic RA enable to relevant interfaces When enabling IPv6 Router Advertisements automatically based on the presence of IPv6 address on an interface, do it only for relevant interfaces. Note: This needs a configure option for completion. Ticket: CM-9358 Reviewed By: CCR-4116 Testing Done: Manual verification --- diff --git a/zebra/connected.c b/zebra/connected.c index f040e9d362..fea7fc06fc 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -68,8 +68,11 @@ connected_withdraw (struct connected *ifc) UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); /* Enable RA suppression if there are no IPv6 addresses on this interface */ - if (! ipv6_address_configured(ifc->ifp)) - ipv6_nd_suppress_ra_set (ifc->ifp, RA_SUPPRESS); + 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)) { @@ -99,7 +102,10 @@ connected_announce (struct interface *ifp, struct connected *ifc) if_subnet_add (ifp, ifc); else if (ifc->address->family == AF_INET6) - ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); + { + if (interface_ipv6_auto_ra_allowed (ifp)) + ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); + } zebra_interface_address_add_update (ifp, ifc); diff --git a/zebra/interface.c b/zebra/interface.c index 051b116b9b..8b25c33f17 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1871,7 +1871,9 @@ ipv6_address_install (struct vty *vty, struct interface *ifp, /* Add to linked list. */ listnode_add (ifp->connected, ifc); - ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); + /* 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. */ @@ -1971,8 +1973,11 @@ ipv6_address_uninstall (struct vty *vty, struct interface *ifp, } /* Enable RA suppression if there are no IPv6 addresses on this interface */ - if (! ipv6_address_configured(ifp)) - ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS); + 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 diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 54652b8531..61dd8b620e 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1221,8 +1221,6 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h, char *name = NULL; char *kind = NULL; char *slave_kind = NULL; - struct connected *ifc; - struct listnode *node; vrf_id_t vrf_id = ns_id; @@ -1295,9 +1293,11 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h, { if_down (ifp); //Ideally, we should have down/delete come from kernel // if_delete_update (ifp); //Pending: see how best to make the old ifp unusable - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) - if (ifc->address->family == AF_INET6) - ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS); + if (interface_ipv6_auto_ra_allowed (ifp)) + { + if (ipv6_address_configured (ifp)) + ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS); + } } if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE) || @@ -1309,9 +1309,11 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h, { if_update_vrf (ifp, name, strlen(name), vrf_id); - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) - if (ifc->address->family == AF_INET6) - ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); + if (interface_ipv6_auto_ra_allowed (ifp)) + { + if (ipv6_address_configured (ifp)) + ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); + } } set_ifindex(ifp, ifi->ifi_index); diff --git a/zebra/rtadv.h b/zebra/rtadv.h index 46b282aed6..e955d34d65 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -110,4 +110,20 @@ extern void rtadv_terminate (struct zebra_vrf *); extern void rtadv_cmd_init (void); extern void ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status); + +/* 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 ((strncmp (ifp->name, "eth", strlen("eth")) == 0) || + (strncmp (ifp->name, "lo", strlen("lo")) == 0) || + (strncmp (ifp->name, "switch", strlen("switch")) == 0)) + return 0; + return 1; +#else + return 0; +#endif +} + #endif /* _ZEBRA_RTADV_H */