summaryrefslogtreecommitdiffstats
path: root/staticd/static_routes.c
diff options
context:
space:
mode:
authorvdhingra <vdhingra@vmware.com>2020-04-24 14:38:43 +0200
committervdhingra <vdhingra@vmware.com>2020-07-16 17:33:00 +0200
commit88fa5104a04af60b7d1107f02ee84fb9c0a15abe (patch)
treec2bbeecd9a5c384b7a615032c5fe13a1ff495c36 /staticd/static_routes.c
parentlib : basic-routing backend configuration northbound code (diff)
downloadfrr-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.c626
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));
+}