From: Igor Ryzhov Date: Tue, 4 May 2021 21:10:31 +0000 (+0300) Subject: isisd: fix redistribution in vrf X-Git-Tag: frr-8.0~21^2~43 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=826417ca798e4a813727c8500a629e936d8c3f85;p=matthieu%2Ffrr.git 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 --- 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",