Merge pull request #8628 from idryzhov/isis-vrf-redist

isisd: fix redistribution in vrf
This commit is contained in:
Donald Sharp 2021-05-20 09:00:46 -04:00 committed by GitHub
commit 21967e4e82
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 166 additions and 79 deletions

View file

@ -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();

View file

@ -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;

View file

@ -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));
@ -359,8 +362,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;
@ -377,20 +381,29 @@ 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);
}
}
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;
}
@ -498,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;
@ -512,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);

View file

@ -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,

View file

@ -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);
}
/**
@ -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)
{

View file

@ -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);
@ -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 */

View file

@ -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;
@ -200,6 +191,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 +220,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);
@ -567,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);
@ -595,6 +589,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;
@ -614,13 +670,10 @@ 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_set_redist_vrf_bitmaps(isis, true);
isis_zebra_vrf_register(isis);
}
}
@ -642,6 +695,10 @@ static int isis_vrf_disable(struct vrf *vrf)
if (isis) {
old_vrf_id = isis->vrf_id;
isis_zebra_vrf_deregister(isis);
isis_set_redist_vrf_bitmaps(isis, false);
/* We have instance configured, unlink
* from VRF and make it "down".
*/

View file

@ -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;

View file

@ -2,7 +2,7 @@
"10.0.10.0/24": [
{
"distance": 115,
"metric": 20,
"metric": 10,
"nexthops": [
{
"active": true,

View file

@ -18,7 +18,7 @@
"2001:db8:2:1::/64": [
{
"distance": 115,
"metric": 20,
"metric": 10,
"nexthops": [
{
"active": true,

View file

@ -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",

View file

@ -2,7 +2,7 @@
"10.0.11.0/24": [
{
"distance": 115,
"metric": 20,
"metric": 10,
"nexthops": [
{
"active": true,

View file

@ -18,7 +18,7 @@
"2001:db8:2:2::/64": [
{
"distance": 115,
"metric": 20,
"metric": 10,
"nexthops": [
{
"active": true,

View file

@ -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",

View file

@ -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,

View file

@ -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,

View file

@ -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",

View file

@ -1,7 +1,7 @@
{
"10.0.10.0/24": [
{
"metric": 20,
"metric": 10,
"nexthops": [
{
"active": true,

View file

@ -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,

View file

@ -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",

View file

@ -2,7 +2,7 @@
"10.0.10.0/24": [
{
"distance": 115,
"metric": 20,
"metric": 10,
"nexthops": [
{
"afi": "ipv4",

View file

@ -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,

View file

@ -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",