diff --git a/sharpd/sharp_globals.h b/sharpd/sharp_globals.h index 065fb092d4..4e5c933667 100644 --- a/sharpd/sharp_globals.h +++ b/sharpd/sharp_globals.h @@ -38,6 +38,7 @@ struct sharp_routes { int32_t repeat; uint8_t inst; + vrf_id_t vrf_id; struct timeval t_start; struct timeval t_end; diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 9018cfb359..fbcbbe3fdc 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -39,17 +39,28 @@ #endif DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd, - "sharp watch X:X::X:X$nhop [connected$connected]", + "sharp watch [vrf NAME$name] X:X::X:X$nhop [connected$connected]", "Sharp routing Protocol\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 import check changes\n" "The v6 nexthop to signal for watching\n" "Should the route be connected\n") { + struct vrf *vrf; struct prefix p; 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) type_import = false; @@ -63,23 +74,36 @@ DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd, p.family = AF_INET6; 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; } DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd, - "sharp watch A.B.C.D$nhop [connected$connected]", + "sharp watch [vrf NAME$name] A.B.C.D$nhop [connected$connected]", "Sharp routing Protocol\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 import check changes\n" "The v4 nexthop to signal for watching\n" "Should the route be connected\n") { + struct vrf *vrf; struct prefix p; 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)); if (n) @@ -92,7 +116,8 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd, p.family = AF_INET; 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; } @@ -132,10 +157,12 @@ DEFPY (install_routes_data_dump, DEFPY (install_routes, install_routes_cmd, - "sharp install routes |nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]", + "sharp install routes [vrf NAME$name] |nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]", "Sharp routing Protocol\n" "install some routes\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" "v6 Address to start /32 generation at\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" "How many times to repeat this command\n") { + struct vrf *vrf; struct prefix prefix; uint32_t rts; @@ -176,6 +204,16 @@ DEFPY (install_routes, } 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) { struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group); if (!nhgc) { @@ -195,12 +233,15 @@ DEFPY (install_routes, 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.inst = instance; + sg.r.vrf_id = vrf->vrf_id; 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; } @@ -237,16 +278,19 @@ DEFPY(vrf_label, vrf_label_cmd, DEFPY (remove_routes, remove_routes_cmd, - "sharp remove routes (1-1000000)$routes [instance (0-255)$instance]", + "sharp remove routes [vrf NAME$name] (1-1000000)$routes [instance (0-255)$instance]", "Sharp Routing Protocol\n" "Remove some routes\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" "v6 Starting spot\n" "Routes to uninstall\n" "instance to use\n" "Value of instance\n") { + struct vrf *vrf; struct prefix prefix; sg.r.total_routes = routes; @@ -265,9 +309,18 @@ DEFPY (remove_routes, 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.vrf_id = vrf->vrf_id; 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; } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 4682dbc73a..f1e83628c2 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -131,8 +131,8 @@ static int interface_state_down(int command, struct zclient *zclient, return 0; } -void sharp_install_routes_helper(struct prefix *p, uint8_t instance, - struct nexthop_group *nhg, +void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id, + uint8_t instance, struct nexthop_group *nhg, uint32_t routes) { uint32_t temp, i; @@ -148,7 +148,7 @@ void sharp_install_routes_helper(struct prefix *p, uint8_t instance, monotime(&sg.r.t_start); for (i = 0; i < routes; i++) { - route_add(p, (uint8_t)instance, nhg); + route_add(p, vrf_id, (uint8_t)instance, nhg); if (v4) p->u.prefix4.s_addr = htonl(++temp); 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, - uint32_t routes) +void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id, + uint8_t instance, uint32_t routes) { uint32_t temp, i; bool v4 = false; @@ -172,7 +172,7 @@ void sharp_remove_routes_helper(struct prefix *p, uint8_t instance, monotime(&sg.r.t_start); for (i = 0; i < routes; i++) { - route_delete(p, (uint8_t)instance); + route_delete(p, vrf_id, (uint8_t)instance); if (v4) p->u.prefix4.s_addr = htonl(++temp); else @@ -190,12 +190,14 @@ static void handle_repeated(bool installed) if (installed) { 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) { 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); } } @@ -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); } -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_nexthop *api_nh; @@ -263,7 +266,7 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg) int i = 0; memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; + api.vrf_id = vrf_id; api.type = ZEBRA_ROUTE_SHARP; api.instance = instance; 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)) { api_nh = &api.nexthops[i]; - api_nh->vrf_id = VRF_DEFAULT; + api_nh->vrf_id = nh->vrf_id; api_nh->type = nh->type; switch (nh->type) { 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); } -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; memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; + api.vrf_id = vrf_id; api.type = ZEBRA_ROUTE_SHARP; api.safi = SAFI_UNICAST; api.instance = instance; @@ -320,7 +323,7 @@ void route_delete(struct prefix *p, uint8_t instance) 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) { int command; @@ -337,7 +340,7 @@ void sharp_zebra_nexthop_watch(struct prefix *p, bool import, 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", __PRETTY_FUNCTION__); } diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index b219022f02..57ffcc7690 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -25,15 +25,16 @@ 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 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); -extern void route_delete(struct prefix *p, uint8_t instance); -extern void sharp_zebra_nexthop_watch(struct prefix *p, bool import, - bool watch, bool connected); +extern void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance); +extern void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, + bool import, bool watch, bool connected); -extern void sharp_install_routes_helper(struct prefix *p, uint8_t instance, - struct nexthop_group *nhg, - uint32_t routes); -extern void sharp_remove_routes_helper(struct prefix *p, uint8_t instance, - uint32_t routes); +extern void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id, + uint8_t instance, + struct nexthop_group *nhg, + uint32_t routes); +extern void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id, + uint8_t instance, uint32_t routes); #endif diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index c3b861c242..cabc8be8dd 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -168,10 +168,31 @@ static void zebra_router_free_table(struct zebra_router_table *zrt) table_info = route_table_get_info(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_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) { return 1 diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index fb28495917..e5043f38ae 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -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, uint32_t tableid, afi_t afi, 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); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index d42aad0d24..1300ca24f3 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -208,8 +208,11 @@ static int zebra_vrf_disable(struct vrf *vrf) * table, see rib_close_table above * 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; + } route_table_finish(zvrf->rnh_table[afi]); zvrf->rnh_table[afi] = NULL; @@ -256,14 +259,12 @@ static int zebra_vrf_delete(struct vrf *vrf) /* release allocated memory */ for (afi = AFI_IP; afi <= AFI_IP6; afi++) { - void *table_info; - for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { table = zvrf->table[afi][safi]; if (table) { - table_info = route_table_get_info(table); - route_table_finish(table); - XFREE(MTYPE_RIB_TABLE_INFO, table_info); + zebra_router_release_table(zvrf, zvrf->table_id, + afi, safi); + zvrf->table[afi][safi] = NULL; } }