mirror of https://github.com/FRRouting/frr.git
isisd: Fix Attach-bit processing
The purpose of the Attach-bit is to accomplish inter-area routing. In other venders, the Attached-bit is automatically set when a router is configured as a L1|L2 router and has two adjacencies. When a L1 router receives a LSP with the Attached-bit set it is supposed to create a default route pointing toward the neighbor to provide a default path out of the L1 area. ISIS implementation has been fixed to support the above definition: Setting the Attach-bit is now the default behavior and we allow the user to turn it off. We will only set the Default Attach-bit when creating a L1 LSP, if we are a L1|L2 router and have a L2 adjacency up. When a L1 router receives a LSP with the Attach-bit set, we will create a default route pointing to the L1|L2 router as the nexthop. The default route will be removed if the LSP is received with the Attach-bit cleared. Signed-off-by: Lynne Morrison <lynne@voltanet.io>
This commit is contained in:
parent
44ba9e779d
commit
f3abc412a5
|
@ -593,6 +593,10 @@ void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode,
|
||||||
vty_out(vty, " set-overload-bit\n");
|
vty_out(vty, " set-overload-bit\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFDATE > 20220119
|
||||||
|
CPP_NOTICE(
|
||||||
|
"Use of `set-attached-bit` is deprecated please use attached-bit [send | receive]")
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-isisd:isis/instance/attached
|
* XPath: /frr-isisd:isis/instance/attached
|
||||||
*/
|
*/
|
||||||
|
@ -600,18 +604,57 @@ DEFPY_YANG(set_attached_bit, set_attached_bit_cmd, "[no] set-attached-bit",
|
||||||
"Reset attached bit\n"
|
"Reset attached bit\n"
|
||||||
"Set attached bit to identify as L1/L2 router for inter-area traffic\n")
|
"Set attached bit to identify as L1/L2 router for inter-area traffic\n")
|
||||||
{
|
{
|
||||||
nb_cli_enqueue_change(vty, "./attached", NB_OP_MODIFY,
|
vty_out(vty,
|
||||||
|
"set-attached-bit deprecated please use attached-bit [send | receive]\n");
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-isisd:isis/instance/attach-send
|
||||||
|
*/
|
||||||
|
DEFPY_YANG(attached_bit_send, attached_bit_send_cmd, "[no] attached-bit send",
|
||||||
|
"Reset attached bit\n"
|
||||||
|
"Set attached bit for inter-area traffic\n"
|
||||||
|
"Set attached bit in LSP sent to L1 router\n")
|
||||||
|
{
|
||||||
|
nb_cli_enqueue_change(vty, "./attach-send", NB_OP_MODIFY,
|
||||||
no ? "false" : "true");
|
no ? "false" : "true");
|
||||||
|
|
||||||
return nb_cli_apply_changes(vty, NULL);
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode,
|
void cli_show_isis_attached_send(struct vty *vty, struct lyd_node *dnode,
|
||||||
bool show_defaults)
|
bool show_defaults)
|
||||||
{
|
{
|
||||||
if (!yang_dnode_get_bool(dnode, NULL))
|
if (!yang_dnode_get_bool(dnode, NULL))
|
||||||
vty_out(vty, " no");
|
vty_out(vty, " no");
|
||||||
vty_out(vty, " set-attached-bit\n");
|
vty_out(vty, " attached-bit send\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-isisd:isis/instance/attach-receive-ignore
|
||||||
|
*/
|
||||||
|
DEFPY_YANG(
|
||||||
|
attached_bit_receive_ignore, attached_bit_receive_ignore_cmd,
|
||||||
|
"[no] attached-bit receive ignore",
|
||||||
|
"Reset attached bit\n"
|
||||||
|
"Set attach bit for inter-area traffic\n"
|
||||||
|
"If LSP received with attached bit set, create default route to neighbor\n"
|
||||||
|
"Do not process attached bit\n")
|
||||||
|
{
|
||||||
|
nb_cli_enqueue_change(vty, "./attach-receive-ignore", NB_OP_MODIFY,
|
||||||
|
no ? "false" : "true");
|
||||||
|
|
||||||
|
return nb_cli_apply_changes(vty, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cli_show_isis_attached_receive(struct vty *vty, struct lyd_node *dnode,
|
||||||
|
bool show_defaults)
|
||||||
|
{
|
||||||
|
if (!yang_dnode_get_bool(dnode, NULL))
|
||||||
|
vty_out(vty, " no");
|
||||||
|
vty_out(vty, " attached-bit receive ignore\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3206,6 +3249,8 @@ void isis_cli_init(void)
|
||||||
|
|
||||||
install_element(ISIS_NODE, &set_overload_bit_cmd);
|
install_element(ISIS_NODE, &set_overload_bit_cmd);
|
||||||
install_element(ISIS_NODE, &set_attached_bit_cmd);
|
install_element(ISIS_NODE, &set_attached_bit_cmd);
|
||||||
|
install_element(ISIS_NODE, &attached_bit_send_cmd);
|
||||||
|
install_element(ISIS_NODE, &attached_bit_receive_ignore_cmd);
|
||||||
|
|
||||||
install_element(ISIS_NODE, &metric_style_cmd);
|
install_element(ISIS_NODE, &metric_style_cmd);
|
||||||
install_element(ISIS_NODE, &no_metric_style_cmd);
|
install_element(ISIS_NODE, &no_metric_style_cmd);
|
||||||
|
|
|
@ -140,7 +140,7 @@
|
||||||
* LSP bit masks
|
* LSP bit masks
|
||||||
*/
|
*/
|
||||||
#define LSPBIT_P 0x80
|
#define LSPBIT_P 0x80
|
||||||
#define LSPBIT_ATT 0x78
|
#define LSPBIT_ATT 0x08 /* only use the Default ATT bit */
|
||||||
#define LSPBIT_OL 0x04
|
#define LSPBIT_OL 0x04
|
||||||
#define LSPBIT_IST 0x03
|
#define LSPBIT_IST 0x03
|
||||||
|
|
||||||
|
@ -158,7 +158,6 @@
|
||||||
#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
|
#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
|
||||||
#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
|
#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
|
||||||
#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
|
#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
|
||||||
#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
|
|
||||||
|
|
||||||
#define LLC_LEN 3
|
#define LLC_LEN 3
|
||||||
|
|
||||||
|
|
|
@ -399,7 +399,50 @@ static void lsp_seqno_update(struct isis_lsp *lsp0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t lsp_bits_generate(int level, int overload_bit, int attached_bit)
|
static bool isis_level2_adj_up(struct isis_area *curr_area)
|
||||||
|
{
|
||||||
|
struct listnode *node, *cnode;
|
||||||
|
struct isis_circuit *circuit;
|
||||||
|
struct list *adjdb;
|
||||||
|
struct isis_adjacency *adj;
|
||||||
|
struct isis *isis = curr_area->isis;
|
||||||
|
struct isis_area *area;
|
||||||
|
|
||||||
|
/* lookup for a Level2 adjacency up in another area */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
||||||
|
if (area->area_tag
|
||||||
|
&& strcmp(area->area_tag, curr_area->area_tag) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
|
||||||
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||||
|
adjdb = circuit->u.bc.adjdb[1];
|
||||||
|
if (adjdb && adjdb->count) {
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(adjdb, node,
|
||||||
|
adj))
|
||||||
|
if ((adj->level
|
||||||
|
== ISIS_ADJ_LEVEL2
|
||||||
|
|| adj->level
|
||||||
|
== ISIS_ADJ_LEVEL1AND2)
|
||||||
|
&& adj->adj_state
|
||||||
|
== ISIS_ADJ_UP)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (circuit->circ_type == CIRCUIT_T_P2P
|
||||||
|
&& circuit->u.p2p.neighbor) {
|
||||||
|
adj = circuit->u.p2p.neighbor;
|
||||||
|
if ((adj->level == ISIS_ADJ_LEVEL2
|
||||||
|
|| adj->level == ISIS_ADJ_LEVEL1AND2)
|
||||||
|
&& adj->adj_state == ISIS_ADJ_UP)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t lsp_bits_generate(int level, int overload_bit, int attached_bit,
|
||||||
|
struct isis_area *area)
|
||||||
{
|
{
|
||||||
uint8_t lsp_bits = 0;
|
uint8_t lsp_bits = 0;
|
||||||
if (level == IS_LEVEL_1)
|
if (level == IS_LEVEL_1)
|
||||||
|
@ -408,8 +451,13 @@ static uint8_t lsp_bits_generate(int level, int overload_bit, int attached_bit)
|
||||||
lsp_bits = IS_LEVEL_1_AND_2;
|
lsp_bits = IS_LEVEL_1_AND_2;
|
||||||
if (overload_bit)
|
if (overload_bit)
|
||||||
lsp_bits |= overload_bit;
|
lsp_bits |= overload_bit;
|
||||||
if (attached_bit)
|
|
||||||
lsp_bits |= attached_bit;
|
/* only set the attach bit if we are a level-1-2 router and this is
|
||||||
|
* a level-1 LSP and we have a level-2 adjacency up from another area
|
||||||
|
*/
|
||||||
|
if (area->is_type == IS_LEVEL_1_AND_2 && level == IS_LEVEL_1
|
||||||
|
&& attached_bit && isis_level2_adj_up(area))
|
||||||
|
lsp_bits |= LSPBIT_ATT;
|
||||||
return lsp_bits;
|
return lsp_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,13 +680,13 @@ static const char *lsp_bits2string(uint8_t lsp_bits, char *buf, size_t buf_size)
|
||||||
return " error";
|
return " error";
|
||||||
|
|
||||||
/* we only focus on the default metric */
|
/* we only focus on the default metric */
|
||||||
pos += sprintf(pos, "%d/",
|
pos += snprintf(pos, buf_size, "%d/",
|
||||||
ISIS_MASK_LSP_ATT_DEFAULT_BIT(lsp_bits) ? 1 : 0);
|
ISIS_MASK_LSP_ATT_BITS(lsp_bits) ? 1 : 0);
|
||||||
|
|
||||||
pos += sprintf(pos, "%d/",
|
pos += snprintf(pos, buf_size, "%d/",
|
||||||
ISIS_MASK_LSP_PARTITION_BIT(lsp_bits) ? 1 : 0);
|
ISIS_MASK_LSP_PARTITION_BIT(lsp_bits) ? 1 : 0);
|
||||||
|
|
||||||
sprintf(pos, "%d", ISIS_MASK_LSP_OL_BIT(lsp_bits) ? 1 : 0);
|
snprintf(pos, buf_size, "%d", ISIS_MASK_LSP_OL_BIT(lsp_bits) ? 1 : 0);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -838,7 +886,7 @@ static struct isis_lsp *lsp_next_frag(uint8_t frag_num, struct isis_lsp *lsp0,
|
||||||
|
|
||||||
lsp = lsp_new(area, frag_id, lsp0->hdr.rem_lifetime, 0,
|
lsp = lsp_new(area, frag_id, lsp0->hdr.rem_lifetime, 0,
|
||||||
lsp_bits_generate(level, area->overload_bit,
|
lsp_bits_generate(level, area->overload_bit,
|
||||||
area->attached_bit),
|
area->attached_bit_send, area),
|
||||||
0, lsp0, level);
|
0, lsp0, level);
|
||||||
lsp->own_lsp = 1;
|
lsp->own_lsp = 1;
|
||||||
lsp_insert(&area->lspdb[level - 1], lsp);
|
lsp_insert(&area->lspdb[level - 1], lsp);
|
||||||
|
@ -864,7 +912,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
|
||||||
area->area_tag, level);
|
area->area_tag, level);
|
||||||
|
|
||||||
lsp->hdr.lsp_bits = lsp_bits_generate(level, area->overload_bit,
|
lsp->hdr.lsp_bits = lsp_bits_generate(level, area->overload_bit,
|
||||||
area->attached_bit);
|
area->attached_bit_send, area);
|
||||||
|
|
||||||
lsp_add_auth(lsp);
|
lsp_add_auth(lsp);
|
||||||
|
|
||||||
|
@ -1223,10 +1271,10 @@ int lsp_generate(struct isis_area *area, int level)
|
||||||
oldlsp->hdr.lsp_id);
|
oldlsp->hdr.lsp_id);
|
||||||
}
|
}
|
||||||
rem_lifetime = lsp_rem_lifetime(area, level);
|
rem_lifetime = lsp_rem_lifetime(area, level);
|
||||||
newlsp =
|
newlsp = lsp_new(area, lspid, rem_lifetime, seq_num,
|
||||||
lsp_new(area, lspid, rem_lifetime, seq_num,
|
lsp_bits_generate(area->is_type, area->overload_bit,
|
||||||
area->is_type | area->overload_bit | area->attached_bit,
|
area->attached_bit_send, area),
|
||||||
0, NULL, level);
|
0, NULL, level);
|
||||||
newlsp->area = area;
|
newlsp->area = area;
|
||||||
newlsp->own_lsp = 1;
|
newlsp->own_lsp = 1;
|
||||||
|
|
||||||
|
@ -1310,8 +1358,9 @@ static int lsp_regenerate(struct isis_area *area, int level)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
frag->hdr.lsp_bits = lsp_bits_generate(
|
frag->hdr.lsp_bits =
|
||||||
level, area->overload_bit, area->attached_bit);
|
lsp_bits_generate(level, area->overload_bit,
|
||||||
|
area->attached_bit_send, area);
|
||||||
/* Set the lifetime values of all the fragments to the same
|
/* Set the lifetime values of all the fragments to the same
|
||||||
* value,
|
* value,
|
||||||
* so that no fragment expires before the lsp is refreshed.
|
* so that no fragment expires before the lsp is refreshed.
|
||||||
|
@ -1518,8 +1567,8 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
|
||||||
|
|
||||||
lsp->level = level;
|
lsp->level = level;
|
||||||
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
|
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
|
||||||
lsp->hdr.lsp_bits =
|
lsp->hdr.lsp_bits = lsp_bits_generate(
|
||||||
lsp_bits_generate(level, 0, circuit->area->attached_bit);
|
level, 0, circuit->area->attached_bit_send, area);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add self to IS neighbours
|
* add self to IS neighbours
|
||||||
|
@ -1617,8 +1666,10 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
|
||||||
rem_lifetime = lsp_rem_lifetime(circuit->area, level);
|
rem_lifetime = lsp_rem_lifetime(circuit->area, level);
|
||||||
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
|
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
|
||||||
lsp = lsp_new(circuit->area, lsp_id, rem_lifetime, 1,
|
lsp = lsp_new(circuit->area, lsp_id, rem_lifetime, 1,
|
||||||
circuit->area->is_type | circuit->area->attached_bit, 0,
|
lsp_bits_generate(circuit->area->is_type, 0,
|
||||||
NULL, level);
|
circuit->area->attached_bit_send,
|
||||||
|
circuit->area),
|
||||||
|
0, NULL, level);
|
||||||
lsp->area = circuit->area;
|
lsp->area = circuit->area;
|
||||||
|
|
||||||
lsp_build_pseudo(lsp, circuit, level);
|
lsp_build_pseudo(lsp, circuit, level);
|
||||||
|
|
|
@ -59,10 +59,23 @@ const struct frr_yang_module_info frr_isisd_info = {
|
||||||
.modify = isis_instance_dynamic_hostname_modify,
|
.modify = isis_instance_dynamic_hostname_modify,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-isisd:isis/instance/attach-send",
|
||||||
|
.cbs = {
|
||||||
|
.cli_show = cli_show_isis_attached_send,
|
||||||
|
.modify = isis_instance_attached_send_modify,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.xpath = "/frr-isisd:isis/instance/attach-receive-ignore",
|
||||||
|
.cbs = {
|
||||||
|
.cli_show = cli_show_isis_attached_receive,
|
||||||
|
.modify = isis_instance_attached_receive_modify,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.xpath = "/frr-isisd:isis/instance/attached",
|
.xpath = "/frr-isisd:isis/instance/attached",
|
||||||
.cbs = {
|
.cbs = {
|
||||||
.cli_show = cli_show_isis_attached,
|
|
||||||
.modify = isis_instance_attached_modify,
|
.modify = isis_instance_attached_modify,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,6 +34,8 @@ int isis_instance_is_type_modify(struct nb_cb_modify_args *args);
|
||||||
int isis_instance_area_address_create(struct nb_cb_create_args *args);
|
int isis_instance_area_address_create(struct nb_cb_create_args *args);
|
||||||
int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args);
|
int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args);
|
||||||
int isis_instance_dynamic_hostname_modify(struct nb_cb_modify_args *args);
|
int isis_instance_dynamic_hostname_modify(struct nb_cb_modify_args *args);
|
||||||
|
int isis_instance_attached_send_modify(struct nb_cb_modify_args *args);
|
||||||
|
int isis_instance_attached_receive_modify(struct nb_cb_modify_args *args);
|
||||||
int isis_instance_attached_modify(struct nb_cb_modify_args *args);
|
int isis_instance_attached_modify(struct nb_cb_modify_args *args);
|
||||||
int isis_instance_overload_modify(struct nb_cb_modify_args *args);
|
int isis_instance_overload_modify(struct nb_cb_modify_args *args);
|
||||||
int isis_instance_metric_style_modify(struct nb_cb_modify_args *args);
|
int isis_instance_metric_style_modify(struct nb_cb_modify_args *args);
|
||||||
|
@ -424,8 +426,10 @@ void cli_show_isis_is_type(struct vty *vty, struct lyd_node *dnode,
|
||||||
bool show_defaults);
|
bool show_defaults);
|
||||||
void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode,
|
void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode,
|
||||||
bool show_defaults);
|
bool show_defaults);
|
||||||
void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode,
|
void cli_show_isis_attached_send(struct vty *vty, struct lyd_node *dnode,
|
||||||
bool show_defaults);
|
bool show_defaults);
|
||||||
|
void cli_show_isis_attached_receive(struct vty *vty, struct lyd_node *dnode,
|
||||||
|
bool show_defaults);
|
||||||
void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode,
|
void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode,
|
||||||
bool show_defaults);
|
bool show_defaults);
|
||||||
void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode,
|
void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode,
|
||||||
|
|
|
@ -272,9 +272,9 @@ int isis_instance_dynamic_hostname_modify(struct nb_cb_modify_args *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-isisd:isis/instance/attached
|
* XPath: /frr-isisd:isis/instance/attach-send
|
||||||
*/
|
*/
|
||||||
int isis_instance_attached_modify(struct nb_cb_modify_args *args)
|
int isis_instance_attached_send_modify(struct nb_cb_modify_args *args)
|
||||||
{
|
{
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
bool attached;
|
bool attached;
|
||||||
|
@ -284,11 +284,37 @@ int isis_instance_attached_modify(struct nb_cb_modify_args *args)
|
||||||
|
|
||||||
area = nb_running_get_entry(args->dnode, NULL, true);
|
area = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
attached = yang_dnode_get_bool(args->dnode, NULL);
|
attached = yang_dnode_get_bool(args->dnode, NULL);
|
||||||
isis_area_attached_bit_set(area, attached);
|
isis_area_attached_bit_send_set(area, attached);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-isisd:isis/instance/attach-receive-ignore
|
||||||
|
*/
|
||||||
|
int isis_instance_attached_receive_modify(struct nb_cb_modify_args *args)
|
||||||
|
{
|
||||||
|
struct isis_area *area;
|
||||||
|
bool attached;
|
||||||
|
|
||||||
|
if (args->event != NB_EV_APPLY)
|
||||||
|
return NB_OK;
|
||||||
|
|
||||||
|
area = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
attached = yang_dnode_get_bool(args->dnode, NULL);
|
||||||
|
isis_area_attached_bit_receive_set(area, attached);
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath: /frr-isisd:isis/instance/attached
|
||||||
|
*/
|
||||||
|
int isis_instance_attached_modify(struct nb_cb_modify_args *args)
|
||||||
|
{
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-isisd:isis/instance/overload
|
* XPath: /frr-isisd:isis/instance/overload
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -729,8 +729,8 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
|
||||||
|
|
||||||
if (!memcmp(iih.sys_id, circuit->isis->sysid, ISIS_SYS_ID_LEN)) {
|
if (!memcmp(iih.sys_id, circuit->isis->sysid, ISIS_SYS_ID_LEN)) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"ISIS-Adj (%s): Received IIH with own sysid - discard",
|
"ISIS-Adj (%s): Received IIH with own sysid on %s - discard",
|
||||||
circuit->area->area_tag);
|
circuit->area->area_tag, circuit->interface->name);
|
||||||
circuit->rej_adjacencies++;
|
circuit->rej_adjacencies++;
|
||||||
#ifndef FABRICD
|
#ifndef FABRICD
|
||||||
isis_notif_reject_adjacency(
|
isis_notif_reject_adjacency(
|
||||||
|
|
|
@ -1046,6 +1046,32 @@ lspfragloop:
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
||||||
|
/* if attach bit set and we are a level-1 router
|
||||||
|
* and attach-bit-rcv-ignore is not configured
|
||||||
|
* add a default route toward this neighbor
|
||||||
|
*/
|
||||||
|
if ((lsp->hdr.lsp_bits & LSPBIT_ATT) == LSPBIT_ATT
|
||||||
|
&& !spftree->area->attached_bit_rcv_ignore
|
||||||
|
&& spftree->area->is_type == IS_LEVEL_1) {
|
||||||
|
struct prefix_pair ip_info = { {0} };
|
||||||
|
if (IS_DEBUG_SPF_EVENTS)
|
||||||
|
zlog_debug("ISIS-Spf (%s): add default %s route",
|
||||||
|
rawlspid_print(lsp->hdr.lsp_id),
|
||||||
|
spftree->family == AF_INET ? "ipv4"
|
||||||
|
: "ipv6");
|
||||||
|
|
||||||
|
if (spftree->family == AF_INET) {
|
||||||
|
ip_info.dest.family = AF_INET;
|
||||||
|
vtype = VTYPE_IPREACH_INTERNAL;
|
||||||
|
} else {
|
||||||
|
ip_info.dest.family = AF_INET6;
|
||||||
|
vtype = VTYPE_IP6REACH_INTERNAL;
|
||||||
|
}
|
||||||
|
process_N(spftree, vtype, &ip_info, cost, depth + 1, NULL,
|
||||||
|
parent);
|
||||||
|
}
|
||||||
|
|
||||||
if (fragnode == NULL)
|
if (fragnode == NULL)
|
||||||
fragnode = listhead(lsp->lspu.frags);
|
fragnode = listhead(lsp->lspu.frags);
|
||||||
else
|
else
|
||||||
|
|
|
@ -316,6 +316,11 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
|
||||||
"/frr-isisd:isis/instance/fast-reroute/level-1/lfa/load-sharing");
|
"/frr-isisd:isis/instance/fast-reroute/level-1/lfa/load-sharing");
|
||||||
area->lfa_load_sharing[1] = yang_get_default_bool(
|
area->lfa_load_sharing[1] = yang_get_default_bool(
|
||||||
"/frr-isisd:isis/instance/fast-reroute/level-2/lfa/load-sharing");
|
"/frr-isisd:isis/instance/fast-reroute/level-2/lfa/load-sharing");
|
||||||
|
area->attached_bit_send =
|
||||||
|
yang_get_default_bool("/frr-isisd:isis/instance/attach-send");
|
||||||
|
area->attached_bit_rcv_ignore = yang_get_default_bool(
|
||||||
|
"/frr-isisd:isis/instance/attach-receive-ignore");
|
||||||
|
|
||||||
#else
|
#else
|
||||||
area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */
|
area->max_lsp_lifetime[0] = DEFAULT_LSP_LIFETIME; /* 1200 */
|
||||||
area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */
|
area->max_lsp_lifetime[1] = DEFAULT_LSP_LIFETIME; /* 1200 */
|
||||||
|
@ -332,6 +337,8 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
|
||||||
area->lsp_mtu = DEFAULT_LSP_MTU;
|
area->lsp_mtu = DEFAULT_LSP_MTU;
|
||||||
area->lfa_load_sharing[0] = true;
|
area->lfa_load_sharing[0] = true;
|
||||||
area->lfa_load_sharing[1] = true;
|
area->lfa_load_sharing[1] = true;
|
||||||
|
area->attached_bit_send = true;
|
||||||
|
area->attached_bit_rcv_ignore = false;
|
||||||
#endif /* ifndef FABRICD */
|
#endif /* ifndef FABRICD */
|
||||||
area->lfa_priority_limit[0] = SPF_PREFIX_PRIO_LOW;
|
area->lfa_priority_limit[0] = SPF_PREFIX_PRIO_LOW;
|
||||||
area->lfa_priority_limit[1] = SPF_PREFIX_PRIO_LOW;
|
area->lfa_priority_limit[1] = SPF_PREFIX_PRIO_LOW;
|
||||||
|
@ -2547,12 +2554,21 @@ void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
|
||||||
#endif /* ifndef FABRICD */
|
#endif /* ifndef FABRICD */
|
||||||
}
|
}
|
||||||
|
|
||||||
void isis_area_attached_bit_set(struct isis_area *area, bool attached_bit)
|
void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit)
|
||||||
{
|
{
|
||||||
char new_attached_bit = attached_bit ? LSPBIT_ATT : 0;
|
|
||||||
|
|
||||||
if (new_attached_bit != area->attached_bit) {
|
if (attached_bit != area->attached_bit_send) {
|
||||||
area->attached_bit = new_attached_bit;
|
area->attached_bit_send = attached_bit;
|
||||||
|
lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void isis_area_attached_bit_receive_set(struct isis_area *area,
|
||||||
|
bool attached_bit)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (attached_bit != area->attached_bit_rcv_ignore) {
|
||||||
|
area->attached_bit_rcv_ignore = attached_bit;
|
||||||
lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
|
lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,8 @@ struct isis_area {
|
||||||
/* are we overloaded? */
|
/* are we overloaded? */
|
||||||
char overload_bit;
|
char overload_bit;
|
||||||
/* L1/L2 router identifier for inter-area traffic */
|
/* L1/L2 router identifier for inter-area traffic */
|
||||||
char attached_bit;
|
char attached_bit_send;
|
||||||
|
char attached_bit_rcv_ignore;
|
||||||
uint16_t lsp_refresh[ISIS_LEVELS];
|
uint16_t lsp_refresh[ISIS_LEVELS];
|
||||||
/* minimum time allowed before lsp retransmission */
|
/* minimum time allowed before lsp retransmission */
|
||||||
uint16_t lsp_gen_interval[ISIS_LEVELS];
|
uint16_t lsp_gen_interval[ISIS_LEVELS];
|
||||||
|
@ -253,7 +254,9 @@ void isis_area_invalidate_routes(struct isis_area *area, int levels);
|
||||||
void isis_area_verify_routes(struct isis_area *area);
|
void isis_area_verify_routes(struct isis_area *area);
|
||||||
|
|
||||||
void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit);
|
void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit);
|
||||||
void isis_area_attached_bit_set(struct isis_area *area, bool attached_bit);
|
void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit);
|
||||||
|
void isis_area_attached_bit_receive_set(struct isis_area *area,
|
||||||
|
bool attached_bit);
|
||||||
void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname);
|
void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname);
|
||||||
void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
|
void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
|
||||||
bool new_metric);
|
bool new_metric);
|
||||||
|
|
|
@ -1043,9 +1043,24 @@ module frr-isisd {
|
||||||
"Dynamic hostname support for IS-IS.";
|
"Dynamic hostname support for IS-IS.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leaf attach-send {
|
||||||
|
type boolean;
|
||||||
|
default "true";
|
||||||
|
description
|
||||||
|
"If true, attached bits are sent in LSP if L1/L2 router for inter-area traffic.";
|
||||||
|
}
|
||||||
|
|
||||||
|
leaf attach-receive-ignore {
|
||||||
|
type boolean;
|
||||||
|
default "false";
|
||||||
|
description
|
||||||
|
"If false, attached bits received in LSP, cause default route add, if L1 router for inter-area traffic.";
|
||||||
|
}
|
||||||
|
|
||||||
leaf attached {
|
leaf attached {
|
||||||
type boolean;
|
type boolean;
|
||||||
default "false";
|
default "false";
|
||||||
|
status deprecated;
|
||||||
description
|
description
|
||||||
"If true, identify as L1/L2 router for inter-area traffic.";
|
"If true, identify as L1/L2 router for inter-area traffic.";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue