diff options
author | vdhingra <vdhingra@vmware.com> | 2020-04-24 14:38:43 +0200 |
---|---|---|
committer | vdhingra <vdhingra@vmware.com> | 2020-07-16 17:33:00 +0200 |
commit | 88fa5104a04af60b7d1107f02ee84fb9c0a15abe (patch) | |
tree | c2bbeecd9a5c384b7a615032c5fe13a1ff495c36 /staticd/static_routes.c | |
parent | lib : basic-routing backend configuration northbound code (diff) | |
download | frr-88fa5104a04af60b7d1107f02ee84fb9c0a15abe.tar.xz frr-88fa5104a04af60b7d1107f02ee84fb9c0a15abe.zip |
staticd : Configuration northbound implementation
1. Modifies the data structs to make the distance, tag and table-id
property of a route, i.e created a hireachical data struct to save
route and nexthop information.
2. Backend northbound implementation
Signed-off-by: VishalDhingra <vdhingra@vmware.com>
Diffstat (limited to 'staticd/static_routes.c')
-rw-r--r-- | staticd/static_routes.c | 626 |
1 files changed, 394 insertions, 232 deletions
diff --git a/staticd/static_routes.c b/staticd/static_routes.c index e8d6a4289..829fe6cd6 100644 --- a/staticd/static_routes.c +++ b/staticd/static_routes.c @@ -32,256 +32,328 @@ #include "static_memory.h" #include "static_zebra.h" -/* Install static route into rib. */ -static void static_install_route(struct route_node *rn, - struct static_route *si_changed, safi_t safi) -{ - struct static_route *si; +DEFINE_MTYPE_STATIC(STATIC, STATIC_ROUTE, "Static Route Info"); +DEFINE_MTYPE(STATIC, STATIC_PATH, "Static Path"); - for (si = rn->info; si; si = si->next) - static_zebra_nht_register(rn, si, true); +/* Install static path into rib. */ +void static_install_path(struct route_node *rn, struct static_path *pn, + safi_t safi, struct static_vrf *svrf) +{ + struct static_nexthop *nh; - si = rn->info; - if (si) - static_zebra_route_add(rn, si_changed, si->vrf_id, safi, true); + frr_each(static_nexthop_list, &pn->nexthop_list, nh) + static_zebra_nht_register(rn, nh, true); + if (static_nexthop_list_count(&pn->nexthop_list) && svrf && svrf->vrf) + static_zebra_route_add(rn, pn, safi, true); } -/* Uninstall static route from RIB. */ -static void static_uninstall_route(vrf_id_t vrf_id, safi_t safi, - struct route_node *rn, - struct static_route *si_changed) +/* Uninstall static path from RIB. */ +static void static_uninstall_path(struct route_node *rn, struct static_path *pn, + safi_t safi, struct static_vrf *svrf) { - - if (rn->info) - static_zebra_route_add(rn, si_changed, vrf_id, safi, true); + if (static_nexthop_list_count(&pn->nexthop_list)) + static_zebra_route_add(rn, pn, safi, true); else - static_zebra_route_add(rn, si_changed, vrf_id, safi, false); + static_zebra_route_add(rn, pn, safi, false); } -int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p, - struct prefix_ipv6 *src_p, union g_addr *gate, - const char *ifname, enum static_blackhole_type bh_type, - route_tag_t tag, uint8_t distance, struct static_vrf *svrf, - struct static_vrf *nh_svrf, - struct static_nh_label *snh_label, uint32_t table_id, - bool onlink) +struct route_node *static_add_route(afi_t afi, safi_t safi, struct prefix *p, + struct prefix_ipv6 *src_p, + struct static_vrf *svrf) { struct route_node *rn; - struct static_route *si; - struct static_route *pp; - struct static_route *cp; - struct static_route *update = NULL; + struct static_route_info *si; struct route_table *stable = svrf->stable[afi][safi]; - struct interface *ifp; if (!stable) - return -1; - - if (!gate && (type == STATIC_IPV4_GATEWAY - || type == STATIC_IPV4_GATEWAY_IFNAME - || type == STATIC_IPV6_GATEWAY - || type == STATIC_IPV6_GATEWAY_IFNAME)) - return -1; - - if (!ifname - && (type == STATIC_IFNAME || type == STATIC_IPV4_GATEWAY_IFNAME - || type == STATIC_IPV6_GATEWAY_IFNAME)) - return -1; + return NULL; /* Lookup static route prefix. */ rn = srcdest_rnode_get(stable, p, src_p); - /* Do nothing if there is a same static route. */ - for (si = rn->info; si; si = si->next) { - if (type == si->type - && (!gate - || ((afi == AFI_IP - && IPV4_ADDR_SAME(&gate->ipv4, &si->addr.ipv4)) - || (afi == AFI_IP6 - && IPV6_ADDR_SAME(gate, &si->addr.ipv6)))) - && (!strcmp(ifname ? ifname : "", si->ifname)) - && nh_svrf->vrf->vrf_id == si->nh_vrf_id) { - if ((distance == si->distance) && (tag == si->tag) - && (table_id == si->table_id) - && !memcmp(&si->snh_label, snh_label, - sizeof(struct static_nh_label)) - && si->bh_type == bh_type && si->onlink == onlink) { - route_unlock_node(rn); - return 0; - } - update = si; + si = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(struct static_route_info)); + static_route_info_init(si); + + rn->info = si; + + /* Mark as having FRR configuration */ + vrf_set_user_cfged(svrf->vrf); + + return rn; +} + +/* To delete the srcnodes */ +static void static_del_src_route(struct route_node *rn, safi_t safi, + struct static_vrf *svrf) +{ + struct static_path *pn; + struct static_route_info *si; + + si = rn->info; + + frr_each_safe(static_path_list, &si->path_list, pn) { + static_del_path(rn, pn, safi, svrf); + } + + XFREE(MTYPE_STATIC_ROUTE, rn->info); + route_unlock_node(rn); + /* If no other FRR config for this VRF, mark accordingly. */ + if (!static_vrf_has_config(svrf)) + vrf_reset_user_cfged(svrf->vrf); +} + +void static_del_route(struct route_node *rn, safi_t safi, + struct static_vrf *svrf) +{ + struct static_path *pn; + struct static_route_info *si; + struct route_table *src_table; + struct route_node *src_node; + + si = rn->info; + + frr_each_safe(static_path_list, &si->path_list, pn) { + static_del_path(rn, pn, safi, svrf); + } + + /* clean up for dst table */ + src_table = srcdest_srcnode_table(rn); + if (src_table) { + /* This means the route_node is part of the top hierarchy + * and refers to a destination prefix. + */ + for (src_node = route_top(src_table); src_node; + src_node = route_next(src_node)) { + static_del_src_route(src_node, safi, svrf); } } + XFREE(MTYPE_STATIC_ROUTE, rn->info); + route_unlock_node(rn); + /* If no other FRR config for this VRF, mark accordingly. */ + if (!static_vrf_has_config(svrf)) + vrf_reset_user_cfged(svrf->vrf); +} + +bool static_add_nexthop_validate(struct static_vrf *svrf, static_types type, + struct ipaddr *ipaddr) +{ + switch (type) { + case STATIC_IPV4_GATEWAY: + case STATIC_IPV4_GATEWAY_IFNAME: + if (if_lookup_exact_address(&ipaddr->ipaddr_v4, AF_INET, + svrf->vrf->vrf_id)) + return false; + break; + case STATIC_IPV6_GATEWAY: + case STATIC_IPV6_GATEWAY_IFNAME: + if (if_lookup_exact_address(&ipaddr->ipaddr_v6, AF_INET6, + svrf->vrf->vrf_id)) + return false; + break; + default: + break; + } + + return true; +} + +struct static_path *static_add_path(struct route_node *rn, uint8_t distance) +{ + struct static_path *pn; + struct static_route_info *si; + + route_lock_node(rn); + + /* Make new static route structure. */ + pn = XCALLOC(MTYPE_STATIC_PATH, sizeof(struct static_path)); + + pn->distance = distance; + static_nexthop_list_init(&(pn->nexthop_list)); + + si = rn->info; + static_path_list_add_head(&(si->path_list), pn); + + return pn; +} + +void static_del_path(struct route_node *rn, struct static_path *pn, safi_t safi, + struct static_vrf *svrf) +{ + struct static_route_info *si; + struct static_nexthop *nh; + + si = rn->info; + + static_path_list_del(&si->path_list, pn); + + frr_each_safe(static_nexthop_list, &pn->nexthop_list, nh) { + static_delete_nexthop(rn, pn, safi, svrf, nh); + } + + route_unlock_node(rn); + + XFREE(MTYPE_STATIC_PATH, pn); +} + +struct static_nexthop * +static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi, + struct static_vrf *svrf, static_types type, + struct ipaddr *ipaddr, const char *ifname, + const char *nh_vrf) +{ + struct static_nexthop *nh; + struct static_vrf *nh_svrf; + struct interface *ifp; + struct static_nexthop *cp; + + route_lock_node(rn); + + nh_svrf = static_vty_get_unknown_vrf(nh_vrf); - /* Distance or tag or label changed, delete existing first. */ - if (update) - static_delete_route(afi, safi, type, p, src_p, gate, ifname, - update->tag, update->distance, svrf, - &update->snh_label, table_id); + if (!nh_svrf) + return NULL; /* Make new static route structure. */ - si = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(struct static_route)); - - si->type = type; - si->distance = distance; - si->bh_type = bh_type; - si->tag = tag; - si->vrf_id = svrf->vrf->vrf_id; - si->nh_vrf_id = nh_svrf->vrf->vrf_id; - strlcpy(si->nh_vrfname, nh_svrf->vrf->name, sizeof(si->nh_vrfname)); - si->table_id = table_id; - si->onlink = onlink; + nh = XCALLOC(MTYPE_STATIC_NEXTHOP, sizeof(struct static_nexthop)); + + nh->type = type; + + nh->nh_vrf_id = nh_svrf->vrf->vrf_id; + strlcpy(nh->nh_vrfname, nh_svrf->vrf->name, sizeof(nh->nh_vrfname)); if (ifname) - strlcpy(si->ifname, ifname, sizeof(si->ifname)); - si->ifindex = IFINDEX_INTERNAL; + strlcpy(nh->ifname, ifname, sizeof(nh->ifname)); + nh->ifindex = IFINDEX_INTERNAL; switch (type) { case STATIC_IPV4_GATEWAY: case STATIC_IPV4_GATEWAY_IFNAME: - si->addr.ipv4 = gate->ipv4; + nh->addr.ipv4 = ipaddr->ipaddr_v4; break; case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY_IFNAME: - si->addr.ipv6 = gate->ipv6; + nh->addr.ipv6 = ipaddr->ipaddr_v6; break; - case STATIC_IFNAME: + default: break; } - - /* Save labels, if any. */ - memcpy(&si->snh_label, snh_label, sizeof(struct static_nh_label)); - /* * Add new static route information to the tree with sort by - * distance value and gateway address. + * gateway address. */ - for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next) { - if (si->distance < cp->distance) - break; - if (si->distance > cp->distance) - continue; - if (si->type == STATIC_IPV4_GATEWAY + frr_each(static_nexthop_list, &pn->nexthop_list, cp) { + if (nh->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY) { - if (ntohl(si->addr.ipv4.s_addr) + if (ntohl(nh->addr.ipv4.s_addr) < ntohl(cp->addr.ipv4.s_addr)) break; - if (ntohl(si->addr.ipv4.s_addr) + if (ntohl(nh->addr.ipv4.s_addr) > ntohl(cp->addr.ipv4.s_addr)) continue; } } + static_nexthop_list_add_after(&(pn->nexthop_list), cp, nh); - /* Make linked list. */ - if (pp) - pp->next = si; - else - rn->info = si; - if (cp) - cp->prev = si; - si->prev = pp; - si->next = cp; + if (nh_svrf->vrf->vrf_id == VRF_UNKNOWN) + return nh; /* check whether interface exists in system & install if it does */ - switch (si->type) { + switch (nh->type) { case STATIC_IPV4_GATEWAY: case STATIC_IPV6_GATEWAY: - static_zebra_nht_register(rn, si, true); break; case STATIC_IPV4_GATEWAY_IFNAME: case STATIC_IPV6_GATEWAY_IFNAME: - ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id); + ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id); if (ifp && ifp->ifindex != IFINDEX_INTERNAL) - si->ifindex = ifp->ifindex; + nh->ifindex = ifp->ifindex; else - zlog_warn("Static Route using %s interface not installed because the interface does not exist in specified vrf", - ifname); + zlog_warn( + "Static Route using %s interface not installed because the interface does not exist in specified vrf", + ifname); - static_zebra_nht_register(rn, si, true); break; case STATIC_BLACKHOLE: - static_install_route(rn, si, safi); break; case STATIC_IFNAME: ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id); if (ifp && ifp->ifindex != IFINDEX_INTERNAL) { - si->ifindex = ifp->ifindex; - static_install_route(rn, si, safi); + nh->ifindex = ifp->ifindex; } else - zlog_warn("Static Route using %s interface not installed because the interface does not exist in specified vrf", - ifname); - + zlog_warn( + "Static Route using %s interface not installed because the interface does not exist in specified vrf", + ifname); break; } - return 1; + return nh; } -int static_delete_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p, - struct prefix_ipv6 *src_p, union g_addr *gate, - const char *ifname, route_tag_t tag, uint8_t distance, - struct static_vrf *svrf, - struct static_nh_label *snh_label, - uint32_t table_id) +void static_install_nexthop(struct route_node *rn, struct static_path *pn, + struct static_nexthop *nh, safi_t safi, + struct static_vrf *svrf, const char *ifname, + static_types type, const char *nh_vrf) { - struct route_node *rn; - struct static_route *si; - struct route_table *stable; + struct static_vrf *nh_svrf; + struct interface *ifp; - /* Lookup table. */ - stable = static_vrf_static_table(afi, safi, svrf); - if (!stable) - return -1; + nh_svrf = static_vty_get_unknown_vrf(nh_vrf); - /* Lookup static route prefix. */ - rn = srcdest_rnode_lookup(stable, p, src_p); - if (!rn) - return 0; - - /* Find same static route is the tree */ - for (si = rn->info; si; si = si->next) - if (type == si->type - && (!gate - || ((afi == AFI_IP - && IPV4_ADDR_SAME(&gate->ipv4, &si->addr.ipv4)) - || (afi == AFI_IP6 - && IPV6_ADDR_SAME(gate, &si->addr.ipv6)))) - && (!strcmp(ifname ? ifname : "", si->ifname)) - && (!tag || (tag == si->tag)) - && (table_id == si->table_id) - && (!snh_label->num_labels - || !memcmp(&si->snh_label, snh_label, - sizeof(struct static_nh_label)))) - break; - - /* Can't find static route. */ - if (!si) { - route_unlock_node(rn); - return 0; + if (!nh_svrf) + return; + + if (nh_svrf->vrf->vrf_id == VRF_UNKNOWN) + return; + + /* check whether interface exists in system & install if it does */ + switch (nh->type) { + case STATIC_IPV4_GATEWAY: + case STATIC_IPV6_GATEWAY: + if (!static_zebra_nh_update(rn, nh)) + static_zebra_nht_register(rn, nh, true); + break; + case STATIC_IPV4_GATEWAY_IFNAME: + case STATIC_IPV6_GATEWAY_IFNAME: + if (!static_zebra_nh_update(rn, nh)) + static_zebra_nht_register(rn, nh, true); + break; + case STATIC_BLACKHOLE: + static_install_path(rn, pn, safi, svrf); + break; + case STATIC_IFNAME: + ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id); + if (ifp && ifp->ifindex != IFINDEX_INTERNAL) + static_install_path(rn, pn, safi, svrf); + + break; } +} - static_zebra_nht_register(rn, si, false); +int static_delete_nexthop(struct route_node *rn, struct static_path *pn, + safi_t safi, struct static_vrf *svrf, + struct static_nexthop *nh) +{ + struct static_vrf *nh_svrf; - /* Unlink static route from linked list. */ - if (si->prev) - si->prev->next = si->next; - else - rn->info = si->next; - if (si->next) - si->next->prev = si->prev; + nh_svrf = static_vrf_lookup_by_name(nh->nh_vrfname); + + static_nexthop_list_del(&(pn->nexthop_list), nh); + + if (nh_svrf->vrf->vrf_id == VRF_UNKNOWN) + goto EXIT; + static_zebra_nht_register(rn, nh, false); /* * If we have other si nodes then route replace * else delete the route */ - static_uninstall_route(si->vrf_id, safi, rn, si); - route_unlock_node(rn); - - /* Free static route configuration. */ - XFREE(MTYPE_STATIC_ROUTE, si); + static_uninstall_path(rn, pn, safi, svrf); +EXIT: route_unlock_node(rn); + /* Free static route configuration. */ + XFREE(MTYPE_STATIC_NEXTHOP, nh); return 1; } @@ -291,8 +363,10 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi, { struct route_table *stable; struct route_node *rn; - struct static_route *si; + struct static_nexthop *nh; + struct static_path *pn; struct vrf *vrf; + struct static_route_info *si; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { struct static_vrf *svrf; @@ -302,26 +376,34 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi, stable = static_vrf_static_table(afi, safi, svrf); if (!stable) continue; - for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { - for (si = rn->info; si; si = si->next) { - if (!si->ifname[0]) - continue; - if (up) { - if (strcmp(si->ifname, ifp->name)) - continue; - if (si->nh_vrf_id != ifp->vrf_id) - continue; - si->ifindex = ifp->ifindex; - } else { - if (si->ifindex != ifp->ifindex) - continue; - if (si->nh_vrf_id != ifp->vrf_id) + si = static_route_info_from_rnode(rn); + if (!si) + continue; + frr_each(static_path_list, &si->path_list, pn) { + frr_each(static_nexthop_list, + &pn->nexthop_list, nh) { + if (!nh->ifname[0]) continue; - si->ifindex = IFINDEX_INTERNAL; + if (up) { + if (strcmp(nh->ifname, + ifp->name)) + continue; + if (nh->nh_vrf_id + != ifp->vrf_id) + continue; + nh->ifindex = ifp->ifindex; + } else { + if (nh->ifindex != ifp->ifindex) + continue; + if (nh->nh_vrf_id + != ifp->vrf_id) + continue; + nh->ifindex = IFINDEX_INTERNAL; + } + + static_install_path(rn, pn, safi, svrf); } - - static_install_route(rn, si, safi); } } } @@ -343,26 +425,34 @@ static void static_fixup_vrf(struct static_vrf *svrf, struct route_table *stable, afi_t afi, safi_t safi) { struct route_node *rn; - struct static_route *si; + struct static_nexthop *nh; struct interface *ifp; + struct static_path *pn; + struct static_route_info *si; for (rn = route_top(stable); rn; rn = route_next(rn)) { - for (si = rn->info; si; si = si->next) { - if (strcmp(svrf->vrf->name, si->nh_vrfname) != 0) - continue; - - si->nh_vrf_id = svrf->vrf->vrf_id; - si->nh_registered = false; - if (si->ifindex) { - ifp = if_lookup_by_name(si->ifname, - si->nh_vrf_id); - if (ifp) - si->ifindex = ifp->ifindex; - else + si = static_route_info_from_rnode(rn); + if (!si) + continue; + frr_each(static_path_list, &si->path_list, pn) { + frr_each(static_nexthop_list, &pn->nexthop_list, nh) { + if (strcmp(svrf->vrf->name, nh->nh_vrfname) + != 0) continue; - } - static_install_route(rn, si, safi); + nh->nh_vrf_id = svrf->vrf->vrf_id; + nh->nh_registered = false; + if (nh->ifindex) { + ifp = if_lookup_by_name(nh->ifname, + nh->nh_vrf_id); + if (ifp) + nh->ifindex = ifp->ifindex; + else + continue; + } + + static_install_path(rn, pn, safi, svrf); + } } } } @@ -377,26 +467,31 @@ static void static_fixup_vrf(struct static_vrf *svrf, * safi -> the safi in question */ static void static_enable_vrf(struct static_vrf *svrf, - struct route_table *stable, - afi_t afi, safi_t safi) + struct route_table *stable, afi_t afi, + safi_t safi) { struct route_node *rn; - struct static_route *si; + struct static_nexthop *nh; struct interface *ifp; - struct vrf *vrf = svrf->vrf; + struct static_path *pn; + struct static_route_info *si; for (rn = route_top(stable); rn; rn = route_next(rn)) { - for (si = rn->info; si; si = si->next) { - si->vrf_id = vrf->vrf_id; - if (si->ifindex) { - ifp = if_lookup_by_name(si->ifname, - si->nh_vrf_id); - if (ifp) - si->ifindex = ifp->ifindex; - else - continue; + si = static_route_info_from_rnode(rn); + if (!si) + continue; + frr_each(static_path_list, &si->path_list, pn) { + frr_each(static_nexthop_list, &pn->nexthop_list, nh) { + if (nh->ifindex) { + ifp = if_lookup_by_name(nh->ifname, + nh->nh_vrf_id); + if (ifp) + nh->ifindex = ifp->ifindex; + else + continue; + } + static_install_path(rn, pn, safi, svrf); } - static_install_route(rn, si, safi); } } } @@ -452,14 +547,22 @@ static void static_cleanup_vrf(struct static_vrf *svrf, afi_t afi, safi_t safi) { struct route_node *rn; - struct static_route *si; + struct static_nexthop *nh; + struct static_path *pn; + struct static_route_info *si; for (rn = route_top(stable); rn; rn = route_next(rn)) { - for (si = rn->info; si; si = si->next) { - if (strcmp(svrf->vrf->name, si->nh_vrfname) != 0) - continue; + si = static_route_info_from_rnode(rn); + if (!si) + continue; + frr_each(static_path_list, &si->path_list, pn) { + frr_each(static_nexthop_list, &pn->nexthop_list, nh) { + if (strcmp(svrf->vrf->name, nh->nh_vrfname) + != 0) + continue; - static_uninstall_route(si->vrf_id, safi, rn, si); + static_uninstall_path(rn, pn, safi, svrf); + } } } } @@ -476,11 +579,23 @@ static void static_disable_vrf(struct route_table *stable, afi_t afi, safi_t safi) { struct route_node *rn; - struct static_route *si; + struct static_nexthop *nh; + struct static_path *pn; + struct stable_info *info; + struct static_route_info *si; - for (rn = route_top(stable); rn; rn = route_next(rn)) - for (si = rn->info; si; si = si->next) - static_uninstall_route(si->vrf_id, safi, rn, si); + info = route_table_get_info(stable); + + for (rn = route_top(stable); rn; rn = route_next(rn)) { + si = static_route_info_from_rnode(rn); + if (!si) + continue; + frr_each(static_path_list, &si->path_list, pn) { + frr_each(static_nexthop_list, &pn->nexthop_list, nh) { + static_uninstall_path(rn, pn, safi, info->svrf); + } + } + } } /* @@ -535,17 +650,27 @@ static void static_fixup_intf_nh(struct route_table *stable, afi_t afi, safi_t safi) { struct route_node *rn; - struct static_route *si; + struct stable_info *info; + struct static_nexthop *nh; + struct static_path *pn; + struct static_route_info *si; + + info = route_table_get_info(stable); for (rn = route_top(stable); rn; rn = route_next(rn)) { - for (si = rn->info; si; si = si->next) { - if (si->nh_vrf_id != ifp->vrf_id) - continue; + si = static_route_info_from_rnode(rn); + if (!si) + continue; + frr_each(static_path_list, &si->path_list, pn) { + frr_each(static_nexthop_list, &pn->nexthop_list, nh) { + if (nh->nh_vrf_id != ifp->vrf_id) + continue; - if (si->ifindex != ifp->ifindex) - continue; + if (nh->ifindex != ifp->ifindex) + continue; - static_install_route(rn, si, safi); + static_install_path(rn, pn, safi, info->svrf); + } } } } @@ -589,3 +714,40 @@ void static_ifindex_update(struct interface *ifp, bool up) static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_UNICAST); static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_MULTICAST); } + +void static_get_nh_type(static_types stype, char *type, size_t size) +{ + switch (stype) { + case STATIC_IFNAME: + strlcpy(type, "ifindex", size); + break; + case STATIC_IPV4_GATEWAY: + strlcpy(type, "ip4", size); + break; + case STATIC_IPV4_GATEWAY_IFNAME: + strlcpy(type, "ip4-ifindex", size); + break; + case STATIC_BLACKHOLE: + strlcpy(type, "blackhole", size); + break; + case STATIC_IPV6_GATEWAY: + strlcpy(type, "ip6", size); + break; + case STATIC_IPV6_GATEWAY_IFNAME: + strlcpy(type, "ip6-ifindex", size); + break; + }; +} + +struct stable_info *static_get_stable_info(struct route_node *rn) +{ + struct route_table *table; + + table = srcdest_rnode_table(rn); + return table->info; +} + +void static_route_info_init(struct static_route_info *si) +{ + static_path_list_init(&(si->path_list)); +} |