summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--isisd/isis_cli.c53
-rw-r--r--isisd/isis_constants.h3
-rw-r--r--isisd/isis_lsp.c91
-rw-r--r--isisd/isis_nb.c15
-rw-r--r--isisd/isis_nb.h8
-rw-r--r--isisd/isis_nb_config.c32
-rw-r--r--isisd/isis_pdu.c4
-rw-r--r--isisd/isis_spf.c26
-rw-r--r--isisd/isisd.c24
-rw-r--r--isisd/isisd.h7
-rw-r--r--yang/frr-isisd.yang15
11 files changed, 238 insertions, 40 deletions
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index 5ca70eab0..b48da9312 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -593,6 +593,10 @@ void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode,
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
*/
@@ -600,18 +604,57 @@ DEFPY_YANG(set_attached_bit, set_attached_bit_cmd, "[no] set-attached-bit",
"Reset attached bit\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");
return nb_cli_apply_changes(vty, NULL);
}
-void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults)
+void cli_show_isis_attached_send(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 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, " set-attached-bit\n");
+ 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_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, &no_metric_style_cmd);
diff --git a/isisd/isis_constants.h b/isisd/isis_constants.h
index 25eae06cb..3d6a20ee6 100644
--- a/isisd/isis_constants.h
+++ b/isisd/isis_constants.h
@@ -140,7 +140,7 @@
* LSP bit masks
*/
#define LSPBIT_P 0x80
-#define LSPBIT_ATT 0x78
+#define LSPBIT_ATT 0x08 /* only use the Default ATT bit */
#define LSPBIT_OL 0x04
#define LSPBIT_IST 0x03
@@ -158,7 +158,6 @@
#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_DELAY_BIT(x) ((x)&0x10)
-#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
#define LLC_LEN 3
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 47225ea2c..4c70bd12b 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -399,7 +399,50 @@ static void lsp_seqno_update(struct isis_lsp *lsp0)
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;
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;
if (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;
}
@@ -632,13 +680,13 @@ static const char *lsp_bits2string(uint8_t lsp_bits, char *buf, size_t buf_size)
return " error";
/* we only focus on the default metric */
- pos += sprintf(pos, "%d/",
- ISIS_MASK_LSP_ATT_DEFAULT_BIT(lsp_bits) ? 1 : 0);
+ pos += snprintf(pos, buf_size, "%d/",
+ ISIS_MASK_LSP_ATT_BITS(lsp_bits) ? 1 : 0);
- pos += sprintf(pos, "%d/",
- ISIS_MASK_LSP_PARTITION_BIT(lsp_bits) ? 1 : 0);
+ pos += snprintf(pos, buf_size, "%d/",
+ 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;
}
@@ -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_bits_generate(level, area->overload_bit,
- area->attached_bit),
+ area->attached_bit_send, area),
0, lsp0, level);
lsp->own_lsp = 1;
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);
lsp->hdr.lsp_bits = lsp_bits_generate(level, area->overload_bit,
- area->attached_bit);
+ area->attached_bit_send, area);
lsp_add_auth(lsp);
@@ -1223,10 +1271,10 @@ int lsp_generate(struct isis_area *area, int level)
oldlsp->hdr.lsp_id);
}
rem_lifetime = lsp_rem_lifetime(area, level);
- newlsp =
- lsp_new(area, lspid, rem_lifetime, seq_num,
- area->is_type | area->overload_bit | area->attached_bit,
- 0, NULL, level);
+ newlsp = lsp_new(area, lspid, rem_lifetime, seq_num,
+ lsp_bits_generate(area->is_type, area->overload_bit,
+ area->attached_bit_send, area),
+ 0, NULL, level);
newlsp->area = area;
newlsp->own_lsp = 1;
@@ -1310,8 +1358,9 @@ static int lsp_regenerate(struct isis_area *area, int level)
continue;
}
- frag->hdr.lsp_bits = lsp_bits_generate(
- level, area->overload_bit, area->attached_bit);
+ frag->hdr.lsp_bits =
+ lsp_bits_generate(level, area->overload_bit,
+ area->attached_bit_send, area);
/* Set the lifetime values of all the fragments to the same
* value,
* 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;
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
- lsp->hdr.lsp_bits =
- lsp_bits_generate(level, 0, circuit->area->attached_bit);
+ lsp->hdr.lsp_bits = lsp_bits_generate(
+ level, 0, circuit->area->attached_bit_send, area);
/*
* 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);
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
lsp = lsp_new(circuit->area, lsp_id, rem_lifetime, 1,
- circuit->area->is_type | circuit->area->attached_bit, 0,
- NULL, level);
+ lsp_bits_generate(circuit->area->is_type, 0,
+ circuit->area->attached_bit_send,
+ circuit->area),
+ 0, NULL, level);
lsp->area = circuit->area;
lsp_build_pseudo(lsp, circuit, level);
diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c
index a02e6a45b..6d46e6b67 100644
--- a/isisd/isis_nb.c
+++ b/isisd/isis_nb.c
@@ -60,9 +60,22 @@ const struct frr_yang_module_info frr_isisd_info = {
},
},
{
+ .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",
.cbs = {
- .cli_show = cli_show_isis_attached,
.modify = isis_instance_attached_modify,
},
},
diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h
index 679bc6345..8ecd8134e 100644
--- a/isisd/isis_nb.h
+++ b/isisd/isis_nb.h
@@ -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_destroy(struct nb_cb_destroy_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_overload_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);
void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
-void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults);
+void cli_show_isis_attached_send(struct vty *vty, struct lyd_node *dnode,
+ 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,
bool show_defaults);
void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode,
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index ed0fea882..45bbc9737 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -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;
bool attached;
@@ -284,12 +284,38 @@ int isis_instance_attached_modify(struct nb_cb_modify_args *args)
area = nb_running_get_entry(args->dnode, NULL, true);
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;
}
/*
+ * 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
*/
int isis_instance_overload_modify(struct nb_cb_modify_args *args)
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 72de5d654..2d68aaa9e 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -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)) {
zlog_warn(
- "ISIS-Adj (%s): Received IIH with own sysid - discard",
- circuit->area->area_tag);
+ "ISIS-Adj (%s): Received IIH with own sysid on %s - discard",
+ circuit->area->area_tag, circuit->interface->name);
circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index dee082fce..ec0313f21 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -1046,6 +1046,32 @@ lspfragloop:
}
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)
fragnode = listhead(lsp->lspu.frags);
else
diff --git a/isisd/isisd.c b/isisd/isisd.c
index eabebab4e..d45690f4d 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -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");
area->lfa_load_sharing[1] = yang_get_default_bool(
"/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
area->max_lsp_lifetime[0] = 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->lfa_load_sharing[0] = true;
area->lfa_load_sharing[1] = true;
+ area->attached_bit_send = true;
+ area->attached_bit_rcv_ignore = false;
#endif /* ifndef FABRICD */
area->lfa_priority_limit[0] = 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 */
}
-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)
+{
+
+ if (attached_bit != area->attached_bit_send) {
+ 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)
{
- char new_attached_bit = attached_bit ? LSPBIT_ATT : 0;
- if (new_attached_bit != area->attached_bit) {
- area->attached_bit = new_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);
}
}
diff --git a/isisd/isisd.h b/isisd/isisd.h
index 9b903eed4..a09f74152 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -169,7 +169,8 @@ struct isis_area {
/* are we overloaded? */
char overload_bit;
/* 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];
/* minimum time allowed before lsp retransmission */
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_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_metricstyle_set(struct isis_area *area, bool old_metric,
bool new_metric);
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
index 812dd4159..8757ab6b8 100644
--- a/yang/frr-isisd.yang
+++ b/yang/frr-isisd.yang
@@ -1043,9 +1043,24 @@ module frr-isisd {
"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 {
type boolean;
default "false";
+ status deprecated;
description
"If true, identify as L1/L2 router for inter-area traffic.";
}