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 <sharpd@cumulusnetworks.com>
Reviewed-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-05-03 20:04:43 -04:00
parent 0b6d694ba0
commit fb148af4a1
6 changed files with 112 additions and 4 deletions

View File

@ -706,6 +706,8 @@ if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id)
ifp->vrf_id, ifp->name); ifp->vrf_id, ifp->name);
rib_update (old_vrf_id, RIB_UPDATE_IF_CHANGE); rib_update (old_vrf_id, RIB_UPDATE_IF_CHANGE);
rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
zebra_vrf_static_route_interface_fixup (ifp);
} }
static void static void

View File

@ -29,6 +29,7 @@
#include "queue.h" #include "queue.h"
#include "nexthop.h" #include "nexthop.h"
#include "vrf.h" #include "vrf.h"
#include "if.h"
#define DISTANCE_INFINITY 255 #define DISTANCE_INFINITY 255
#define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */ #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; union g_addr addr;
unsigned int ifindex; unsigned int ifindex;
char ifname[INTERFACE_NAMSIZ + 1];
/* bit flags */ /* bit flags */
u_char 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 unsigned long rib_score_proto (u_char proto, u_short instance);
extern void rib_queue_add (struct route_node *rn); 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 extern int
static_add_ipv4 (struct prefix *p, struct in_addr *gate, unsigned int ifindex, static_add_ipv4 (struct prefix *p, struct in_addr *gate, unsigned int ifindex,

View File

@ -2742,7 +2742,7 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
} }
/* Install static route into rib. */ /* Install static route into rib. */
static void void
static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
{ {
struct rib *rib; struct rib *rib;
@ -2914,7 +2914,7 @@ static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
} }
/* Uninstall static route from RIB. */ /* Uninstall static route from RIB. */
static void void
static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
{ {
struct route_node *rn; 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->tag = tag;
si->vrf_id = zvrf->vrf_id; si->vrf_id = zvrf->vrf_id;
si->ifindex = ifindex; si->ifindex = ifindex;
if (si->ifindex)
strcpy(si->ifname, ifindex2ifname_vrf (si->ifindex, si->vrf_id));
if (gate) if (gate)
si->addr.ipv4 = *gate; si->addr.ipv4 = *gate;

View File

@ -94,16 +94,93 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
return 0; 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. */ /* Callback upon enabling a VRF. */
static int static int
zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info) zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
{ {
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*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); assert (zvrf);
zebra_vrf_add_update (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; return 0;
} }
@ -112,11 +189,30 @@ static int
zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info) zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
{ {
struct zebra_vrf *zvrf = (struct zebra_vrf *)(*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) if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug ("VRF %s id %u is now disabled.", zlog_debug ("VRF %s id %u is now disabled.",
zvrf->name, zvrf->vrf_id); 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; return 0;
} }

View File

@ -80,6 +80,7 @@ struct route_table *
zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
vrf_id_t vrf_id, u_int32_t table_id); 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 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_lookup (vrf_id_t vrf_id);
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *); extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *);

View File

@ -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)); vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
break; break;
case STATIC_IFINDEX: case STATIC_IFINDEX:
vty_out (vty, " %s", ifindex2ifname_vrf(si->ifindex, si->vrf_id)); vty_out (vty, " %s", si->ifname);
break; break;
case STATIC_IPV4_BLACKHOLE: case STATIC_IPV4_BLACKHOLE:
vty_out (vty, " Null0"); 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)); vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
break; break;
case STATIC_IFINDEX: case STATIC_IFINDEX:
vty_out (vty, " %s", ifindex2ifname_vrf (si->ifindex, si->vrf_id)); vty_out (vty, " %s", si->ifname);
break; break;
case STATIC_IPV6_GATEWAY_IFINDEX: case STATIC_IPV6_GATEWAY_IFINDEX:
vty_out (vty, " %s %s", vty_out (vty, " %s %s",