Merge pull request #3889 from donaldsharp/rnh_vrf_down_stuff

zebra Rnh vrf down stuff
This commit is contained in:
Mark Stapp 2019-03-08 14:48:19 -05:00 committed by GitHub
commit 9af85338e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 38 deletions

View File

@ -38,6 +38,7 @@ struct sharp_routes {
int32_t repeat; int32_t repeat;
uint8_t inst; uint8_t inst;
vrf_id_t vrf_id;
struct timeval t_start; struct timeval t_start;
struct timeval t_end; struct timeval t_end;

View File

@ -39,17 +39,28 @@
#endif #endif
DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd, DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
"sharp watch <nexthop$n|import$import> X:X::X:X$nhop [connected$connected]", "sharp watch [vrf NAME$name] <nexthop$n|import$import> X:X::X:X$nhop [connected$connected]",
"Sharp routing Protocol\n" "Sharp routing Protocol\n"
"Watch for changes\n" "Watch for changes\n"
"The vrf we would like to watch if non-default\n"
"The NAME of the vrf\n"
"Watch for nexthop changes\n" "Watch for nexthop changes\n"
"Watch for import check changes\n" "Watch for import check changes\n"
"The v6 nexthop to signal for watching\n" "The v6 nexthop to signal for watching\n"
"Should the route be connected\n") "Should the route be connected\n")
{ {
struct vrf *vrf;
struct prefix p; struct prefix p;
bool type_import; bool type_import;
if (!name)
name = VRF_DEFAULT_NAME;
vrf = vrf_lookup_by_name(name);
if (!vrf) {
vty_out(vty, "The vrf NAME specified: %s does not exist\n",
name);
return CMD_WARNING;
}
if (n) if (n)
type_import = false; type_import = false;
@ -63,23 +74,36 @@ DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
p.family = AF_INET6; p.family = AF_INET6;
sharp_nh_tracker_get(&p); sharp_nh_tracker_get(&p);
sharp_zebra_nexthop_watch(&p, type_import, true, !!connected); sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
true, !!connected);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd, DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
"sharp watch <nexthop$n|import$import> A.B.C.D$nhop [connected$connected]", "sharp watch [vrf NAME$name] <nexthop$n|import$import> A.B.C.D$nhop [connected$connected]",
"Sharp routing Protocol\n" "Sharp routing Protocol\n"
"Watch for changes\n" "Watch for changes\n"
"The vrf we would like to watch if non-default\n"
"The NAME of the vrf\n"
"Watch for nexthop changes\n" "Watch for nexthop changes\n"
"Watch for import check changes\n" "Watch for import check changes\n"
"The v4 nexthop to signal for watching\n" "The v4 nexthop to signal for watching\n"
"Should the route be connected\n") "Should the route be connected\n")
{ {
struct vrf *vrf;
struct prefix p; struct prefix p;
bool type_import; bool type_import;
if (!name)
name = VRF_DEFAULT_NAME;
vrf = vrf_lookup_by_name(name);
if (!vrf) {
vty_out(vty, "The vrf NAME specified: %s does not exist\n",
name);
return CMD_WARNING;
}
memset(&p, 0, sizeof(p)); memset(&p, 0, sizeof(p));
if (n) if (n)
@ -92,7 +116,8 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
p.family = AF_INET; p.family = AF_INET;
sharp_nh_tracker_get(&p); sharp_nh_tracker_get(&p);
sharp_zebra_nexthop_watch(&p, type_import, true, !!connected); sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
true, !!connected);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -132,10 +157,12 @@ DEFPY (install_routes_data_dump,
DEFPY (install_routes, DEFPY (install_routes,
install_routes_cmd, install_routes_cmd,
"sharp install routes <A.B.C.D$start4|X:X::X:X$start6> <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]", "sharp install routes [vrf NAME$name] <A.B.C.D$start4|X:X::X:X$start6> <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
"Sharp routing Protocol\n" "Sharp routing Protocol\n"
"install some routes\n" "install some routes\n"
"Routes to install\n" "Routes to install\n"
"The vrf we would like to install into if non-default\n"
"The NAME of the vrf\n"
"v4 Address to start /32 generation at\n" "v4 Address to start /32 generation at\n"
"v6 Address to start /32 generation at\n" "v6 Address to start /32 generation at\n"
"Nexthop to use(Can be an IPv4 or IPv6 address)\n" "Nexthop to use(Can be an IPv4 or IPv6 address)\n"
@ -149,6 +176,7 @@ DEFPY (install_routes,
"Should we repeat this command\n" "Should we repeat this command\n"
"How many times to repeat this command\n") "How many times to repeat this command\n")
{ {
struct vrf *vrf;
struct prefix prefix; struct prefix prefix;
uint32_t rts; uint32_t rts;
@ -176,6 +204,16 @@ DEFPY (install_routes,
} }
sg.r.orig_prefix = prefix; sg.r.orig_prefix = prefix;
if (!name)
name = VRF_DEFAULT_NAME;
vrf = vrf_lookup_by_name(name);
if (!vrf) {
vty_out(vty, "The vrf NAME specified: %s does not exist\n",
name);
return CMD_WARNING;
}
if (nexthop_group) { if (nexthop_group) {
struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group); struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
if (!nhgc) { if (!nhgc) {
@ -195,12 +233,15 @@ DEFPY (install_routes,
sg.r.nhop.type = NEXTHOP_TYPE_IPV6; sg.r.nhop.type = NEXTHOP_TYPE_IPV6;
} }
sg.r.nhop.vrf_id = vrf->vrf_id;
sg.r.nhop_group.nexthop = &sg.r.nhop; sg.r.nhop_group.nexthop = &sg.r.nhop;
} }
sg.r.inst = instance; sg.r.inst = instance;
sg.r.vrf_id = vrf->vrf_id;
rts = routes; rts = routes;
sharp_install_routes_helper(&prefix, sg.r.inst, &sg.r.nhop_group, rts); sharp_install_routes_helper(&prefix, sg.r.vrf_id,
sg.r.inst, &sg.r.nhop_group, rts);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -237,16 +278,19 @@ DEFPY(vrf_label, vrf_label_cmd,
DEFPY (remove_routes, DEFPY (remove_routes,
remove_routes_cmd, remove_routes_cmd,
"sharp remove routes <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]", "sharp remove routes [vrf NAME$name] <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]",
"Sharp Routing Protocol\n" "Sharp Routing Protocol\n"
"Remove some routes\n" "Remove some routes\n"
"Routes to remove\n" "Routes to remove\n"
"The vrf we would like to remove from if non-default\n"
"The NAME of the vrf\n"
"v4 Starting spot\n" "v4 Starting spot\n"
"v6 Starting spot\n" "v6 Starting spot\n"
"Routes to uninstall\n" "Routes to uninstall\n"
"instance to use\n" "instance to use\n"
"Value of instance\n") "Value of instance\n")
{ {
struct vrf *vrf;
struct prefix prefix; struct prefix prefix;
sg.r.total_routes = routes; sg.r.total_routes = routes;
@ -265,9 +309,18 @@ DEFPY (remove_routes,
prefix.u.prefix6 = start6; prefix.u.prefix6 = start6;
} }
vrf = vrf_lookup_by_name(name ? name : VRF_DEFAULT_NAME);
if (!vrf) {
vty_out(vty, "The vrf NAME specified: %s does not exist\n",
name ? name : VRF_DEFAULT_NAME);
return CMD_WARNING;
}
sg.r.inst = instance; sg.r.inst = instance;
sg.r.vrf_id = vrf->vrf_id;
rts = routes; rts = routes;
sharp_remove_routes_helper(&prefix, sg.r.inst, rts); sharp_remove_routes_helper(&prefix, sg.r.vrf_id,
sg.r.inst, rts);
return CMD_SUCCESS; return CMD_SUCCESS;
} }

View File

@ -131,8 +131,8 @@ static int interface_state_down(int command, struct zclient *zclient,
return 0; return 0;
} }
void sharp_install_routes_helper(struct prefix *p, uint8_t instance, void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
struct nexthop_group *nhg, uint8_t instance, struct nexthop_group *nhg,
uint32_t routes) uint32_t routes)
{ {
uint32_t temp, i; uint32_t temp, i;
@ -148,7 +148,7 @@ void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
monotime(&sg.r.t_start); monotime(&sg.r.t_start);
for (i = 0; i < routes; i++) { for (i = 0; i < routes; i++) {
route_add(p, (uint8_t)instance, nhg); route_add(p, vrf_id, (uint8_t)instance, nhg);
if (v4) if (v4)
p->u.prefix4.s_addr = htonl(++temp); p->u.prefix4.s_addr = htonl(++temp);
else else
@ -156,8 +156,8 @@ void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
} }
} }
void sharp_remove_routes_helper(struct prefix *p, uint8_t instance, void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
uint32_t routes) uint8_t instance, uint32_t routes)
{ {
uint32_t temp, i; uint32_t temp, i;
bool v4 = false; bool v4 = false;
@ -172,7 +172,7 @@ void sharp_remove_routes_helper(struct prefix *p, uint8_t instance,
monotime(&sg.r.t_start); monotime(&sg.r.t_start);
for (i = 0; i < routes; i++) { for (i = 0; i < routes; i++) {
route_delete(p, (uint8_t)instance); route_delete(p, vrf_id, (uint8_t)instance);
if (v4) if (v4)
p->u.prefix4.s_addr = htonl(++temp); p->u.prefix4.s_addr = htonl(++temp);
else else
@ -190,12 +190,14 @@ static void handle_repeated(bool installed)
if (installed) { if (installed) {
sg.r.removed_routes = 0; sg.r.removed_routes = 0;
sharp_remove_routes_helper(&p, sg.r.inst, sg.r.total_routes); sharp_remove_routes_helper(&p, sg.r.vrf_id,
sg.r.inst, sg.r.total_routes);
} }
if (installed) { if (installed) {
sg.r.installed_routes = 0; sg.r.installed_routes = 0;
sharp_install_routes_helper(&p, sg.r.inst, &sg.r.nhop_group, sharp_install_routes_helper(&p, sg.r.vrf_id, sg.r.inst,
&sg.r.nhop_group,
sg.r.total_routes); sg.r.total_routes);
} }
} }
@ -255,7 +257,8 @@ void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label)
zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP); zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
} }
void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg) void route_add(struct prefix *p, vrf_id_t vrf_id,
uint8_t instance, struct nexthop_group *nhg)
{ {
struct zapi_route api; struct zapi_route api;
struct zapi_nexthop *api_nh; struct zapi_nexthop *api_nh;
@ -263,7 +266,7 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg)
int i = 0; int i = 0;
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = vrf_id;
api.type = ZEBRA_ROUTE_SHARP; api.type = ZEBRA_ROUTE_SHARP;
api.instance = instance; api.instance = instance;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
@ -274,7 +277,7 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg)
for (ALL_NEXTHOPS_PTR(nhg, nh)) { for (ALL_NEXTHOPS_PTR(nhg, nh)) {
api_nh = &api.nexthops[i]; api_nh = &api.nexthops[i];
api_nh->vrf_id = VRF_DEFAULT; api_nh->vrf_id = nh->vrf_id;
api_nh->type = nh->type; api_nh->type = nh->type;
switch (nh->type) { switch (nh->type) {
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
@ -305,12 +308,12 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg)
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
} }
void route_delete(struct prefix *p, uint8_t instance) void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance)
{ {
struct zapi_route api; struct zapi_route api;
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = vrf_id;
api.type = ZEBRA_ROUTE_SHARP; api.type = ZEBRA_ROUTE_SHARP;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.instance = instance; api.instance = instance;
@ -320,7 +323,7 @@ void route_delete(struct prefix *p, uint8_t instance)
return; return;
} }
void sharp_zebra_nexthop_watch(struct prefix *p, bool import, void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import,
bool watch, bool connected) bool watch, bool connected)
{ {
int command; int command;
@ -337,7 +340,7 @@ void sharp_zebra_nexthop_watch(struct prefix *p, bool import,
command = ZEBRA_IMPORT_ROUTE_UNREGISTER; command = ZEBRA_IMPORT_ROUTE_UNREGISTER;
} }
if (zclient_send_rnh(zclient, command, p, connected, VRF_DEFAULT) < 0) if (zclient_send_rnh(zclient, command, p, connected, vrf_id) < 0)
zlog_warn("%s: Failure to send nexthop to zebra", zlog_warn("%s: Failure to send nexthop to zebra",
__PRETTY_FUNCTION__); __PRETTY_FUNCTION__);
} }

