From: Donald Sharp Date: Wed, 4 May 2016 00:04:43 +0000 (-0400) Subject: zebra: Add code to add/remove statics from the rib X-Git-Tag: frr-2.0-rc1~938 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=fb148af4a143a521c8274d54a6d65e698e179aa3;p=mirror%2Ffrr.git zebra: Add code to add/remove statics from the rib On enable/disable of static routes add and remove them from the rib as appropriate. Ticket: CM-10139 Signed-off-by: Donald Sharp Reviewed-by: Vivek Venkatraman Reviewed-by: Don Slice --- diff --git a/zebra/interface.c b/zebra/interface.c index 91eb5c49ce..ff7cf21512 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -706,6 +706,8 @@ if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id) ifp->vrf_id, ifp->name); rib_update (old_vrf_id, RIB_UPDATE_IF_CHANGE); rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); + + zebra_vrf_static_route_interface_fixup (ifp); } static void diff --git a/zebra/rib.h b/zebra/rib.h index f22d7aa420..d41519042e 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -29,6 +29,7 @@ #include "queue.h" #include "nexthop.h" #include "vrf.h" +#include "if.h" #define DISTANCE_INFINITY 255 #define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */ @@ -204,6 +205,8 @@ struct static_route union g_addr addr; unsigned int ifindex; + char ifname[INTERFACE_NAMSIZ + 1]; + /* bit flags */ u_char flags; /* @@ -379,6 +382,10 @@ extern void rib_init (void); extern unsigned long rib_score_proto (u_char proto, u_short instance); extern void rib_queue_add (struct route_node *rn); +extern void +static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si); +extern void +static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si); extern int static_add_ipv4 (struct prefix *p, struct in_addr *gate, unsigned int ifindex, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 59da68e245..312a90bc5f 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2742,7 +2742,7 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p, } /* Install static route into rib. */ -static void +void static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) { struct rib *rib; @@ -2914,7 +2914,7 @@ static_nexthop_same (struct nexthop *nexthop, struct static_route *si) } /* Uninstall static route from RIB. */ -static void +void static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) { struct route_node *rn; @@ -3074,6 +3074,8 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, unsigned int ifindex, si->tag = tag; si->vrf_id = zvrf->vrf_id; si->ifindex = ifindex; + if (si->ifindex) + strcpy(si->ifname, ifindex2ifname_vrf (si->ifindex, si->vrf_id)); if (gate) si->addr.ipv4 = *gate; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 0eba902112..f76bc98190 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -94,16 +94,93 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info) return 0; } +/* + * Moving an interface amongst different vrf's + * causes the interface to get a new ifindex + * so we need to find static routes with + * the old ifindex and replace with new + * ifindex to insert back into the table + */ +void +zebra_vrf_static_route_interface_fixup (struct interface *ifp) +{ + afi_t afi; + safi_t safi; + struct zebra_vrf *zvrf = zebra_vrf_lookup (ifp->vrf_id); + struct route_table *stable = NULL; + struct route_node *rn = NULL; + struct static_route *si = NULL; + + if (!zvrf) + return; + + for (afi = AFI_IP; afi < AFI_MAX; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + stable = zvrf->stable[afi][safi]; + if (stable) + for (rn = route_top (stable); rn; rn = route_next (rn)) + { + if (rn->info) + { + si = rn->info; + if ((strcmp (si->ifname, ifp->name) == 0) && + (si->ifindex != ifp->ifindex)) + { + si->ifindex = ifp->ifindex; + static_install_route (afi, safi, &rn->p, si); + } + } + } + } + } + +} + /* Callback upon enabling a VRF. */ static int zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) { struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info); + struct route_table *stable = NULL; + struct route_node *rn = NULL; + struct static_route *si = NULL; + struct interface *ifp = NULL; + afi_t afi; + safi_t safi; assert (zvrf); zebra_vrf_add_update (zvrf); + for (afi = AFI_IP; afi < AFI_MAX; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + stable = zvrf->stable[afi][safi]; + if (stable) + { + for (rn = route_top (stable); rn; rn = route_next (rn)) + { + if (rn->info) + { + si = rn->info; + si->vrf_id = vrf_id; + if (si->ifindex) + { + ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id); + if (ifp) + si->ifindex = ifp->ifindex; + else + continue; + } + static_install_route (afi, safi, &rn->p, si); + } + } + } + } + } return 0; } @@ -112,11 +189,30 @@ static int zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) { struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info); + struct route_table *stable = NULL; + struct route_node *rn = NULL; + afi_t afi; + safi_t safi; if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug ("VRF %s id %u is now disabled.", zvrf->name, zvrf->vrf_id); + for (afi = AFI_IP; afi < AFI_MAX; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + stable = zvrf->stable[afi][safi]; + if (stable) + { + for (rn = route_top (stable); rn; rn = route_next (rn)) + { + if (rn->info) + static_uninstall_route(afi, safi, &rn->p, rn->info); + } + } + } + } return 0; } diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 36889e089d..54f8bdc744 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -80,6 +80,7 @@ struct route_table * zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, vrf_id_t vrf_id, u_int32_t table_id); +extern void zebra_vrf_static_route_interface_fixup (struct interface *ifp); extern void zebra_vrf_update_all (struct zserv *client); extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id); extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index de86efef3e..6b2f65d700 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3243,7 +3243,7 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) vty_out (vty, " %s", inet_ntoa (si->addr.ipv4)); break; case STATIC_IFINDEX: - vty_out (vty, " %s", ifindex2ifname_vrf(si->ifindex, si->vrf_id)); + vty_out (vty, " %s", si->ifname); break; case STATIC_IPV4_BLACKHOLE: vty_out (vty, " Null0"); @@ -5509,7 +5509,7 @@ static_config_ipv6 (struct vty *vty) vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ)); break; case STATIC_IFINDEX: - vty_out (vty, " %s", ifindex2ifname_vrf (si->ifindex, si->vrf_id)); + vty_out (vty, " %s", si->ifname); break; case STATIC_IPV6_GATEWAY_IFINDEX: vty_out (vty, " %s %s",