mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 08:50:26 +00:00
Merge pull request #13945 from pguibert6WIND/redistribute_isis_table
Redistribute isis table
This commit is contained in:
commit
82d8e7d5fa
@ -166,6 +166,11 @@ flavors (local LFA, Remote LFA and TI-LFA).
|
||||
Configure a prefix-list to select eligible PQ nodes for remote LFA
|
||||
backups (valid for all protected interfaces).
|
||||
|
||||
.. clicmd:: redistribute <ipv4 | ipv6> table (1-65535) <level-1 | level-2> [metric (0-16777215)|route-map WORD]
|
||||
|
||||
Redistribute routes from a given routing table into the given ISIS
|
||||
level database.
|
||||
|
||||
.. _isis-region:
|
||||
|
||||
ISIS region
|
||||
|
126
isisd/isis_cli.c
126
isisd/isis_cli.c
@ -1430,20 +1430,99 @@ DEFPY_YANG(isis_redistribute, isis_redistribute_cmd,
|
||||
level);
|
||||
}
|
||||
|
||||
static void vty_print_redistribute(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults, const char *family)
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/redistribute/table
|
||||
*/
|
||||
DEFPY_YANG(isis_redistribute_table, isis_redistribute_table_cmd,
|
||||
"[no] redistribute <ipv4|ipv6>$ip table (1-65535)$table"
|
||||
"<level-1|level-2>$level [{metric (0-16777215)|route-map WORD}]",
|
||||
NO_STR REDIST_STR "Redistribute IPv4 routes\n"
|
||||
"Redistribute IPv6 routes\n"
|
||||
"Non-main Kernel Routing Table\n"
|
||||
"Table Id\n"
|
||||
"Redistribute into level-1\n"
|
||||
"Redistribute into level-2\n"
|
||||
"Metric for redistributed routes\n"
|
||||
"IS-IS default metric\n"
|
||||
"Route map reference\n"
|
||||
"Pointer to route-map entries\n")
|
||||
{
|
||||
const char *level = yang_dnode_get_string(dnode, "./level");
|
||||
const char *protocol = yang_dnode_get_string(dnode, "./protocol");
|
||||
struct isis_redist_table_present_args rtda = {};
|
||||
char xpath[XPATH_MAXLEN];
|
||||
char xpath_entry[XPATH_MAXLEN + 128];
|
||||
int rv;
|
||||
|
||||
vty_out(vty, " redistribute %s %s %s", family, protocol, level);
|
||||
rtda.rtda_table = table_str;
|
||||
rtda.rtda_ip = ip;
|
||||
rtda.rtda_level = level;
|
||||
|
||||
if (no) {
|
||||
if (!isis_redist_table_is_present(vty, &rtda))
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
|
||||
snprintf(xpath, sizeof(xpath), "./table[table='%s']", table_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
rv = nb_cli_apply_changes(vty,
|
||||
"./redistribute/%s[protocol='table'][level='%s']",
|
||||
ip, level);
|
||||
if (rv == CMD_SUCCESS) {
|
||||
if (isis_redist_table_get_first(vty, &rtda) > 0)
|
||||
return CMD_SUCCESS;
|
||||
nb_cli_enqueue_change(vty, "./table", NB_OP_DESTROY,
|
||||
NULL);
|
||||
nb_cli_apply_changes(vty,
|
||||
"./redistribute/%s[protocol='table'][level='%s']",
|
||||
ip, level);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
if (isis_redist_table_is_present(vty, &rtda))
|
||||
return CMD_SUCCESS;
|
||||
|
||||
snprintf(xpath, sizeof(xpath), "./table[table='%s']", table_str);
|
||||
nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
snprintf(xpath_entry, sizeof(xpath_entry), "%s/route-map", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_entry,
|
||||
route_map ? NB_OP_MODIFY : NB_OP_DESTROY,
|
||||
route_map ? route_map : NULL);
|
||||
snprintf(xpath_entry, sizeof(xpath_entry), "%s/metric", xpath);
|
||||
nb_cli_enqueue_change(vty, xpath_entry, NB_OP_MODIFY,
|
||||
metric_str ? metric_str : NULL);
|
||||
return nb_cli_apply_changes(vty,
|
||||
"./redistribute/%s[protocol='table'][level='%s']",
|
||||
ip, level);
|
||||
}
|
||||
|
||||
static void vty_print_redistribute(struct vty *vty, const struct lyd_node *dnode,
|
||||
bool show_defaults, const char *family,
|
||||
bool table)
|
||||
{
|
||||
const char *level;
|
||||
const char *protocol = NULL;
|
||||
const char *routemap = NULL;
|
||||
uint16_t tableid;
|
||||
|
||||
if (table) {
|
||||
level = yang_dnode_get_string(dnode, "../level");
|
||||
tableid = yang_dnode_get_uint16(dnode, "./table");
|
||||
vty_out(vty, " redistribute %s table %d ", family, tableid);
|
||||
} else {
|
||||
protocol = yang_dnode_get_string(dnode, "./protocol");
|
||||
if (!table && strmatch(protocol, "table"))
|
||||
return;
|
||||
level = yang_dnode_get_string(dnode, "./level");
|
||||
vty_out(vty, " redistribute %s %s ", family, protocol);
|
||||
}
|
||||
vty_out(vty, "%s", level);
|
||||
if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
|
||||
vty_out(vty, " metric %s",
|
||||
yang_dnode_get_string(dnode, "./metric"));
|
||||
yang_dnode_get_string(dnode, "%s", "./metric"));
|
||||
|
||||
if (yang_dnode_exists(dnode, "./route-map"))
|
||||
vty_out(vty, " route-map %s",
|
||||
yang_dnode_get_string(dnode, "./route-map"));
|
||||
routemap = yang_dnode_get_string(dnode, "./route-map");
|
||||
if (routemap)
|
||||
vty_out(vty, " route-map %s", routemap);
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
@ -1451,13 +1530,37 @@ void cli_show_isis_redistribute_ipv4(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults)
|
||||
{
|
||||
vty_print_redistribute(vty, dnode, show_defaults, "ipv4");
|
||||
vty_print_redistribute(vty, dnode, show_defaults, "ipv4", false);
|
||||
}
|
||||
|
||||
void cli_show_isis_redistribute_ipv6(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults)
|
||||
{
|
||||
vty_print_redistribute(vty, dnode, show_defaults, "ipv6");
|
||||
vty_print_redistribute(vty, dnode, show_defaults, "ipv6", false);
|
||||
}
|
||||
|
||||
void cli_show_isis_redistribute_ipv4_table(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults)
|
||||
{
|
||||
vty_print_redistribute(vty, dnode, show_defaults, "ipv4", true);
|
||||
}
|
||||
|
||||
void cli_show_isis_redistribute_ipv6_table(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults)
|
||||
{
|
||||
vty_print_redistribute(vty, dnode, show_defaults, "ipv6", true);
|
||||
}
|
||||
|
||||
int cli_cmp_isis_redistribute_table(const struct lyd_node *dnode1,
|
||||
const struct lyd_node *dnode2)
|
||||
{
|
||||
uint16_t table1 = yang_dnode_get_uint16(dnode1, "./table");
|
||||
uint16_t table2 = yang_dnode_get_uint16(dnode2, "./table");
|
||||
|
||||
return table1 - table2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3681,6 +3784,7 @@ void isis_cli_init(void)
|
||||
|
||||
install_element(ISIS_NODE, &isis_default_originate_cmd);
|
||||
install_element(ISIS_NODE, &isis_redistribute_cmd);
|
||||
install_element(ISIS_NODE, &isis_redistribute_table_cmd);
|
||||
|
||||
install_element(ISIS_NODE, &isis_topology_cmd);
|
||||
|
||||
|
@ -381,6 +381,29 @@ const struct frr_yang_module_info frr_isisd_info = {
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/metric",
|
||||
.cbs = {
|
||||
.destroy = isis_instance_redistribute_ipv4_metric_destroy,
|
||||
.modify = isis_instance_redistribute_ipv4_metric_modify,
|
||||
},
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/table",
|
||||
.cbs = {
|
||||
.cli_show = cli_show_isis_redistribute_ipv4_table,
|
||||
.cli_cmp = cli_cmp_isis_redistribute_table,
|
||||
.create = isis_instance_redistribute_ipv4_table_create,
|
||||
.destroy = isis_instance_redistribute_ipv4_table_destroy,
|
||||
},
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/table/route-map",
|
||||
.cbs = {
|
||||
.destroy = isis_instance_redistribute_ipv4_route_map_destroy,
|
||||
.modify = isis_instance_redistribute_ipv4_route_map_modify,
|
||||
},
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/table/metric",
|
||||
.cbs = {
|
||||
.modify = isis_instance_redistribute_ipv4_metric_modify,
|
||||
},
|
||||
@ -403,6 +426,29 @@ const struct frr_yang_module_info frr_isisd_info = {
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/metric",
|
||||
.cbs = {
|
||||
.destroy = isis_instance_redistribute_ipv6_metric_destroy,
|
||||
.modify = isis_instance_redistribute_ipv6_metric_modify,
|
||||
},
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/table",
|
||||
.cbs = {
|
||||
.cli_show = cli_show_isis_redistribute_ipv6_table,
|
||||
.cli_cmp = cli_cmp_isis_redistribute_table,
|
||||
.create = isis_instance_redistribute_ipv6_table_create,
|
||||
.destroy = isis_instance_redistribute_ipv6_table_destroy,
|
||||
},
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/table/route-map",
|
||||
.cbs = {
|
||||
.destroy = isis_instance_redistribute_ipv6_route_map_destroy,
|
||||
.modify = isis_instance_redistribute_ipv6_route_map_modify,
|
||||
},
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/table/metric",
|
||||
.cbs = {
|
||||
.modify = isis_instance_redistribute_ipv6_metric_modify,
|
||||
},
|
||||
|
@ -121,6 +121,11 @@ int isis_instance_redistribute_ipv4_route_map_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int isis_instance_redistribute_ipv4_metric_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int isis_instance_redistribute_ipv4_metric_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int isis_instance_redistribute_ipv4_table_create(struct nb_cb_create_args *args);
|
||||
int isis_instance_redistribute_ipv4_table_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int isis_instance_redistribute_ipv6_create(struct nb_cb_create_args *args);
|
||||
int isis_instance_redistribute_ipv6_destroy(struct nb_cb_destroy_args *args);
|
||||
int isis_instance_redistribute_ipv6_route_map_modify(
|
||||
@ -129,6 +134,11 @@ int isis_instance_redistribute_ipv6_route_map_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int isis_instance_redistribute_ipv6_metric_modify(
|
||||
struct nb_cb_modify_args *args);
|
||||
int isis_instance_redistribute_ipv6_metric_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int isis_instance_redistribute_ipv6_table_create(struct nb_cb_create_args *args);
|
||||
int isis_instance_redistribute_ipv6_table_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
int isis_instance_multi_topology_ipv4_multicast_create(
|
||||
struct nb_cb_create_args *args);
|
||||
int isis_instance_multi_topology_ipv4_multicast_destroy(
|
||||
@ -587,6 +597,12 @@ void cli_show_isis_redistribute_ipv6(struct vty *vty,
|
||||
void cli_show_isis_mt_ipv4_multicast(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_isis_redistribute_ipv4_table(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_isis_redistribute_ipv6_table(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_isis_mt_ipv4_mgmt(struct vty *vty, const struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_isis_mt_ipv6_unicast(struct vty *vty,
|
||||
@ -742,6 +758,9 @@ void isis_notif_seqno_skipped(const struct isis_circuit *circuit,
|
||||
const uint8_t *lsp_id);
|
||||
void isis_notif_own_lsp_purge(const struct isis_circuit *circuit,
|
||||
const uint8_t *lsp_id);
|
||||
/* cmp */
|
||||
int cli_cmp_isis_redistribute_table(const struct lyd_node *dnode1,
|
||||
const struct lyd_node *dnode2);
|
||||
|
||||
/* We also declare hook for every notification */
|
||||
|
||||
|
@ -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,13 +1274,14 @@ 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map
|
||||
* XPath: /frr-isisd:isis/instance/redistribute/ipv4/table/route-map
|
||||
*/
|
||||
int isis_instance_redistribute_ipv4_route_map_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
@ -1298,6 +1299,7 @@ int isis_instance_redistribute_ipv4_route_map_destroy(
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric
|
||||
* XPath: /frr-isisd:isis/instance/redistribute/ipv4/table/metric
|
||||
*/
|
||||
int isis_instance_redistribute_ipv4_metric_modify(
|
||||
struct nb_cb_modify_args *args)
|
||||
@ -1306,6 +1308,58 @@ int isis_instance_redistribute_ipv4_metric_modify(
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int isis_instance_redistribute_ipv4_metric_destroy(struct nb_cb_destroy_args *args)
|
||||
{
|
||||
/* It's all done by redistribute_apply_finish */
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/redistribute/ipv4/table
|
||||
*/
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/redistribute/ipv6
|
||||
*/
|
||||
@ -1326,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;
|
||||
}
|
||||
@ -1358,6 +1412,33 @@ int isis_instance_redistribute_ipv6_metric_modify(
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int isis_instance_redistribute_ipv6_metric_destroy(struct nb_cb_destroy_args *args)
|
||||
{
|
||||
/* It's all done by redistribute_apply_finish */
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/redistribute/ipv6/table
|
||||
*/
|
||||
int isis_instance_redistribute_ipv6_table_create(struct nb_cb_create_args *args)
|
||||
{
|
||||
if (args->event != NB_EV_APPLY)
|
||||
return NB_OK;
|
||||
|
||||
/* TODO */
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int isis_instance_redistribute_ipv6_table_destroy(struct nb_cb_destroy_args *args)
|
||||
{
|
||||
if (args->event != NB_EV_APPLY)
|
||||
return NB_OK;
|
||||
|
||||
/* TODO */
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast
|
||||
*/
|
||||
|
@ -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)
|
||||
@ -206,10 +238,57 @@ static void isis_redist_ensure_default(struct isis *isis, int family)
|
||||
info->metric = MAX_WIDE_PATH_METRIC;
|
||||
}
|
||||
|
||||
static int _isis_redist_table_is_present(const struct lyd_node *dnode, void *arg)
|
||||
{
|
||||
struct isis_redist_table_present_args *rtda = arg;
|
||||
|
||||
/* This entry is the caller, so skip it. */
|
||||
if (yang_dnode_get_uint16(dnode, "table") !=
|
||||
(uint16_t)atoi(rtda->rtda_table))
|
||||
return YANG_ITER_CONTINUE;
|
||||
|
||||
/* found */
|
||||
rtda->rtda_found = true;
|
||||
return YANG_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
static int _isis_redist_table_get_first_cb(const struct lyd_node *dnode,
|
||||
void *arg)
|
||||
{
|
||||
uint16_t *table = arg;
|
||||
|
||||
*table = yang_dnode_get_uint16(dnode, "table");
|
||||
return YANG_ITER_STOP;
|
||||
}
|
||||
|
||||
uint16_t isis_redist_table_get_first(const struct vty *vty,
|
||||
struct isis_redist_table_present_args *rtda)
|
||||
{
|
||||
uint16_t table = 0;
|
||||
|
||||
yang_dnode_iterate(_isis_redist_table_get_first_cb, &table,
|
||||
vty->candidate_config->dnode,
|
||||
"%s/redistribute/%s[protocol='table'][level='%s']/table",
|
||||
VTY_CURR_XPATH, rtda->rtda_ip, rtda->rtda_level);
|
||||
return table;
|
||||
}
|
||||
|
||||
bool isis_redist_table_is_present(const struct vty *vty,
|
||||
struct isis_redist_table_present_args *rtda)
|
||||
{
|
||||
rtda->rtda_found = false;
|
||||
yang_dnode_iterate(_isis_redist_table_is_present, rtda,
|
||||
vty->candidate_config->dnode,
|
||||
"%s/redistribute/%s[protocol='table'][level='%s']/table",
|
||||
VTY_CURR_XPATH, rtda->rtda_ip, rtda->rtda_level);
|
||||
|
||||
return rtda->rtda_found;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
@ -249,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,
|
||||
@ -259,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);
|
||||
@ -279,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;
|
||||
}
|
||||
|
||||
@ -302,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);
|
||||
@ -329,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;
|
||||
@ -397,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;
|
||||
@ -421,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);
|
||||
@ -452,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__);
|
||||
@ -493,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)
|
||||
@ -502,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;
|
||||
@ -523,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
|
||||
@ -581,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;
|
||||
}
|
||||
|
||||
@ -617,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;
|
||||
}
|
||||
|
||||
@ -677,7 +734,7 @@ DEFUN (isis_default_originate,
|
||||
}
|
||||
|
||||
isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
|
||||
originate_type);
|
||||
originate_type, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -701,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 */
|
||||
@ -713,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";
|
||||
@ -727,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,15 @@ struct isis_redist {
|
||||
uint32_t metric;
|
||||
char *map_name;
|
||||
struct route_map *map;
|
||||
uint16_t table;
|
||||
};
|
||||
|
||||
struct isis_redist_table_present_args {
|
||||
/* from filter.h, struct acl_dup_args */
|
||||
const char *rtda_ip;
|
||||
const char *rtda_level;
|
||||
const char *rtda_table;
|
||||
bool rtda_found;
|
||||
};
|
||||
|
||||
struct isis;
|
||||
@ -40,17 +49,24 @@ 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);
|
||||
|
||||
bool isis_redist_table_is_present(const struct vty *vty,
|
||||
struct isis_redist_table_present_args *rtda);
|
||||
uint16_t isis_redist_table_get_first(const struct vty *vty,
|
||||
struct isis_redist_table_present_args *rtda);
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -146,5 +146,20 @@
|
||||
"protocol": "isis",
|
||||
"selected": true
|
||||
}
|
||||
],
|
||||
"192.0.2.6/32": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"active": true,
|
||||
"fib": true,
|
||||
"ip": "10.0.10.1",
|
||||
"interfaceName": "r3-eth1"
|
||||
}
|
||||
],
|
||||
"prefix": "192.0.2.6/32",
|
||||
"protocol": "isis",
|
||||
"selected": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -61,5 +61,20 @@
|
||||
"protocol": "connected",
|
||||
"selected": true
|
||||
}
|
||||
],
|
||||
"192.0.2.6/32": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"active": true,
|
||||
"fib": true,
|
||||
"ip": "10.0.11.1",
|
||||
"interfaceName": "r4-eth1"
|
||||
}
|
||||
],
|
||||
"prefix": "192.0.2.6/32",
|
||||
"protocol": "isis",
|
||||
"selected": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -20,4 +20,5 @@ router isis 1
|
||||
is-type level-1
|
||||
redistribute ipv4 connected level-1
|
||||
redistribute ipv6 connected level-1
|
||||
redistribute ipv4 table 20 level-1
|
||||
!
|
||||
|
@ -141,5 +141,21 @@
|
||||
"protocol": "connected",
|
||||
"selected": true
|
||||
}
|
||||
],
|
||||
"192.0.2.6/32": [
|
||||
{
|
||||
"nexthops": [
|
||||
{
|
||||
"active": true,
|
||||
"fib": true,
|
||||
"ip": "10.0.10.6",
|
||||
"interfaceName": "r5-eth0"
|
||||
}
|
||||
],
|
||||
"prefix": "192.0.2.6/32",
|
||||
"protocol": "table",
|
||||
"instance": 20,
|
||||
"selected": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
hostname r5
|
||||
ip route 192.0.2.6/32 10.0.10.6 table 20
|
||||
ip import 20
|
||||
interface r5-eth0
|
||||
ip address 10.0.10.1/24
|
||||
ipv6 address 2001:db8:2:1::1/64
|
||||
|
@ -1495,9 +1495,32 @@ module frr-isisd {
|
||||
"IS-IS level into which the routes should be redistributed.";
|
||||
}
|
||||
|
||||
uses redistribute-attributes;
|
||||
}
|
||||
choice protocol-type {
|
||||
case protocol-table {
|
||||
when "./protocol = \"table\"";
|
||||
list table {
|
||||
key "table";
|
||||
when "../protocol = \"table\"";
|
||||
description
|
||||
"Routing table number";
|
||||
|
||||
leaf table {
|
||||
type uint16 {
|
||||
range "1..65535";
|
||||
}
|
||||
description
|
||||
"Routing table number.";
|
||||
}
|
||||
|
||||
uses redistribute-attributes;
|
||||
}
|
||||
}
|
||||
case protocol-other {
|
||||
uses redistribute-attributes;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
list ipv6 {
|
||||
key "protocol level";
|
||||
description
|
||||
@ -1516,7 +1539,29 @@ module frr-isisd {
|
||||
"IS-IS level into which the routes should be redistributed.";
|
||||
}
|
||||
|
||||
uses redistribute-attributes;
|
||||
choice protocol-type {
|
||||
case protocol-table {
|
||||
when "./protocol = \"table\"";
|
||||
list table {
|
||||
key "table";
|
||||
when "../protocol = \"table\"";
|
||||
|
||||
leaf table {
|
||||
type uint16 {
|
||||
range "1..65535";
|
||||
}
|
||||
description
|
||||
"Routing table number.";
|
||||
}
|
||||
|
||||
uses redistribute-attributes;
|
||||
}
|
||||
}
|
||||
case protocol-other {
|
||||
uses redistribute-attributes;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -675,6 +675,8 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
|
||||
zebra_del_import_table_entry(zvrf, rn, same);
|
||||
}
|
||||
|
||||
UNSET_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE);
|
||||
|
||||
newre = zebra_rib_route_entry_new(
|
||||
0, ZEBRA_ROUTE_TABLE, re->table, re->flags, re->nhe_id,
|
||||
zvrf->table_id, re->metric, re->mtu,
|
||||
|
Loading…
Reference in New Issue
Block a user