From 164ab8965e442d42710da6a94c537452ce0d51a0 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Tue, 4 May 2021 21:58:23 +0300 Subject: [PATCH 1/5] isisd: deregister vrf from zebra when vrf is disabled Currently the VRF is deregistered only when it is re-enabled again. Signed-off-by: Igor Ryzhov --- isisd/isis_zebra.c | 12 ++++++++++++ isisd/isis_zebra.h | 1 + isisd/isisd.c | 11 ++++------- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 4bd42ead86..9c80f4e836 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -724,6 +724,18 @@ void isis_zebra_vrf_register(struct isis *isis) } } +void isis_zebra_vrf_deregister(struct isis *isis) +{ + if (!zclient || zclient->sock < 0 || !isis) + return; + + if (isis->vrf_id != VRF_UNKNOWN) { + if (IS_DEBUG_EVENTS) + zlog_debug("%s: Deregister VRF %s id %u", __func__, + isis->name, isis->vrf_id); + zclient_send_dereg_requests(zclient, isis->vrf_id); + } +} static void isis_zebra_connected(struct zclient *zclient) { diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index b44ec4f085..006f020757 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -66,5 +66,6 @@ int isis_zebra_label_manager_connect(void); int isis_zebra_request_label_range(uint32_t base, uint32_t chunk_size); int isis_zebra_release_label_range(uint32_t start, uint32_t end); void isis_zebra_vrf_register(struct isis *isis); +void isis_zebra_vrf_deregister(struct isis *isis); #endif /* _ZEBRA_ISIS_ZEBRA_H */ diff --git a/isisd/isisd.c b/isisd/isisd.c index cb3734bd41..4f27690197 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -614,13 +614,8 @@ static int isis_vrf_enable(struct vrf *vrf) "%s: isis linked to vrf %s vrf_id %u (old id %u)", __func__, vrf->name, isis->vrf_id, old_vrf_id); if (old_vrf_id != isis->vrf_id) { - frr_with_privs (&isisd_privs) { - /* stop zebra redist to us for old vrf */ - zclient_send_dereg_requests(zclient, - old_vrf_id); - /* start zebra redist to us for new vrf */ - isis_zebra_vrf_register(isis); - } + /* start zebra redist to us for new vrf */ + isis_zebra_vrf_register(isis); } } @@ -642,6 +637,8 @@ static int isis_vrf_disable(struct vrf *vrf) if (isis) { old_vrf_id = isis->vrf_id; + isis_zebra_vrf_deregister(isis); + /* We have instance configured, unlink * from VRF and make it "down". */ From a601d662743f379d4626dc252115ece7bd7ba83b Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Sun, 9 May 2021 17:07:39 +0300 Subject: [PATCH 2/5] isisd: fix "default-information originate always" We don't need to register for default routes from zebra, when the origination type is set to "always". Signed-off-by: Igor Ryzhov --- isisd/isis_redist.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index c33d56e625..843df3a849 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -359,8 +359,9 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis) for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) for (level = 0; level < ISIS_LEVELS; level++) if (area->redist_settings[protocol] - [type] - [level].redist) + [type][level] + .redist + == 1) do_subscribe[protocol][type] = 1; From 8c6482db8ced19032101444ddb19c9c2ae04ec9d Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Wed, 5 May 2021 00:10:31 +0300 Subject: [PATCH 3/5] isisd: fix redistribution in vrf When the redistribution is configured in non-default VRF, isisd should redistribute routes from this VRF instead of default. Signed-off-by: Igor Ryzhov --- isisd/isis_redist.c | 11 ++- isisd/isis_redist.h | 2 + isisd/isis_zebra.c | 12 ++-- isisd/isis_zebra.h | 4 +- isisd/isisd.c | 70 +++++++++++++++++++ .../topotests/isis_topo1_vrf/r1/r1_route.json | 2 +- .../isis_topo1_vrf/r1/r1_route6.json | 2 +- .../isis_topo1_vrf/r1/r1_topology.json | 6 +- .../topotests/isis_topo1_vrf/r2/r2_route.json | 2 +- .../isis_topo1_vrf/r2/r2_route6.json | 2 +- .../isis_topo1_vrf/r2/r2_topology.json | 6 +- .../topotests/isis_topo1_vrf/r3/r3_route.json | 6 +- .../isis_topo1_vrf/r3/r3_route6.json | 4 +- .../isis_topo1_vrf/r3/r3_topology.json | 12 ++-- .../topotests/isis_topo1_vrf/r4/r4_route.json | 2 +- .../isis_topo1_vrf/r4/r4_route6.json | 4 +- .../isis_topo1_vrf/r4/r4_topology.json | 12 ++-- .../topotests/isis_topo1_vrf/r5/r5_route.json | 2 +- .../isis_topo1_vrf/r5/r5_route6.json | 4 +- .../isis_topo1_vrf/r5/r5_topology.json | 12 ++-- 20 files changed, 127 insertions(+), 50 deletions(-) diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index 843df3a849..ce0f44bf7a 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -56,7 +56,7 @@ static int redist_protocol(int family) return 0; } -static afi_t afi_for_redist_protocol(int protocol) +afi_t afi_for_redist_protocol(int protocol) { if (protocol == 0) return AFI_IP; @@ -350,6 +350,9 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis) int level; int protocol; + if (isis->vrf_id == VRF_UNKNOWN) + return; + char do_subscribe[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1]; memset(do_subscribe, 0, sizeof(do_subscribe)); @@ -378,9 +381,11 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis) afi_t afi = afi_for_redist_protocol(protocol); if (do_subscribe[protocol][type]) - isis_zebra_redistribute_set(afi, type); + isis_zebra_redistribute_set(afi, type, + isis->vrf_id); else - isis_zebra_redistribute_unset(afi, type); + isis_zebra_redistribute_unset(afi, type, + isis->vrf_id); } } diff --git a/isisd/isis_redist.h b/isisd/isis_redist.h index fcc4ceadf4..10dccbc518 100644 --- a/isisd/isis_redist.h +++ b/isisd/isis_redist.h @@ -47,6 +47,8 @@ struct prefix; struct prefix_ipv6; struct vty; +afi_t afi_for_redist_protocol(int protocol); + struct route_table *get_ext_reach(struct isis_area *area, int family, int level); void isis_redist_add(struct isis *isis, int type, struct prefix *p, diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 9c80f4e836..0142e30b2b 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -523,24 +523,24 @@ int isis_distribute_list_update(int routetype) return 0; } -void isis_zebra_redistribute_set(afi_t afi, int type) +void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id) { if (type == DEFAULT_ROUTE) zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, - zclient, afi, VRF_DEFAULT); + zclient, afi, vrf_id); else zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, - 0, VRF_DEFAULT); + 0, vrf_id); } -void isis_zebra_redistribute_unset(afi_t afi, int type) +void isis_zebra_redistribute_unset(afi_t afi, int type, vrf_id_t vrf_id) { if (type == DEFAULT_ROUTE) zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, - zclient, afi, VRF_DEFAULT); + zclient, afi, vrf_id); else zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, - type, 0, VRF_DEFAULT); + type, 0, vrf_id); } /** diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index 006f020757..348d7b3eab 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -57,8 +57,8 @@ void isis_zebra_prefix_sid_uninstall(struct isis_area *area, struct isis_sr_psid_info *psid); void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra); int isis_distribute_list_update(int routetype); -void isis_zebra_redistribute_set(afi_t afi, int type); -void isis_zebra_redistribute_unset(afi_t afi, int type); +void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id); +void isis_zebra_redistribute_unset(afi_t afi, int type, vrf_id_t vrf_id); int isis_zebra_rlfa_register(struct isis_spftree *spftree, struct rlfa *rlfa); void isis_zebra_rlfa_unregister_all(struct isis_spftree *spftree); bool isis_zebra_label_manager_ready(void); diff --git a/isisd/isisd.c b/isisd/isisd.c index 4f27690197..172d202150 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -200,6 +200,8 @@ struct isis *isis_new(const char *vrf_name) else isis->vrf_id = VRF_UNKNOWN; + isis_zebra_vrf_register(isis); + if (IS_DEBUG_EVENTS) zlog_debug( "%s: Create new isis instance with vrf_name %s vrf_id %u", @@ -227,6 +229,8 @@ void isis_finish(struct isis *isis) listnode_delete(im->isis, isis); + isis_zebra_vrf_deregister(isis); + vrf = vrf_lookup_by_name(isis->name); if (vrf) isis_vrf_unlink(isis, vrf); @@ -595,6 +599,68 @@ static int isis_vrf_delete(struct vrf *vrf) return 0; } +static void isis_set_redist_vrf_bitmaps(struct isis *isis, bool set) +{ + struct listnode *node; + struct isis_area *area; + int type; + int level; + int protocol; + + char do_subscribe[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1]; + + memset(do_subscribe, 0, sizeof(do_subscribe)); + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) + for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++) + for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) + for (level = 0; level < ISIS_LEVELS; level++) + if (area->redist_settings[protocol] + [type][level] + .redist + == 1) + do_subscribe[protocol][type] = + 1; + + for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++) + for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) { + /* This field is actually controlling transmission of + * the IS-IS + * routes to Zebra and has nothing to do with + * redistribution, + * so skip it. */ + if (type == PROTO_TYPE) + continue; + + if (!do_subscribe[protocol][type]) + continue; + + afi_t afi = afi_for_redist_protocol(protocol); + + if (type == DEFAULT_ROUTE) { + if (set) + vrf_bitmap_set( + zclient->default_information + [afi], + isis->vrf_id); + else + vrf_bitmap_unset( + zclient->default_information + [afi], + isis->vrf_id); + } else { + if (set) + vrf_bitmap_set( + zclient->redist[afi][type], + isis->vrf_id); + else + vrf_bitmap_unset( + zclient->redist[afi][type], + isis->vrf_id); + } + } +} + static int isis_vrf_enable(struct vrf *vrf) { struct isis *isis; @@ -615,6 +681,8 @@ static int isis_vrf_enable(struct vrf *vrf) __func__, vrf->name, isis->vrf_id, old_vrf_id); if (old_vrf_id != isis->vrf_id) { /* start zebra redist to us for new vrf */ + isis_set_redist_vrf_bitmaps(isis, true); + isis_zebra_vrf_register(isis); } } @@ -639,6 +707,8 @@ static int isis_vrf_disable(struct vrf *vrf) isis_zebra_vrf_deregister(isis); + isis_set_redist_vrf_bitmaps(isis, false); + /* We have instance configured, unlink * from VRF and make it "down". */ diff --git a/tests/topotests/isis_topo1_vrf/r1/r1_route.json b/tests/topotests/isis_topo1_vrf/r1/r1_route.json index f0a3593a4c..8359baadaf 100644 --- a/tests/topotests/isis_topo1_vrf/r1/r1_route.json +++ b/tests/topotests/isis_topo1_vrf/r1/r1_route.json @@ -2,7 +2,7 @@ "10.0.10.0/24": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r1/r1_route6.json b/tests/topotests/isis_topo1_vrf/r1/r1_route6.json index 888b9e2c42..74961262b4 100644 --- a/tests/topotests/isis_topo1_vrf/r1/r1_route6.json +++ b/tests/topotests/isis_topo1_vrf/r1/r1_route6.json @@ -18,7 +18,7 @@ "2001:db8:2:1::/64": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r1/r1_topology.json b/tests/topotests/isis_topo1_vrf/r1/r1_topology.json index 1a6fe6d5c6..666fa52b19 100644 --- a/tests/topotests/isis_topo1_vrf/r1/r1_topology.json +++ b/tests/topotests/isis_topo1_vrf/r1/r1_topology.json @@ -33,7 +33,7 @@ }, { "interface": "r1-eth0", - "metric": "20", + "metric": "10", "next-hop": "r3", "parent": "r3(4)", "type": "IP TE", @@ -41,7 +41,7 @@ }, { "interface": "r1-eth0", - "metric": "20", + "metric": "10", "next-hop": "r3", "parent": "r3(4)", "type": "IP TE", @@ -67,8 +67,8 @@ "vertex": "r3" }, { + "metric": "10", "interface": "r1-eth0", - "metric": "20", "next-hop": "r3", "parent": "r3(4)", "type": "IP6 internal", diff --git a/tests/topotests/isis_topo1_vrf/r2/r2_route.json b/tests/topotests/isis_topo1_vrf/r2/r2_route.json index a26cdfad8e..e2eee112b3 100644 --- a/tests/topotests/isis_topo1_vrf/r2/r2_route.json +++ b/tests/topotests/isis_topo1_vrf/r2/r2_route.json @@ -2,7 +2,7 @@ "10.0.11.0/24": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r2/r2_route6.json b/tests/topotests/isis_topo1_vrf/r2/r2_route6.json index b01789b8d9..21b953d0f7 100644 --- a/tests/topotests/isis_topo1_vrf/r2/r2_route6.json +++ b/tests/topotests/isis_topo1_vrf/r2/r2_route6.json @@ -18,7 +18,7 @@ "2001:db8:2:2::/64": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r2/r2_topology.json b/tests/topotests/isis_topo1_vrf/r2/r2_topology.json index a77f7977f9..c26ad1ee37 100644 --- a/tests/topotests/isis_topo1_vrf/r2/r2_topology.json +++ b/tests/topotests/isis_topo1_vrf/r2/r2_topology.json @@ -33,7 +33,7 @@ }, { "interface": "r2-eth0", - "metric": "20", + "metric": "10", "next-hop": "r4", "parent": "r4(4)", "type": "IP TE", @@ -41,7 +41,7 @@ }, { "interface": "r2-eth0", - "metric": "20", + "metric": "10", "next-hop": "r4", "parent": "r4(4)", "type": "IP TE", @@ -67,8 +67,8 @@ "vertex": "r4" }, { + "metric": "10", "interface": "r2-eth0", - "metric": "20", "next-hop": "r4", "parent": "r4(4)", "type": "IP6 internal", diff --git a/tests/topotests/isis_topo1_vrf/r3/r3_route.json b/tests/topotests/isis_topo1_vrf/r3/r3_route.json index 9717df5c1a..33ad90cda1 100644 --- a/tests/topotests/isis_topo1_vrf/r3/r3_route.json +++ b/tests/topotests/isis_topo1_vrf/r3/r3_route.json @@ -2,7 +2,7 @@ "10.0.10.0/24": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "afi": "ipv4", @@ -32,7 +32,7 @@ "10.0.11.0/24": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, @@ -67,7 +67,7 @@ "10.0.21.0/24": [ { "distance": 115, - "metric": 30, + "metric": 20, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r3/r3_route6.json b/tests/topotests/isis_topo1_vrf/r3/r3_route6.json index 31a1e4620f..519fe4968a 100644 --- a/tests/topotests/isis_topo1_vrf/r3/r3_route6.json +++ b/tests/topotests/isis_topo1_vrf/r3/r3_route6.json @@ -18,7 +18,7 @@ "2001:db8:1:2::/64": [ { "distance": 115, - "metric": 30, + "metric": 20, "nexthops": [ { "active": true, @@ -52,7 +52,7 @@ "2001:db8:2:2::/64": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r3/r3_topology.json b/tests/topotests/isis_topo1_vrf/r3/r3_topology.json index 1e5d331965..34892d4a3a 100644 --- a/tests/topotests/isis_topo1_vrf/r3/r3_topology.json +++ b/tests/topotests/isis_topo1_vrf/r3/r3_topology.json @@ -21,7 +21,7 @@ }, { "interface": "r3-eth1", - "metric": "20", + "metric": "10", "next-hop": "r5", "parent": "r5(4)", "type": "IP TE", @@ -29,7 +29,7 @@ }, { "interface": "r3-eth1", - "metric": "20", + "metric": "10", "next-hop": "r5", "parent": "r5(4)", "type": "IP TE", @@ -37,7 +37,7 @@ }, { "interface": "r3-eth1", - "metric": "30", + "metric": "20", "next-hop": "r5", "parent": "r4(4)", "type": "IP TE", @@ -63,16 +63,16 @@ "vertex": "r5" }, { + "metric": "10", "interface": "r3-eth1", - "metric": "20", "next-hop": "r5", "parent": "r5(4)", "type": "IP6 internal", "vertex": "2001:db8:2:2::/64" }, { + "metric": "20", "interface": "r3-eth1", - "metric": "30", "next-hop": "r5", "parent": "r4(4)", "type": "IP6 internal", @@ -101,7 +101,7 @@ }, { "interface": "r3-eth0", - "metric": "20", + "metric": "10", "next-hop": "r3", "parent": "r3(4)", "type": "IP TE", diff --git a/tests/topotests/isis_topo1_vrf/r4/r4_route.json b/tests/topotests/isis_topo1_vrf/r4/r4_route.json index 6cb79b0301..6fb3bd99d1 100644 --- a/tests/topotests/isis_topo1_vrf/r4/r4_route.json +++ b/tests/topotests/isis_topo1_vrf/r4/r4_route.json @@ -1,7 +1,7 @@ { "10.0.10.0/24": [ { - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r4/r4_route6.json b/tests/topotests/isis_topo1_vrf/r4/r4_route6.json index 88a91749c2..702a83fb72 100644 --- a/tests/topotests/isis_topo1_vrf/r4/r4_route6.json +++ b/tests/topotests/isis_topo1_vrf/r4/r4_route6.json @@ -2,7 +2,7 @@ "2001:db8:1:1::/64": [ { "distance": 115, - "metric": 30, + "metric": 20, "nexthops": [ { "active": true, @@ -36,7 +36,7 @@ "2001:db8:2:1::/64": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r4/r4_topology.json b/tests/topotests/isis_topo1_vrf/r4/r4_topology.json index 34f5ac9ca4..d40008aa30 100644 --- a/tests/topotests/isis_topo1_vrf/r4/r4_topology.json +++ b/tests/topotests/isis_topo1_vrf/r4/r4_topology.json @@ -21,7 +21,7 @@ }, { "interface": "r4-eth1", - "metric": "20", + "metric": "10", "next-hop": "r5", "parent": "r5(4)", "type": "IP TE", @@ -29,7 +29,7 @@ }, { "interface": "r4-eth1", - "metric": "20", + "metric": "10", "next-hop": "r5", "parent": "r5(4)", "type": "IP TE", @@ -37,7 +37,7 @@ }, { "interface": "r4-eth1", - "metric": "30", + "metric": "20", "next-hop": "r5", "parent": "r3(4)", "type": "IP TE", @@ -63,16 +63,16 @@ "vertex": "r5" }, { + "metric": "10", "interface": "r4-eth1", - "metric": "20", "next-hop": "r5", "parent": "r5(4)", "type": "IP6 internal", "vertex": "2001:db8:2:1::/64" }, { + "metric": "20", "interface": "r4-eth1", - "metric": "30", "next-hop": "r5", "parent": "r3(4)", "type": "IP6 internal", @@ -101,7 +101,7 @@ }, { "interface": "r4-eth0", - "metric": "20", + "metric": "10", "next-hop": "r2", "parent": "r2(4)", "type": "IP TE", diff --git a/tests/topotests/isis_topo1_vrf/r5/r5_route.json b/tests/topotests/isis_topo1_vrf/r5/r5_route.json index 5efa36bce6..a254b6fdd5 100644 --- a/tests/topotests/isis_topo1_vrf/r5/r5_route.json +++ b/tests/topotests/isis_topo1_vrf/r5/r5_route.json @@ -2,7 +2,7 @@ "10.0.10.0/24": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "afi": "ipv4", diff --git a/tests/topotests/isis_topo1_vrf/r5/r5_route6.json b/tests/topotests/isis_topo1_vrf/r5/r5_route6.json index 5e8f6364af..06fc78f703 100644 --- a/tests/topotests/isis_topo1_vrf/r5/r5_route6.json +++ b/tests/topotests/isis_topo1_vrf/r5/r5_route6.json @@ -2,7 +2,7 @@ "2001:db8:1:1::/64": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, @@ -20,7 +20,7 @@ "2001:db8:1:2::/64": [ { "distance": 115, - "metric": 20, + "metric": 10, "nexthops": [ { "active": true, diff --git a/tests/topotests/isis_topo1_vrf/r5/r5_topology.json b/tests/topotests/isis_topo1_vrf/r5/r5_topology.json index ace56536e9..2a088cae30 100644 --- a/tests/topotests/isis_topo1_vrf/r5/r5_topology.json +++ b/tests/topotests/isis_topo1_vrf/r5/r5_topology.json @@ -35,7 +35,7 @@ }, { "interface": "r5-eth0", - "metric": "20", + "metric": "10", "next-hop": "r3", "parent": "r3(4)", "type": "IP TE", @@ -43,7 +43,7 @@ }, { "interface": "r5-eth0", - "metric": "20", + "metric": "10", "next-hop": "r3", "parent": "r3(4)", "type": "IP TE", @@ -51,7 +51,7 @@ }, { "interface": "r5-eth1", - "metric": "20", + "metric": "10", "next-hop": "r4", "parent": "r4(4)", "type": "IP TE", @@ -59,7 +59,7 @@ }, { "interface": "r5-eth1", - "metric": "20", + "metric": "10", "next-hop": "r4", "parent": "r4(4)", "type": "IP TE", @@ -99,16 +99,16 @@ "vertex": "r4" }, { + "metric": "10", "interface": "r5-eth0", - "metric": "20", "next-hop": "r3", "parent": "r3(4)", "type": "IP6 internal", "vertex": "2001:db8:1:1::/64" }, { + "metric": "10", "interface": "r5-eth1", - "metric": "20", "next-hop": "r4", "parent": "r4(4)", "type": "IP6 internal", From 46c9042fbc098322c9978fdb440dfa48642ee643 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Sun, 9 May 2021 16:09:38 +0300 Subject: [PATCH 4/5] isisd: fix memleak when deleting area and instance Release memory for all redistributed route info. Signed-off-by: Igor Ryzhov --- isisd/isis_redist.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index ce0f44bf7a..2f5e490da1 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -391,12 +391,19 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis) void isis_redist_free(struct isis *isis) { + struct route_node *rn; int i; for (i = 0; i < REDIST_PROTOCOL_COUNT; i++) { if (!isis->ext_info[i]) continue; + for (rn = route_top(isis->ext_info[i]); rn; + rn = srcdest_route_next(rn)) { + if (rn->info) + XFREE(MTYPE_ISIS_EXT_INFO, rn->info); + } + route_table_finish(isis->ext_info[i]); isis->ext_info[i] = NULL; } @@ -504,6 +511,7 @@ void isis_redist_unset(struct isis_area *area, int level, int family, int type) void isis_redist_area_finish(struct isis_area *area) { + struct route_node *rn; int protocol; int level; int type; @@ -518,7 +526,15 @@ void isis_redist_area_finish(struct isis_area *area) redist->redist = 0; XFREE(MTYPE_ISIS_RMAP_NAME, redist->map_name); } + if (!area->ext_reach[protocol][level]) + continue; + for (rn = route_top(area->ext_reach[protocol][level]); + rn; rn = srcdest_route_next(rn)) { + if (rn->info) + XFREE(MTYPE_ISIS_EXT_INFO, rn->info); + } route_table_finish(area->ext_reach[protocol][level]); + area->ext_reach[protocol][level] = NULL; } isis_redist_update_zebra_subscriptions(area->isis); From 5cfffcdd8dc6dfac0f0ffa444dcbcebaa8d7d58f Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Sun, 9 May 2021 16:43:29 +0300 Subject: [PATCH 5/5] isisd: fix dangling instances We only need an instance when we have at least one area configured in a VRF. Currently we have the following issues: - instance for the default VRF is always created - instance is not removed after the last area config is removed This commit fixes both issues. Signed-off-by: Igor Ryzhov --- isisd/isis_main.c | 3 --- isisd/isis_nb_config.c | 2 +- isisd/isisd.c | 12 +----------- tests/isisd/test_isis_spf.c | 6 +----- 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/isisd/isis_main.c b/isisd/isis_main.c index c93bbb83af..acfa1a29d4 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -265,9 +265,6 @@ int main(int argc, char **argv, char **envp) lsp_init(); mt_init(); - /* create the global 'isis' instance */ - isis_global_instance_create(VRF_DEFAULT_NAME); - isis_zebra_init(master, instance); isis_bfd_init(master); isis_ldp_sync_init(); diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 68a4581a46..a00c86eeaf 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -68,7 +68,7 @@ int isis_instance_create(struct nb_cb_create_args *args) return NB_OK; vrf_name = yang_dnode_get_string(args->dnode, "./vrf"); area_tag = yang_dnode_get_string(args->dnode, "./area-tag"); - isis_global_instance_create(vrf_name); + area = isis_area_lookup_by_vrf(area_tag, vrf_name); if (area) return NB_ERR_INCONSISTENCY; diff --git a/isisd/isisd.c b/isisd/isisd.c index 172d202150..bda2295ae1 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -175,15 +175,6 @@ void isis_master_init(struct thread_master *master) im->master = master; } -void isis_global_instance_create(const char *vrf_name) -{ - struct isis *isis; - - isis = isis_lookup_by_vrfname(vrf_name); - if (isis == NULL) - isis_new(vrf_name); -} - struct isis *isis_new(const char *vrf_name) { struct vrf *vrf; @@ -571,8 +562,7 @@ void isis_area_destroy(struct isis_area *area) area_mt_finish(area); if (listcount(area->isis->area_list) == 0) { - memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN); - area->isis->sysid_set = 0; + isis_finish(area->isis); } XFREE(MTYPE_ISIS_AREA, area); diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c index 915f849aec..b89a5a008e 100644 --- a/tests/isisd/test_isis_spf.c +++ b/tests/isisd/test_isis_spf.c @@ -51,8 +51,6 @@ enum test_type { #define F_LEVEL1_ONLY 0x08 #define F_LEVEL2_ONLY 0x10 -static struct isis *isis; - static void test_run_spf(struct vty *vty, const struct isis_topology *topology, const struct isis_test_node *root, struct isis_area *area, struct lspdb_head *lspdb, @@ -257,8 +255,8 @@ static int test_run(struct vty *vty, const struct isis_topology *topology, uint8_t fail_id[ISIS_SYS_ID_LEN] = {}; /* Init topology. */ - memcpy(isis->sysid, root->sysid, sizeof(isis->sysid)); area = isis_area_create("1", NULL); + memcpy(area->isis->sysid, root->sysid, sizeof(area->isis->sysid)); area->is_type = IS_LEVEL_1_AND_2; area->srdb.enabled = true; if (test_topology_load(topology, area, area->lspdb) != 0) { @@ -470,7 +468,6 @@ static void vty_do_exit(int isexit) { printf("\nend.\n"); - isis_finish(isis); cmd_terminate(); vty_terminate(); yang_terminate(); @@ -555,7 +552,6 @@ int main(int argc, char **argv) /* IS-IS inits. */ yang_module_load("frr-isisd"); - isis = isis_new(VRF_DEFAULT_NAME); SET_FLAG(im->options, F_ISIS_UNIT_TEST); debug_spf_events |= DEBUG_SPF_EVENTS; debug_lfa |= DEBUG_LFA;