mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 01:40:16 +00:00
Merge pull request #9024 from idryzhov/isis-attached-bit
isisd: fix setting of the attached bit
This commit is contained in:
commit
c88229774f
@ -401,20 +401,15 @@ static void lsp_seqno_update(struct isis_lsp *lsp0)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isis_level2_adj_up(struct isis_area *curr_area)
|
bool isis_level2_adj_up(struct isis_area *area)
|
||||||
{
|
{
|
||||||
struct listnode *node, *cnode;
|
struct listnode *node, *cnode;
|
||||||
struct isis_circuit *circuit;
|
struct isis_circuit *circuit;
|
||||||
struct list *adjdb;
|
struct list *adjdb;
|
||||||
struct isis_adjacency *adj;
|
struct isis_adjacency *adj;
|
||||||
struct isis *isis = curr_area->isis;
|
|
||||||
struct isis_area *area;
|
|
||||||
|
|
||||||
/* lookup for a Level2 adjacency up in another area */
|
if (area->is_type == IS_LEVEL_1)
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
return false;
|
||||||
if (area->area_tag
|
|
||||||
&& strcmp(area->area_tag, curr_area->area_tag) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
|
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
|
||||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||||
@ -435,36 +430,28 @@ static bool isis_level2_adj_up(struct isis_area *curr_area)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void isis_reset_attach_bit(struct isis_adjacency *curr_adj)
|
static void isis_reset_attach_bit(struct isis_adjacency *adj)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct isis_area *area = adj->circuit->area;
|
||||||
struct isis_area *curr_area = curr_adj->circuit->area;
|
|
||||||
struct isis *isis = curr_area->isis;
|
|
||||||
struct isis_area *area;
|
|
||||||
struct lspdb_head *head;
|
struct lspdb_head *head;
|
||||||
struct isis_lsp *lsp;
|
struct isis_lsp *lsp;
|
||||||
uint8_t lspid[ISIS_SYS_ID_LEN + 2];
|
uint8_t lspid[ISIS_SYS_ID_LEN + 2];
|
||||||
|
|
||||||
/* If new adjaceny is up and area is level2 or level1and2 verify if
|
/*
|
||||||
* we have LSPs in other areas that should now set the attach bit.
|
* If an L2 adjacency changed its state in L-1-2 area, we have to:
|
||||||
*
|
* - set the attached bit in L1 LSPs if it's the first L2 adjacency
|
||||||
* If adjacenty is down, verify if we no longer have another level2
|
* - remove the attached bit in L1 LSPs if it's the last L2 adjacency
|
||||||
* or level1and2 areas so that we should now remove the attach bit.
|
|
||||||
*/
|
*/
|
||||||
if (curr_area->is_type == IS_LEVEL_1)
|
|
||||||
|
if (area->is_type != IS_LEVEL_1_AND_2 || adj->level == ISIS_ADJ_LEVEL1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
|
||||||
if (area->area_tag
|
|
||||||
&& strcmp(area->area_tag, curr_area->area_tag) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!area->attached_bit_send)
|
if (!area->attached_bit_send)
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
head = &area->lspdb[IS_LEVEL_1 - 1];
|
head = &area->lspdb[IS_LEVEL_1 - 1];
|
||||||
memset(lspid, 0, ISIS_SYS_ID_LEN + 2);
|
memset(lspid, 0, ISIS_SYS_ID_LEN + 2);
|
||||||
@ -472,30 +459,27 @@ static void isis_reset_attach_bit(struct isis_adjacency *curr_adj)
|
|||||||
|
|
||||||
lsp = lsp_search(head, lspid);
|
lsp = lsp_search(head, lspid);
|
||||||
if (!lsp)
|
if (!lsp)
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
if (curr_adj->adj_state == ISIS_ADJ_UP
|
if (adj->adj_state == ISIS_ADJ_UP
|
||||||
&& !(lsp->hdr.lsp_bits & LSPBIT_ATT)) {
|
&& !(lsp->hdr.lsp_bits & LSPBIT_ATT)) {
|
||||||
sched_debug(
|
sched_debug("ISIS (%s): adj going up regenerate lsp-bits",
|
||||||
"ISIS (%s): adj going up regenerate lsp-bits",
|
|
||||||
area->area_tag);
|
area->area_tag);
|
||||||
lsp_regenerate_schedule(area, IS_LEVEL_1, 0);
|
lsp_regenerate_schedule(area, IS_LEVEL_1, 0);
|
||||||
} else if (curr_adj->adj_state == ISIS_ADJ_DOWN
|
} else if (adj->adj_state == ISIS_ADJ_DOWN
|
||||||
&& lsp->hdr.lsp_bits & LSPBIT_ATT
|
&& (lsp->hdr.lsp_bits & LSPBIT_ATT)
|
||||||
&& !isis_level2_adj_up(area)) {
|
&& !isis_level2_adj_up(area)) {
|
||||||
sched_debug(
|
sched_debug("ISIS (%s): adj going down regenerate lsp-bits",
|
||||||
"ISIS (%s): adj going down regenerate lsp-bits",
|
|
||||||
area->area_tag);
|
area->area_tag);
|
||||||
lsp_regenerate_schedule(area, IS_LEVEL_1, 0);
|
lsp_regenerate_schedule(area, IS_LEVEL_1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t lsp_bits_generate(int level, int overload_bit, int attached_bit,
|
static uint8_t lsp_bits_generate(int level, int overload_bit, int attached_bit,
|
||||||
struct isis_area *area)
|
struct isis_area *area)
|
||||||
{
|
{
|
||||||
uint8_t lsp_bits = 0;
|
uint8_t lsp_bits = 0;
|
||||||
if (level == IS_LEVEL_1)
|
if (area->is_type == IS_LEVEL_1)
|
||||||
lsp_bits = IS_LEVEL_1;
|
lsp_bits = IS_LEVEL_1;
|
||||||
else
|
else
|
||||||
lsp_bits = IS_LEVEL_1_AND_2;
|
lsp_bits = IS_LEVEL_1_AND_2;
|
||||||
|
@ -77,6 +77,8 @@ int _lsp_regenerate_schedule(struct isis_area *area, int level,
|
|||||||
int lsp_generate_pseudo(struct isis_circuit *circuit, int level);
|
int lsp_generate_pseudo(struct isis_circuit *circuit, int level);
|
||||||
int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level);
|
int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level);
|
||||||
|
|
||||||
|
bool isis_level2_adj_up(struct isis_area *area);
|
||||||
|
|
||||||
struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id,
|
struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id,
|
||||||
uint16_t rem_lifetime, uint32_t seq_num,
|
uint16_t rem_lifetime, uint32_t seq_num,
|
||||||
uint8_t lsp_bits, uint16_t checksum,
|
uint8_t lsp_bits, uint16_t checksum,
|
||||||
|
@ -1070,8 +1070,8 @@ end:
|
|||||||
*/
|
*/
|
||||||
if ((lsp->hdr.lsp_bits & LSPBIT_ATT) == LSPBIT_ATT
|
if ((lsp->hdr.lsp_bits & LSPBIT_ATT) == LSPBIT_ATT
|
||||||
&& !spftree->area->attached_bit_rcv_ignore
|
&& !spftree->area->attached_bit_rcv_ignore
|
||||||
&& spftree->area->is_type == IS_LEVEL_1
|
&& (spftree->area->is_type & IS_LEVEL_1)
|
||||||
&& !isis_area_count(spftree->area->isis, IS_LEVEL_2)) {
|
&& !isis_level2_adj_up(spftree->area)) {
|
||||||
struct prefix_pair ip_info = { {0} };
|
struct prefix_pair ip_info = { {0} };
|
||||||
if (IS_DEBUG_RTE_EVENTS)
|
if (IS_DEBUG_RTE_EVENTS)
|
||||||
zlog_debug("ISIS-Spf (%s): add default %s route",
|
zlog_debug("ISIS-Spf (%s): add default %s route",
|
||||||
|
@ -469,22 +469,6 @@ int isis_area_get(struct vty *vty, const char *area_tag)
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the number of Level1 and level-1-2 routers or
|
|
||||||
* the number of Level2 and level-1-2 routers configured
|
|
||||||
*/
|
|
||||||
int isis_area_count(const struct isis *isis, int levels)
|
|
||||||
{
|
|
||||||
struct isis_area *area;
|
|
||||||
struct listnode *node;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
|
|
||||||
if (area->is_type & levels)
|
|
||||||
count++;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void isis_area_destroy(struct isis_area *area)
|
void isis_area_destroy(struct isis_area *area)
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
@ -269,7 +269,6 @@ struct isis_area *isis_area_lookup(const char *, vrf_id_t vrf_id);
|
|||||||
struct isis_area *isis_area_lookup_by_vrf(const char *area_tag,
|
struct isis_area *isis_area_lookup_by_vrf(const char *area_tag,
|
||||||
const char *vrf_name);
|
const char *vrf_name);
|
||||||
int isis_area_get(struct vty *vty, const char *area_tag);
|
int isis_area_get(struct vty *vty, const char *area_tag);
|
||||||
int isis_area_count(const struct isis *isis, int levels);
|
|
||||||
void isis_area_destroy(struct isis_area *area);
|
void isis_area_destroy(struct isis_area *area);
|
||||||
void isis_filter_update(struct access_list *access);
|
void isis_filter_update(struct access_list *access);
|
||||||
void isis_prefix_list_update(struct prefix_list *plist);
|
void isis_prefix_list_update(struct prefix_list *plist);
|
||||||
|
Loading…
Reference in New Issue
Block a user