mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 06:59:21 +00:00
isisd: add the 'redistribute table' internal support
The 'redistribute table' command does not create the internal contexts with the appropriate table identifier. Redistributed prefixes in IS-IS do not care about the table identifier. Add a linked list of redistribution contexts, and map the nb configuration to the linked list. - A new 'table' attribute is added in the 'struct isis_redist' context. - The 'isis_redist_update_zebra_subscriptions()' function is removed and is replaced by direct call to zebra API for turning on/off redirection. - The redistributed routes coming from zebra import the 'tableid' information. - The fabricd redistribute running-config is reworked, and the 'get_redist_settings()' function is removed. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
2150647069
commit
4aee03bfd5
@ -1088,7 +1088,7 @@ void default_info_origin_apply_finish(const struct lyd_node *dnode, int family)
|
||||
routemap = yang_dnode_get_string(dnode, "./route-map");
|
||||
|
||||
isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
|
||||
originate_type);
|
||||
originate_type, 0);
|
||||
}
|
||||
|
||||
void default_info_origin_ipv4_apply_finish(struct nb_cb_apply_finish_args *args)
|
||||
@ -1119,7 +1119,7 @@ int isis_instance_default_information_originate_ipv4_destroy(
|
||||
|
||||
area = nb_running_get_entry(args->dnode, NULL, true);
|
||||
level = yang_dnode_get_enum(args->dnode, "./level");
|
||||
isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE);
|
||||
isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE, 0);
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
@ -1182,7 +1182,7 @@ int isis_instance_default_information_originate_ipv6_destroy(
|
||||
|
||||
area = nb_running_get_entry(args->dnode, NULL, true);
|
||||
level = yang_dnode_get_enum(args->dnode, "./level");
|
||||
isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE);
|
||||
isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE, 0);
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
@ -1244,7 +1244,7 @@ void redistribute_apply_finish(const struct lyd_node *dnode, int family)
|
||||
if (yang_dnode_exists(dnode, "./route-map"))
|
||||
routemap = yang_dnode_get_string(dnode, "./route-map");
|
||||
|
||||
isis_redist_set(area, level, family, type, metric, routemap, 0);
|
||||
isis_redist_set(area, level, family, type, metric, routemap, 0, 0);
|
||||
}
|
||||
|
||||
void redistribute_ipv4_apply_finish(struct nb_cb_apply_finish_args *args)
|
||||
@ -1274,7 +1274,7 @@ int isis_instance_redistribute_ipv4_destroy(struct nb_cb_destroy_args *args)
|
||||
area = nb_running_get_entry(args->dnode, NULL, true);
|
||||
level = yang_dnode_get_enum(args->dnode, "./level");
|
||||
type = yang_dnode_get_enum(args->dnode, "./protocol");
|
||||
isis_redist_unset(area, level, AF_INET, type);
|
||||
isis_redist_unset(area, level, AF_INET, type, 0);
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
@ -1319,14 +1319,44 @@ int isis_instance_redistribute_ipv4_metric_destroy(struct nb_cb_destroy_args *ar
|
||||
*/
|
||||
int isis_instance_redistribute_ipv4_table_create(struct nb_cb_create_args *args)
|
||||
{
|
||||
uint16_t table;
|
||||
int type, level;
|
||||
unsigned long metric = 0;
|
||||
const char *routemap = NULL;
|
||||
struct isis_area *area;
|
||||
|
||||
if (args->event != NB_EV_APPLY)
|
||||
return NB_OK;
|
||||
|
||||
/* TODO */
|
||||
type = yang_dnode_get_enum(args->dnode, "../protocol");
|
||||
level = yang_dnode_get_enum(args->dnode, "../level");
|
||||
area = nb_running_get_entry(args->dnode, "../.", true);
|
||||
|
||||
if (yang_dnode_exists(args->dnode, "./metric"))
|
||||
metric = yang_dnode_get_uint32(args->dnode, "./metric");
|
||||
if (yang_dnode_exists(args->dnode, "./route-map"))
|
||||
routemap = yang_dnode_get_string(args->dnode, "./route-map");
|
||||
|
||||
table = yang_dnode_get_uint16(args->dnode, "./table");
|
||||
isis_redist_set(area, level, AF_INET, type, metric, routemap, 0, table);
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
int isis_instance_redistribute_ipv4_table_destroy(struct nb_cb_destroy_args *args)
|
||||
{
|
||||
struct isis_area *area;
|
||||
int level, type;
|
||||
uint16_t table;
|
||||
|
||||
if (args->event != NB_EV_APPLY)
|
||||
return NB_OK;
|
||||
|
||||
area = nb_running_get_entry(args->dnode, "../.", true);
|
||||
level = yang_dnode_get_enum(args->dnode, "../level");
|
||||
type = yang_dnode_get_enum(args->dnode, "../protocol");
|
||||
table = yang_dnode_get_uint16(args->dnode, "./table");
|
||||
isis_redist_unset(area, level, AF_INET, type, table);
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
@ -1350,7 +1380,7 @@ int isis_instance_redistribute_ipv6_destroy(struct nb_cb_destroy_args *args)
|
||||
area = nb_running_get_entry(args->dnode, NULL, true);
|
||||
level = yang_dnode_get_enum(args->dnode, "./level");
|
||||
type = yang_dnode_get_enum(args->dnode, "./protocol");
|
||||
isis_redist_unset(area, level, AF_INET6, type);
|
||||
isis_redist_unset(area, level, AF_INET6, type, 0);
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
DEFINE_MTYPE_STATIC(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route");
|
||||
DEFINE_MTYPE_STATIC(ISISD, ISIS_EXT_INFO, "ISIS redistributed route info");
|
||||
DEFINE_MTYPE_STATIC(ISISD, ISIS_RMAP_NAME, "ISIS redistribute route-map name");
|
||||
DEFINE_MTYPE_STATIC(ISISD, ISIS_REDISTRIBUTE, "ISIS redistribute");
|
||||
|
||||
static int redist_protocol(int family)
|
||||
{
|
||||
@ -61,12 +62,43 @@ static struct route_table *get_ext_info(struct isis *i, int family)
|
||||
return i->ext_info[protocol];
|
||||
}
|
||||
|
||||
static struct isis_redist *get_redist_settings(struct isis_area *area,
|
||||
int family, int type, int level)
|
||||
static struct isis_redist *isis_redist_lookup(struct isis_area *area,
|
||||
int family, int type, int level,
|
||||
uint16_t table)
|
||||
{
|
||||
int protocol = redist_protocol(family);
|
||||
struct listnode *node;
|
||||
struct isis_redist *red;
|
||||
|
||||
return &area->redist_settings[protocol][type][level - 1];
|
||||
if (area->redist_settings[protocol][type][level - 1]) {
|
||||
for (ALL_LIST_ELEMENTS_RO(area->redist_settings[protocol][type]
|
||||
[level - 1],
|
||||
node, red))
|
||||
if (red->table == table)
|
||||
return red;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct isis_redist *isis_redist_get(struct isis_area *area, int family,
|
||||
int type, int level, uint16_t table)
|
||||
{
|
||||
struct isis_redist *red;
|
||||
int protocol;
|
||||
|
||||
red = isis_redist_lookup(area, family, type, level, table);
|
||||
if (red)
|
||||
return red;
|
||||
|
||||
protocol = redist_protocol(family);
|
||||
if (area->redist_settings[protocol][type][level - 1] == NULL)
|
||||
area->redist_settings[protocol][type][level - 1] = list_new();
|
||||
|
||||
red = XCALLOC(MTYPE_ISIS_REDISTRIBUTE, sizeof(struct isis_redist));
|
||||
red->table = table;
|
||||
|
||||
listnode_add(area->redist_settings[protocol][type][level - 1], red);
|
||||
return red;
|
||||
}
|
||||
|
||||
struct route_table *get_ext_reach(struct isis_area *area, int family, int level)
|
||||
@ -256,7 +288,7 @@ bool isis_redist_table_is_present(const struct vty *vty,
|
||||
/* Handle notification about route being added */
|
||||
void isis_redist_add(struct isis *isis, int type, struct prefix *p,
|
||||
struct prefix_ipv6 *src_p, uint8_t distance,
|
||||
uint32_t metric, const route_tag_t tag)
|
||||
uint32_t metric, const route_tag_t tag, uint16_t table)
|
||||
{
|
||||
int family = p->family;
|
||||
struct route_table *ei_table = get_ext_info(isis, family);
|
||||
@ -296,8 +328,9 @@ void isis_redist_add(struct isis *isis, int type, struct prefix *p,
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
|
||||
for (level = 1; level <= ISIS_LEVELS; level++) {
|
||||
redist = get_redist_settings(area, family, type, level);
|
||||
if (!redist->redist)
|
||||
redist = isis_redist_lookup(area, family, type, level,
|
||||
table);
|
||||
if (!redist || !redist->redist)
|
||||
continue;
|
||||
|
||||
isis_redist_update_ext_reach(area, level, redist, p,
|
||||
@ -306,7 +339,7 @@ void isis_redist_add(struct isis *isis, int type, struct prefix *p,
|
||||
}
|
||||
|
||||
void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
|
||||
struct prefix_ipv6 *src_p)
|
||||
struct prefix_ipv6 *src_p, uint16_t table)
|
||||
{
|
||||
int family = p->family;
|
||||
struct route_table *ei_table = get_ext_info(isis, family);
|
||||
@ -326,7 +359,7 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
|
||||
* "always" setting will ignore routes with origin
|
||||
* DEFAULT_ROUTE. */
|
||||
isis_redist_add(isis, DEFAULT_ROUTE, p, NULL, 254,
|
||||
MAX_WIDE_PATH_METRIC, 0);
|
||||
MAX_WIDE_PATH_METRIC, 0, table);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -349,8 +382,9 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
|
||||
for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
|
||||
redist = get_redist_settings(area, family, type, level);
|
||||
if (!redist->redist)
|
||||
redist = isis_redist_lookup(area, family, type, level,
|
||||
table);
|
||||
if (!redist || !redist->redist)
|
||||
continue;
|
||||
|
||||
isis_redist_uninstall(area, level, p, src_p);
|
||||
@ -376,53 +410,6 @@ static void isis_redist_routemap_set(struct isis_redist *redist,
|
||||
}
|
||||
}
|
||||
|
||||
static void isis_redist_update_zebra_subscriptions(struct isis *isis)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_area *area;
|
||||
int type;
|
||||
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));
|
||||
|
||||
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;
|
||||
|
||||
afi_t afi = afi_for_redist_protocol(protocol);
|
||||
|
||||
if (do_subscribe[protocol][type])
|
||||
isis_zebra_redistribute_set(afi, type,
|
||||
isis->vrf_id);
|
||||
else
|
||||
isis_zebra_redistribute_unset(afi, type,
|
||||
isis->vrf_id);
|
||||
}
|
||||
}
|
||||
|
||||
void isis_redist_free(struct isis *isis)
|
||||
{
|
||||
struct route_node *rn;
|
||||
@ -444,11 +431,12 @@ void isis_redist_free(struct isis *isis)
|
||||
}
|
||||
|
||||
void isis_redist_set(struct isis_area *area, int level, int family, int type,
|
||||
uint32_t metric, const char *routemap, int originate_type)
|
||||
uint32_t metric, const char *routemap, int originate_type,
|
||||
uint16_t table)
|
||||
{
|
||||
int protocol = redist_protocol(family);
|
||||
struct isis_redist *redist =
|
||||
get_redist_settings(area, family, type, level);
|
||||
struct isis_redist *redist = isis_redist_get(area, family, type, level,
|
||||
table);
|
||||
int i;
|
||||
struct route_table *ei_table;
|
||||
struct route_node *rn;
|
||||
@ -468,7 +456,8 @@ void isis_redist_set(struct isis_area *area, int level, int family, int type,
|
||||
}
|
||||
}
|
||||
|
||||
isis_redist_update_zebra_subscriptions(area->isis);
|
||||
isis_zebra_redistribute_set(afi_for_redist_protocol(protocol), type,
|
||||
area->isis->vrf_id, redist->table);
|
||||
|
||||
if (type == DEFAULT_ROUTE && originate_type == DEFAULT_ORIGINATE_ALWAYS)
|
||||
isis_redist_ensure_default(area->isis, family);
|
||||
@ -499,18 +488,26 @@ void isis_redist_set(struct isis_area *area, int level, int family, int type,
|
||||
}
|
||||
}
|
||||
|
||||
void isis_redist_unset(struct isis_area *area, int level, int family, int type)
|
||||
void isis_redist_unset(struct isis_area *area, int level, int family, int type,
|
||||
uint16_t table)
|
||||
{
|
||||
struct isis_redist *redist =
|
||||
get_redist_settings(area, family, type, level);
|
||||
struct isis_redist *redist = isis_redist_lookup(area, family, type,
|
||||
level, table);
|
||||
struct route_table *er_table = get_ext_reach(area, family, level);
|
||||
struct route_node *rn;
|
||||
struct isis_ext_info *info;
|
||||
struct list *redist_list;
|
||||
int protocol = redist_protocol(family);
|
||||
|
||||
if (!redist->redist)
|
||||
if (!redist || !redist->redist)
|
||||
return;
|
||||
|
||||
redist->redist = 0;
|
||||
|
||||
redist_list = area->redist_settings[protocol][type][level - 1];
|
||||
listnode_delete(redist_list, redist);
|
||||
XFREE(MTYPE_ISIS_REDISTRIBUTE, redist);
|
||||
|
||||
if (!er_table) {
|
||||
zlog_warn("%s: External reachability table uninitialized.",
|
||||
__func__);
|
||||
@ -540,7 +537,8 @@ void isis_redist_unset(struct isis_area *area, int level, int family, int type)
|
||||
}
|
||||
|
||||
lsp_regenerate_schedule(area, level, 0);
|
||||
isis_redist_update_zebra_subscriptions(area->isis);
|
||||
isis_zebra_redistribute_unset(afi_for_redist_protocol(protocol), type,
|
||||
area->isis->vrf_id, table);
|
||||
}
|
||||
|
||||
void isis_redist_area_finish(struct isis_area *area)
|
||||
@ -549,16 +547,30 @@ void isis_redist_area_finish(struct isis_area *area)
|
||||
int protocol;
|
||||
int level;
|
||||
int type;
|
||||
struct isis_redist *redist;
|
||||
struct listnode *node, *nnode;
|
||||
struct list *redist_list;
|
||||
|
||||
for (protocol = 0; protocol < REDIST_PROTOCOL_COUNT; protocol++)
|
||||
for (level = 0; level < ISIS_LEVELS; level++) {
|
||||
for (type = 0; type < ZEBRA_ROUTE_MAX + 1; type++) {
|
||||
struct isis_redist *redist;
|
||||
|
||||
redist = &area->redist_settings[protocol][type]
|
||||
[level];
|
||||
redist->redist = 0;
|
||||
XFREE(MTYPE_ISIS_RMAP_NAME, redist->map_name);
|
||||
redist_list = area->redist_settings[protocol]
|
||||
[type][level];
|
||||
if (!redist_list)
|
||||
continue;
|
||||
for (ALL_LIST_ELEMENTS(redist_list, node, nnode,
|
||||
redist)) {
|
||||
redist->redist = 0;
|
||||
XFREE(MTYPE_ISIS_RMAP_NAME,
|
||||
redist->map_name);
|
||||
isis_zebra_redistribute_unset(
|
||||
afi_for_redist_protocol(protocol),
|
||||
type, area->isis->vrf_id,
|
||||
redist->table);
|
||||
listnode_delete(redist_list, redist);
|
||||
XFREE(MTYPE_ISIS_REDISTRIBUTE, redist);
|
||||
}
|
||||
list_delete(&redist_list);
|
||||
}
|
||||
if (!area->ext_reach[protocol][level])
|
||||
continue;
|
||||
@ -570,8 +582,6 @@ void isis_redist_area_finish(struct isis_area *area)
|
||||
route_table_finish(area->ext_reach[protocol][level]);
|
||||
area->ext_reach[protocol][level] = NULL;
|
||||
}
|
||||
|
||||
isis_redist_update_zebra_subscriptions(area->isis);
|
||||
}
|
||||
|
||||
#ifdef FABRICD
|
||||
@ -628,7 +638,7 @@ DEFUN (isis_redistribute,
|
||||
routemap = argv[idx_metric_rmap + 1]->arg;
|
||||
}
|
||||
|
||||
isis_redist_set(area, level, family, type, metric, routemap, 0);
|
||||
isis_redist_set(area, level, family, type, metric, routemap, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -664,7 +674,7 @@ DEFUN (no_isis_redistribute,
|
||||
|
||||
level = 2;
|
||||
|
||||
isis_redist_unset(area, level, family, type);
|
||||
isis_redist_unset(area, level, family, type, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -724,7 +734,7 @@ DEFUN (isis_default_originate,
|
||||
}
|
||||
|
||||
isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
|
||||
originate_type);
|
||||
originate_type, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -748,7 +758,7 @@ DEFUN (no_isis_default_originate,
|
||||
|
||||
level = 2;
|
||||
|
||||
isis_redist_unset(area, level, family, DEFAULT_ROUTE);
|
||||
isis_redist_unset(area, level, family, DEFAULT_ROUTE, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif /* ifdef FABRICD */
|
||||
@ -760,7 +770,9 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
|
||||
int level;
|
||||
int write = 0;
|
||||
struct isis_redist *redist;
|
||||
struct list *redist_list;
|
||||
const char *family_str;
|
||||
struct listnode *node;
|
||||
|
||||
if (family == AF_INET)
|
||||
family_str = "ipv4";
|
||||
@ -774,25 +786,36 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
|
||||
continue;
|
||||
|
||||
for (level = 1; level <= ISIS_LEVELS; level++) {
|
||||
redist = get_redist_settings(area, family, type, level);
|
||||
if (!redist->redist)
|
||||
redist_list = area->redist_settings[redist_protocol(
|
||||
family)][type][level - 1];
|
||||
if (!redist_list)
|
||||
continue;
|
||||
vty_out(vty, " redistribute %s %s", family_str,
|
||||
zebra_route_string(type));
|
||||
if (!fabricd)
|
||||
vty_out(vty, " level-%d", level);
|
||||
if (redist->metric)
|
||||
vty_out(vty, " metric %u", redist->metric);
|
||||
if (redist->map_name)
|
||||
vty_out(vty, " route-map %s", redist->map_name);
|
||||
vty_out(vty, "\n");
|
||||
write++;
|
||||
for (ALL_LIST_ELEMENTS_RO(redist_list, node, redist)) {
|
||||
if (!redist->redist)
|
||||
continue;
|
||||
vty_out(vty, " redistribute %s %s", family_str,
|
||||
zebra_route_string(type));
|
||||
if (type == ZEBRA_ROUTE_TABLE)
|
||||
vty_out(vty, " %u", redist->table);
|
||||
if (!fabricd)
|
||||
vty_out(vty, " level-%d", level);
|
||||
if (redist->metric)
|
||||
vty_out(vty, " metric %u",
|
||||
redist->metric);
|
||||
if (redist->map_name)
|
||||
vty_out(vty, " route-map %s",
|
||||
redist->map_name);
|
||||
vty_out(vty, "\n");
|
||||
write++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (level = 1; level <= ISIS_LEVELS; level++) {
|
||||
redist =
|
||||
get_redist_settings(area, family, DEFAULT_ROUTE, level);
|
||||
redist = isis_redist_lookup(area, family, DEFAULT_ROUTE, level,
|
||||
0);
|
||||
if (!redist)
|
||||
continue;
|
||||
if (!redist->redist)
|
||||
continue;
|
||||
vty_out(vty, " default-information originate %s",
|
||||
|
@ -26,6 +26,7 @@ struct isis_redist {
|
||||
uint32_t metric;
|
||||
char *map_name;
|
||||
struct route_map *map;
|
||||
uint16_t table;
|
||||
};
|
||||
|
||||
struct isis_redist_table_present_args {
|
||||
@ -48,17 +49,19 @@ 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,
|
||||
struct prefix_ipv6 *src_p, uint8_t distance,
|
||||
uint32_t metric, route_tag_t tag);
|
||||
uint32_t metric, route_tag_t tag, uint16_t instance);
|
||||
void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
|
||||
struct prefix_ipv6 *src_p);
|
||||
struct prefix_ipv6 *src_p, uint16_t tableid);
|
||||
int isis_redist_config_write(struct vty *vty, struct isis_area *area,
|
||||
int family);
|
||||
void isis_redist_init(void);
|
||||
void isis_redist_area_finish(struct isis_area *area);
|
||||
|
||||
void isis_redist_set(struct isis_area *area, int level, int family, int type,
|
||||
uint32_t metric, const char *routemap, int originate_type);
|
||||
void isis_redist_unset(struct isis_area *area, int level, int family, int type);
|
||||
uint32_t metric, const char *routemap, int originate_type,
|
||||
uint16_t table);
|
||||
void isis_redist_unset(struct isis_area *area, int level, int family, int type,
|
||||
uint16_t table);
|
||||
|
||||
void isis_redist_free(struct isis *isis);
|
||||
|
||||
|
@ -498,10 +498,10 @@ static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
|
||||
|
||||
if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
|
||||
isis_redist_add(isis, api.type, &api.prefix, &api.src_prefix,
|
||||
api.distance, api.metric, api.tag);
|
||||
api.distance, api.metric, api.tag, api.instance);
|
||||
else
|
||||
isis_redist_delete(isis, api.type, &api.prefix,
|
||||
&api.src_prefix);
|
||||
isis_redist_delete(isis, api.type, &api.prefix, &api.src_prefix,
|
||||
api.instance);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -511,24 +511,26 @@ int isis_distribute_list_update(int routetype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id)
|
||||
void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id,
|
||||
uint16_t tableid)
|
||||
{
|
||||
if (type == DEFAULT_ROUTE)
|
||||
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
|
||||
zclient, afi, vrf_id);
|
||||
else
|
||||
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
|
||||
0, vrf_id);
|
||||
tableid, vrf_id);
|
||||
}
|
||||
|
||||
void isis_zebra_redistribute_unset(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,
|
||||
uint16_t tableid)
|
||||
{
|
||||
if (type == DEFAULT_ROUTE)
|
||||
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
|
||||
zclient, afi, vrf_id);
|
||||
else
|
||||
zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
|
||||
type, 0, vrf_id);
|
||||
type, tableid, vrf_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,8 +43,10 @@ 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, vrf_id_t vrf_id);
|
||||
void isis_zebra_redistribute_unset(afi_t afi, int type, vrf_id_t vrf_id);
|
||||
void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id,
|
||||
uint16_t tableid);
|
||||
void isis_zebra_redistribute_unset(afi_t afi, int type, vrf_id_t vrf_id,
|
||||
uint16_t tableid);
|
||||
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);
|
||||
|
100
isisd/isisd.c
100
isisd/isisd.c
@ -599,64 +599,66 @@ static int isis_vrf_delete(struct vrf *vrf)
|
||||
|
||||
static void isis_set_redist_vrf_bitmaps(struct isis *isis, bool set)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct listnode *node, *lnode;
|
||||
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));
|
||||
struct isis_redist *redist;
|
||||
|
||||
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 (level = 0; level < ISIS_LEVELS; level++) {
|
||||
if (area->redist_settings[protocol][type]
|
||||
[level] == NULL)
|
||||
continue;
|
||||
for (ALL_LIST_ELEMENTS_RO(area->redist_settings
|
||||
[protocol]
|
||||
[type]
|
||||
[level],
|
||||
lnode,
|
||||
redist)) {
|
||||
if (redist->redist == 0)
|
||||
continue;
|
||||
/* This field is actually
|
||||
* controlling transmission of
|
||||
* the IS-IS
|
||||
* routes to Zebra and has
|
||||
* nothing to do with
|
||||
* redistribution,
|
||||
* so skip it. */
|
||||
afi_t afi =
|
||||
afi_for_redist_protocol(
|
||||
protocol);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
@ -230,8 +230,8 @@ struct isis_area {
|
||||
#endif /* ifndef FABRICD */
|
||||
/* Counters */
|
||||
uint32_t circuit_state_changes;
|
||||
struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT]
|
||||
[ZEBRA_ROUTE_MAX + 1][ISIS_LEVELS];
|
||||
struct list *redist_settings[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1]
|
||||
[ISIS_LEVELS];
|
||||
struct route_table *ext_reach[REDIST_PROTOCOL_COUNT][ISIS_LEVELS];
|
||||
|
||||
struct spf_backoff *spf_delay_ietf[ISIS_LEVELS]; /*Structure with IETF
|
||||
|
Loading…
Reference in New Issue
Block a user