forked from Mirror/frr
isisd: couple of bug fixes
This commit is contained in:
parent
3f045a0881
commit
e38e0df01a
|
@ -1,3 +1,4 @@
|
||||||
Sampo Saaristo <sambo@cs.tut.fi>
|
Sampo Saaristo <sambo@cs.tut.fi>
|
||||||
Ofer Wald <ofersf@islands.co.il>
|
Ofer Wald <ofersf@islands.co.il>
|
||||||
Hannes Gredler <hannes@gredler.at>
|
Hannes Gredler <hannes@gredler.at>
|
||||||
|
Subbaiah Venkata <svenkata@google.com>
|
||||||
|
|
|
@ -220,29 +220,33 @@ isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state
|
||||||
if ((adj->level & level) == 0)
|
if ((adj->level & level) == 0)
|
||||||
continue;
|
continue;
|
||||||
if (new_state == ISIS_ADJ_UP)
|
if (new_state == ISIS_ADJ_UP)
|
||||||
{
|
{
|
||||||
circuit->upadjcount[level - 1]++;
|
circuit->upadjcount[level - 1]++;
|
||||||
isis_event_adjacency_state_change (adj, new_state);
|
isis_event_adjacency_state_change (adj, new_state);
|
||||||
/* update counter & timers for debugging purposes */
|
/* update counter & timers for debugging purposes */
|
||||||
adj->last_flap = time (NULL);
|
adj->last_flap = time (NULL);
|
||||||
adj->flaps++;
|
adj->flaps++;
|
||||||
}
|
}
|
||||||
else if (new_state == ISIS_ADJ_DOWN)
|
else if (new_state == ISIS_ADJ_DOWN)
|
||||||
{
|
{
|
||||||
listnode_delete (circuit->u.bc.adjdb[level - 1], adj);
|
listnode_delete (circuit->u.bc.adjdb[level - 1], adj);
|
||||||
circuit->upadjcount[level - 1]--;
|
circuit->upadjcount[level - 1]--;
|
||||||
if (circuit->upadjcount[level - 1] == 0)
|
if (circuit->upadjcount[level - 1] == 0)
|
||||||
{
|
{
|
||||||
/* Clean lsp_queue when no adj is up. */
|
/* Clean lsp_queue when no adj is up. */
|
||||||
if (circuit->lsp_queue)
|
if (circuit->lsp_queue)
|
||||||
list_delete_all_node (circuit->lsp_queue);
|
list_delete_all_node (circuit->lsp_queue);
|
||||||
}
|
}
|
||||||
isis_event_adjacency_state_change (adj, new_state);
|
isis_event_adjacency_state_change (adj, new_state);
|
||||||
isis_delete_adj (adj);
|
isis_delete_adj (adj);
|
||||||
}
|
}
|
||||||
list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
|
|
||||||
isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
|
if (circuit->u.bc.lan_neighs[level - 1])
|
||||||
circuit->u.bc.lan_neighs[level - 1]);
|
{
|
||||||
|
list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
|
||||||
|
isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
|
||||||
|
circuit->u.bc.lan_neighs[level - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
/* On adjacency state change send new pseudo LSP if we are the DR */
|
/* On adjacency state change send new pseudo LSP if we are the DR */
|
||||||
if (circuit->u.bc.is_dr[level - 1])
|
if (circuit->u.bc.is_dr[level - 1])
|
||||||
|
@ -256,35 +260,35 @@ isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state
|
||||||
if ((adj->level & level) == 0)
|
if ((adj->level & level) == 0)
|
||||||
continue;
|
continue;
|
||||||
if (new_state == ISIS_ADJ_UP)
|
if (new_state == ISIS_ADJ_UP)
|
||||||
{
|
{
|
||||||
circuit->upadjcount[level - 1]++;
|
circuit->upadjcount[level - 1]++;
|
||||||
isis_event_adjacency_state_change (adj, new_state);
|
isis_event_adjacency_state_change (adj, new_state);
|
||||||
|
|
||||||
if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
|
if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
|
||||||
send_hello (circuit, level);
|
send_hello (circuit, level);
|
||||||
|
|
||||||
/* update counter & timers for debugging purposes */
|
/* update counter & timers for debugging purposes */
|
||||||
adj->last_flap = time (NULL);
|
adj->last_flap = time (NULL);
|
||||||
adj->flaps++;
|
adj->flaps++;
|
||||||
|
|
||||||
/* 7.3.17 - going up on P2P -> send CSNP */
|
/* 7.3.17 - going up on P2P -> send CSNP */
|
||||||
/* FIXME: yup, I know its wrong... but i will do it! (for now) */
|
/* FIXME: yup, I know its wrong... but i will do it! (for now) */
|
||||||
send_csnp (circuit, level);
|
send_csnp (circuit, level);
|
||||||
}
|
}
|
||||||
else if (new_state == ISIS_ADJ_DOWN)
|
else if (new_state == ISIS_ADJ_DOWN)
|
||||||
{
|
{
|
||||||
if (adj->circuit->u.p2p.neighbor == adj)
|
if (adj->circuit->u.p2p.neighbor == adj)
|
||||||
adj->circuit->u.p2p.neighbor = NULL;
|
adj->circuit->u.p2p.neighbor = NULL;
|
||||||
circuit->upadjcount[level - 1]--;
|
circuit->upadjcount[level - 1]--;
|
||||||
if (circuit->upadjcount[level - 1] == 0)
|
if (circuit->upadjcount[level - 1] == 0)
|
||||||
{
|
{
|
||||||
/* Clean lsp_queue when no adj is up. */
|
/* Clean lsp_queue when no adj is up. */
|
||||||
if (circuit->lsp_queue)
|
if (circuit->lsp_queue)
|
||||||
list_delete_all_node (circuit->lsp_queue);
|
list_delete_all_node (circuit->lsp_queue);
|
||||||
}
|
}
|
||||||
isis_event_adjacency_state_change (adj, new_state);
|
isis_event_adjacency_state_change (adj, new_state);
|
||||||
isis_delete_adj (adj);
|
isis_delete_adj (adj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ enum isis_system_type
|
||||||
|
|
||||||
enum isis_adj_state
|
enum isis_adj_state
|
||||||
{
|
{
|
||||||
|
ISIS_ADJ_UNKNOWN,
|
||||||
ISIS_ADJ_INITIALIZING,
|
ISIS_ADJ_INITIALIZING,
|
||||||
ISIS_ADJ_UP,
|
ISIS_ADJ_UP,
|
||||||
ISIS_ADJ_DOWN
|
ISIS_ADJ_DOWN
|
||||||
|
@ -83,8 +84,10 @@ struct isis_adjacency
|
||||||
struct list *area_addrs; /* areaAdressesOfNeighbour */
|
struct list *area_addrs; /* areaAdressesOfNeighbour */
|
||||||
struct nlpids nlpids; /* protocols spoken ... */
|
struct nlpids nlpids; /* protocols spoken ... */
|
||||||
struct list *ipv4_addrs;
|
struct list *ipv4_addrs;
|
||||||
|
struct in_addr router_address;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
struct list *ipv6_addrs;
|
struct list *ipv6_addrs;
|
||||||
|
struct in6_addr router_address6;
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */
|
u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */
|
||||||
int circuit_t; /* from hello PDU hdr */
|
int circuit_t; /* from hello PDU hdr */
|
||||||
|
|
|
@ -2720,6 +2720,15 @@ isis_if_new_hook (struct interface *ifp)
|
||||||
int
|
int
|
||||||
isis_if_delete_hook (struct interface *ifp)
|
isis_if_delete_hook (struct interface *ifp)
|
||||||
{
|
{
|
||||||
|
struct isis_circuit *circuit;
|
||||||
|
/* Clean up the circuit data */
|
||||||
|
if (ifp && ifp->info)
|
||||||
|
{
|
||||||
|
circuit = ifp->info;
|
||||||
|
isis_csm_state_change (IF_DOWN_FROM_Z, circuit, circuit->area);
|
||||||
|
isis_csm_state_change (ISIS_DISABLE, circuit, circuit->area);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2734,6 +2743,7 @@ isis_circuit_init ()
|
||||||
/* Install interface node */
|
/* Install interface node */
|
||||||
install_node (&interface_node, isis_interface_config_write);
|
install_node (&interface_node, isis_interface_config_write);
|
||||||
install_element (CONFIG_NODE, &interface_cmd);
|
install_element (CONFIG_NODE, &interface_cmd);
|
||||||
|
install_element (CONFIG_NODE, &no_interface_cmd);
|
||||||
|
|
||||||
install_default (INTERFACE_NODE);
|
install_default (INTERFACE_NODE);
|
||||||
install_element (INTERFACE_NODE, &interface_desc_cmd);
|
install_element (INTERFACE_NODE, &interface_desc_cmd);
|
||||||
|
|
|
@ -130,20 +130,16 @@ isis_event_system_type_change (struct isis_area *area, int newtype)
|
||||||
{
|
{
|
||||||
case IS_LEVEL_1:
|
case IS_LEVEL_1:
|
||||||
if (newtype == IS_LEVEL_2)
|
if (newtype == IS_LEVEL_2)
|
||||||
{
|
|
||||||
area_resign_level (area, IS_LEVEL_1);
|
area_resign_level (area, IS_LEVEL_1);
|
||||||
}
|
|
||||||
else
|
if (area->lspdb[1] == NULL)
|
||||||
{
|
area->lspdb[1] = lsp_db_init ();
|
||||||
if (area->lspdb[1] == NULL)
|
if (area->route_table[1] == NULL)
|
||||||
area->lspdb[1] = lsp_db_init ();
|
area->route_table[1] = route_table_init ();
|
||||||
if (area->route_table[1] == NULL)
|
|
||||||
area->route_table[1] = route_table_init ();
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
if (area->route_table6[1] == NULL)
|
if (area->route_table6[1] == NULL)
|
||||||
area->route_table6[1] = route_table_init ();
|
area->route_table6[1] = route_table_init ();
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IS_LEVEL_1_AND_2:
|
case IS_LEVEL_1_AND_2:
|
||||||
|
@ -155,21 +151,18 @@ isis_event_system_type_change (struct isis_area *area, int newtype)
|
||||||
|
|
||||||
case IS_LEVEL_2:
|
case IS_LEVEL_2:
|
||||||
if (newtype == IS_LEVEL_1)
|
if (newtype == IS_LEVEL_1)
|
||||||
{
|
|
||||||
area_resign_level (area, IS_LEVEL_2);
|
area_resign_level (area, IS_LEVEL_2);
|
||||||
}
|
|
||||||
else
|
if (area->lspdb[0] == NULL)
|
||||||
{
|
area->lspdb[0] = lsp_db_init ();
|
||||||
if (area->lspdb[0] == NULL)
|
if (area->route_table[0] == NULL)
|
||||||
area->lspdb[0] = lsp_db_init ();
|
area->route_table[0] = route_table_init ();
|
||||||
if (area->route_table[0] == NULL)
|
|
||||||
area->route_table[0] = route_table_init ();
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
if (area->route_table6[0] == NULL)
|
if (area->route_table6[0] == NULL)
|
||||||
area->route_table6[0] = route_table_init ();
|
area->route_table6[0] = route_table_init ();
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -199,8 +192,9 @@ circuit_commence_level (struct isis_circuit *circuit, int level)
|
||||||
{
|
{
|
||||||
if (level == 1)
|
if (level == 1)
|
||||||
{
|
{
|
||||||
THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
|
if (! circuit->is_passive)
|
||||||
isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
|
THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
|
||||||
|
isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
|
||||||
|
|
||||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||||
{
|
{
|
||||||
|
@ -217,8 +211,9 @@ circuit_commence_level (struct isis_circuit *circuit, int level)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
|
if (! circuit->is_passive)
|
||||||
isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
|
THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
|
||||||
|
isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
|
||||||
|
|
||||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||||
{
|
{
|
||||||
|
|
|
@ -441,6 +441,19 @@ lsp_seqnum_update (struct isis_lsp *lsp0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u_int8_t
|
||||||
|
lsp_bits_generate (int level, int overload_bit)
|
||||||
|
{
|
||||||
|
u_int8_t lsp_bits = 0;
|
||||||
|
if (level == IS_LEVEL_1)
|
||||||
|
lsp_bits = IS_LEVEL_1;
|
||||||
|
else
|
||||||
|
lsp_bits = IS_LEVEL_1_AND_2;
|
||||||
|
if (overload_bit)
|
||||||
|
lsp_bits |= overload_bit;
|
||||||
|
return lsp_bits;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lsp_update_data (struct isis_lsp *lsp, struct stream *stream,
|
lsp_update_data (struct isis_lsp *lsp, struct stream *stream,
|
||||||
struct isis_area *area, int level)
|
struct isis_area *area, int level)
|
||||||
|
@ -470,8 +483,6 @@ lsp_update_data (struct isis_lsp *lsp, struct stream *stream,
|
||||||
expected |= TLVFLAG_AUTH_INFO;
|
expected |= TLVFLAG_AUTH_INFO;
|
||||||
expected |= TLVFLAG_AREA_ADDRS;
|
expected |= TLVFLAG_AREA_ADDRS;
|
||||||
expected |= TLVFLAG_IS_NEIGHS;
|
expected |= TLVFLAG_IS_NEIGHS;
|
||||||
if ((lsp->lsp_header->lsp_bits & 3) == 3) /* a level 2 LSP */
|
|
||||||
expected |= TLVFLAG_PARTITION_DESIG_LEVEL2_IS;
|
|
||||||
expected |= TLVFLAG_NLPID;
|
expected |= TLVFLAG_NLPID;
|
||||||
if (area->dynhostname)
|
if (area->dynhostname)
|
||||||
expected |= TLVFLAG_DYN_HOSTNAME;
|
expected |= TLVFLAG_DYN_HOSTNAME;
|
||||||
|
@ -503,10 +514,9 @@ lsp_update_data (struct isis_lsp *lsp, struct stream *stream,
|
||||||
|
|
||||||
if ((found & TLVFLAG_DYN_HOSTNAME) && (area->dynhostname))
|
if ((found & TLVFLAG_DYN_HOSTNAME) && (area->dynhostname))
|
||||||
{
|
{
|
||||||
isis_dynhn_insert (lsp->lsp_header->lsp_id, lsp->tlv_data.hostname,
|
isis_dynhn_insert (lsp->lsp_header->lsp_id, lsp->tlv_data.hostname,
|
||||||
(lsp->lsp_header->lsp_bits & LSPBIT_IST) ==
|
(lsp->lsp_header->lsp_bits & LSPBIT_IST) ==
|
||||||
IS_LEVEL_1_AND_2 ? IS_LEVEL_2 :
|
IS_LEVEL_1_AND_2 ? IS_LEVEL_2 : IS_LEVEL_1);
|
||||||
(lsp->lsp_header->lsp_bits & LSPBIT_IST));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1125,7 +1135,7 @@ lsp_next_frag (u_char frag_num, struct isis_lsp *lsp0, struct isis_area *area,
|
||||||
return lsp;
|
return lsp;
|
||||||
}
|
}
|
||||||
lsp = lsp_new (frag_id, ntohs(lsp0->lsp_header->rem_lifetime), 0,
|
lsp = lsp_new (frag_id, ntohs(lsp0->lsp_header->rem_lifetime), 0,
|
||||||
area->is_type | area->overload_bit, 0, level);
|
lsp_bits_generate (level, area->overload_bit), 0, level);
|
||||||
lsp->area = area;
|
lsp->area = area;
|
||||||
lsp->own_lsp = 1;
|
lsp->own_lsp = 1;
|
||||||
lsp_insert (lsp, area->lspdb[level - 1]);
|
lsp_insert (lsp, area->lspdb[level - 1]);
|
||||||
|
@ -1644,7 +1654,7 @@ lsp_regenerate (struct isis_area *area, int level)
|
||||||
|
|
||||||
lsp_clear_data (lsp);
|
lsp_clear_data (lsp);
|
||||||
lsp_build (lsp, area);
|
lsp_build (lsp, area);
|
||||||
lsp->lsp_header->lsp_bits = area->is_type | area->overload_bit;
|
lsp->lsp_header->lsp_bits = lsp_bits_generate (level, area->overload_bit);
|
||||||
rem_lifetime = lsp_rem_lifetime (area, level);
|
rem_lifetime = lsp_rem_lifetime (area, level);
|
||||||
lsp->lsp_header->rem_lifetime = htons (rem_lifetime);
|
lsp->lsp_header->rem_lifetime = htons (rem_lifetime);
|
||||||
lsp_seqnum_update (lsp);
|
lsp_seqnum_update (lsp);
|
||||||
|
@ -1653,7 +1663,8 @@ lsp_regenerate (struct isis_area *area, int level)
|
||||||
lsp_set_all_srmflags (lsp);
|
lsp_set_all_srmflags (lsp);
|
||||||
for (ALL_LIST_ELEMENTS_RO (lsp->lspu.frags, node, frag))
|
for (ALL_LIST_ELEMENTS_RO (lsp->lspu.frags, node, frag))
|
||||||
{
|
{
|
||||||
frag->lsp_header->lsp_bits = area->is_type | area->overload_bit;
|
frag->lsp_header->lsp_bits = lsp_bits_generate (level,
|
||||||
|
area->overload_bit);
|
||||||
/* Set the lifetime values of all the fragments to the same value,
|
/* Set the lifetime values of all the fragments to the same value,
|
||||||
* so that no fragment expires before the lsp is refreshed.
|
* so that no fragment expires before the lsp is refreshed.
|
||||||
*/
|
*/
|
||||||
|
@ -1803,10 +1814,7 @@ 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 */
|
||||||
if (level == IS_LEVEL_1)
|
lsp->lsp_header->lsp_bits = lsp_bits_generate (level, 0);
|
||||||
lsp->lsp_header->lsp_bits |= IS_LEVEL_1;
|
|
||||||
else
|
|
||||||
lsp->lsp_header->lsp_bits |= IS_LEVEL_2;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* add self to IS neighbours
|
* add self to IS neighbours
|
||||||
|
@ -2002,7 +2010,7 @@ lsp_regenerate_pseudo (struct isis_circuit *circuit, int level)
|
||||||
lsp_build_pseudo (lsp, circuit, level);
|
lsp_build_pseudo (lsp, circuit, 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_header->lsp_bits = circuit->area->is_type;
|
lsp->lsp_header->lsp_bits = lsp_bits_generate (level, 0);
|
||||||
rem_lifetime = lsp_rem_lifetime (circuit->area, level);
|
rem_lifetime = lsp_rem_lifetime (circuit->area, level);
|
||||||
lsp->lsp_header->rem_lifetime = htons (rem_lifetime);
|
lsp->lsp_header->rem_lifetime = htons (rem_lifetime);
|
||||||
lsp_inc_seqnum (lsp, 0);
|
lsp_inc_seqnum (lsp, 0);
|
||||||
|
@ -2321,7 +2329,8 @@ lsp_purge_non_exist (struct isis_link_state_hdr *lsp_hdr,
|
||||||
*/
|
*/
|
||||||
lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp));
|
lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp));
|
||||||
lsp->area = area;
|
lsp->area = area;
|
||||||
lsp->level = ((lsp_hdr->lsp_bits & LSPBIT_IST) == IS_LEVEL_1) ? 1 : 2;
|
lsp->level = ((lsp_hdr->lsp_bits & LSPBIT_IST) == IS_LEVEL_1) ?
|
||||||
|
IS_LEVEL_1 : IS_LEVEL_2;
|
||||||
/* FIXME: Should be minimal mtu? */
|
/* FIXME: Should be minimal mtu? */
|
||||||
lsp->pdu = stream_new (1500);
|
lsp->pdu = stream_new (1500);
|
||||||
lsp->isis_header = (struct isis_fixed_hdr *) STREAM_DATA (lsp->pdu);
|
lsp->isis_header = (struct isis_fixed_hdr *) STREAM_DATA (lsp->pdu);
|
||||||
|
@ -2404,7 +2413,8 @@ top_lsp_refresh (struct thread *thread)
|
||||||
isis_dynhn_insert (lsp->lsp_header->lsp_id, lsp->tlv_data.hostname,
|
isis_dynhn_insert (lsp->lsp_header->lsp_id, lsp->tlv_data.hostname,
|
||||||
IS_LEVEL_1);
|
IS_LEVEL_1);
|
||||||
|
|
||||||
lsp->lsp_header->lsp_bits = lsp->area->is_type | lsp->area->overload_bit;
|
lsp->lsp_header->lsp_bits = lsp_bits_generate (level,
|
||||||
|
lsp->area->overload_bit);
|
||||||
rem_lifetime = lsp_rem_lifetime (lsp->area, IS_LEVEL_1);
|
rem_lifetime = lsp_rem_lifetime (lsp->area, IS_LEVEL_1);
|
||||||
lsp->lsp_header->rem_lifetime = htons (rem_lifetime);
|
lsp->lsp_header->rem_lifetime = htons (rem_lifetime);
|
||||||
|
|
||||||
|
|
138
isisd/isis_pdu.c
138
isisd/isis_pdu.c
|
@ -62,7 +62,7 @@
|
||||||
#endif /* PNBBY */
|
#endif /* PNBBY */
|
||||||
|
|
||||||
/* Utility mask array. */
|
/* Utility mask array. */
|
||||||
static const u_char maskbit[] = {
|
static u_char maskbit[] = {
|
||||||
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
|
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -225,16 +225,16 @@ lsp_authentication_check (struct stream *stream, struct isis_area *area,
|
||||||
{
|
{
|
||||||
struct isis_link_state_hdr *hdr;
|
struct isis_link_state_hdr *hdr;
|
||||||
uint32_t expected = 0, found = 0, auth_tlv_offset = 0;
|
uint32_t expected = 0, found = 0, auth_tlv_offset = 0;
|
||||||
uint16_t checksum, rem_lifetime;
|
uint16_t checksum, rem_lifetime, pdu_len;
|
||||||
struct tlvs tlvs;
|
struct tlvs tlvs;
|
||||||
int retval = ISIS_OK;
|
int retval = ISIS_OK;
|
||||||
|
|
||||||
hdr = (struct isis_link_state_hdr *) (STREAM_PNT (stream));
|
hdr = (struct isis_link_state_hdr *) (STREAM_PNT (stream));
|
||||||
|
pdu_len = ntohs (hdr->pdu_len);
|
||||||
expected |= TLVFLAG_AUTH_INFO;
|
expected |= TLVFLAG_AUTH_INFO;
|
||||||
auth_tlv_offset = stream_get_getp (stream) + ISIS_LSP_HDR_LEN;
|
auth_tlv_offset = stream_get_getp (stream) + ISIS_LSP_HDR_LEN;
|
||||||
retval = parse_tlvs (area->area_tag, STREAM_PNT (stream) + ISIS_LSP_HDR_LEN,
|
retval = parse_tlvs (area->area_tag, STREAM_PNT (stream) + ISIS_LSP_HDR_LEN,
|
||||||
ntohs (hdr->pdu_len) - ISIS_FIXED_HDR_LEN -
|
pdu_len - ISIS_FIXED_HDR_LEN - ISIS_LSP_HDR_LEN,
|
||||||
ISIS_LSP_HDR_LEN,
|
|
||||||
&expected, &found, &tlvs, &auth_tlv_offset);
|
&expected, &found, &tlvs, &auth_tlv_offset);
|
||||||
|
|
||||||
if (retval != ISIS_OK)
|
if (retval != ISIS_OK)
|
||||||
|
@ -243,7 +243,7 @@ lsp_authentication_check (struct stream *stream, struct isis_area *area,
|
||||||
"cksum 0x%04x, lifetime %us, len %u",
|
"cksum 0x%04x, lifetime %us, len %u",
|
||||||
area->area_tag, level, rawlspid_print (hdr->lsp_id),
|
area->area_tag, level, rawlspid_print (hdr->lsp_id),
|
||||||
ntohl (hdr->seq_num), ntohs (hdr->checksum),
|
ntohl (hdr->seq_num), ntohs (hdr->checksum),
|
||||||
ntohs (hdr->rem_lifetime), ntohs (hdr->pdu_len));
|
ntohs (hdr->rem_lifetime), pdu_len);
|
||||||
if ((isis->debugs & DEBUG_UPDATE_PACKETS) &&
|
if ((isis->debugs & DEBUG_UPDATE_PACKETS) &&
|
||||||
(isis->debugs & DEBUG_PACKET_DUMP))
|
(isis->debugs & DEBUG_PACKET_DUMP))
|
||||||
zlog_dump_data (STREAM_DATA (stream), stream_get_endp (stream));
|
zlog_dump_data (STREAM_DATA (stream), stream_get_endp (stream));
|
||||||
|
@ -397,6 +397,7 @@ process_p2p_hello (struct isis_circuit *circuit)
|
||||||
struct isis_p2p_hello_hdr *hdr;
|
struct isis_p2p_hello_hdr *hdr;
|
||||||
struct isis_adjacency *adj;
|
struct isis_adjacency *adj;
|
||||||
u_int32_t expected = 0, found = 0, auth_tlv_offset = 0;
|
u_int32_t expected = 0, found = 0, auth_tlv_offset = 0;
|
||||||
|
uint16_t pdu_len;
|
||||||
struct tlvs tlvs;
|
struct tlvs tlvs;
|
||||||
|
|
||||||
if (isis->debugs & DEBUG_ADJ_PACKETS)
|
if (isis->debugs & DEBUG_ADJ_PACKETS)
|
||||||
|
@ -439,23 +440,26 @@ process_p2p_hello (struct isis_circuit *circuit)
|
||||||
* Get the header
|
* Get the header
|
||||||
*/
|
*/
|
||||||
hdr = (struct isis_p2p_hello_hdr *) STREAM_PNT (circuit->rcv_stream);
|
hdr = (struct isis_p2p_hello_hdr *) STREAM_PNT (circuit->rcv_stream);
|
||||||
stream_forward_getp (circuit->rcv_stream, ISIS_P2PHELLO_HDRLEN);
|
pdu_len = ntohs (hdr->pdu_len);
|
||||||
|
|
||||||
/* hdr.circuit_t = stream_getc (stream);
|
if (pdu_len > ISO_MTU(circuit) ||
|
||||||
stream_get (hdr.source_id, stream, ISIS_SYS_ID_LEN);
|
pdu_len > stream_get_endp (circuit->rcv_stream))
|
||||||
hdr.hold_time = stream_getw (stream);
|
|
||||||
hdr.pdu_len = stream_getw (stream);
|
|
||||||
hdr.local_id = stream_getc (stream); */
|
|
||||||
|
|
||||||
if (ntohs (hdr->pdu_len) > ISO_MTU(circuit))
|
|
||||||
{
|
{
|
||||||
zlog_warn ("ISIS-Adj (%s): Rcvd P2P IIH from (%s) with "
|
zlog_warn ("ISIS-Adj (%s): Rcvd P2P IIH from (%s) with "
|
||||||
"invalid pdu length %d",
|
"invalid pdu length %d",
|
||||||
circuit->area->area_tag, circuit->interface->name,
|
circuit->area->area_tag, circuit->interface->name, pdu_len);
|
||||||
ntohs (hdr->pdu_len));
|
|
||||||
return ISIS_WARNING;
|
return ISIS_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the stream endp to PDU length, ignoring additional padding
|
||||||
|
* introduced by transport chips.
|
||||||
|
*/
|
||||||
|
if (pdu_len < stream_get_endp (circuit->rcv_stream))
|
||||||
|
stream_set_endp (circuit->rcv_stream, pdu_len);
|
||||||
|
|
||||||
|
stream_forward_getp (circuit->rcv_stream, ISIS_P2PHELLO_HDRLEN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lets get the TLVS now
|
* Lets get the TLVS now
|
||||||
*/
|
*/
|
||||||
|
@ -468,9 +472,8 @@ process_p2p_hello (struct isis_circuit *circuit)
|
||||||
auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
|
auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
|
||||||
retval = parse_tlvs (circuit->area->area_tag,
|
retval = parse_tlvs (circuit->area->area_tag,
|
||||||
STREAM_PNT (circuit->rcv_stream),
|
STREAM_PNT (circuit->rcv_stream),
|
||||||
ntohs (hdr->pdu_len) - ISIS_P2PHELLO_HDRLEN
|
pdu_len - ISIS_P2PHELLO_HDRLEN - ISIS_FIXED_HDR_LEN,
|
||||||
- ISIS_FIXED_HDR_LEN, &expected, &found, &tlvs,
|
&expected, &found, &tlvs, &auth_tlv_offset);
|
||||||
&auth_tlv_offset);
|
|
||||||
|
|
||||||
if (retval > ISIS_WARNING)
|
if (retval > ISIS_WARNING)
|
||||||
{
|
{
|
||||||
|
@ -821,7 +824,7 @@ process_p2p_hello (struct isis_circuit *circuit)
|
||||||
" cir id %02d, length %d",
|
" cir id %02d, length %d",
|
||||||
circuit->area->area_tag, circuit->interface->name,
|
circuit->area->area_tag, circuit->interface->name,
|
||||||
circuit_t2string (circuit->is_type),
|
circuit_t2string (circuit->is_type),
|
||||||
circuit->circuit_id, ntohs (hdr->pdu_len));
|
circuit->circuit_id, pdu_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_tlvs (&tlvs);
|
free_tlvs (&tlvs);
|
||||||
|
@ -906,15 +909,23 @@ process_lan_hello (int level, struct isis_circuit *circuit, u_char * ssnpa)
|
||||||
hdr.prio = stream_getc (circuit->rcv_stream);
|
hdr.prio = stream_getc (circuit->rcv_stream);
|
||||||
stream_get (hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1);
|
stream_get (hdr.lan_id, circuit->rcv_stream, ISIS_SYS_ID_LEN + 1);
|
||||||
|
|
||||||
if (hdr.pdu_len > ISO_MTU(circuit))
|
if (hdr.pdu_len > ISO_MTU(circuit) ||
|
||||||
|
hdr.pdu_len > stream_get_endp (circuit->rcv_stream))
|
||||||
{
|
{
|
||||||
zlog_warn ("ISIS-Adj (%s): Rcvd LAN IIH from (%s) with "
|
zlog_warn ("ISIS-Adj (%s): Rcvd LAN IIH from (%s) with "
|
||||||
"invalid pdu length %d",
|
"invalid pdu length %d",
|
||||||
circuit->area->area_tag, circuit->interface->name,
|
circuit->area->area_tag, circuit->interface->name,
|
||||||
hdr.pdu_len);
|
hdr.pdu_len);
|
||||||
hdr.pdu_len = stream_get_endp (circuit->rcv_stream);
|
return ISIS_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the stream endp to PDU length, ignoring additional padding
|
||||||
|
* introduced by transport chips.
|
||||||
|
*/
|
||||||
|
if (hdr.pdu_len < stream_get_endp (circuit->rcv_stream))
|
||||||
|
stream_set_endp (circuit->rcv_stream, hdr.pdu_len);
|
||||||
|
|
||||||
if (hdr.circuit_t != IS_LEVEL_1 &&
|
if (hdr.circuit_t != IS_LEVEL_1 &&
|
||||||
hdr.circuit_t != IS_LEVEL_2 &&
|
hdr.circuit_t != IS_LEVEL_2 &&
|
||||||
hdr.circuit_t != IS_LEVEL_1_AND_2 &&
|
hdr.circuit_t != IS_LEVEL_1_AND_2 &&
|
||||||
|
@ -1167,6 +1178,7 @@ process_lsp (int level, struct isis_circuit *circuit, u_char * ssnpa)
|
||||||
int retval = ISIS_OK, comp = 0;
|
int retval = ISIS_OK, comp = 0;
|
||||||
u_char lspid[ISIS_SYS_ID_LEN + 2];
|
u_char lspid[ISIS_SYS_ID_LEN + 2];
|
||||||
struct isis_passwd *passwd;
|
struct isis_passwd *passwd;
|
||||||
|
uint16_t pdu_len;
|
||||||
|
|
||||||
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
||||||
{
|
{
|
||||||
|
@ -1187,6 +1199,26 @@ process_lsp (int level, struct isis_circuit *circuit, u_char * ssnpa)
|
||||||
|
|
||||||
/* Reference the header */
|
/* Reference the header */
|
||||||
hdr = (struct isis_link_state_hdr *) STREAM_PNT (circuit->rcv_stream);
|
hdr = (struct isis_link_state_hdr *) STREAM_PNT (circuit->rcv_stream);
|
||||||
|
pdu_len = ntohs (hdr->pdu_len);
|
||||||
|
|
||||||
|
/* lsp length check */
|
||||||
|
if (pdu_len < ISIS_LSP_HDR_LEN ||
|
||||||
|
pdu_len > ISO_MTU(circuit) ||
|
||||||
|
pdu_len > stream_get_endp (circuit->rcv_stream))
|
||||||
|
{
|
||||||
|
zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP length %d",
|
||||||
|
circuit->area->area_tag,
|
||||||
|
rawlspid_print (hdr->lsp_id), pdu_len);
|
||||||
|
|
||||||
|
return ISIS_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the stream endp to PDU length, ignoring additional padding
|
||||||
|
* introduced by transport chips.
|
||||||
|
*/
|
||||||
|
if (pdu_len < stream_get_endp (circuit->rcv_stream))
|
||||||
|
stream_set_endp (circuit->rcv_stream, pdu_len);
|
||||||
|
|
||||||
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
||||||
{
|
{
|
||||||
|
@ -1198,24 +1230,25 @@ process_lsp (int level, struct isis_circuit *circuit, u_char * ssnpa)
|
||||||
ntohl (hdr->seq_num),
|
ntohl (hdr->seq_num),
|
||||||
ntohs (hdr->checksum),
|
ntohs (hdr->checksum),
|
||||||
ntohs (hdr->rem_lifetime),
|
ntohs (hdr->rem_lifetime),
|
||||||
ntohs (hdr->pdu_len),
|
pdu_len,
|
||||||
circuit->interface->name);
|
circuit->interface->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntohs (hdr->pdu_len) <= ISIS_LSP_HDR_LEN ||
|
/* lsp is_type check */
|
||||||
ntohs (hdr->pdu_len) > ISO_MTU(circuit))
|
if ((hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1 &&
|
||||||
|
(hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1_AND_2)
|
||||||
{
|
{
|
||||||
zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP length %d",
|
zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP is type %x",
|
||||||
circuit->area->area_tag,
|
circuit->area->area_tag,
|
||||||
rawlspid_print (hdr->lsp_id), ntohs (hdr->pdu_len));
|
rawlspid_print (hdr->lsp_id), hdr->lsp_bits);
|
||||||
|
/* continue as per RFC1122 Be liberal in what you accept, and
|
||||||
return ISIS_WARNING;
|
* conservative in what you send */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checksum sanity check - FIXME: move to correct place */
|
/* Checksum sanity check - FIXME: move to correct place */
|
||||||
/* 12 = sysid+pdu+remtime */
|
/* 12 = sysid+pdu+remtime */
|
||||||
if (iso_csum_verify (STREAM_PNT (circuit->rcv_stream) + 4,
|
if (iso_csum_verify (STREAM_PNT (circuit->rcv_stream) + 4,
|
||||||
ntohs (hdr->pdu_len) - 12, &hdr->checksum))
|
pdu_len - 12, &hdr->checksum))
|
||||||
{
|
{
|
||||||
zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x",
|
zlog_debug ("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x",
|
||||||
circuit->area->area_tag,
|
circuit->area->area_tag,
|
||||||
|
@ -1403,17 +1436,19 @@ dontcheckadj:
|
||||||
* has information that the current sequence number for source S is
|
* has information that the current sequence number for source S is
|
||||||
* "greater" than that held by S, ... */
|
* "greater" than that held by S, ... */
|
||||||
|
|
||||||
else if (ntohl (hdr->seq_num) > ntohl (lsp->lsp_header->seq_num))
|
if (ntohl (hdr->seq_num) > ntohl (lsp->lsp_header->seq_num))
|
||||||
{
|
{
|
||||||
/* 7.3.16.1 */
|
/* 7.3.16.1 */
|
||||||
lsp_inc_seqnum (lsp, ntohl (hdr->seq_num));
|
lsp_inc_seqnum (lsp, ntohl (hdr->seq_num));
|
||||||
lsp_set_all_srmflags (lsp);
|
|
||||||
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
||||||
zlog_debug ("ISIS-Upd (%s): (2) re-originating LSP %s new seq "
|
zlog_debug ("ISIS-Upd (%s): (2) re-originating LSP %s new seq "
|
||||||
"0x%08x", circuit->area->area_tag,
|
"0x%08x", circuit->area->area_tag,
|
||||||
rawlspid_print (hdr->lsp_id),
|
rawlspid_print (hdr->lsp_id),
|
||||||
ntohl (lsp->lsp_header->seq_num));
|
ntohl (lsp->lsp_header->seq_num));
|
||||||
}
|
}
|
||||||
|
/* If the received LSP is older or equal,
|
||||||
|
* resend the LSP which will act as ACK */
|
||||||
|
lsp_set_all_srmflags (lsp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1440,7 +1475,7 @@ dontcheckadj:
|
||||||
if (!lsp)
|
if (!lsp)
|
||||||
{
|
{
|
||||||
lsp = lsp_new_from_stream_ptr (circuit->rcv_stream,
|
lsp = lsp_new_from_stream_ptr (circuit->rcv_stream,
|
||||||
ntohs (hdr->pdu_len), lsp0,
|
pdu_len, lsp0,
|
||||||
circuit->area, level);
|
circuit->area, level);
|
||||||
lsp_insert (lsp, circuit->area->lspdb[level - 1]);
|
lsp_insert (lsp, circuit->area->lspdb[level - 1]);
|
||||||
}
|
}
|
||||||
|
@ -1489,7 +1524,7 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit,
|
||||||
int retval = ISIS_OK;
|
int retval = ISIS_OK;
|
||||||
int cmp, own_lsp;
|
int cmp, own_lsp;
|
||||||
char typechar = ' ';
|
char typechar = ' ';
|
||||||
unsigned int len;
|
uint16_t pdu_len;
|
||||||
struct isis_adjacency *adj;
|
struct isis_adjacency *adj;
|
||||||
struct isis_complete_seqnum_hdr *chdr = NULL;
|
struct isis_complete_seqnum_hdr *chdr = NULL;
|
||||||
struct isis_partial_seqnum_hdr *phdr = NULL;
|
struct isis_partial_seqnum_hdr *phdr = NULL;
|
||||||
|
@ -1508,12 +1543,14 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit,
|
||||||
typechar = 'C';
|
typechar = 'C';
|
||||||
chdr =
|
chdr =
|
||||||
(struct isis_complete_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream);
|
(struct isis_complete_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream);
|
||||||
circuit->rcv_stream->getp += ISIS_CSNP_HDRLEN;
|
stream_forward_getp (circuit->rcv_stream, ISIS_CSNP_HDRLEN);
|
||||||
len = ntohs (chdr->pdu_len);
|
pdu_len = ntohs (chdr->pdu_len);
|
||||||
if (len < ISIS_CSNP_HDRLEN || len > ISO_MTU(circuit))
|
if (pdu_len < ISIS_CSNP_HDRLEN ||
|
||||||
|
pdu_len > ISO_MTU(circuit) ||
|
||||||
|
pdu_len > stream_get_endp (circuit->rcv_stream))
|
||||||
{
|
{
|
||||||
zlog_warn ("Received a CSNP with bogus length %d", len);
|
zlog_warn ("Received a CSNP with bogus length %d", pdu_len);
|
||||||
return ISIS_OK;
|
return ISIS_WARNING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1521,15 +1558,24 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit,
|
||||||
typechar = 'P';
|
typechar = 'P';
|
||||||
phdr =
|
phdr =
|
||||||
(struct isis_partial_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream);
|
(struct isis_partial_seqnum_hdr *) STREAM_PNT (circuit->rcv_stream);
|
||||||
circuit->rcv_stream->getp += ISIS_PSNP_HDRLEN;
|
stream_forward_getp (circuit->rcv_stream, ISIS_PSNP_HDRLEN);
|
||||||
len = ntohs (phdr->pdu_len);
|
pdu_len = ntohs (phdr->pdu_len);
|
||||||
if (len < ISIS_PSNP_HDRLEN || len > ISO_MTU(circuit))
|
if (pdu_len < ISIS_PSNP_HDRLEN ||
|
||||||
|
pdu_len > ISO_MTU(circuit) ||
|
||||||
|
pdu_len > stream_get_endp (circuit->rcv_stream))
|
||||||
{
|
{
|
||||||
zlog_warn ("Received a CSNP with bogus length %d", len);
|
zlog_warn ("Received a CSNP with bogus length %d", pdu_len);
|
||||||
return ISIS_OK;
|
return ISIS_WARNING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the stream endp to PDU length, ignoring additional padding
|
||||||
|
* introduced by transport chips.
|
||||||
|
*/
|
||||||
|
if (pdu_len < stream_get_endp (circuit->rcv_stream))
|
||||||
|
stream_set_endp (circuit->rcv_stream, pdu_len);
|
||||||
|
|
||||||
/* 7.3.15.2 a) 1 - external domain circuit will discard snp pdu */
|
/* 7.3.15.2 a) 1 - external domain circuit will discard snp pdu */
|
||||||
if (circuit->ext_domain)
|
if (circuit->ext_domain)
|
||||||
{
|
{
|
||||||
|
@ -1617,7 +1663,7 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit,
|
||||||
auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
|
auth_tlv_offset = stream_get_getp (circuit->rcv_stream);
|
||||||
retval = parse_tlvs (circuit->area->area_tag,
|
retval = parse_tlvs (circuit->area->area_tag,
|
||||||
STREAM_PNT (circuit->rcv_stream),
|
STREAM_PNT (circuit->rcv_stream),
|
||||||
len - circuit->rcv_stream->getp,
|
pdu_len - stream_get_getp (circuit->rcv_stream),
|
||||||
&expected, &found, &tlvs, &auth_tlv_offset);
|
&expected, &found, &tlvs, &auth_tlv_offset);
|
||||||
|
|
||||||
if (retval > ISIS_WARNING)
|
if (retval > ISIS_WARNING)
|
||||||
|
@ -2585,6 +2631,7 @@ max_lsps_per_snp (int snp_type, int level, struct isis_circuit *circuit)
|
||||||
auth_tlv_len = auth_tlv_length (level, circuit);
|
auth_tlv_len = auth_tlv_length (level, circuit);
|
||||||
lsp_count = get_max_lsp_count (
|
lsp_count = get_max_lsp_count (
|
||||||
stream_get_size (circuit->snd_stream) - snp_hdr_len - auth_tlv_len);
|
stream_get_size (circuit->snd_stream) - snp_hdr_len - auth_tlv_len);
|
||||||
|
return lsp_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2862,6 +2909,9 @@ send_psnp (int level, struct isis_circuit *circuit)
|
||||||
dict_count (circuit->area->lspdb[level - 1]) == 0)
|
dict_count (circuit->area->lspdb[level - 1]) == 0)
|
||||||
return ISIS_OK;
|
return ISIS_OK;
|
||||||
|
|
||||||
|
if (! circuit->snd_stream)
|
||||||
|
return ISIS_ERROR;
|
||||||
|
|
||||||
num_lsps = max_lsps_per_snp (ISIS_SNP_PSNP_FLAG, level, circuit);
|
num_lsps = max_lsps_per_snp (ISIS_SNP_PSNP_FLAG, level, circuit);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
|
|
@ -114,7 +114,7 @@ struct isis_fixed_hdr
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* | Holding Time | 2
|
* | Holding Time | 2
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* | PDU Lenght | 2
|
* | PDU Length | 2
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* | R | Priority | 1
|
* | R | Priority | 1
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
|
@ -142,7 +142,7 @@ struct isis_lan_hello_hdr
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* + Holding Time + 2
|
* + Holding Time + 2
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* + PDU Lenght + 2
|
* + PDU Length + 2
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* | Local Circuit ID | 1
|
* | Local Circuit ID | 1
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
|
@ -202,7 +202,7 @@ struct isis_link_state_hdr
|
||||||
/*
|
/*
|
||||||
* L1 and L2 IS to IS complete sequence numbers PDU header
|
* L1 and L2 IS to IS complete sequence numbers PDU header
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* + PDU Lenght + 2
|
* + PDU Length + 2
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
* + Source ID + id_len + 1
|
* + Source ID + id_len + 1
|
||||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||||
|
|
|
@ -244,6 +244,7 @@ adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj)
|
||||||
{
|
{
|
||||||
nh = isis_nexthop_create (ipv4_addr,
|
nh = isis_nexthop_create (ipv4_addr,
|
||||||
adj->circuit->interface->ifindex);
|
adj->circuit->interface->ifindex);
|
||||||
|
nh->router_address = adj->router_address;
|
||||||
listnode_add (nexthops, nh);
|
listnode_add (nexthops, nh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,6 +268,7 @@ adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
|
||||||
{
|
{
|
||||||
nh6 = isis_nexthop6_create (ipv6_addr,
|
nh6 = isis_nexthop6_create (ipv6_addr,
|
||||||
adj->circuit->interface->ifindex);
|
adj->circuit->interface->ifindex);
|
||||||
|
nh6->router_address6 = adj->router_address6;
|
||||||
listnode_add (nexthops6, nh6);
|
listnode_add (nexthops6, nh6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,8 +276,8 @@ adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
|
||||||
static struct isis_route_info *
|
static struct isis_route_info *
|
||||||
isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
|
isis_route_info_new (struct prefix *prefix, uint32_t cost, uint32_t depth,
|
||||||
struct list *adjacencies)
|
struct list *adjacencies)
|
||||||
{
|
{
|
||||||
struct isis_route_info *rinfo;
|
struct isis_route_info *rinfo;
|
||||||
struct isis_adjacency *adj;
|
struct isis_adjacency *adj;
|
||||||
|
@ -288,7 +290,7 @@ isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (family == AF_INET)
|
if (prefix->family == AF_INET)
|
||||||
{
|
{
|
||||||
rinfo->nexthops = list_new ();
|
rinfo->nexthops = list_new ();
|
||||||
for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj))
|
for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj))
|
||||||
|
@ -296,11 +298,14 @@ isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
|
||||||
/* check for force resync this route */
|
/* check for force resync this route */
|
||||||
if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
|
if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
|
||||||
SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
|
SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
|
||||||
|
/* update neighbor router address */
|
||||||
|
if (depth == 2 && prefix->prefixlen == 32)
|
||||||
|
adj->router_address = prefix->u.prefix4;
|
||||||
adjinfo2nexthop (rinfo->nexthops, adj);
|
adjinfo2nexthop (rinfo->nexthops, adj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
if (family == AF_INET6)
|
if (prefix->family == AF_INET6)
|
||||||
{
|
{
|
||||||
rinfo->nexthops6 = list_new ();
|
rinfo->nexthops6 = list_new ();
|
||||||
for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj))
|
for (ALL_LIST_ELEMENTS_RO (adjacencies, node, adj))
|
||||||
|
@ -308,6 +313,9 @@ isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
|
||||||
/* check for force resync this route */
|
/* check for force resync this route */
|
||||||
if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
|
if (CHECK_FLAG (adj->circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
|
||||||
SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
|
SET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
|
||||||
|
/* update neighbor router address */
|
||||||
|
if (depth == 2 && prefix->prefixlen == 128)
|
||||||
|
adj->router_address6 = prefix->u.prefix6;
|
||||||
adjinfo2nexthop6 (rinfo->nexthops6, adj);
|
adjinfo2nexthop6 (rinfo->nexthops6, adj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,7 +423,7 @@ isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth,
|
||||||
/* for debugs */
|
/* for debugs */
|
||||||
prefix2str (prefix, (char *) buff, BUFSIZ);
|
prefix2str (prefix, (char *) buff, BUFSIZ);
|
||||||
|
|
||||||
rinfo_new = isis_route_info_new (cost, depth, family, adjacencies);
|
rinfo_new = isis_route_info_new (prefix, cost, depth, adjacencies);
|
||||||
if (!rinfo_new)
|
if (!rinfo_new)
|
||||||
{
|
{
|
||||||
zlog_err ("ISIS-Rte (%s): isis_route_create: out of memory!",
|
zlog_err ("ISIS-Rte (%s): isis_route_create: out of memory!",
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct isis_nexthop6
|
||||||
{
|
{
|
||||||
unsigned int ifindex;
|
unsigned int ifindex;
|
||||||
struct in6_addr ip6;
|
struct in6_addr ip6;
|
||||||
|
struct in6_addr router_address6;
|
||||||
unsigned int lock;
|
unsigned int lock;
|
||||||
};
|
};
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
@ -38,6 +39,7 @@ struct isis_nexthop
|
||||||
{
|
{
|
||||||
unsigned int ifindex;
|
unsigned int ifindex;
|
||||||
struct in_addr ip;
|
struct in_addr ip;
|
||||||
|
struct in_addr router_address;
|
||||||
unsigned int lock;
|
unsigned int lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -274,7 +274,8 @@ isis_spftree_new (struct isis_area *area)
|
||||||
tree->tents = list_new ();
|
tree->tents = list_new ();
|
||||||
tree->paths = list_new ();
|
tree->paths = list_new ();
|
||||||
tree->area = area;
|
tree->area = area;
|
||||||
tree->lastrun = 0;
|
tree->last_run_timestamp = 0;
|
||||||
|
tree->last_run_duration = 0;
|
||||||
tree->runcount = 0;
|
tree->runcount = 0;
|
||||||
tree->pending = 0;
|
tree->pending = 0;
|
||||||
return tree;
|
return tree;
|
||||||
|
@ -408,12 +409,16 @@ spftree_area_adj_del (struct isis_area *area, struct isis_adjacency *adj)
|
||||||
static struct isis_lsp *
|
static struct isis_lsp *
|
||||||
isis_root_system_lsp (struct isis_area *area, int level, u_char *sysid)
|
isis_root_system_lsp (struct isis_area *area, int level, u_char *sysid)
|
||||||
{
|
{
|
||||||
|
struct isis_lsp *lsp;
|
||||||
u_char lspid[ISIS_SYS_ID_LEN + 2];
|
u_char lspid[ISIS_SYS_ID_LEN + 2];
|
||||||
|
|
||||||
memcpy (lspid, sysid, ISIS_SYS_ID_LEN);
|
memcpy (lspid, sysid, ISIS_SYS_ID_LEN);
|
||||||
LSP_PSEUDO_ID (lspid) = 0;
|
LSP_PSEUDO_ID (lspid) = 0;
|
||||||
LSP_FRAGMENT (lspid) = 0;
|
LSP_FRAGMENT (lspid) = 0;
|
||||||
return (lsp_search (lspid, area->lspdb[level - 1]));
|
lsp = lsp_search (lspid, area->lspdb[level - 1]);
|
||||||
|
if (lsp && lsp->lsp_header->rem_lifetime != 0)
|
||||||
|
return lsp;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1021,7 +1026,7 @@ isis_spf_preload_tent (struct isis_spftree *spftree, int level,
|
||||||
LSP_PSEUDO_ID (lsp_id) = 0;
|
LSP_PSEUDO_ID (lsp_id) = 0;
|
||||||
LSP_FRAGMENT (lsp_id) = 0;
|
LSP_FRAGMENT (lsp_id) = 0;
|
||||||
lsp = lsp_search (lsp_id, spftree->area->lspdb[level - 1]);
|
lsp = lsp_search (lsp_id, spftree->area->lspdb[level - 1]);
|
||||||
if (!lsp)
|
if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0)
|
||||||
zlog_warn ("ISIS-Spf: No LSP %s found for IS adjacency "
|
zlog_warn ("ISIS-Spf: No LSP %s found for IS adjacency "
|
||||||
"L%d on %s (ID %u)",
|
"L%d on %s (ID %u)",
|
||||||
rawlspid_print (lsp_id), level,
|
rawlspid_print (lsp_id), level,
|
||||||
|
@ -1171,6 +1176,13 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
|
||||||
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
|
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
|
||||||
struct isis_lsp *lsp;
|
struct isis_lsp *lsp;
|
||||||
struct route_table *table = NULL;
|
struct route_table *table = NULL;
|
||||||
|
struct timespec time_now;
|
||||||
|
unsigned long long start_time, end_time;
|
||||||
|
|
||||||
|
/* Get time that can't roll backwards. */
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &time_now);
|
||||||
|
start_time = time_now.tv_sec;
|
||||||
|
start_time = (start_time * 1000000) + (time_now.tv_nsec / 1000);
|
||||||
|
|
||||||
if (family == AF_INET)
|
if (family == AF_INET)
|
||||||
spftree = area->spftree[level - 1];
|
spftree = area->spftree[level - 1];
|
||||||
|
@ -1237,7 +1249,7 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
|
||||||
memcpy (lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
|
memcpy (lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
|
||||||
LSP_FRAGMENT (lsp_id) = 0;
|
LSP_FRAGMENT (lsp_id) = 0;
|
||||||
lsp = lsp_search (lsp_id, area->lspdb[level - 1]);
|
lsp = lsp_search (lsp_id, area->lspdb[level - 1]);
|
||||||
if (lsp)
|
if (lsp && lsp->lsp_header->rem_lifetime != 0)
|
||||||
{
|
{
|
||||||
if (LSP_PSEUDO_ID (lsp_id))
|
if (LSP_PSEUDO_ID (lsp_id))
|
||||||
{
|
{
|
||||||
|
@ -1263,9 +1275,14 @@ isis_run_spf (struct isis_area *area, int level, int family, u_char *sysid)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
isis_route_validate (area);
|
isis_route_validate (area);
|
||||||
spftree->lastrun = time (NULL);
|
|
||||||
spftree->runcount++;
|
|
||||||
spftree->pending = 0;
|
spftree->pending = 0;
|
||||||
|
spftree->runcount++;
|
||||||
|
spftree->last_run_timestamp = time (NULL);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &time_now);
|
||||||
|
end_time = time_now.tv_sec;
|
||||||
|
end_time = (end_time * 1000000) + (time_now.tv_nsec / 1000);
|
||||||
|
spftree->last_run_duration = end_time - start_time;
|
||||||
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1332,7 +1349,7 @@ isis_spf_schedule (struct isis_area *area, int level)
|
||||||
{
|
{
|
||||||
struct isis_spftree *spftree = area->spftree[level - 1];
|
struct isis_spftree *spftree = area->spftree[level - 1];
|
||||||
time_t now = time (NULL);
|
time_t now = time (NULL);
|
||||||
int diff = now - spftree->lastrun;
|
int diff = now - spftree->last_run_timestamp;
|
||||||
|
|
||||||
assert (diff >= 0);
|
assert (diff >= 0);
|
||||||
assert (area->is_type & level);
|
assert (area->is_type & level);
|
||||||
|
@ -1346,20 +1363,20 @@ isis_spf_schedule (struct isis_area *area, int level)
|
||||||
|
|
||||||
THREAD_TIMER_OFF (spftree->t_spf);
|
THREAD_TIMER_OFF (spftree->t_spf);
|
||||||
|
|
||||||
/* wait MINIMUM_SPF_INTERVAL before doing the SPF */
|
/* wait configured min_spf_interval before doing the SPF */
|
||||||
if (diff >= MINIMUM_SPF_INTERVAL)
|
if (diff >= area->min_spf_interval[level-1])
|
||||||
return isis_run_spf (area, level, AF_INET, isis->sysid);
|
return isis_run_spf (area, level, AF_INET, isis->sysid);
|
||||||
|
|
||||||
if (level == 1)
|
if (level == 1)
|
||||||
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf_l1, area,
|
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf_l1, area,
|
||||||
MINIMUM_SPF_INTERVAL - diff);
|
area->min_spf_interval[0] - diff);
|
||||||
else
|
else
|
||||||
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf_l2, area,
|
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf_l2, area,
|
||||||
MINIMUM_SPF_INTERVAL - diff);
|
area->min_spf_interval[1] - diff);
|
||||||
|
|
||||||
if (isis->debugs & DEBUG_SPF_EVENTS)
|
if (isis->debugs & DEBUG_SPF_EVENTS)
|
||||||
zlog_debug ("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
|
zlog_debug ("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
|
||||||
area->area_tag, level, MINIMUM_SPF_INTERVAL - diff);
|
area->area_tag, level, area->min_spf_interval[level-1] - diff);
|
||||||
|
|
||||||
spftree->pending = 1;
|
spftree->pending = 1;
|
||||||
|
|
||||||
|
@ -1428,34 +1445,37 @@ isis_spf_schedule6 (struct isis_area *area, int level)
|
||||||
{
|
{
|
||||||
int retval = ISIS_OK;
|
int retval = ISIS_OK;
|
||||||
struct isis_spftree *spftree = area->spftree6[level - 1];
|
struct isis_spftree *spftree = area->spftree6[level - 1];
|
||||||
time_t diff, now = time (NULL);
|
time_t now = time (NULL);
|
||||||
|
time_t diff = now - spftree->last_run_timestamp;
|
||||||
|
|
||||||
|
assert (diff >= 0);
|
||||||
|
assert (area->is_type & level);
|
||||||
|
|
||||||
|
if (isis->debugs & DEBUG_SPF_EVENTS)
|
||||||
|
zlog_debug ("ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago",
|
||||||
|
area->area_tag, level, diff);
|
||||||
|
|
||||||
if (spftree->pending)
|
if (spftree->pending)
|
||||||
return retval;
|
return ISIS_OK;
|
||||||
|
|
||||||
THREAD_TIMER_OFF (spftree->t_spf);
|
THREAD_TIMER_OFF (spftree->t_spf);
|
||||||
|
|
||||||
/* FIXME: let's wait MINIMUM_SPF_INTERVAL before doing the SPF */
|
/* wait configured min_spf_interval before doing the SPF */
|
||||||
if (now - isis->uptime < MINIMUM_SPF_INTERVAL || isis->uptime == 0)
|
if (diff >= area->min_spf_interval[level-1])
|
||||||
diff = 0;
|
return isis_run_spf (area, level, AF_INET6, isis->sysid);
|
||||||
else
|
|
||||||
diff = now - spftree->lastrun;
|
|
||||||
|
|
||||||
if (diff < MINIMUM_SPF_INTERVAL)
|
if (level == 1)
|
||||||
{
|
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l1, area,
|
||||||
if (level == 1)
|
area->min_spf_interval[0] - diff);
|
||||||
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l1, area,
|
|
||||||
MINIMUM_SPF_INTERVAL - diff);
|
|
||||||
else
|
|
||||||
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l2, area,
|
|
||||||
MINIMUM_SPF_INTERVAL - diff);
|
|
||||||
|
|
||||||
spftree->pending = 1;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
THREAD_TIMER_ON (master, spftree->t_spf, isis_run_spf6_l2, area,
|
||||||
retval = isis_run_spf (area, level, AF_INET6, isis->sysid);
|
area->min_spf_interval[1] - diff);
|
||||||
}
|
|
||||||
|
if (isis->debugs & DEBUG_SPF_EVENTS)
|
||||||
|
zlog_debug ("ISIS-Spf (%s) L%d SPF scheduled %d sec from now",
|
||||||
|
area->area_tag, level, area->min_spf_interval[level-1] - diff);
|
||||||
|
|
||||||
|
spftree->pending = 1;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,8 +68,9 @@ struct isis_spftree
|
||||||
struct list *tents; /* TENT */
|
struct list *tents; /* TENT */
|
||||||
struct isis_area *area; /* back pointer to area */
|
struct isis_area *area; /* back pointer to area */
|
||||||
int pending; /* already scheduled */
|
int pending; /* already scheduled */
|
||||||
time_t lastrun; /* for scheduling */
|
|
||||||
unsigned int runcount; /* number of runs since uptime */
|
unsigned int runcount; /* number of runs since uptime */
|
||||||
|
time_t last_run_timestamp; /* last run timestamp for scheduling */
|
||||||
|
time_t last_run_duration; /* last run duration in msec */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct isis_spftree * isis_spftree_new (struct isis_area *area);
|
struct isis_spftree * isis_spftree_new (struct isis_area *area);
|
||||||
|
|
105
isisd/isisd.c
105
isisd/isisd.c
|
@ -720,7 +720,7 @@ DEFUN (clear_isis_neighbor,
|
||||||
|
|
||||||
DEFUN (clear_isis_neighbor_arg,
|
DEFUN (clear_isis_neighbor_arg,
|
||||||
clear_isis_neighbor_arg_cmd,
|
clear_isis_neighbor_arg_cmd,
|
||||||
"claer isis neighbor WORD",
|
"clear isis neighbor WORD",
|
||||||
CLEAR_STR
|
CLEAR_STR
|
||||||
"ISIS network information\n"
|
"ISIS network information\n"
|
||||||
"ISIS neighbor adjacencies\n"
|
"ISIS neighbor adjacencies\n"
|
||||||
|
@ -1273,10 +1273,13 @@ DEFUN (show_isis_summary,
|
||||||
vty_out (vty, " minimum interval : %d%s",
|
vty_out (vty, " minimum interval : %d%s",
|
||||||
area->min_spf_interval[level - 1], VTY_NEWLINE);
|
area->min_spf_interval[level - 1], VTY_NEWLINE);
|
||||||
|
|
||||||
vty_out (vty, " last run : ");
|
vty_out (vty, " last run elapsed : ");
|
||||||
vty_out_timestr(vty, spftree->lastrun);
|
vty_out_timestr(vty, spftree->last_run_timestamp);
|
||||||
vty_out (vty, "%s", VTY_NEWLINE);
|
vty_out (vty, "%s", VTY_NEWLINE);
|
||||||
|
|
||||||
|
vty_out (vty, " last run duration : %u usec%s",
|
||||||
|
(u_int32_t)spftree->last_run_duration, VTY_NEWLINE);
|
||||||
|
|
||||||
vty_out (vty, " run count : %d%s",
|
vty_out (vty, " run count : %d%s",
|
||||||
spftree->runcount, VTY_NEWLINE);
|
spftree->runcount, VTY_NEWLINE);
|
||||||
|
|
||||||
|
@ -1290,10 +1293,13 @@ DEFUN (show_isis_summary,
|
||||||
vty_out (vty, " minimum interval : %d%s",
|
vty_out (vty, " minimum interval : %d%s",
|
||||||
area->min_spf_interval[level - 1], VTY_NEWLINE);
|
area->min_spf_interval[level - 1], VTY_NEWLINE);
|
||||||
|
|
||||||
vty_out (vty, " last run : ");
|
vty_out (vty, " last run elapsed : ");
|
||||||
vty_out_timestr(vty, spftree->lastrun);
|
vty_out_timestr(vty, spftree->last_run_timestamp);
|
||||||
vty_out (vty, "%s", VTY_NEWLINE);
|
vty_out (vty, "%s", VTY_NEWLINE);
|
||||||
|
|
||||||
|
vty_out (vty, " last run duration : %u msec%s",
|
||||||
|
spftree->last_run_duration, VTY_NEWLINE);
|
||||||
|
|
||||||
vty_out (vty, " run count : %d%s",
|
vty_out (vty, " run count : %d%s",
|
||||||
spftree->runcount, VTY_NEWLINE);
|
spftree->runcount, VTY_NEWLINE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1329,7 +1335,7 @@ show_isis_database (struct vty *vty, const char *argv, int ui_level)
|
||||||
struct isis_dynhn *dynhn;
|
struct isis_dynhn *dynhn;
|
||||||
const char *pos = argv;
|
const char *pos = argv;
|
||||||
u_char lspid[ISIS_SYS_ID_LEN+2];
|
u_char lspid[ISIS_SYS_ID_LEN+2];
|
||||||
char sysid[15]; /* len of xxxx.xxxx.xxxx + place for #0 termination */
|
char sysid[255];
|
||||||
u_char number[3];
|
u_char number[3];
|
||||||
int level, lsp_count;
|
int level, lsp_count;
|
||||||
|
|
||||||
|
@ -1337,13 +1343,7 @@ show_isis_database (struct vty *vty, const char *argv, int ui_level)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
memset (&lspid, 0, ISIS_SYS_ID_LEN);
|
memset (&lspid, 0, ISIS_SYS_ID_LEN);
|
||||||
memset (&sysid, 0, 15);
|
memset (&sysid, 0, 255);
|
||||||
|
|
||||||
if (argv)
|
|
||||||
{
|
|
||||||
strncpy (sysid, argv, 15);
|
|
||||||
sysid[14] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* extract fragment and pseudo id from the string argv
|
* extract fragment and pseudo id from the string argv
|
||||||
|
@ -1354,6 +1354,8 @@ show_isis_database (struct vty *vty, const char *argv, int ui_level)
|
||||||
* Where systemid is in the form:
|
* Where systemid is in the form:
|
||||||
* xxxx.xxxx.xxxx
|
* xxxx.xxxx.xxxx
|
||||||
*/
|
*/
|
||||||
|
if (argv)
|
||||||
|
strncpy (sysid, argv, 254);
|
||||||
if (argv && strlen (argv) > 3)
|
if (argv && strlen (argv) > 3)
|
||||||
{
|
{
|
||||||
pos = argv + strlen (argv) - 3;
|
pos = argv + strlen (argv) - 3;
|
||||||
|
@ -2033,6 +2035,44 @@ ALIAS (no_lsp_gen_interval_l2,
|
||||||
"Set interval for level 2 only\n"
|
"Set interval for level 2 only\n"
|
||||||
"Minimum interval in seconds\n")
|
"Minimum interval in seconds\n")
|
||||||
|
|
||||||
|
static int
|
||||||
|
validate_metric_style_narrow (struct vty *vty, struct isis_area *area)
|
||||||
|
{
|
||||||
|
struct isis_circuit *circuit;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
if (! vty)
|
||||||
|
return CMD_ERR_AMBIGUOUS;
|
||||||
|
|
||||||
|
if (! area)
|
||||||
|
{
|
||||||
|
vty_out (vty, "ISIS area is invalid%s", VTY_NEWLINE);
|
||||||
|
return CMD_ERR_AMBIGUOUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
|
||||||
|
{
|
||||||
|
if ((area->is_type & IS_LEVEL_1) &&
|
||||||
|
(circuit->is_type & IS_LEVEL_1) &&
|
||||||
|
(circuit->metrics[0].metric_default > MAX_NARROW_LINK_METRIC))
|
||||||
|
{
|
||||||
|
vty_out (vty, "ISIS circuit %s metric is invalid%s",
|
||||||
|
circuit->interface->name, VTY_NEWLINE);
|
||||||
|
return CMD_ERR_AMBIGUOUS;
|
||||||
|
}
|
||||||
|
if ((area->is_type & IS_LEVEL_2) &&
|
||||||
|
(circuit->is_type & IS_LEVEL_2) &&
|
||||||
|
(circuit->metrics[1].metric_default > MAX_NARROW_LINK_METRIC))
|
||||||
|
{
|
||||||
|
vty_out (vty, "ISIS circuit %s metric is invalid%s",
|
||||||
|
circuit->interface->name, VTY_NEWLINE);
|
||||||
|
return CMD_ERR_AMBIGUOUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (metric_style,
|
DEFUN (metric_style,
|
||||||
metric_style_cmd,
|
metric_style_cmd,
|
||||||
"metric-style (narrow|transition|wide)",
|
"metric-style (narrow|transition|wide)",
|
||||||
|
@ -2042,8 +2082,7 @@ DEFUN (metric_style,
|
||||||
"Use new style of TLVs to carry wider metric\n")
|
"Use new style of TLVs to carry wider metric\n")
|
||||||
{
|
{
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct isis_circuit *circuit;
|
int ret;
|
||||||
struct listnode *node;
|
|
||||||
|
|
||||||
area = vty->index;
|
area = vty->index;
|
||||||
assert (area);
|
assert (area);
|
||||||
|
@ -2060,25 +2099,10 @@ DEFUN (metric_style,
|
||||||
}
|
}
|
||||||
else if (strncmp (argv[0], "n", 1) == 0)
|
else if (strncmp (argv[0], "n", 1) == 0)
|
||||||
{
|
{
|
||||||
for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
|
ret = validate_metric_style_narrow (vty, area);
|
||||||
{
|
if (ret != CMD_SUCCESS)
|
||||||
if ((area->is_type & IS_LEVEL_1) &&
|
return ret;
|
||||||
(circuit->is_type & IS_LEVEL_1) &&
|
|
||||||
(circuit->metrics[0].metric_default > MAX_NARROW_LINK_METRIC))
|
|
||||||
{
|
|
||||||
vty_out (vty, "ISIS circuit %s metric is invalid%s",
|
|
||||||
circuit->interface->name, VTY_NEWLINE);
|
|
||||||
return CMD_ERR_AMBIGUOUS;
|
|
||||||
}
|
|
||||||
if ((area->is_type & IS_LEVEL_2) &&
|
|
||||||
(circuit->is_type & IS_LEVEL_2) &&
|
|
||||||
(circuit->metrics[1].metric_default > MAX_NARROW_LINK_METRIC))
|
|
||||||
{
|
|
||||||
vty_out (vty, "ISIS circuit %s metric is invalid%s",
|
|
||||||
circuit->interface->name, VTY_NEWLINE);
|
|
||||||
return CMD_ERR_AMBIGUOUS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
area->newmetric = 0;
|
area->newmetric = 0;
|
||||||
area->oldmetric = 1;
|
area->oldmetric = 1;
|
||||||
}
|
}
|
||||||
|
@ -2093,10 +2117,15 @@ DEFUN (no_metric_style,
|
||||||
"Use old-style (ISO 10589) or new-style packet formats\n")
|
"Use old-style (ISO 10589) or new-style packet formats\n")
|
||||||
{
|
{
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
|
int ret;
|
||||||
|
|
||||||
area = vty->index;
|
area = vty->index;
|
||||||
assert (area);
|
assert (area);
|
||||||
|
|
||||||
|
ret = validate_metric_style_narrow (vty, area);
|
||||||
|
if (ret != CMD_SUCCESS)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Default is narrow metric. */
|
/* Default is narrow metric. */
|
||||||
area->newmetric = 0;
|
area->newmetric = 0;
|
||||||
area->oldmetric = 1;
|
area->oldmetric = 1;
|
||||||
|
@ -2819,11 +2848,11 @@ isis_config_write (struct vty *vty)
|
||||||
vty_out (vty, " no hostname dynamic%s", VTY_NEWLINE);
|
vty_out (vty, " no hostname dynamic%s", VTY_NEWLINE);
|
||||||
write++;
|
write++;
|
||||||
}
|
}
|
||||||
/* ISIS - Metric-Style - when true displays narrow */
|
/* ISIS - Metric-Style - when true displays wide */
|
||||||
if (area->oldmetric)
|
if (area->newmetric)
|
||||||
{
|
{
|
||||||
if (!area->newmetric)
|
if (!area->oldmetric)
|
||||||
vty_out (vty, " metric-style narrow%s", VTY_NEWLINE);
|
vty_out (vty, " metric-style wide%s", VTY_NEWLINE);
|
||||||
else
|
else
|
||||||
vty_out (vty, " metric-style transition%s", VTY_NEWLINE);
|
vty_out (vty, " metric-style transition%s", VTY_NEWLINE);
|
||||||
write++;
|
write++;
|
||||||
|
|
Loading…
Reference in a new issue