View File

@ -25,15 +25,16 @@
extern void sharp_zebra_init(void); extern void sharp_zebra_init(void);
extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label); extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
extern void route_add(struct prefix *p, uint8_t instance, extern void route_add(struct prefix *p, vrf_id_t, uint8_t instance,
struct nexthop_group *nhg); struct nexthop_group *nhg);
extern void route_delete(struct prefix *p, uint8_t instance); extern void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance);
extern void sharp_zebra_nexthop_watch(struct prefix *p, bool import, extern void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id,
bool watch, bool connected); bool import, bool watch, bool connected);
extern void sharp_install_routes_helper(struct prefix *p, uint8_t instance, extern void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
uint8_t instance,
struct nexthop_group *nhg, struct nexthop_group *nhg,
uint32_t routes); uint32_t routes);
extern void sharp_remove_routes_helper(struct prefix *p, uint8_t instance, extern void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
uint32_t routes); uint8_t instance, uint32_t routes);
#endif #endif

View File

@ -168,10 +168,31 @@ static void zebra_router_free_table(struct zebra_router_table *zrt)
table_info = route_table_get_info(zrt->table); table_info = route_table_get_info(zrt->table);
route_table_finish(zrt->table); route_table_finish(zrt->table);
RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
XFREE(MTYPE_RIB_TABLE_INFO, table_info); XFREE(MTYPE_RIB_TABLE_INFO, table_info);
XFREE(MTYPE_ZEBRA_NS, zrt); XFREE(MTYPE_ZEBRA_NS, zrt);
} }
void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
afi_t afi, safi_t safi)
{
struct zebra_router_table finder;
struct zebra_router_table *zrt;
memset(&finder, 0, sizeof(finder));
finder.afi = afi;
finder.safi = safi;
finder.tableid = tableid;
finder.ns_id = zvrf->zns->ns_id;
zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
if (!zrt)
return;
zebra_router_free_table(zrt);
}
uint32_t zebra_router_get_next_sequence(void) uint32_t zebra_router_get_next_sequence(void)
{ {
return 1 return 1

View File

@ -117,6 +117,8 @@ extern struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf,
extern struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf, extern struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
uint32_t tableid, afi_t afi, uint32_t tableid, afi_t afi,
safi_t safi); safi_t safi);
extern void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
afi_t afi, safi_t safi);
extern int zebra_router_config_write(struct vty *vty); extern int zebra_router_config_write(struct vty *vty);

View File

@ -208,8 +208,11 @@ static int zebra_vrf_disable(struct vrf *vrf)
* table, see rib_close_table above * table, see rib_close_table above
* we no-longer need this pointer. * we no-longer need this pointer.
*/ */
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
zebra_router_release_table(zvrf, zvrf->table_id, afi,
safi);
zvrf->table[afi][safi] = NULL; zvrf->table[afi][safi] = NULL;
}
route_table_finish(zvrf->rnh_table[afi]); route_table_finish(zvrf->rnh_table[afi]);
zvrf->rnh_table[afi] = NULL; zvrf->rnh_table[afi] = NULL;
@ -256,14 +259,12 @@ static int zebra_vrf_delete(struct vrf *vrf)
/* release allocated memory */ /* release allocated memory */
for (afi = AFI_IP; afi <= AFI_IP6; afi++) { for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
void *table_info;
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
table = zvrf->table[afi][safi]; table = zvrf->table[afi][safi];
if (table) { if (table) {
table_info = route_table_get_info(table); zebra_router_release_table(zvrf, zvrf->table_id,
route_table_finish(table); afi, safi);
XFREE(MTYPE_RIB_TABLE_INFO, table_info); zvrf->table[afi][safi] = NULL;
} }
} }