diff options
Diffstat (limited to 'staticd/static_vrf.c')
-rw-r--r-- | staticd/static_vrf.c | 126 |
1 files changed, 77 insertions, 49 deletions
diff --git a/staticd/static_vrf.c b/staticd/static_vrf.c index a67dce2..710827a 100644 --- a/staticd/static_vrf.c +++ b/staticd/static_vrf.c @@ -18,16 +18,37 @@ DEFINE_MTYPE_STATIC(STATIC, STATIC_RTABLE_INFO, "Static Route Table Info"); -static struct static_vrf *static_vrf_alloc(void) +static int svrf_name_compare(const struct static_vrf *a, + const struct static_vrf *b) +{ + return strcmp(a->name, b->name); +} + +RB_GENERATE(svrf_name_head, static_vrf, entry, svrf_name_compare); + +struct svrf_name_head svrfs = RB_INITIALIZER(&svrfs); + +static struct static_vrf *static_vrf_lookup_by_name(const char *name) +{ + struct static_vrf svrf; + + strlcpy(svrf.name, name, sizeof(svrf.name)); + return RB_FIND(svrf_name_head, &svrfs, &svrf); +} + +struct static_vrf *static_vrf_alloc(const char *name) { struct route_table *table; struct static_vrf *svrf; struct stable_info *info; + struct vrf *vrf; safi_t safi; afi_t afi; svrf = XCALLOC(MTYPE_STATIC_RTABLE_INFO, sizeof(struct static_vrf)); + strlcpy(svrf->name, name, sizeof(svrf->name)); + for (afi = AFI_IP; afi <= AFI_IP6; afi++) { for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { if (afi == AFI_IP6) @@ -46,16 +67,56 @@ static struct static_vrf *static_vrf_alloc(void) svrf->stable[afi][safi] = table; } } + + RB_INSERT(svrf_name_head, &svrfs, svrf); + + vrf = vrf_lookup_by_name(name); + if (vrf) { + svrf->vrf = vrf; + vrf->info = svrf; + } + return svrf; } +void static_vrf_free(struct static_vrf *svrf) +{ + struct route_table *table; + struct vrf *vrf; + safi_t safi; + afi_t afi; + void *info; + + vrf = svrf->vrf; + if (vrf) { + vrf->info = NULL; + svrf->vrf = NULL; + } + + RB_REMOVE(svrf_name_head, &svrfs, svrf); + + for (afi = AFI_IP; afi <= AFI_IP6; afi++) { + for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { + table = svrf->stable[afi][safi]; + info = route_table_get_info(table); + route_table_finish(table); + XFREE(MTYPE_STATIC_RTABLE_INFO, info); + svrf->stable[afi][safi] = NULL; + } + } + + XFREE(MTYPE_STATIC_RTABLE_INFO, svrf); +} + static int static_vrf_new(struct vrf *vrf) { struct static_vrf *svrf; - svrf = static_vrf_alloc(); - vrf->info = svrf; - svrf->vrf = vrf; + svrf = static_vrf_lookup_by_name(vrf->name); + if (svrf) { + vrf->info = svrf; + svrf->vrf = vrf; + } return 0; } @@ -63,37 +124,27 @@ static int static_vrf_new(struct vrf *vrf) static int static_vrf_enable(struct vrf *vrf) { static_zebra_vrf_register(vrf); - - static_fixup_vrf_ids(vrf->info); - + static_fixup_vrf_ids(vrf); return 0; } static int static_vrf_disable(struct vrf *vrf) { + static_cleanup_vrf_ids(vrf); static_zebra_vrf_unregister(vrf); return 0; } static int static_vrf_delete(struct vrf *vrf) { - struct route_table *table; struct static_vrf *svrf; - safi_t safi; - afi_t afi; - void *info; svrf = vrf->info; - for (afi = AFI_IP; afi <= AFI_IP6; afi++) { - for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { - table = svrf->stable[afi][safi]; - info = route_table_get_info(table); - route_table_finish(table); - XFREE(MTYPE_STATIC_RTABLE_INFO, info); - svrf->stable[afi][safi] = NULL; - } + if (svrf) { + svrf->vrf = NULL; + vrf->info = NULL; } - XFREE(MTYPE_STATIC_RTABLE_INFO, svrf); + return 0; } @@ -110,43 +161,20 @@ struct route_table *static_vrf_static_table(afi_t afi, safi_t safi, return svrf->stable[afi][safi]; } -struct static_vrf *static_vrf_lookup_by_name(const char *name) -{ - struct vrf *vrf; - - if (!name) - name = VRF_DEFAULT_NAME; - - vrf = vrf_lookup_by_name(name); - if (vrf) - return ((struct static_vrf *)vrf->info); - - return NULL; -} - -static int static_vrf_config_write(struct vty *vty) -{ - struct lyd_node *dnode; - int written = 0; - - dnode = yang_dnode_get(running_config->dnode, "/frr-routing:routing"); - if (dnode) { - nb_cli_show_dnode_cmds(vty, dnode, false); - written = 1; - } - - return written; -} - void static_vrf_init(void) { vrf_init(static_vrf_new, static_vrf_enable, static_vrf_disable, static_vrf_delete); - vrf_cmd_init(static_vrf_config_write); + vrf_cmd_init(NULL); } void static_vrf_terminate(void) { + struct static_vrf *svrf, *svrf_next; + + RB_FOREACH_SAFE (svrf, svrf_name_head, &svrfs, svrf_next) + static_vrf_free(svrf); + vrf_terminate(); } |