From fe257ae73337de31ad0c239a89f44713169b4ca9 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 25 Jun 2019 17:07:30 -0400 Subject: [PATCH] zebra: Push VRF_DEFAULT outside of import table code The import table code assumes that they will only work in the default vrf. This is ok, but we should push the vrf_id and zvrf to be passed in instead of just using VRF_DEFAULT. This will allow us to fix a couple of things: 1) A bug in import where we are not creating the route entry with the appropriate table so the imported entry is showing up in the wrong spot. 2) In the future allow `ip import-table X` to become vrf aware very easily. Signed-off-by: Donald Sharp --- zebra/redistribute.c | 146 +++++++++++++++++++++++++------------------ zebra/redistribute.h | 14 +++-- zebra/zebra_rib.c | 12 ++-- zebra/zebra_vty.c | 9 +-- 4 files changed, 108 insertions(+), 73 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 7c5320a349..8aa005a40e 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -52,7 +52,7 @@ static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; static uint32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -int is_zebra_import_table_enabled(afi_t afi, uint32_t table_id) +int is_zebra_import_table_enabled(afi_t afi, vrf_id_t vrf_id, uint32_t table_id) { /* * Make sure that what we are called with actualy makes sense @@ -568,8 +568,8 @@ void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id) } } -int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re, - const char *rmap_name) +int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, + struct route_entry *re, const char *rmap_name) { struct route_entry *newre; struct route_entry *same; @@ -581,11 +581,11 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re, if (rmap_name) ret = zebra_import_table_route_map_check( afi, re->type, re->instance, &rn->p, re->ng.nexthop, - re->vrf_id, re->tag, rmap_name); + zvrf->vrf->vrf_id, re->tag, rmap_name); if (ret != RMAP_MATCH) { UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED); - zebra_del_import_table_entry(rn, re); + zebra_del_import_table_entry(zvrf, rn, re); return 0; } @@ -603,7 +603,7 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re, if (same) { UNSET_FLAG(same->flags, ZEBRA_FLAG_SELECTED); - zebra_del_import_table_entry(rn, same); + zebra_del_import_table_entry(zvrf, rn, same); } newre = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); @@ -623,7 +623,8 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re, return 0; } -int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re) +int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn, + struct route_entry *re) { struct prefix p; afi_t afi; @@ -631,20 +632,21 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re) afi = family2afi(rn->p.family); prefix_copy(&p, &rn->p); - rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table, - re->flags, &p, NULL, re->ng.nexthop, 0, re->metric, - re->distance, false); + rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE, + re->table, re->flags, &p, NULL, re->ng.nexthop, 0, + re->metric, re->distance, false); return 0; } /* Assuming no one calls this with the main routing table */ -int zebra_import_table(afi_t afi, uint32_t table_id, uint32_t distance, - const char *rmap_name, int add) +int zebra_import_table(afi_t afi, vrf_id_t vrf_id, uint32_t table_id, + uint32_t distance, const char *rmap_name, int add) { struct route_table *table; struct route_entry *re; struct route_node *rn; + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vrf_id); if (!is_zebra_valid_kernel_table(table_id) || (table_id == RT_TABLE_MAIN)) @@ -653,8 +655,8 @@ int zebra_import_table(afi_t afi, uint32_t table_id, uint32_t distance, if (afi >= AFI_MAX) return (-1); - table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST, - VRF_DEFAULT, table_id); + table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST, vrf_id, + table_id); if (table == NULL) { return 0; } else if (IS_ZEBRA_DEBUG_RIB) { @@ -708,15 +710,16 @@ int zebra_import_table(afi_t afi, uint32_t table_id, uint32_t distance, if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) { if (add) - zebra_add_import_table_entry(rn, re, rmap_name); + zebra_add_import_table_entry(zvrf, rn, re, + rmap_name); else - zebra_del_import_table_entry(rn, re); + zebra_del_import_table_entry(zvrf, rn, re); } } return 0; } -int zebra_import_table_config(struct vty *vty) +int zebra_import_table_config(struct vty *vty, vrf_id_t vrf_id) { int i; afi_t afi; @@ -726,7 +729,7 @@ int zebra_import_table_config(struct vty *vty) for (afi = AFI_IP; afi < AFI_MAX; afi++) { for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { - if (!is_zebra_import_table_enabled(afi, i)) + if (!is_zebra_import_table_enabled(afi, vrf_id, i)) continue; if (zebra_import_table_distance[afi][i] @@ -751,61 +754,84 @@ int zebra_import_table_config(struct vty *vty) return write; } -void zebra_import_table_rm_update(const char *rmap) +static void zebra_import_table_rm_update_vrf_afi(struct zebra_vrf *zvrf, + afi_t afi, int table_id, + const char *rmap) { - afi_t afi; - int i; struct route_table *table; struct route_entry *re; struct route_node *rn; const char *rmap_name; - for (afi = AFI_IP; afi < AFI_MAX; afi++) { - for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { - if (!is_zebra_import_table_enabled(afi, i)) - continue; + rmap_name = zebra_get_import_table_route_map(afi, table_id); + if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0)) + return; - rmap_name = zebra_get_import_table_route_map(afi, i); - if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0)) + table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST, + zvrf->vrf->vrf_id, table_id); + if (!table) { + if (IS_ZEBRA_DEBUG_RIB_DETAILED) + zlog_debug("%s: Table id=%d not found", __func__, + table_id); + return; + } + + for (rn = route_top(table); rn; rn = route_next(rn)) { + /* + * For each entry in the non-default routing table, + * add the entry in the main table + */ + if (!rn->info) + continue; + + RNODE_FOREACH_RE (rn, re) { + if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) continue; - table = zebra_vrf_table_with_table_id(afi, SAFI_UNICAST, - VRF_DEFAULT, i); - if (!table) { - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug("%s: Table id=%d not found", - __func__, i); + break; + } + + if (!re) + continue; + + if (((afi == AFI_IP) && (rn->p.family == AF_INET)) + || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) + zebra_add_import_table_entry(zvrf, rn, re, rmap_name); + } + + return; +} + +static void zebra_import_table_rm_update_vrf(struct zebra_vrf *zvrf, + const char *rmap) +{ + afi_t afi; + int i; + + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { + if (!is_zebra_import_table_enabled( + afi, zvrf->vrf->vrf_id, i)) continue; - } - for (rn = route_top(table); rn; rn = route_next(rn)) { - /* For each entry in the non-default - * routing table, - * add the entry in the main table - */ - if (!rn->info) - continue; - - RNODE_FOREACH_RE (rn, re) { - if (CHECK_FLAG(re->status, - ROUTE_ENTRY_REMOVED)) - continue; - break; - } - - if (!re) - continue; - - if (((afi == AFI_IP) - && (rn->p.family == AF_INET)) - || ((afi == AFI_IP6) - && (rn->p.family == AF_INET6))) - zebra_add_import_table_entry(rn, re, - rmap_name); - } + zebra_import_table_rm_update_vrf_afi(zvrf, afi, i, + rmap); } } +} - return; +void zebra_import_table_rm_update(const char *rmap) +{ + struct vrf *vrf; + struct zebra_vrf *zvrf; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + zvrf = vrf->info; + + if (!zvrf) + continue; + + zebra_import_table_rm_update_vrf(zvrf, rmap); + } } /* Interface parameters update */ diff --git a/zebra/redistribute.h b/zebra/redistribute.h index 74a593b240..30ff6bcd09 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -64,17 +64,21 @@ extern void zebra_interface_vrf_update_del(struct interface *, extern void zebra_interface_vrf_update_add(struct interface *, vrf_id_t old_vrf_id); -extern int zebra_import_table(afi_t afi, uint32_t table_id, uint32_t distance, +extern int zebra_import_table(afi_t afi, vrf_id_t vrf_id, + uint32_t table_id, uint32_t distance, const char *rmap_name, int add); -extern int zebra_add_import_table_entry(struct route_node *rn, +extern int zebra_add_import_table_entry(struct zebra_vrf *zvrf, + struct route_node *rn, struct route_entry *re, const char *rmap_name); -extern int zebra_del_import_table_entry(struct route_node *rn, +extern int zebra_del_import_table_entry(struct zebra_vrf *zvrf, + struct route_node *rn, struct route_entry *re); -extern int is_zebra_import_table_enabled(afi_t, uint32_t table_id); +extern int is_zebra_import_table_enabled(afi_t, vrf_id_t vrf_id, + uint32_t table_id); -extern int zebra_import_table_config(struct vty *); +extern int zebra_import_table_config(struct vty *, vrf_id_t vrf_id); extern void zebra_import_table_rm_update(const char *rmap); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 55cd4112c3..d5a9b82073 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2346,9 +2346,11 @@ static void rib_link(struct route_node *rn, struct route_entry *re, int process) afi = (rn->p.family == AF_INET) ? AFI_IP : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; - if (is_zebra_import_table_enabled(afi, re->table)) { + if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + rmap_name = zebra_get_import_table_route_map(afi, re->table); - zebra_add_import_table_entry(rn, re, rmap_name); + zebra_add_import_table_entry(zvrf, rn, re, rmap_name); } else if (process) rib_queue_add(rn); } @@ -2414,8 +2416,10 @@ void rib_delnode(struct route_node *rn, struct route_entry *re) afi = (rn->p.family == AF_INET) ? AFI_IP : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; - if (is_zebra_import_table_enabled(afi, re->table)) { - zebra_del_import_table_entry(rn, re); + if (is_zebra_import_table_enabled(afi, re->vrf_id, re->table)) { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id); + + zebra_del_import_table_entry(zvrf, rn, re); /* Just clean up if non main table */ if (IS_ZEBRA_DEBUG_RIB) { char buf[SRCDEST2STR_BUFFER]; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 1f8eec9cad..74baabbf24 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -2435,7 +2435,7 @@ static int zebra_ip_config(struct vty *vty) { int write = 0; - write += zebra_import_table_config(vty); + write += zebra_import_table_config(vty, VRF_DEFAULT); return write; } @@ -2482,7 +2482,8 @@ DEFUN (ip_zebra_import_table_distance, return CMD_WARNING; } - ret = zebra_import_table(AFI_IP, table_id, distance, rmap, 1); + ret = zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, + distance, rmap, 1); if (rmap) XFREE(MTYPE_ROUTE_MAP_NAME, rmap); @@ -2573,10 +2574,10 @@ DEFUN (no_ip_zebra_import_table, return CMD_WARNING; } - if (!is_zebra_import_table_enabled(AFI_IP, table_id)) + if (!is_zebra_import_table_enabled(AFI_IP, VRF_DEFAULT, table_id)) return CMD_SUCCESS; - return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0)); + return (zebra_import_table(AFI_IP, VRF_DEFAULT, table_id, 0, NULL, 0)); } static int config_write_protocol(struct vty *vty) -- 2.39.5