From e9748a89019f03cffd1ba2fcc87543171cbe3a26 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 28 Mar 2018 10:46:14 +0200 Subject: [PATCH] zebra: table_id election with the vrf backend As table_id for VRF with netns backend is main table ( RT_TABLE_MAIN or zebrad.rtm_table_default), this makes possible to return the table id that wants to be configured for those cases. ( in addition to default VRF). In other cases ( VRF Lite presumably), then vrf table_id is returned. Signed-off-by: Philippe Guibert --- zebra/zebra_static.c | 22 ++++++++++++++++++---- zebra/zebra_vrf.c | 25 +++++++++++++++++++++---- zebra/zebra_vty.c | 22 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 84d6edec3a..67b2954f35 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -49,7 +49,9 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, struct vrf *nh_vrf; /* Lookup table. */ - table = zebra_vrf_table(afi, safi, si->vrf_id); + table = zebra_vrf_table_with_table_id(afi, safi, + si->vrf_id, + si->table_id); if (!table) return; @@ -170,10 +172,20 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, re->metric = 0; re->mtu = 0; re->vrf_id = si->vrf_id; - re->table = - (si->vrf_id != VRF_DEFAULT) + if (!vrf_is_backend_netns()) { + re->table = + (si->vrf_id != VRF_DEFAULT) ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default; + } else { + struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(si->vrf_id); + + if (zvrf->table_id != RT_TABLE_MAIN || + zvrf->table_id != zebrad.rtm_table_default) + re->table = zvrf->table_id; + else + re->table = zebrad.rtm_table_default; + } re->nexthop_num = 0; re->tag = si->tag; @@ -290,7 +302,9 @@ void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p, struct prefix nh_p; /* Lookup table. */ - table = zebra_vrf_table(afi, safi, si->vrf_id); + table = zebra_vrf_table_with_table_id(afi, safi, + si->vrf_id, + si->table_id); if (!table) return; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 46443dec4f..d443f725b0 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -328,7 +328,9 @@ int zebra_vrf_has_config(struct zebra_vrf *zvrf) } /* Lookup the routing table in a VRF based on both VRF-Id and table-id. - * NOTE: Table-id is relevant only in the Default VRF. + * NOTE: Table-id is relevant on two modes: + * - case VRF backend is default : on default VRF only + * - case VRF backend is netns : on all VRFs */ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi, vrf_id_t vrf_id, @@ -346,6 +348,13 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi, else table = zebra_vrf_other_route_table(afi, table_id, vrf_id); + } else if (vrf_is_backend_netns()) { + if (table_id == RT_TABLE_MAIN + || table_id == zebrad.rtm_table_default) + table = zebra_vrf_table(afi, safi, vrf_id); + else + table = zebra_vrf_other_route_table(afi, table_id, + vrf_id); } else table = zebra_vrf_table(afi, safi, vrf_id); @@ -434,7 +443,8 @@ struct zebra_vrf *zebra_vrf_alloc(void) zebra_vxlan_init_tables(zvrf); zebra_mpls_init_tables(zvrf); zebra_pw_init(zvrf); - + zvrf->table_id = RT_TABLE_MAIN; + /* by default table ID is default one */ return zvrf; } @@ -501,9 +511,16 @@ struct route_table *zebra_vrf_other_route_table(afi_t afi, uint32_t table_id, if (afi >= AFI_MAX) return NULL; - if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) + if ((table_id != RT_TABLE_MAIN) && (table_id != zebrad.rtm_table_default)) { - return zebra_ns_get_table(zns, zvrf, table_id, afi); + if (zvrf->table_id == RT_TABLE_MAIN || + zvrf->table_id == zebrad.rtm_table_default) { + /* this VRF use default table + * so in all cases, it does not use specific table + * so it is possible to configure tables in this VRF + */ + return zebra_ns_get_table(zns, zvrf, table_id, afi); + } } return zvrf->table[afi][SAFI_UNICAST]; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 4c2d6002b9..49bd5e0a7d 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -355,6 +355,23 @@ static int zebra_static_route_leak( mask_str, src_str, gate_str, ifname, flag_str, tag_str, distance_str, label_str, table_str); } + if (table_str) { + /* table configured. check consistent with vrf config + */ + if (zvrf->table_id != RT_TABLE_MAIN && + zvrf->table_id != zebrad.rtm_table_default) { + if (vty) + vty_out(vty, + "%% Table %s overlaps vrf table %u\n", + table_str, zvrf->table_id); + else + zlog_warn( + "%s: Table %s overlaps vrf table %u", + __PRETTY_FUNCTION__, + table_str, zvrf->table_id); + return CMD_WARNING_CONFIG_FAILED; + } + } /* Administrative distance. */ if (distance_str) @@ -2644,6 +2661,11 @@ int static_config(struct vty *vty, struct zebra_vrf *zvrf, afi_t afi, vty_out(vty, " nexthop-vrf %s", si->nh_vrfname); } + /* table ID from VRF overrides configured + */ + if (si->table_id && zvrf->table_id == RT_TABLE_MAIN) + vty_out(vty, " table %u", si->table_id); + vty_out(vty, "\n"); write = 1; -- 2.39.5