2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* IS-IS Rout(e)ing protocol - isis_circuit.h
|
|
|
|
*
|
|
|
|
* Copyright (C) 2001,2002 Sampo Saaristo
|
|
|
|
* Tampere University of Technology
|
|
|
|
* Institute of Communications Engineering
|
|
|
|
*/
|
|
|
|
#include <zebra.h>
|
2004-05-19 13:38:40 +02:00
|
|
|
#ifdef GNU_LINUX
|
2003-12-23 09:09:43 +01:00
|
|
|
#include <net/ethernet.h>
|
2004-05-19 13:38:40 +02:00
|
|
|
#else
|
|
|
|
#include <netinet/if_ether.h>
|
|
|
|
#endif
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
#include "log.h"
|
|
|
|
#include "memory.h"
|
2016-04-08 15:16:14 +02:00
|
|
|
#include "vrf.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
#include "if.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "command.h"
|
2023-03-07 20:22:48 +01:00
|
|
|
#include "frrevent.h"
|
2016-04-19 19:03:05 +02:00
|
|
|
#include "vty.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
#include "hash.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "stream.h"
|
2016-04-05 23:54:53 +02:00
|
|
|
#include "qobj.h"
|
2018-11-14 14:50:53 +01:00
|
|
|
#include "lib/northbound_cli.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
#include "isisd/isis_constants.h"
|
|
|
|
#include "isisd/isis_common.h"
|
2012-03-24 16:35:20 +01:00
|
|
|
#include "isisd/isis_flags.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
#include "isisd/isis_circuit.h"
|
|
|
|
#include "isisd/isis_lsp.h"
|
|
|
|
#include "isisd/isis_pdu.h"
|
|
|
|
#include "isisd/isis_network.h"
|
|
|
|
#include "isisd/isis_misc.h"
|
|
|
|
#include "isisd/isis_constants.h"
|
|
|
|
#include "isisd/isis_adjacency.h"
|
|
|
|
#include "isisd/isis_dr.h"
|
|
|
|
#include "isisd/isisd.h"
|
|
|
|
#include "isisd/isis_csm.h"
|
|
|
|
#include "isisd/isis_events.h"
|
2023-09-03 08:54:57 +02:00
|
|
|
#include "isisd/isis_srv6.h"
|
2016-04-19 19:03:05 +02:00
|
|
|
#include "isisd/isis_te.h"
|
2017-04-27 13:56:35 +02:00
|
|
|
#include "isisd/isis_mt.h"
|
2018-06-18 20:56:15 +02:00
|
|
|
#include "isisd/isis_errors.h"
|
fabricd: reimplement LSP transmission logic
Before this commit, isisd/fabricd maintained a bitfield for each LSP
to track the SRM bit for each circuit, which specifies whether an LSP
needs to be sent on that circuit. Every second, it would scan over all
LSPs in `lsp_tick` and queue them up for transmission accordingly.
This design has two drawbacks: a) it scales poorly b) it adds
unacceptable latency to the update process: each router takes a random
amount of time between 0 and 1 seconds to forward an update. In a
network with a diamter of 10, it might already take 10 seconds for an
update to traverse the network.
To mitigate this, a new design was chosen. Instead of tracking SRM in a
bitfield, have one tx_queue per circuit and declare that an LSP is in
that queue if and only if it would have SRM set for that circuit.
This way, we can track SRM similarly as we did before, however, on
insertion into the LSP queue, we can add a timer for (re)transmission,
alleviating the need for a periodic scan with LSP tick and reducing the
latency for forwarding of updates.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
2018-05-10 17:37:05 +02:00
|
|
|
#include "isisd/isis_tx_queue.h"
|
2019-10-17 20:33:53 +02:00
|
|
|
#include "isisd/isis_nb.h"
|
2020-07-22 20:32:35 +02:00
|
|
|
#include "isisd/isis_ldp_sync.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2021-03-22 18:27:58 +01:00
|
|
|
DEFINE_MTYPE_STATIC(ISISD, ISIS_CIRCUIT, "ISIS circuit");
|
|
|
|
|
2016-04-05 23:54:53 +02:00
|
|
|
DEFINE_QOBJ_TYPE(isis_circuit);
|
|
|
|
|
2019-09-19 04:26:55 +02:00
|
|
|
DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp));
|
|
|
|
|
2006-12-08 02:09:50 +01:00
|
|
|
/*
|
|
|
|
* Prototypes.
|
|
|
|
*/
|
|
|
|
int isis_if_new_hook(struct interface *);
|
|
|
|
int isis_if_delete_hook(struct interface *);
|
|
|
|
|
2021-04-27 16:28:44 +02:00
|
|
|
DEFINE_HOOK(isis_circuit_new_hook, (struct isis_circuit *circuit), (circuit));
|
|
|
|
DEFINE_HOOK(isis_circuit_del_hook, (struct isis_circuit *circuit), (circuit));
|
2020-09-15 22:46:15 +02:00
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
static void isis_circuit_enable(struct isis_circuit *circuit)
|
|
|
|
{
|
2021-06-16 14:54:17 +02:00
|
|
|
struct isis_area *area = circuit->area;
|
2021-04-28 00:57:21 +02:00
|
|
|
struct interface *ifp = circuit->interface;
|
|
|
|
|
2021-06-16 14:54:17 +02:00
|
|
|
if (!area) {
|
2021-10-22 00:17:40 +02:00
|
|
|
area = isis_area_lookup(circuit->tag, ifp->vrf->vrf_id);
|
2021-06-16 14:54:17 +02:00
|
|
|
if (area)
|
|
|
|
isis_area_add_circuit(area, circuit);
|
|
|
|
}
|
2021-04-28 00:57:21 +02:00
|
|
|
|
|
|
|
if (if_is_operative(ifp))
|
|
|
|
isis_csm_state_change(IF_UP_FROM_Z, circuit, ifp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void isis_circuit_disable(struct isis_circuit *circuit)
|
|
|
|
{
|
|
|
|
struct isis_area *area = circuit->area;
|
|
|
|
struct interface *ifp = circuit->interface;
|
|
|
|
|
|
|
|
if (if_is_operative(ifp))
|
|
|
|
isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
|
|
|
|
|
|
|
|
if (area)
|
|
|
|
isis_area_del_circuit(area, circuit);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_circuit *circuit;
|
|
|
|
int i;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-09-28 20:45:54 +02:00
|
|
|
circuit = XCALLOC(MTYPE_ISIS_CIRCUIT, sizeof(struct isis_circuit));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
circuit->tag = XSTRDUP(MTYPE_ISIS_CIRCUIT, tag);
|
2020-09-15 22:46:15 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/*
|
|
|
|
* Default values
|
|
|
|
*/
|
2018-12-10 14:30:40 +01:00
|
|
|
#ifndef FABRICD
|
2021-10-30 02:15:24 +02:00
|
|
|
circuit->is_type_config = yang_get_default_enum(
|
2018-12-10 14:30:40 +01:00
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/circuit-type");
|
|
|
|
circuit->flags = 0;
|
|
|
|
|
2023-01-21 02:08:45 +01:00
|
|
|
circuit->pad_hellos = yang_get_default_enum(
|
2018-12-10 14:30:40 +01:00
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/hello/padding");
|
|
|
|
circuit->hello_interval[0] = yang_get_default_uint32(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1");
|
|
|
|
circuit->hello_interval[1] = yang_get_default_uint32(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2");
|
|
|
|
circuit->hello_multiplier[0] = yang_get_default_uint32(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1");
|
|
|
|
circuit->hello_multiplier[1] = yang_get_default_uint32(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2");
|
|
|
|
circuit->csnp_interval[0] = yang_get_default_uint16(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1");
|
|
|
|
circuit->csnp_interval[1] = yang_get_default_uint16(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2");
|
|
|
|
circuit->psnp_interval[0] = yang_get_default_uint16(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1");
|
|
|
|
circuit->psnp_interval[1] = yang_get_default_uint16(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2");
|
|
|
|
circuit->priority[0] = yang_get_default_uint8(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/priority/level-1");
|
|
|
|
circuit->priority[1] = yang_get_default_uint8(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/priority/level-2");
|
|
|
|
circuit->metric[0] = yang_get_default_uint32(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/metric/level-1");
|
|
|
|
circuit->metric[1] = yang_get_default_uint32(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/metric/level-2");
|
|
|
|
circuit->te_metric[0] = yang_get_default_uint32(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/metric/level-1");
|
|
|
|
circuit->te_metric[1] = yang_get_default_uint32(
|
|
|
|
"/frr-interface:lib/interface/frr-isisd:isis/metric/level-2");
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
circuit->level_arg[i].level = i + 1;
|
|
|
|
circuit->level_arg[i].circuit = circuit;
|
|
|
|
}
|
|
|
|
#else
|
2021-10-30 02:15:24 +02:00
|
|
|
circuit->is_type_config = IS_LEVEL_1_AND_2;
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->flags = 0;
|
2023-01-21 02:08:45 +01:00
|
|
|
circuit->pad_hellos = ISIS_HELLO_PADDING_ALWAYS;
|
2012-03-24 16:35:20 +01:00
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
circuit->hello_interval[i] = DEFAULT_HELLO_INTERVAL;
|
|
|
|
circuit->hello_multiplier[i] = DEFAULT_HELLO_MULTIPLIER;
|
|
|
|
circuit->csnp_interval[i] = DEFAULT_CSNP_INTERVAL;
|
|
|
|
circuit->psnp_interval[i] = DEFAULT_PSNP_INTERVAL;
|
|
|
|
circuit->priority[i] = DEFAULT_PRIORITY;
|
2016-07-28 17:23:32 +02:00
|
|
|
circuit->metric[i] = DEFAULT_CIRCUIT_METRIC;
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->te_metric[i] = DEFAULT_CIRCUIT_METRIC;
|
2018-11-05 20:07:11 +01:00
|
|
|
circuit->level_arg[i].level = i + 1;
|
|
|
|
circuit->level_arg[i].circuit = circuit;
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2018-12-10 14:30:40 +01:00
|
|
|
#endif /* ifndef FABRICD */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-10-30 02:15:24 +02:00
|
|
|
circuit->is_type = circuit->is_type_config;
|
|
|
|
|
2017-04-27 13:56:35 +02:00
|
|
|
circuit_mt_init(circuit);
|
2020-11-07 01:15:39 +01:00
|
|
|
isis_lfa_excluded_ifaces_init(circuit, ISIS_LEVEL1);
|
|
|
|
isis_lfa_excluded_ifaces_init(circuit, ISIS_LEVEL2);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-04-29 00:59:56 +02:00
|
|
|
circuit->ldp_sync_info = ldp_sync_info_create();
|
|
|
|
circuit->ldp_sync_info->enabled = LDP_IGP_SYNC_ENABLED;
|
|
|
|
|
2016-04-05 23:54:53 +02:00
|
|
|
QOBJ_REG(circuit, isis_circuit);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
isis_circuit_if_bind(circuit, ifp);
|
|
|
|
|
2022-06-18 20:37:14 +02:00
|
|
|
circuit->ip_addrs = list_new();
|
|
|
|
circuit->ipv6_link = list_new();
|
|
|
|
circuit->ipv6_non_link = list_new();
|
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
if (ifp->ifindex != IFINDEX_INTERNAL)
|
|
|
|
isis_circuit_enable(circuit);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return circuit;
|
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
void isis_circuit_del(struct isis_circuit *circuit)
|
|
|
|
{
|
|
|
|
if (!circuit)
|
|
|
|
return;
|
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
if (circuit->interface->ifindex != IFINDEX_INTERNAL)
|
|
|
|
isis_circuit_disable(circuit);
|
2020-09-15 22:46:15 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_circuit_if_unbind(circuit, circuit->interface);
|
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
QOBJ_UNREG(circuit);
|
|
|
|
|
2021-04-29 00:59:56 +02:00
|
|
|
ldp_sync_info_free(&circuit->ldp_sync_info);
|
|
|
|
|
2017-04-27 13:56:35 +02:00
|
|
|
circuit_mt_finish(circuit);
|
2024-08-08 19:17:42 +02:00
|
|
|
isis_lfa_excluded_ifaces_delete(circuit, ISIS_LEVEL1);
|
|
|
|
isis_lfa_excluded_ifaces_delete(circuit, ISIS_LEVEL2);
|
2017-04-27 13:56:35 +02:00
|
|
|
|
2022-06-18 20:37:14 +02:00
|
|
|
list_delete(&circuit->ip_addrs);
|
|
|
|
list_delete(&circuit->ipv6_link);
|
|
|
|
list_delete(&circuit->ipv6_non_link);
|
|
|
|
|
2022-08-05 16:00:48 +02:00
|
|
|
if (circuit->ext) {
|
|
|
|
isis_del_ext_subtlvs(circuit->ext);
|
|
|
|
circuit->ext = NULL;
|
|
|
|
}
|
|
|
|
|
2021-05-06 13:44:05 +02:00
|
|
|
XFREE(MTYPE_TMP, circuit->bfd_config.profile);
|
2021-04-28 00:57:21 +02:00
|
|
|
XFREE(MTYPE_ISIS_CIRCUIT, circuit->tag);
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* and lastly the circuit itself */
|
|
|
|
XFREE(MTYPE_ISIS_CIRCUIT, circuit);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
void isis_circuit_configure(struct isis_circuit *circuit,
|
|
|
|
struct isis_area *area)
|
|
|
|
{
|
2012-03-24 16:35:20 +01:00
|
|
|
assert(area);
|
2021-04-28 00:57:21 +02:00
|
|
|
circuit->isis = area->isis;
|
2003-12-23 09:09:43 +01:00
|
|
|
circuit->area = area;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
2015-11-10 18:04:48 +01:00
|
|
|
* Whenever the is-type of an area is changed, the is-type of each
|
|
|
|
* circuit
|
|
|
|
* in that area is updated to a non-empty subset of the area is-type.
|
|
|
|
* Inversely, when configuring a new circuit, this property should be
|
|
|
|
* ensured as well.
|
2003-12-23 09:09:43 +01:00
|
|
|
*/
|
2015-11-10 18:04:48 +01:00
|
|
|
if (area->is_type != IS_LEVEL_1_AND_2)
|
|
|
|
circuit->is_type = area->is_type;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* Add the circuit into area
|
|
|
|
*/
|
|
|
|
listnode_add(area->circuit_list, circuit);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
circuit->idx = flags_get_index(&area->flags);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
hook_call(isis_circuit_new_hook, circuit);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
void isis_circuit_deconfigure(struct isis_circuit *circuit,
|
|
|
|
struct isis_area *area)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2021-04-28 00:57:21 +02:00
|
|
|
hook_call(isis_circuit_del_hook, circuit);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* Free the index of SRM and SSN flags */
|
|
|
|
flags_free_index(&area->flags, circuit->idx);
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->idx = 0;
|
2021-10-30 02:15:24 +02:00
|
|
|
|
|
|
|
/* Reset IS type to configured */
|
|
|
|
circuit->is_type = circuit->is_type_config;
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* Remove circuit from area */
|
|
|
|
assert(circuit->area == area);
|
|
|
|
listnode_delete(area->circuit_list, circuit);
|
|
|
|
circuit->area = NULL;
|
2021-04-28 00:57:21 +02:00
|
|
|
circuit->isis = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct isis_circuit *circuit_scan_by_ifp(struct interface *ifp)
|
|
|
|
{
|
2021-04-28 00:57:21 +02:00
|
|
|
return (struct isis_circuit *)ifp->info;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2020-10-30 22:46:32 +01:00
|
|
|
DEFINE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit),
|
|
|
|
(circuit));
|
|
|
|
|
2004-09-14 15:54:30 +02:00
|
|
|
void isis_circuit_add_addr(struct isis_circuit *circuit,
|
|
|
|
struct connected *connected)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2012-03-24 16:35:20 +01:00
|
|
|
struct listnode *node;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct prefix_ipv4 *ipv4;
|
|
|
|
struct prefix_ipv6 *ipv6;
|
2004-09-14 15:54:30 +02:00
|
|
|
|
|
|
|
if (connected->address->family == AF_INET) {
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t addr = connected->address->u.prefix4.s_addr;
|
2012-03-24 16:35:20 +01:00
|
|
|
addr = ntohl(addr);
|
2023-04-03 18:06:48 +02:00
|
|
|
if (IPV4_NET0(addr) || IPV4_NET127(addr) || IN_CLASSD(addr))
|
2012-03-24 16:35:20 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, ipv4))
|
|
|
|
if (prefix_same((struct prefix *)ipv4,
|
|
|
|
connected->address))
|
|
|
|
return;
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
ipv4 = prefix_ipv4_new();
|
2004-09-14 15:54:30 +02:00
|
|
|
ipv4->prefixlen = connected->address->prefixlen;
|
|
|
|
ipv4->prefix = connected->address->u.prefix4;
|
2004-09-10 22:48:21 +02:00
|
|
|
listnode_add(circuit->ip_addrs, ipv4);
|
2016-04-19 19:03:05 +02:00
|
|
|
|
isisd: Update TLVs processing for TE, RI & SR
In preparation to Segment Routing:
- Update the management of Traffic Engineering subTLVs to the new tlvs parser
- Add Router Capability TLV 242 as per RFC 4971 & 7981
- Add Segment Routing subTLVs as per draft-isis-segment-routing-extension-25
Modified files:
- isis_tlvs.h: add new structure to manage TE subTLVs, TLV 242 & SR subTLVs
- isis_tlvs.c: add new functions (pack, copy, free, unpack & print) to process
TE subTLVs, Router Capability TLV and SR subTLVs
- isis_circuit.[c,h] & isis_lsp.[c,h]: update to new subTLVs & TLV processing
- isis_te.[c,h]: remove all old TE structures and managment functions,
and add hook call to set local and remote IP addresses as wellas update TE
parameters
- isis_zebra.[c,h]: add hook call when new interface is up
- isis_mt.[c,h], isis_pdu.c & isis_northbound.c: adjust to new TE subTLVs
- tests/isisd/test_fuzz_isis_tlv_tests.h.gz: adapte fuuz tests to new parser
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2019-07-26 16:07:39 +02:00
|
|
|
/* Update Local IP address parameter if MPLS TE is enable */
|
2020-05-28 15:46:56 +02:00
|
|
|
if (circuit->ext && circuit->area
|
|
|
|
&& IS_MPLS_TE(circuit->area->mta)) {
|
isisd: Update TLVs processing for TE, RI & SR
In preparation to Segment Routing:
- Update the management of Traffic Engineering subTLVs to the new tlvs parser
- Add Router Capability TLV 242 as per RFC 4971 & 7981
- Add Segment Routing subTLVs as per draft-isis-segment-routing-extension-25
Modified files:
- isis_tlvs.h: add new structure to manage TE subTLVs, TLV 242 & SR subTLVs
- isis_tlvs.c: add new functions (pack, copy, free, unpack & print) to process
TE subTLVs, Router Capability TLV and SR subTLVs
- isis_circuit.[c,h] & isis_lsp.[c,h]: update to new subTLVs & TLV processing
- isis_te.[c,h]: remove all old TE structures and managment functions,
and add hook call to set local and remote IP addresses as wellas update TE
parameters
- isis_zebra.[c,h]: add hook call when new interface is up
- isis_mt.[c,h], isis_pdu.c & isis_northbound.c: adjust to new TE subTLVs
- tests/isisd/test_fuzz_isis_tlv_tests.h.gz: adapte fuuz tests to new parser
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2019-07-26 16:07:39 +02:00
|
|
|
circuit->ext->local_addr.s_addr = ipv4->prefix.s_addr;
|
|
|
|
SET_SUBTLV(circuit->ext, EXT_LOCAL_ADDR);
|
|
|
|
}
|
2016-04-19 19:03:05 +02:00
|
|
|
|
2004-09-26 21:53:47 +02:00
|
|
|
if (circuit->area)
|
2012-03-24 16:35:20 +01:00
|
|
|
lsp_regenerate_schedule(circuit->area, circuit->is_type,
|
|
|
|
0);
|
2004-09-14 15:54:30 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef EXTREME_DEBUG
|
2022-02-16 15:35:40 +01:00
|
|
|
if (IS_DEBUG_EVENTS)
|
|
|
|
zlog_debug("Added IP address %pFX to circuit %s",
|
|
|
|
connected->address,
|
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
#endif /* EXTREME_DEBUG */
|
|
|
|
}
|
2004-09-14 15:54:30 +02:00
|
|
|
if (connected->address->family == AF_INET6) {
|
2012-03-24 16:35:20 +01:00
|
|
|
if (IN6_IS_ADDR_LOOPBACK(&connected->address->u.prefix6))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node, ipv6))
|
|
|
|
if (prefix_same((struct prefix *)ipv6,
|
|
|
|
connected->address))
|
|
|
|
return;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, ipv6))
|
|
|
|
if (prefix_same((struct prefix *)ipv6,
|
|
|
|
connected->address))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
ipv6 = prefix_ipv6_new();
|
2004-09-14 15:54:30 +02:00
|
|
|
ipv6->prefixlen = connected->address->prefixlen;
|
|
|
|
ipv6->prefix = connected->address->u.prefix6;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&ipv6->prefix))
|
2004-09-14 15:54:30 +02:00
|
|
|
listnode_add(circuit->ipv6_link, ipv6);
|
2021-06-30 17:23:56 +02:00
|
|
|
else {
|
2004-09-14 15:54:30 +02:00
|
|
|
listnode_add(circuit->ipv6_non_link, ipv6);
|
2021-06-30 17:23:56 +02:00
|
|
|
/* Update Local IPv6 address param. if MPLS TE is on */
|
|
|
|
if (circuit->ext && circuit->area
|
|
|
|
&& IS_MPLS_TE(circuit->area->mta)) {
|
|
|
|
IPV6_ADDR_COPY(&circuit->ext->local_addr6,
|
|
|
|
&ipv6->prefix);
|
|
|
|
SET_SUBTLV(circuit->ext, EXT_LOCAL_ADDR6);
|
|
|
|
}
|
|
|
|
}
|
2004-09-26 21:53:47 +02:00
|
|
|
if (circuit->area)
|
2012-03-24 16:35:20 +01:00
|
|
|
lsp_regenerate_schedule(circuit->area, circuit->is_type,
|
|
|
|
0);
|
2004-09-14 15:54:30 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef EXTREME_DEBUG
|
2022-02-16 15:35:40 +01:00
|
|
|
if (IS_DEBUG_EVENTS)
|
|
|
|
zlog_debug("Added IPv6 address %pFX to circuit %s",
|
|
|
|
connected->address,
|
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
#endif /* EXTREME_DEBUG */
|
|
|
|
}
|
2020-10-30 22:46:32 +01:00
|
|
|
|
|
|
|
hook_call(isis_circuit_add_addr_hook, circuit);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void isis_circuit_del_addr(struct isis_circuit *circuit,
|
2004-09-10 22:48:21 +02:00
|
|
|
struct connected *connected)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2004-09-14 15:54:30 +02:00
|
|
|
struct prefix_ipv4 *ipv4, *ip = NULL;
|
|
|
|
struct listnode *node;
|
|
|
|
struct prefix_ipv6 *ipv6, *ip6 = NULL;
|
2006-12-08 02:09:50 +01:00
|
|
|
int found = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-14 15:54:30 +02:00
|
|
|
if (connected->address->family == AF_INET) {
|
|
|
|
ipv4 = prefix_ipv4_new();
|
|
|
|
ipv4->prefixlen = connected->address->prefixlen;
|
|
|
|
ipv4->prefix = connected->address->u.prefix4;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node, ip))
|
2012-03-24 16:35:20 +01:00
|
|
|
if (prefix_same((struct prefix *)ip,
|
|
|
|
(struct prefix *)ipv4))
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-14 15:54:30 +02:00
|
|
|
if (ip) {
|
|
|
|
listnode_delete(circuit->ip_addrs, ip);
|
2019-10-30 01:05:27 +01:00
|
|
|
prefix_ipv4_free(&ip);
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->area)
|
|
|
|
lsp_regenerate_schedule(circuit->area,
|
|
|
|
circuit->is_type, 0);
|
|
|
|
} else {
|
2015-11-10 18:33:12 +01:00
|
|
|
zlog_warn(
|
2020-10-18 13:33:54 +02:00
|
|
|
"Nonexistent ip address %pFX removal attempt from circuit %s",
|
|
|
|
connected->address, circuit->interface->name);
|
2015-11-10 18:33:12 +01:00
|
|
|
zlog_warn("Current ip addresses on %s:",
|
|
|
|
circuit->interface->name);
|
2012-03-24 16:35:20 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node,
|
2017-07-17 14:03:14 +02:00
|
|
|
ip)) {
|
2020-10-18 13:33:54 +02:00
|
|
|
zlog_warn(" %pFX", ip);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2015-11-10 18:33:12 +01:00
|
|
|
zlog_warn("End of addresses");
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2019-10-30 01:05:27 +01:00
|
|
|
prefix_ipv4_free(&ipv4);
|
2004-09-14 15:54:30 +02:00
|
|
|
}
|
|
|
|
if (connected->address->family == AF_INET6) {
|
|
|
|
ipv6 = prefix_ipv6_new();
|
|
|
|
ipv6->prefixlen = connected->address->prefixlen;
|
|
|
|
ipv6->prefix = connected->address->u.prefix6;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-14 15:54:30 +02:00
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&ipv6->prefix)) {
|
2015-11-10 18:33:12 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
|
2017-07-17 14:03:14 +02:00
|
|
|
ip6)) {
|
2004-09-14 15:54:30 +02:00
|
|
|
if (prefix_same((struct prefix *)ip6,
|
|
|
|
(struct prefix *)ipv6))
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ip6) {
|
2004-09-14 15:54:30 +02:00
|
|
|
listnode_delete(circuit->ipv6_link, ip6);
|
2019-10-30 01:05:27 +01:00
|
|
|
prefix_ipv6_free(&ip6);
|
2004-09-14 15:54:30 +02:00
|
|
|
found = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2004-09-14 15:54:30 +02:00
|
|
|
} else {
|
2015-11-23 21:44:34 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
|
2017-07-17 14:03:14 +02:00
|
|
|
ip6)) {
|
2015-11-23 21:44:34 +01:00
|
|
|
if (prefix_same((struct prefix *)ip6,
|
2004-09-14 15:54:30 +02:00
|
|
|
(struct prefix *)ipv6))
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ip6) {
|
2004-09-14 15:54:30 +02:00
|
|
|
listnode_delete(circuit->ipv6_non_link, ip6);
|
2019-10-30 01:05:27 +01:00
|
|
|
prefix_ipv6_free(&ip6);
|
2004-09-14 15:54:30 +02:00
|
|
|
found = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-14 15:54:30 +02:00
|
|
|
if (!found) {
|
2017-02-13 19:27:54 +01:00
|
|
|
zlog_warn(
|
2020-10-18 13:33:54 +02:00
|
|
|
"Nonexistent ip address %pFX removal attempt from circuit %s",
|
|
|
|
connected->address, circuit->interface->name);
|
2015-11-10 18:33:12 +01:00
|
|
|
zlog_warn("Current ip addresses on %s:",
|
|
|
|
circuit->interface->name);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
|
2020-10-18 13:33:54 +02:00
|
|
|
ip6))
|
|
|
|
zlog_warn(" %pFX", (struct prefix *)ip6);
|
2015-11-10 18:33:12 +01:00
|
|
|
zlog_warn(" -----");
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
|
2020-10-18 13:33:54 +02:00
|
|
|
ip6))
|
|
|
|
zlog_warn(" %pFX", (struct prefix *)ip6);
|
2015-11-10 18:33:12 +01:00
|
|
|
zlog_warn("End of addresses");
|
2012-03-24 16:35:20 +01:00
|
|
|
} else if (circuit->area)
|
2016-04-03 17:46:27 +02:00
|
|
|
lsp_regenerate_schedule(circuit->area, circuit->is_type,
|
2017-07-17 14:03:14 +02:00
|
|
|
0);
|
|
|
|
|
2019-10-30 01:05:27 +01:00
|
|
|
prefix_ipv6_free(&ipv6);
|
2004-09-14 15:54:30 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-11-27 02:10:30 +01:00
|
|
|
|
2018-03-05 18:45:02 +01:00
|
|
|
static uint8_t isis_circuit_id_gen(struct isis *isis, struct interface *ifp)
|
2004-09-14 15:54:30 +02:00
|
|
|
{
|
2017-09-14 15:26:33 +02:00
|
|
|
/* Circuit ids MUST be unique for any broadcast circuits. Otherwise,
|
|
|
|
* Pseudo-Node LSPs cannot be generated correctly.
|
|
|
|
*
|
2018-03-10 18:16:34 +01:00
|
|
|
* Currently, allocate one circuit ID for any circuit, limiting the total
|
2017-09-14 15:26:33 +02:00
|
|
|
* numer of circuits IS-IS can run on to 255.
|
|
|
|
*
|
2018-03-10 18:16:34 +01:00
|
|
|
* We should revisit this when implementing 3-way adjacencies for p2p, since
|
2017-09-14 15:26:33 +02:00
|
|
|
* we then have extended interface IDs available.
|
|
|
|
*/
|
|
|
|
uint8_t id = ifp->ifindex;
|
2012-03-24 16:35:20 +01:00
|
|
|
unsigned int i;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-09-14 15:26:33 +02:00
|
|
|
for (i = 0; i < 256; i++) {
|
|
|
|
if (id && !_ISIS_CHECK_FLAG(isis->circuit_ids_used, id))
|
2004-09-14 15:54:30 +02:00
|
|
|
break;
|
2017-09-14 15:26:33 +02:00
|
|
|
id++;
|
2004-09-14 15:54:30 +02:00
|
|
|
}
|
|
|
|
|
2017-09-14 15:26:33 +02:00
|
|
|
if (i == 256) {
|
|
|
|
zlog_warn("Could not allocate a circuit id for '%s'",
|
|
|
|
ifp->name);
|
|
|
|
return 0;
|
2004-09-14 15:54:30 +02:00
|
|
|
}
|
2012-11-27 02:10:30 +01:00
|
|
|
|
2018-03-05 18:45:02 +01:00
|
|
|
_ISIS_SET_FLAG(isis->circuit_ids_used, id);
|
2012-03-24 16:35:20 +01:00
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct connected *conn;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2025-02-25 10:24:58 +01:00
|
|
|
if (if_is_loopback(ifp) || (isis_option_check(ISIS_OPT_DUMMY_AS_LOOPBACK) &&
|
|
|
|
CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_DUMMY))) {
|
|
|
|
circuit->circ_type = CIRCUIT_T_LOOPBACK;
|
|
|
|
circuit->is_passive = 1;
|
|
|
|
} else if (if_is_broadcast(ifp)) {
|
2018-03-22 14:58:53 +01:00
|
|
|
if (fabricd || circuit->circ_type_config == CIRCUIT_T_P2P)
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->circ_type = CIRCUIT_T_P2P;
|
2004-09-10 22:48:21 +02:00
|
|
|
else
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->circ_type = CIRCUIT_T_BROADCAST;
|
2004-09-10 22:48:21 +02:00
|
|
|
} else if (if_is_pointopoint(ifp)) {
|
|
|
|
circuit->circ_type = CIRCUIT_T_P2P;
|
|
|
|
} else {
|
2005-09-04 23:36:36 +02:00
|
|
|
/* It's normal in case of loopback etc. */
|
2020-06-19 21:04:33 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2022-08-29 08:53:46 +02:00
|
|
|
zlog_debug("%s: unsupported media", __func__);
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->circ_type = CIRCUIT_T_UNKNOWN;
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-11-22 19:05:41 +01:00
|
|
|
frr_each (if_connected, ifp->connected, conn)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
isis_circuit_add_addr(circuit, conn);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
void isis_circuit_if_del(struct isis_circuit *circuit, struct interface *ifp)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2012-03-24 16:35:20 +01:00
|
|
|
struct connected *conn;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
assert(circuit->interface == ifp);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* destroy addresses */
|
2023-11-22 19:05:41 +01:00
|
|
|
frr_each_safe (if_connected, ifp->connected, conn)
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_circuit_del_addr(circuit, conn);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->circ_type = CIRCUIT_T_UNKNOWN;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
void isis_circuit_if_bind(struct isis_circuit *circuit, struct interface *ifp)
|
|
|
|
{
|
|
|
|
assert(circuit != NULL);
|
|
|
|
assert(ifp != NULL);
|
|
|
|
if (circuit->interface)
|
|
|
|
assert(circuit->interface == ifp);
|
|
|
|
else
|
|
|
|
circuit->interface = ifp;
|
|
|
|
if (ifp->info)
|
|
|
|
assert(ifp->info == circuit);
|
|
|
|
else
|
|
|
|
ifp->info = circuit;
|
|
|
|
}
|
|
|
|
|
|
|
|
void isis_circuit_if_unbind(struct isis_circuit *circuit, struct interface *ifp)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2012-03-24 16:35:20 +01:00
|
|
|
assert(circuit != NULL);
|
|
|
|
assert(ifp != NULL);
|
|
|
|
assert(circuit->interface == ifp);
|
|
|
|
assert(ifp->info == circuit);
|
2003-12-23 09:09:43 +01:00
|
|
|
circuit->interface = NULL;
|
2012-03-24 16:35:20 +01:00
|
|
|
ifp->info = NULL;
|
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
static void isis_circuit_update_all_srmflags(struct isis_circuit *circuit,
|
|
|
|
int is_set)
|
|
|
|
{
|
|
|
|
struct isis_area *area;
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
int level;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
assert(circuit);
|
|
|
|
area = circuit->area;
|
|
|
|
assert(area);
|
|
|
|
for (level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
|
fabricd: reimplement LSP transmission logic
Before this commit, isisd/fabricd maintained a bitfield for each LSP
to track the SRM bit for each circuit, which specifies whether an LSP
needs to be sent on that circuit. Every second, it would scan over all
LSPs in `lsp_tick` and queue them up for transmission accordingly.
This design has two drawbacks: a) it scales poorly b) it adds
unacceptable latency to the update process: each router takes a random
amount of time between 0 and 1 seconds to forward an update. In a
network with a diamter of 10, it might already take 10 seconds for an
update to traverse the network.
To mitigate this, a new design was chosen. Instead of tracking SRM in a
bitfield, have one tx_queue per circuit and declare that an LSP is in
that queue if and only if it would have SRM set for that circuit.
This way, we can track SRM similarly as we did before, however, on
insertion into the LSP queue, we can add a timer for (re)transmission,
alleviating the need for a periodic scan with LSP tick and reducing the
latency for forwarding of updates.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
2018-05-10 17:37:05 +02:00
|
|
|
if (!(level & circuit->is_type))
|
|
|
|
continue;
|
|
|
|
|
2019-02-04 01:22:03 +01:00
|
|
|
if (!lspdb_count(&area->lspdb[level - 1]))
|
fabricd: reimplement LSP transmission logic
Before this commit, isisd/fabricd maintained a bitfield for each LSP
to track the SRM bit for each circuit, which specifies whether an LSP
needs to be sent on that circuit. Every second, it would scan over all
LSPs in `lsp_tick` and queue them up for transmission accordingly.
This design has two drawbacks: a) it scales poorly b) it adds
unacceptable latency to the update process: each router takes a random
amount of time between 0 and 1 seconds to forward an update. In a
network with a diamter of 10, it might already take 10 seconds for an
update to traverse the network.
To mitigate this, a new design was chosen. Instead of tracking SRM in a
bitfield, have one tx_queue per circuit and declare that an LSP is in
that queue if and only if it would have SRM set for that circuit.
This way, we can track SRM similarly as we did before, however, on
insertion into the LSP queue, we can add a timer for (re)transmission,
alleviating the need for a periodic scan with LSP tick and reducing the
latency for forwarding of updates.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
2018-05-10 17:37:05 +02:00
|
|
|
continue;
|
|
|
|
|
2019-05-20 23:52:16 +02:00
|
|
|
frr_each (lspdb, &area->lspdb[level - 1], lsp) {
|
fabricd: reimplement LSP transmission logic
Before this commit, isisd/fabricd maintained a bitfield for each LSP
to track the SRM bit for each circuit, which specifies whether an LSP
needs to be sent on that circuit. Every second, it would scan over all
LSPs in `lsp_tick` and queue them up for transmission accordingly.
This design has two drawbacks: a) it scales poorly b) it adds
unacceptable latency to the update process: each router takes a random
amount of time between 0 and 1 seconds to forward an update. In a
network with a diamter of 10, it might already take 10 seconds for an
update to traverse the network.
To mitigate this, a new design was chosen. Instead of tracking SRM in a
bitfield, have one tx_queue per circuit and declare that an LSP is in
that queue if and only if it would have SRM set for that circuit.
This way, we can track SRM similarly as we did before, however, on
insertion into the LSP queue, we can add a timer for (re)transmission,
alleviating the need for a periodic scan with LSP tick and reducing the
latency for forwarding of updates.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
2018-05-10 17:37:05 +02:00
|
|
|
if (is_set) {
|
|
|
|
isis_tx_queue_add(circuit->tx_queue, lsp,
|
|
|
|
TX_LSP_NORMAL);
|
|
|
|
} else {
|
|
|
|
isis_tx_queue_del(circuit->tx_queue, lsp);
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2015-11-10 18:43:31 +01:00
|
|
|
size_t isis_circuit_pdu_size(struct isis_circuit *circuit)
|
|
|
|
{
|
|
|
|
return ISO_MTU(circuit);
|
|
|
|
}
|
|
|
|
|
2022-03-21 17:59:27 +01:00
|
|
|
static bool isis_circuit_lfa_enabled(struct isis_circuit *circuit, int level)
|
|
|
|
{
|
|
|
|
return (circuit->lfa_protection[level - 1] ||
|
|
|
|
circuit->rlfa_protection[level - 1] ||
|
|
|
|
circuit->tilfa_protection[level - 1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void isis_circuit_switchover_routes(struct isis_circuit *circuit, int family,
|
|
|
|
union g_addr *nexthop_ip, ifindex_t ifindex)
|
|
|
|
{
|
|
|
|
char is_type;
|
|
|
|
|
|
|
|
if (!circuit->area)
|
|
|
|
return;
|
|
|
|
|
|
|
|
is_type = circuit->area->is_type;
|
|
|
|
if ((is_type == IS_LEVEL_1 || is_type == IS_LEVEL_1_AND_2) &&
|
|
|
|
isis_circuit_lfa_enabled(circuit, IS_LEVEL_1))
|
|
|
|
isis_area_switchover_routes(circuit->area, family, nexthop_ip,
|
|
|
|
ifindex, IS_LEVEL_1);
|
|
|
|
if ((is_type == IS_LEVEL_2 || is_type == IS_LEVEL_1_AND_2) &&
|
|
|
|
isis_circuit_lfa_enabled(circuit, IS_LEVEL_2))
|
|
|
|
isis_area_switchover_routes(circuit->area, family, nexthop_ip,
|
|
|
|
ifindex, IS_LEVEL_2);
|
|
|
|
}
|
|
|
|
|
2015-11-10 18:43:31 +01:00
|
|
|
void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream)
|
|
|
|
{
|
|
|
|
size_t stream_size = isis_circuit_pdu_size(circuit);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-11-10 18:43:31 +01:00
|
|
|
if (!*stream) {
|
|
|
|
*stream = stream_new(stream_size);
|
|
|
|
} else {
|
|
|
|
if (STREAM_SIZE(*stream) != stream_size)
|
2018-08-22 02:22:28 +02:00
|
|
|
stream_resize_inplace(stream, stream_size);
|
2015-11-10 18:43:31 +01:00
|
|
|
stream_reset(*stream);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-28 21:55:01 +01:00
|
|
|
void isis_circuit_prepare(struct isis_circuit *circuit)
|
|
|
|
{
|
2018-02-07 19:26:25 +01:00
|
|
|
#if ISIS_METHOD != ISIS_METHOD_DLPI
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_read(master, isis_receive, circuit, circuit->fd,
|
|
|
|
&circuit->t_read);
|
2016-11-28 21:55:01 +01:00
|
|
|
#else
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer_msec(master, isis_receive, circuit,
|
|
|
|
listcount(circuit->area->circuit_list) * 100,
|
|
|
|
&circuit->t_read);
|
2016-11-28 21:55:01 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
int isis_circuit_up(struct isis_circuit *circuit)
|
|
|
|
{
|
2012-03-24 16:35:20 +01:00
|
|
|
int retv;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* Set the flags for all the lsps of the circuit. */
|
|
|
|
isis_circuit_update_all_srmflags(circuit, 1);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->state == C_STATE_UP)
|
|
|
|
return ISIS_OK;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-29 09:51:27 +01:00
|
|
|
if (circuit->is_passive) {
|
2020-09-15 22:46:15 +02:00
|
|
|
circuit->last_uptime = time(NULL);
|
2020-10-29 09:51:27 +01:00
|
|
|
/* make sure the union fields are initialized, else we
|
|
|
|
* could end with garbage values from a previous circuit
|
|
|
|
* type, which would then cause a segfault when building
|
|
|
|
* LSPs or computing the SPF tree
|
|
|
|
*/
|
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
|
|
|
circuit->u.bc.adjdb[0] = list_new();
|
|
|
|
circuit->u.bc.adjdb[1] = list_new();
|
|
|
|
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
|
|
|
|
circuit->u.p2p.neighbor = NULL;
|
|
|
|
}
|
2012-03-24 16:35:20 +01:00
|
|
|
return ISIS_OK;
|
2020-10-29 09:51:27 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-11-10 18:43:31 +01:00
|
|
|
if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:12:08 +02:00
|
|
|
EC_ISIS_CONFIG,
|
2015-11-10 18:43:31 +01:00
|
|
|
"Interface MTU %zu on %s is too low to support area lsp mtu %u!",
|
|
|
|
isis_circuit_pdu_size(circuit),
|
|
|
|
circuit->interface->name, circuit->area->lsp_mtu);
|
2022-04-13 22:07:44 +02:00
|
|
|
|
|
|
|
/* Allow ISIS to continue configuration. With this
|
|
|
|
* configuration failure ISIS will attempt to send lsp
|
|
|
|
* packets but will fail until the mtu is configured properly
|
|
|
|
*/
|
2015-11-10 18:43:31 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
2020-10-09 14:00:44 +02:00
|
|
|
circuit->circuit_id =
|
|
|
|
isis_circuit_id_gen(circuit->isis, circuit->interface);
|
2018-03-05 18:45:02 +01:00
|
|
|
if (!circuit->circuit_id) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:12:08 +02:00
|
|
|
EC_ISIS_CONFIG,
|
2018-06-18 20:56:15 +02:00
|
|
|
"There are already 255 broadcast circuits active!");
|
2018-03-05 18:45:02 +01:00
|
|
|
return ISIS_ERROR;
|
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/*
|
|
|
|
* Get the Hardware Address
|
|
|
|
*/
|
|
|
|
if (circuit->interface->hw_addr_len != ETH_ALEN) {
|
|
|
|
zlog_warn("unsupported link layer");
|
|
|
|
} else {
|
|
|
|
memcpy(circuit->u.bc.snpa, circuit->interface->hw_addr,
|
|
|
|
ETH_ALEN);
|
|
|
|
}
|
|
|
|
#ifdef EXTREME_DEGUG
|
2022-02-16 15:35:40 +01:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2023-01-26 17:47:04 +01:00
|
|
|
zlog_debug("%s: if_id %d, isomtu %d snpa %pSY",
|
|
|
|
__func__, circuit->interface->ifindex,
|
|
|
|
ISO_MTU(circuit), circuit->u.bc.snpa);
|
2012-03-24 16:35:20 +01:00
|
|
|
#endif /* EXTREME_DEBUG */
|
|
|
|
|
|
|
|
circuit->u.bc.adjdb[0] = list_new();
|
|
|
|
circuit->u.bc.adjdb[1] = list_new();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/*
|
|
|
|
* ISO 10589 - 8.4.1 Enabling of broadcast circuits
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/* initilizing the hello sending threads
|
|
|
|
* for a broadcast IF
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/* 8.4.1 a) commence sending of IIH PDUs */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-10 11:16:39 +02:00
|
|
|
for (int level = ISIS_LEVEL1; level <= ISIS_LEVEL2; level++) {
|
|
|
|
if (!(circuit->is_type & level))
|
|
|
|
continue;
|
|
|
|
|
2018-10-10 15:43:01 +02:00
|
|
|
send_hello_sched(circuit, level, TRIGGERED_IIH_DELAY);
|
2018-10-10 11:16:39 +02:00
|
|
|
circuit->u.bc.lan_neighs[level - 1] = list_new();
|
|
|
|
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(master, isis_run_dr,
|
|
|
|
&circuit->level_arg[level - 1],
|
|
|
|
2 * circuit->hello_interval[level - 1],
|
|
|
|
&circuit->u.bc.t_run_dr[level - 1]);
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/* 8.4.1 b) FIXME: solicit ES - 8.4.6 */
|
|
|
|
/* 8.4.1 c) FIXME: listen for ESH PDUs */
|
2018-07-17 21:14:54 +02:00
|
|
|
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
|
2004-09-10 22:48:21 +02:00
|
|
|
/* initializing the hello send threads
|
|
|
|
* for a ptp IF
|
|
|
|
*/
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->u.p2p.neighbor = NULL;
|
2018-10-10 15:43:01 +02:00
|
|
|
send_hello_sched(circuit, 0, TRIGGERED_IIH_DELAY);
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* initializing PSNP timers */
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->is_type & IS_LEVEL_1)
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(
|
2017-04-25 00:33:25 +02:00
|
|
|
master, send_l1_psnp, circuit,
|
|
|
|
isis_jitter(circuit->psnp_interval[0], PSNP_JITTER),
|
|
|
|
&circuit->t_send_psnp[0]);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->is_type & IS_LEVEL_2)
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(
|
2017-04-25 00:33:25 +02:00
|
|
|
master, send_l2_psnp, circuit,
|
|
|
|
isis_jitter(circuit->psnp_interval[1], PSNP_JITTER),
|
|
|
|
&circuit->t_send_psnp[1]);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* unified init for circuits; ignore warnings below this level */
|
|
|
|
retv = isis_sock_init(circuit);
|
|
|
|
if (retv != ISIS_OK) {
|
|
|
|
isis_circuit_down(circuit);
|
|
|
|
return retv;
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* initialize the circuit streams after opening connection */
|
2015-11-10 18:43:31 +01:00
|
|
|
isis_circuit_stream(circuit, &circuit->rcv_stream);
|
|
|
|
isis_circuit_stream(circuit, &circuit->snd_stream);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-11-28 21:55:01 +01:00
|
|
|
isis_circuit_prepare(circuit);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
fabricd: reimplement LSP transmission logic
Before this commit, isisd/fabricd maintained a bitfield for each LSP
to track the SRM bit for each circuit, which specifies whether an LSP
needs to be sent on that circuit. Every second, it would scan over all
LSPs in `lsp_tick` and queue them up for transmission accordingly.
This design has two drawbacks: a) it scales poorly b) it adds
unacceptable latency to the update process: each router takes a random
amount of time between 0 and 1 seconds to forward an update. In a
network with a diamter of 10, it might already take 10 seconds for an
update to traverse the network.
To mitigate this, a new design was chosen. Instead of tracking SRM in a
bitfield, have one tx_queue per circuit and declare that an LSP is in
that queue if and only if it would have SRM set for that circuit.
This way, we can track SRM similarly as we did before, however, on
insertion into the LSP queue, we can add a timer for (re)transmission,
alleviating the need for a periodic scan with LSP tick and reducing the
latency for forwarding of updates.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
2018-05-10 17:37:05 +02:00
|
|
|
circuit->tx_queue = isis_tx_queue_new(circuit, send_lsp);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-09-15 22:46:15 +02:00
|
|
|
circuit->last_uptime = time(NULL);
|
|
|
|
|
2021-04-27 14:06:37 +02:00
|
|
|
if (circuit->area->mta && circuit->area->mta->status)
|
|
|
|
isis_link_params_update(circuit, circuit->interface);
|
|
|
|
|
2021-04-29 00:59:56 +02:00
|
|
|
isis_if_ldp_sync_enable(circuit);
|
|
|
|
|
2018-11-14 15:04:51 +01:00
|
|
|
#ifndef FABRICD
|
|
|
|
/* send northbound notification */
|
|
|
|
isis_notif_if_state_change(circuit, false);
|
|
|
|
#endif /* ifndef FABRICD */
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
return ISIS_OK;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void isis_circuit_down(struct isis_circuit *circuit)
|
|
|
|
{
|
2018-11-14 15:04:51 +01:00
|
|
|
#ifndef FABRICD
|
|
|
|
/* send northbound notification */
|
|
|
|
isis_notif_if_state_change(circuit, true);
|
|
|
|
#endif /* ifndef FABRICD */
|
|
|
|
|
2021-04-29 00:59:56 +02:00
|
|
|
isis_if_ldp_sync_disable(circuit);
|
|
|
|
|
2020-07-01 19:37:16 +02:00
|
|
|
/* log adjacency changes if configured to do so */
|
2020-07-10 15:55:52 +02:00
|
|
|
if (circuit->area->log_adj_changes) {
|
2020-07-01 19:37:16 +02:00
|
|
|
struct isis_adjacency *adj = NULL;
|
|
|
|
if (circuit->circ_type == CIRCUIT_T_P2P) {
|
|
|
|
adj = circuit->u.p2p.neighbor;
|
|
|
|
if (adj)
|
|
|
|
isis_log_adj_change(
|
|
|
|
adj, adj->adj_state, ISIS_ADJ_DOWN,
|
|
|
|
"circuit is being brought down");
|
|
|
|
} else if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
|
|
|
struct list *adj_list;
|
|
|
|
struct listnode *node;
|
|
|
|
if (circuit->u.bc.adjdb[0]) {
|
|
|
|
adj_list = list_new();
|
|
|
|
isis_adj_build_up_list(circuit->u.bc.adjdb[0],
|
|
|
|
adj_list);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(adj_list, node, adj))
|
|
|
|
isis_log_adj_change(
|
|
|
|
adj, adj->adj_state,
|
|
|
|
ISIS_ADJ_DOWN,
|
|
|
|
"circuit is being brought down");
|
|
|
|
list_delete(&adj_list);
|
|
|
|
}
|
|
|
|
if (circuit->u.bc.adjdb[1]) {
|
|
|
|
adj_list = list_new();
|
|
|
|
isis_adj_build_up_list(circuit->u.bc.adjdb[1],
|
|
|
|
adj_list);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(adj_list, node, adj))
|
|
|
|
isis_log_adj_change(
|
|
|
|
adj, adj->adj_state,
|
|
|
|
ISIS_ADJ_DOWN,
|
|
|
|
"circuit is being brought down");
|
|
|
|
list_delete(&adj_list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* Clear the flags for all the lsps of the circuit. */
|
|
|
|
isis_circuit_update_all_srmflags(circuit, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
2012-03-24 16:35:20 +01:00
|
|
|
/* destroy neighbour lists */
|
|
|
|
if (circuit->u.bc.lan_neighs[0]) {
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&circuit->u.bc.lan_neighs[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->u.bc.lan_neighs[0] = NULL;
|
|
|
|
}
|
|
|
|
if (circuit->u.bc.lan_neighs[1]) {
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&circuit->u.bc.lan_neighs[1]);
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->u.bc.lan_neighs[1] = NULL;
|
|
|
|
}
|
|
|
|
/* destroy adjacency databases */
|
|
|
|
if (circuit->u.bc.adjdb[0]) {
|
|
|
|
circuit->u.bc.adjdb[0]->del = isis_delete_adj;
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&circuit->u.bc.adjdb[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
|
|
|
if (circuit->u.bc.adjdb[1]) {
|
|
|
|
circuit->u.bc.adjdb[1]->del = isis_delete_adj;
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&circuit->u.bc.adjdb[1]);
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
|
|
|
if (circuit->u.bc.is_dr[0]) {
|
|
|
|
isis_dr_resign(circuit, 1);
|
|
|
|
circuit->u.bc.is_dr[0] = 0;
|
|
|
|
}
|
isisd: fix crash when switching P2P after shutdowning LAN circuit
When shutdown a LAN-type circuit, and if the current device is not the DIS (assuming it is a level-1 device), the isis_circuit_down() function will not call the isis_dr_resign() function to clear the circuit->u.bc.run_dr_elect[0] bit (this bit is set on interfaces in the isis_run_dr() function). After switching the link to a P2P type, since u.p2p and u.bc form a union, and circuit->u.bc.snpa = "\000\000\000\000\000" and circuit->u.bc.run_dr_elect = "\001", this results in circuit->u.p2p.neighbor = 0x1000000000000. Consequently, the value of adj->sysid accesses a wild pointer, causing the current crash.
The backtrace is as follows:
(gdb) bt
#0 0x00007fbd30e55fe1 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007fbd30f76b29 in core_handler (signo=11, siginfo=0x7ffc60b7a270,
context=0x7ffc60b7a140) at ../lib/sigevent.c:261
#2 <signal handler called>
#3 0x00007fbd30dddba4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x0000562aec46617f in isis_spf_run_lfa (area=0x562aee3a56d0, spftree=0x562aee3a51a0)
at ../isisd/isis_lfa.c:2403
#5 0x0000562aec483854 in isis_run_spf_with_protection (area=0x562aee3a56d0,
spftree=0x562aee3a51a0) at ../isisd/isis_spf.c:1891
#6 0x0000562aec483b05 in isis_run_spf_cb (thread=0x7ffc60b7b000)
at ../isisd/isis_spf.c:1953
#7 0x00007fbd30f900bb in thread_call (thread=0x7ffc60b7b000) at ../lib/thread.c:1990
#8 0x00007fbd30f2897b in frr_run (master=0x562aee0833c0) at ../lib/libfrr.c:1198
#9 0x0000562aec454d6d in main (argc=5, argv=0x7ffc60b7b228, envp=0x7ffc60b7b258)
at ../isisd/isis_main.c:273
(gdb) f 4
#4 0x0000562aec46617f in isis_spf_run_lfa (area=0x562aee3a56d0, spftree=0x562aee3a51a0)
at ../isisd/isis_lfa.c:2403
2403 ../isisd/isis_lfa.c: No such file or directory.
(gdb) p circuit->u.p2p.neighbor
$1 = (struct isis_adjacency *) 0x1000000000000
(gdb) p adj->sysid
Cannot access memory at address 0x1000000000006
(gdb) p circuit->u.bc
$2 = {snpa = "\000\000\000\000\000", run_dr_elect = "\001", t_run_dr = {0x0, 0x0},
t_send_lan_hello = {0x0, 0x0}, adjdb = {0x0, 0x0}, lan_neighs = {0x0, 0x0},
is_dr = "\000", l1_desig_is = "\000\000\000\000\000\000",
l2_desig_is = "\000\000\000\000\000\000", t_refresh_pseudo_lsp = {0x0, 0x0}}
(gdb)
The backtrace provided above pertains to version 8.5.4, but it seems that the same issue exists in the code of the master branch as well.
Signed-off-by: baozhen-H3C <bao.zhen@h3c.com>
2024-11-06 13:17:03 +01:00
|
|
|
circuit->u.bc.run_dr_elect[0] = 0;
|
2012-03-24 16:35:20 +01:00
|
|
|
memset(circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1);
|
|
|
|
if (circuit->u.bc.is_dr[1]) {
|
|
|
|
isis_dr_resign(circuit, 2);
|
|
|
|
circuit->u.bc.is_dr[1] = 0;
|
|
|
|
}
|
isisd: fix crash when switching P2P after shutdowning LAN circuit
When shutdown a LAN-type circuit, and if the current device is not the DIS (assuming it is a level-1 device), the isis_circuit_down() function will not call the isis_dr_resign() function to clear the circuit->u.bc.run_dr_elect[0] bit (this bit is set on interfaces in the isis_run_dr() function). After switching the link to a P2P type, since u.p2p and u.bc form a union, and circuit->u.bc.snpa = "\000\000\000\000\000" and circuit->u.bc.run_dr_elect = "\001", this results in circuit->u.p2p.neighbor = 0x1000000000000. Consequently, the value of adj->sysid accesses a wild pointer, causing the current crash.
The backtrace is as follows:
(gdb) bt
#0 0x00007fbd30e55fe1 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x00007fbd30f76b29 in core_handler (signo=11, siginfo=0x7ffc60b7a270,
context=0x7ffc60b7a140) at ../lib/sigevent.c:261
#2 <signal handler called>
#3 0x00007fbd30dddba4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x0000562aec46617f in isis_spf_run_lfa (area=0x562aee3a56d0, spftree=0x562aee3a51a0)
at ../isisd/isis_lfa.c:2403
#5 0x0000562aec483854 in isis_run_spf_with_protection (area=0x562aee3a56d0,
spftree=0x562aee3a51a0) at ../isisd/isis_spf.c:1891
#6 0x0000562aec483b05 in isis_run_spf_cb (thread=0x7ffc60b7b000)
at ../isisd/isis_spf.c:1953
#7 0x00007fbd30f900bb in thread_call (thread=0x7ffc60b7b000) at ../lib/thread.c:1990
#8 0x00007fbd30f2897b in frr_run (master=0x562aee0833c0) at ../lib/libfrr.c:1198
#9 0x0000562aec454d6d in main (argc=5, argv=0x7ffc60b7b228, envp=0x7ffc60b7b258)
at ../isisd/isis_main.c:273
(gdb) f 4
#4 0x0000562aec46617f in isis_spf_run_lfa (area=0x562aee3a56d0, spftree=0x562aee3a51a0)
at ../isisd/isis_lfa.c:2403
2403 ../isisd/isis_lfa.c: No such file or directory.
(gdb) p circuit->u.p2p.neighbor
$1 = (struct isis_adjacency *) 0x1000000000000
(gdb) p adj->sysid
Cannot access memory at address 0x1000000000006
(gdb) p circuit->u.bc
$2 = {snpa = "\000\000\000\000\000", run_dr_elect = "\001", t_run_dr = {0x0, 0x0},
t_send_lan_hello = {0x0, 0x0}, adjdb = {0x0, 0x0}, lan_neighs = {0x0, 0x0},
is_dr = "\000", l1_desig_is = "\000\000\000\000\000\000",
l2_desig_is = "\000\000\000\000\000\000", t_refresh_pseudo_lsp = {0x0, 0x0}}
(gdb)
The backtrace provided above pertains to version 8.5.4, but it seems that the same issue exists in the code of the master branch as well.
Signed-off-by: baozhen-H3C <bao.zhen@h3c.com>
2024-11-06 13:17:03 +01:00
|
|
|
circuit->u.bc.run_dr_elect[1] = 0;
|
2012-03-24 16:35:20 +01:00
|
|
|
memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
|
|
|
|
memset(circuit->u.bc.snpa, 0, ETH_ALEN);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-12-25 16:26:52 +01:00
|
|
|
EVENT_OFF(circuit->u.bc.t_send_lan_hello[0]);
|
|
|
|
EVENT_OFF(circuit->u.bc.t_send_lan_hello[1]);
|
|
|
|
EVENT_OFF(circuit->u.bc.t_run_dr[0]);
|
|
|
|
EVENT_OFF(circuit->u.bc.t_run_dr[1]);
|
|
|
|
EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[0]);
|
|
|
|
EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[1]);
|
2015-11-10 18:43:34 +01:00
|
|
|
circuit->lsp_regenerate_pending[0] = 0;
|
|
|
|
circuit->lsp_regenerate_pending[1] = 0;
|
2018-03-05 18:45:02 +01:00
|
|
|
|
2020-10-09 14:00:44 +02:00
|
|
|
_ISIS_CLEAR_FLAG(circuit->isis->circuit_ids_used,
|
2020-07-13 14:37:59 +02:00
|
|
|
circuit->circuit_id);
|
2018-03-05 18:45:02 +01:00
|
|
|
circuit->circuit_id = 0;
|
2004-09-10 22:48:21 +02:00
|
|
|
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_delete_adj(circuit->u.p2p.neighbor);
|
|
|
|
circuit->u.p2p.neighbor = NULL;
|
2022-12-25 16:26:52 +01:00
|
|
|
EVENT_OFF(circuit->u.p2p.t_send_p2p_hello);
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-09-15 22:46:15 +02:00
|
|
|
/*
|
|
|
|
* All adjacencies have to be gone, delete snmp list
|
|
|
|
* and reset snmpd idx generator
|
|
|
|
*/
|
|
|
|
if (circuit->snmp_adj_list != NULL)
|
|
|
|
list_delete(&circuit->snmp_adj_list);
|
|
|
|
|
|
|
|
circuit->snmp_adj_idx_gen = 0;
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* Cancel all active threads */
|
2022-12-25 16:26:52 +01:00
|
|
|
EVENT_OFF(circuit->t_send_csnp[0]);
|
|
|
|
EVENT_OFF(circuit->t_send_csnp[1]);
|
|
|
|
EVENT_OFF(circuit->t_send_psnp[0]);
|
|
|
|
EVENT_OFF(circuit->t_send_psnp[1]);
|
|
|
|
EVENT_OFF(circuit->t_read);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
fabricd: reimplement LSP transmission logic
Before this commit, isisd/fabricd maintained a bitfield for each LSP
to track the SRM bit for each circuit, which specifies whether an LSP
needs to be sent on that circuit. Every second, it would scan over all
LSPs in `lsp_tick` and queue them up for transmission accordingly.
This design has two drawbacks: a) it scales poorly b) it adds
unacceptable latency to the update process: each router takes a random
amount of time between 0 and 1 seconds to forward an update. In a
network with a diamter of 10, it might already take 10 seconds for an
update to traverse the network.
To mitigate this, a new design was chosen. Instead of tracking SRM in a
bitfield, have one tx_queue per circuit and declare that an LSP is in
that queue if and only if it would have SRM set for that circuit.
This way, we can track SRM similarly as we did before, however, on
insertion into the LSP queue, we can add a timer for (re)transmission,
alleviating the need for a periodic scan with LSP tick and reducing the
latency for forwarding of updates.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
2018-05-10 17:37:05 +02:00
|
|
|
if (circuit->tx_queue) {
|
|
|
|
isis_tx_queue_free(circuit->tx_queue);
|
|
|
|
circuit->tx_queue = NULL;
|
2017-10-03 01:42:22 +02:00
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* send one gratuitous hello to spead up convergence */
|
2018-07-17 21:14:54 +02:00
|
|
|
if (circuit->state == C_STATE_UP) {
|
|
|
|
if (circuit->is_type & IS_LEVEL_1)
|
|
|
|
send_hello(circuit, IS_LEVEL_1);
|
|
|
|
if (circuit->is_type & IS_LEVEL_2)
|
|
|
|
send_hello(circuit, IS_LEVEL_2);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->upadjcount[0] = 0;
|
|
|
|
circuit->upadjcount[1] = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* close the socket */
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->fd) {
|
|
|
|
close(circuit->fd);
|
|
|
|
circuit->fd = 0;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->rcv_stream != NULL) {
|
|
|
|
stream_free(circuit->rcv_stream);
|
|
|
|
circuit->rcv_stream = NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->snd_stream != NULL) {
|
|
|
|
stream_free(circuit->snd_stream);
|
|
|
|
circuit->snd_stream = NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-12-10 15:08:37 +01:00
|
|
|
event_cancel_event(master, circuit);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void circuit_update_nlpids(struct isis_circuit *circuit)
|
|
|
|
{
|
|
|
|
circuit->nlpids.count = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (circuit->ip_router) {
|
|
|
|
circuit->nlpids.nlpids[0] = NLPID_IP;
|
|
|
|
circuit->nlpids.count++;
|
|
|
|
}
|
|
|
|
if (circuit->ipv6_router) {
|
|
|
|
circuit->nlpids.nlpids[circuit->nlpids.count] = NLPID_IPV6;
|
|
|
|
circuit->nlpids.count++;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-23 16:51:07 +01:00
|
|
|
void isis_circuit_print_json(struct isis_circuit *circuit,
|
|
|
|
struct json_object *json, char detail)
|
|
|
|
{
|
|
|
|
int level;
|
|
|
|
json_object *iface_json, *ipv4_addr_json, *ipv6_link_json,
|
|
|
|
*ipv6_non_link_json, *hold_json, *lan_prio_json, *levels_json,
|
|
|
|
*level_json;
|
|
|
|
char buf_prx[INET6_BUFSIZ];
|
|
|
|
char buf[255];
|
|
|
|
|
|
|
|
snprintfrr(buf, sizeof(buf), "0x%x", circuit->circuit_id);
|
|
|
|
if (detail == ISIS_UI_LEVEL_BRIEF) {
|
|
|
|
iface_json = json_object_new_object();
|
|
|
|
json_object_object_add(json, "interface", iface_json);
|
|
|
|
json_object_string_add(iface_json, "name",
|
|
|
|
circuit->interface->name);
|
|
|
|
json_object_string_add(iface_json, "circuit-id", buf);
|
|
|
|
json_object_string_add(iface_json, "state",
|
|
|
|
circuit_state2string(circuit->state));
|
|
|
|
json_object_string_add(iface_json, "type",
|
|
|
|
circuit_type2string(circuit->circ_type));
|
|
|
|
json_object_string_add(iface_json, "level",
|
|
|
|
circuit_t2string(circuit->is_type));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (detail == ISIS_UI_LEVEL_DETAIL) {
|
|
|
|
struct listnode *node;
|
|
|
|
struct prefix *ip_addr;
|
|
|
|
|
|
|
|
iface_json = json_object_new_object();
|
|
|
|
json_object_object_add(json, "interface", iface_json);
|
|
|
|
json_object_string_add(iface_json, "name",
|
|
|
|
circuit->interface->name);
|
|
|
|
json_object_string_add(iface_json, "state",
|
|
|
|
circuit_state2string(circuit->state));
|
|
|
|
if (circuit->is_passive)
|
|
|
|
json_object_string_add(iface_json, "is-passive",
|
|
|
|
"passive");
|
|
|
|
else
|
|
|
|
json_object_string_add(iface_json, "is-passive",
|
|
|
|
"active");
|
|
|
|
json_object_string_add(iface_json, "circuit-id", buf);
|
|
|
|
json_object_string_add(iface_json, "type",
|
|
|
|
circuit_type2string(circuit->circ_type));
|
|
|
|
json_object_string_add(iface_json, "level",
|
|
|
|
circuit_t2string(circuit->is_type));
|
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
2023-01-26 17:47:04 +01:00
|
|
|
json_object_string_addf(iface_json, "snpa", "%pSY",
|
|
|
|
circuit->u.bc.snpa);
|
2022-02-23 16:51:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
levels_json = json_object_new_array();
|
|
|
|
json_object_object_add(iface_json, "levels", levels_json);
|
|
|
|
for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
|
|
|
|
if ((circuit->is_type & level) == 0)
|
|
|
|
continue;
|
|
|
|
level_json = json_object_new_object();
|
|
|
|
json_object_string_add(level_json, "level",
|
|
|
|
circuit_t2string(level));
|
|
|
|
if (circuit->area->newmetric)
|
|
|
|
json_object_int_add(level_json, "metric",
|
isisd: Show correct level information for `show isis interface detail json`
Having this configuration:
```
!
interface r1-eth0
ip address 10.0.0.1/30
ip router isis 1
isis priority 44 level-1
isis priority 88 level-2
isis csnp-interval 90 level-1
isis csnp-interval 99 level-2
isis psnp-interval 70 level-1
isis psnp-interval 50 level-2
isis hello-interval level-1 120
isis hello-interval level-2 150
!
interface r1-eth1
ip address 10.0.0.10/30
ip router isis 1
!
interface lo
ip address 192.0.2.1/32
ip router isis 1
isis passive
!
router isis 1
net 49.0000.0000.0000.0001.00
metric-style wide
```
Produces:
```
{
"areas":[
{
"area":"1",
"circuits":[
{
"circuit":2,
"interface":{
"name":"r1-eth0",
"state":"Up",
"is-passive":"active",
"circuit-id":"0x2",
"type":"lan",
"level":"L1L2",
"snpa":"6e28.9c92.da5e",
"levels":[
{
"level":"L1",
"metric":10,
"active-neighbors":1,
"hello-interval":120,
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90,
"psnp-interval":70,
"lan":{
"priority":44,
"is-dis":"no"
}
},
{
"level":"L2",
"metric":10,
"active-neighbors":1,
"hello-interval":120, <<<<<<<<<<<<<<<<<<
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90, <<<<<<<<<<<<<<<<<<
"psnp-interval":70, <<<<<<<<<<<<<<<<<<
"lan":{
"priority":44, <<<<<<<<<<<<<<<<<<
"is-dis":"no"
}
}
],
...
```
Fixes: 9fee4d4c6038ef6b14e9f509d6b04d189660c4cd ("isisd: Add json to show isis interface command.")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2024-12-30 09:31:44 +01:00
|
|
|
circuit->te_metric[level - 1]);
|
2022-02-23 16:51:07 +01:00
|
|
|
else
|
|
|
|
json_object_int_add(level_json, "metric",
|
isisd: Show correct level information for `show isis interface detail json`
Having this configuration:
```
!
interface r1-eth0
ip address 10.0.0.1/30
ip router isis 1
isis priority 44 level-1
isis priority 88 level-2
isis csnp-interval 90 level-1
isis csnp-interval 99 level-2
isis psnp-interval 70 level-1
isis psnp-interval 50 level-2
isis hello-interval level-1 120
isis hello-interval level-2 150
!
interface r1-eth1
ip address 10.0.0.10/30
ip router isis 1
!
interface lo
ip address 192.0.2.1/32
ip router isis 1
isis passive
!
router isis 1
net 49.0000.0000.0000.0001.00
metric-style wide
```
Produces:
```
{
"areas":[
{
"area":"1",
"circuits":[
{
"circuit":2,
"interface":{
"name":"r1-eth0",
"state":"Up",
"is-passive":"active",
"circuit-id":"0x2",
"type":"lan",
"level":"L1L2",
"snpa":"6e28.9c92.da5e",
"levels":[
{
"level":"L1",
"metric":10,
"active-neighbors":1,
"hello-interval":120,
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90,
"psnp-interval":70,
"lan":{
"priority":44,
"is-dis":"no"
}
},
{
"level":"L2",
"metric":10,
"active-neighbors":1,
"hello-interval":120, <<<<<<<<<<<<<<<<<<
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90, <<<<<<<<<<<<<<<<<<
"psnp-interval":70, <<<<<<<<<<<<<<<<<<
"lan":{
"priority":44, <<<<<<<<<<<<<<<<<<
"is-dis":"no"
}
}
],
...
```
Fixes: 9fee4d4c6038ef6b14e9f509d6b04d189660c4cd ("isisd: Add json to show isis interface command.")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2024-12-30 09:31:44 +01:00
|
|
|
circuit->metric[level - 1]);
|
2022-02-23 16:51:07 +01:00
|
|
|
if (!circuit->is_passive) {
|
isisd: Show correct level information for `show isis interface detail json`
Having this configuration:
```
!
interface r1-eth0
ip address 10.0.0.1/30
ip router isis 1
isis priority 44 level-1
isis priority 88 level-2
isis csnp-interval 90 level-1
isis csnp-interval 99 level-2
isis psnp-interval 70 level-1
isis psnp-interval 50 level-2
isis hello-interval level-1 120
isis hello-interval level-2 150
!
interface r1-eth1
ip address 10.0.0.10/30
ip router isis 1
!
interface lo
ip address 192.0.2.1/32
ip router isis 1
isis passive
!
router isis 1
net 49.0000.0000.0000.0001.00
metric-style wide
```
Produces:
```
{
"areas":[
{
"area":"1",
"circuits":[
{
"circuit":2,
"interface":{
"name":"r1-eth0",
"state":"Up",
"is-passive":"active",
"circuit-id":"0x2",
"type":"lan",
"level":"L1L2",
"snpa":"6e28.9c92.da5e",
"levels":[
{
"level":"L1",
"metric":10,
"active-neighbors":1,
"hello-interval":120,
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90,
"psnp-interval":70,
"lan":{
"priority":44,
"is-dis":"no"
}
},
{
"level":"L2",
"metric":10,
"active-neighbors":1,
"hello-interval":120, <<<<<<<<<<<<<<<<<<
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90, <<<<<<<<<<<<<<<<<<
"psnp-interval":70, <<<<<<<<<<<<<<<<<<
"lan":{
"priority":44, <<<<<<<<<<<<<<<<<<
"is-dis":"no"
}
}
],
...
```
Fixes: 9fee4d4c6038ef6b14e9f509d6b04d189660c4cd ("isisd: Add json to show isis interface command.")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2024-12-30 09:31:44 +01:00
|
|
|
json_object_int_add(level_json, "active-neighbors",
|
|
|
|
circuit->upadjcount[level - 1]);
|
|
|
|
json_object_int_add(level_json, "hello-interval",
|
|
|
|
circuit->hello_interval[level - 1]);
|
2022-02-23 16:51:07 +01:00
|
|
|
hold_json = json_object_new_object();
|
|
|
|
json_object_object_add(level_json, "holddown",
|
|
|
|
hold_json);
|
isisd: Show correct level information for `show isis interface detail json`
Having this configuration:
```
!
interface r1-eth0
ip address 10.0.0.1/30
ip router isis 1
isis priority 44 level-1
isis priority 88 level-2
isis csnp-interval 90 level-1
isis csnp-interval 99 level-2
isis psnp-interval 70 level-1
isis psnp-interval 50 level-2
isis hello-interval level-1 120
isis hello-interval level-2 150
!
interface r1-eth1
ip address 10.0.0.10/30
ip router isis 1
!
interface lo
ip address 192.0.2.1/32
ip router isis 1
isis passive
!
router isis 1
net 49.0000.0000.0000.0001.00
metric-style wide
```
Produces:
```
{
"areas":[
{
"area":"1",
"circuits":[
{
"circuit":2,
"interface":{
"name":"r1-eth0",
"state":"Up",
"is-passive":"active",
"circuit-id":"0x2",
"type":"lan",
"level":"L1L2",
"snpa":"6e28.9c92.da5e",
"levels":[
{
"level":"L1",
"metric":10,
"active-neighbors":1,
"hello-interval":120,
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90,
"psnp-interval":70,
"lan":{
"priority":44,
"is-dis":"no"
}
},
{
"level":"L2",
"metric":10,
"active-neighbors":1,
"hello-interval":120, <<<<<<<<<<<<<<<<<<
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90, <<<<<<<<<<<<<<<<<<
"psnp-interval":70, <<<<<<<<<<<<<<<<<<
"lan":{
"priority":44, <<<<<<<<<<<<<<<<<<
"is-dis":"no"
}
}
],
...
```
Fixes: 9fee4d4c6038ef6b14e9f509d6b04d189660c4cd ("isisd: Add json to show isis interface command.")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2024-12-30 09:31:44 +01:00
|
|
|
json_object_int_add(hold_json, "count",
|
|
|
|
circuit->hello_multiplier[level - 1]);
|
2022-02-23 16:51:07 +01:00
|
|
|
json_object_string_add(
|
|
|
|
hold_json, "pad",
|
2023-01-21 02:08:45 +01:00
|
|
|
isis_hello_padding2string(
|
|
|
|
circuit->pad_hellos));
|
2022-02-23 16:51:07 +01:00
|
|
|
json_object_int_add(level_json, "cnsp-interval",
|
isisd: Show correct level information for `show isis interface detail json`
Having this configuration:
```
!
interface r1-eth0
ip address 10.0.0.1/30
ip router isis 1
isis priority 44 level-1
isis priority 88 level-2
isis csnp-interval 90 level-1
isis csnp-interval 99 level-2
isis psnp-interval 70 level-1
isis psnp-interval 50 level-2
isis hello-interval level-1 120
isis hello-interval level-2 150
!
interface r1-eth1
ip address 10.0.0.10/30
ip router isis 1
!
interface lo
ip address 192.0.2.1/32
ip router isis 1
isis passive
!
router isis 1
net 49.0000.0000.0000.0001.00
metric-style wide
```
Produces:
```
{
"areas":[
{
"area":"1",
"circuits":[
{
"circuit":2,
"interface":{
"name":"r1-eth0",
"state":"Up",
"is-passive":"active",
"circuit-id":"0x2",
"type":"lan",
"level":"L1L2",
"snpa":"6e28.9c92.da5e",
"levels":[
{
"level":"L1",
"metric":10,
"active-neighbors":1,
"hello-interval":120,
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90,
"psnp-interval":70,
"lan":{
"priority":44,
"is-dis":"no"
}
},
{
"level":"L2",
"metric":10,
"active-neighbors":1,
"hello-interval":120, <<<<<<<<<<<<<<<<<<
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90, <<<<<<<<<<<<<<<<<<
"psnp-interval":70, <<<<<<<<<<<<<<<<<<
"lan":{
"priority":44, <<<<<<<<<<<<<<<<<<
"is-dis":"no"
}
}
],
...
```
Fixes: 9fee4d4c6038ef6b14e9f509d6b04d189660c4cd ("isisd: Add json to show isis interface command.")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2024-12-30 09:31:44 +01:00
|
|
|
circuit->csnp_interval[level - 1]);
|
2022-02-23 16:51:07 +01:00
|
|
|
json_object_int_add(level_json, "psnp-interval",
|
isisd: Show correct level information for `show isis interface detail json`
Having this configuration:
```
!
interface r1-eth0
ip address 10.0.0.1/30
ip router isis 1
isis priority 44 level-1
isis priority 88 level-2
isis csnp-interval 90 level-1
isis csnp-interval 99 level-2
isis psnp-interval 70 level-1
isis psnp-interval 50 level-2
isis hello-interval level-1 120
isis hello-interval level-2 150
!
interface r1-eth1
ip address 10.0.0.10/30
ip router isis 1
!
interface lo
ip address 192.0.2.1/32
ip router isis 1
isis passive
!
router isis 1
net 49.0000.0000.0000.0001.00
metric-style wide
```
Produces:
```
{
"areas":[
{
"area":"1",
"circuits":[
{
"circuit":2,
"interface":{
"name":"r1-eth0",
"state":"Up",
"is-passive":"active",
"circuit-id":"0x2",
"type":"lan",
"level":"L1L2",
"snpa":"6e28.9c92.da5e",
"levels":[
{
"level":"L1",
"metric":10,
"active-neighbors":1,
"hello-interval":120,
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90,
"psnp-interval":70,
"lan":{
"priority":44,
"is-dis":"no"
}
},
{
"level":"L2",
"metric":10,
"active-neighbors":1,
"hello-interval":120, <<<<<<<<<<<<<<<<<<
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90, <<<<<<<<<<<<<<<<<<
"psnp-interval":70, <<<<<<<<<<<<<<<<<<
"lan":{
"priority":44, <<<<<<<<<<<<<<<<<<
"is-dis":"no"
}
}
],
...
```
Fixes: 9fee4d4c6038ef6b14e9f509d6b04d189660c4cd ("isisd: Add json to show isis interface command.")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2024-12-30 09:31:44 +01:00
|
|
|
circuit->psnp_interval[level - 1]);
|
2022-02-23 16:51:07 +01:00
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
|
|
|
lan_prio_json =
|
|
|
|
json_object_new_object();
|
|
|
|
json_object_object_add(level_json,
|
|
|
|
"lan",
|
|
|
|
lan_prio_json);
|
isisd: Show correct level information for `show isis interface detail json`
Having this configuration:
```
!
interface r1-eth0
ip address 10.0.0.1/30
ip router isis 1
isis priority 44 level-1
isis priority 88 level-2
isis csnp-interval 90 level-1
isis csnp-interval 99 level-2
isis psnp-interval 70 level-1
isis psnp-interval 50 level-2
isis hello-interval level-1 120
isis hello-interval level-2 150
!
interface r1-eth1
ip address 10.0.0.10/30
ip router isis 1
!
interface lo
ip address 192.0.2.1/32
ip router isis 1
isis passive
!
router isis 1
net 49.0000.0000.0000.0001.00
metric-style wide
```
Produces:
```
{
"areas":[
{
"area":"1",
"circuits":[
{
"circuit":2,
"interface":{
"name":"r1-eth0",
"state":"Up",
"is-passive":"active",
"circuit-id":"0x2",
"type":"lan",
"level":"L1L2",
"snpa":"6e28.9c92.da5e",
"levels":[
{
"level":"L1",
"metric":10,
"active-neighbors":1,
"hello-interval":120,
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90,
"psnp-interval":70,
"lan":{
"priority":44,
"is-dis":"no"
}
},
{
"level":"L2",
"metric":10,
"active-neighbors":1,
"hello-interval":120, <<<<<<<<<<<<<<<<<<
"holddown":{
"count":10,
"pad":"yes"
},
"cnsp-interval":90, <<<<<<<<<<<<<<<<<<
"psnp-interval":70, <<<<<<<<<<<<<<<<<<
"lan":{
"priority":44, <<<<<<<<<<<<<<<<<<
"is-dis":"no"
}
}
],
...
```
Fixes: 9fee4d4c6038ef6b14e9f509d6b04d189660c4cd ("isisd: Add json to show isis interface command.")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2024-12-30 09:31:44 +01:00
|
|
|
json_object_int_add(lan_prio_json, "priority",
|
|
|
|
circuit->priority[level - 1]);
|
|
|
|
json_object_string_add(lan_prio_json, "is-dis",
|
|
|
|
(circuit->u.bc.is_dr[level - 1]
|
|
|
|
? "yes"
|
|
|
|
: "no"));
|
2022-02-23 16:51:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
json_object_array_add(levels_json, level_json);
|
|
|
|
}
|
|
|
|
|
2022-06-18 20:37:14 +02:00
|
|
|
if (listcount(circuit->ip_addrs) > 0) {
|
2022-02-23 16:51:07 +01:00
|
|
|
ipv4_addr_json = json_object_new_object();
|
|
|
|
json_object_object_add(iface_json, "ip-prefix",
|
|
|
|
ipv4_addr_json);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node,
|
|
|
|
ip_addr)) {
|
|
|
|
snprintfrr(buf_prx, INET6_BUFSIZ, "%pFX",
|
|
|
|
ip_addr);
|
|
|
|
json_object_string_add(ipv4_addr_json, "ip",
|
|
|
|
buf_prx);
|
|
|
|
}
|
|
|
|
}
|
2022-06-18 20:37:14 +02:00
|
|
|
if (listcount(circuit->ipv6_link) > 0) {
|
2022-02-23 16:51:07 +01:00
|
|
|
ipv6_link_json = json_object_new_object();
|
|
|
|
json_object_object_add(iface_json, "ipv6-link-locals",
|
|
|
|
ipv6_link_json);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
|
|
|
|
ip_addr)) {
|
|
|
|
snprintfrr(buf_prx, INET6_BUFSIZ, "%pFX",
|
|
|
|
ip_addr);
|
|
|
|
json_object_string_add(ipv6_link_json, "ipv6",
|
|
|
|
buf_prx);
|
|
|
|
}
|
|
|
|
}
|
2022-06-18 20:37:14 +02:00
|
|
|
if (listcount(circuit->ipv6_non_link) > 0) {
|
2022-02-23 16:51:07 +01:00
|
|
|
ipv6_non_link_json = json_object_new_object();
|
|
|
|
json_object_object_add(iface_json, "ipv6-prefixes",
|
|
|
|
ipv6_non_link_json);
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
|
|
|
|
ip_addr)) {
|
|
|
|
snprintfrr(buf_prx, INET6_BUFSIZ, "%pFX",
|
|
|
|
ip_addr);
|
|
|
|
json_object_string_add(ipv6_non_link_json,
|
|
|
|
"ipv6", buf_prx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
|
|
|
|
char detail)
|
|
|
|
{
|
|
|
|
if (detail == ISIS_UI_LEVEL_BRIEF) {
|
|
|
|
vty_out(vty, " %-12s", circuit->interface->name);
|
|
|
|
vty_out(vty, "0x%-7x", circuit->circuit_id);
|
|
|
|
vty_out(vty, "%-9s", circuit_state2string(circuit->state));
|
|
|
|
vty_out(vty, "%-9s", circuit_type2string(circuit->circ_type));
|
|
|
|
vty_out(vty, "%-9s", circuit_t2string(circuit->is_type));
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
if (detail == ISIS_UI_LEVEL_DETAIL) {
|
2015-11-10 18:33:13 +01:00
|
|
|
struct listnode *node;
|
|
|
|
struct prefix *ip_addr;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
vty_out(vty, " Interface: %s", circuit->interface->name);
|
|
|
|
vty_out(vty, ", State: %s",
|
|
|
|
circuit_state2string(circuit->state));
|
|
|
|
if (circuit->is_passive)
|
|
|
|
vty_out(vty, ", Passive");
|
|
|
|
else
|
|
|
|
vty_out(vty, ", Active");
|
|
|
|
vty_out(vty, ", Circuit Id: 0x%x", circuit->circuit_id);
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
vty_out(vty, " Type: %s",
|
|
|
|
circuit_type2string(circuit->circ_type));
|
|
|
|
vty_out(vty, ", Level: %s", circuit_t2string(circuit->is_type));
|
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
2023-01-26 17:47:04 +01:00
|
|
|
vty_out(vty, ", SNPA: %-10pSY", circuit->u.bc.snpa);
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->is_type & IS_LEVEL_1) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " Level-1 Information:\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->area->newmetric)
|
|
|
|
vty_out(vty, " Metric: %d",
|
|
|
|
circuit->te_metric[0]);
|
|
|
|
else
|
|
|
|
vty_out(vty, " Metric: %d",
|
2016-07-28 17:23:32 +02:00
|
|
|
circuit->metric[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
if (!circuit->is_passive) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, ", Active neighbors: %u\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->upadjcount[0]);
|
2017-07-13 18:50:29 +02:00
|
|
|
vty_out(vty,
|
2023-01-21 02:08:45 +01:00
|
|
|
" Hello interval: %u, Holddown count: %u, Padding: %s\n",
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->hello_interval[0],
|
|
|
|
circuit->hello_multiplier[0],
|
2023-01-21 02:08:45 +01:00
|
|
|
isis_hello_padding2string(
|
|
|
|
circuit->pad_hellos));
|
2017-07-13 18:50:29 +02:00
|
|
|
vty_out(vty,
|
2020-03-27 12:35:23 +01:00
|
|
|
" CNSP interval: %u, PSNP interval: %u\n",
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->csnp_interval[0],
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->psnp_interval[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
|
|
|
" LAN Priority: %u, %s\n",
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->priority[0],
|
2017-06-21 05:10:57 +02:00
|
|
|
(circuit->u.bc.is_dr[0]
|
|
|
|
? "is DIS"
|
|
|
|
: "is not DIS"));
|
2012-03-24 16:35:20 +01:00
|
|
|
} else {
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->is_type & IS_LEVEL_2) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " Level-2 Information:\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->area->newmetric)
|
|
|
|
vty_out(vty, " Metric: %d",
|
|
|
|
circuit->te_metric[1]);
|
|
|
|
else
|
|
|
|
vty_out(vty, " Metric: %d",
|
2016-07-28 17:23:32 +02:00
|
|
|
circuit->metric[1]);
|
2012-03-24 16:35:20 +01:00
|
|
|
if (!circuit->is_passive) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, ", Active neighbors: %u\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->upadjcount[1]);
|
2017-07-13 18:50:29 +02:00
|
|
|
vty_out(vty,
|
2023-01-21 02:08:45 +01:00
|
|
|
" Hello interval: %u, Holddown count: %u, Padding: %s\n",
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->hello_interval[1],
|
|
|
|
circuit->hello_multiplier[1],
|
2023-01-21 02:08:45 +01:00
|
|
|
isis_hello_padding2string(
|
|
|
|
circuit->pad_hellos));
|
2017-07-13 18:50:29 +02:00
|
|
|
vty_out(vty,
|
2020-03-27 12:35:23 +01:00
|
|
|
" CNSP interval: %u, PSNP interval: %u\n",
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->csnp_interval[1],
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->psnp_interval[1]);
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
|
|
|
" LAN Priority: %u, %s\n",
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->priority[1],
|
2017-06-21 05:10:57 +02:00
|
|
|
(circuit->u.bc.is_dr[1]
|
|
|
|
? "is DIS"
|
|
|
|
: "is not DIS"));
|
2012-03-24 16:35:20 +01:00
|
|
|
} else {
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2022-06-18 20:37:14 +02:00
|
|
|
if (listcount(circuit->ip_addrs) > 0) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " IP Prefix(es):\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node,
|
2020-10-18 13:33:54 +02:00
|
|
|
ip_addr))
|
|
|
|
vty_out(vty, " %pFX\n", ip_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2022-06-18 20:37:14 +02:00
|
|
|
if (listcount(circuit->ipv6_link) > 0) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " IPv6 Link-Locals:\n");
|
2015-11-10 18:33:13 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
|
2020-10-18 13:33:54 +02:00
|
|
|
ip_addr))
|
|
|
|
vty_out(vty, " %pFX\n", ip_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2022-06-18 20:37:14 +02:00
|
|
|
if (listcount(circuit->ipv6_non_link) > 0) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " IPv6 Prefixes:\n");
|
2015-11-10 18:33:13 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
|
2020-10-18 13:33:54 +02:00
|
|
|
ip_addr))
|
|
|
|
vty_out(vty, " %pFX\n", ip_addr);
|
2015-11-10 18:33:13 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-23 16:49:01 +02:00
|
|
|
#ifdef FABRICD
|
2018-09-28 15:39:01 +02:00
|
|
|
DEFINE_HOOK(isis_circuit_config_write,
|
|
|
|
(struct isis_circuit *circuit, struct vty *vty),
|
|
|
|
(circuit, vty));
|
|
|
|
|
2018-09-08 22:31:43 +02:00
|
|
|
static int isis_interface_config_write(struct vty *vty)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2017-10-03 03:06:01 +02:00
|
|
|
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
2003-12-23 09:09:43 +01:00
|
|
|
int write = 0;
|
|
|
|
struct interface *ifp;
|
2012-03-24 16:35:20 +01:00
|
|
|
struct isis_circuit *circuit;
|
2003-12-23 09:09:43 +01:00
|
|
|
int i;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-10-06 20:25:58 +02:00
|
|
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
2012-03-24 16:35:20 +01:00
|
|
|
/* IF name */
|
2022-01-23 22:07:20 +01:00
|
|
|
if_vty_config_start(vty, ifp);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
/* IF desc */
|
|
|
|
if (ifp->desc) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " description %s\n", ifp->desc);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
/* ISIS Circuit */
|
2021-11-02 13:22:23 +01:00
|
|
|
do {
|
|
|
|
circuit = circuit_scan_by_ifp(ifp);
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit == NULL)
|
2021-11-02 13:22:23 +01:00
|
|
|
break;
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->ip_router) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " ip router " PROTO_NAME " %s\n",
|
2021-11-02 13:22:23 +01:00
|
|
|
circuit->tag);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
if (circuit->is_passive) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " " PROTO_NAME " passive\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
if (circuit->circ_type_config == CIRCUIT_T_P2P) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " " PROTO_NAME " network point-to-point\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
if (circuit->ipv6_router) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " ipv6 router " PROTO_NAME " %s\n",
|
2021-11-02 13:22:23 +01:00
|
|
|
circuit->tag);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* ISIS - circuit type */
|
2018-03-22 14:58:53 +01:00
|
|
|
if (!fabricd) {
|
|
|
|
if (circuit->is_type == IS_LEVEL_1) {
|
|
|
|
vty_out(vty, " " PROTO_NAME " circuit-type level-1\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
2018-03-22 14:58:53 +01:00
|
|
|
} else {
|
|
|
|
if (circuit->is_type == IS_LEVEL_2) {
|
|
|
|
vty_out(vty,
|
|
|
|
" " PROTO_NAME " circuit-type level-2-only\n");
|
|
|
|
write++;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* ISIS - CSNP interval */
|
|
|
|
if (circuit->csnp_interval[0]
|
|
|
|
== circuit->csnp_interval[1]) {
|
|
|
|
if (circuit->csnp_interval[0]
|
|
|
|
!= DEFAULT_CSNP_INTERVAL) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " " PROTO_NAME " csnp-interval %d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->csnp_interval[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
if (circuit->csnp_interval[i]
|
|
|
|
!= DEFAULT_CSNP_INTERVAL) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
2018-03-22 15:01:08 +01:00
|
|
|
" " PROTO_NAME " csnp-interval %d level-%d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->csnp_interval
|
|
|
|
[i],
|
|
|
|
i + 1);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* ISIS - PSNP interval */
|
|
|
|
if (circuit->psnp_interval[0]
|
|
|
|
== circuit->psnp_interval[1]) {
|
|
|
|
if (circuit->psnp_interval[0]
|
|
|
|
!= DEFAULT_PSNP_INTERVAL) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " " PROTO_NAME " psnp-interval %d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->psnp_interval[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
if (circuit->psnp_interval[i]
|
|
|
|
!= DEFAULT_PSNP_INTERVAL) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
2018-03-22 15:01:08 +01:00
|
|
|
" " PROTO_NAME " psnp-interval %d level-%d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->psnp_interval
|
|
|
|
[i],
|
|
|
|
i + 1);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-01-21 02:08:45 +01:00
|
|
|
/* ISIS - Hello padding - Defaults to always so only
|
|
|
|
* display if not always */
|
|
|
|
switch (circuit->pad_hellos) {
|
|
|
|
case ISIS_HELLO_PADDING_DISABLED:
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " no " PROTO_NAME " hello padding\n");
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
2023-01-21 02:08:45 +01:00
|
|
|
break;
|
2023-01-26 18:29:51 +01:00
|
|
|
case ISIS_HELLO_PADDING_DURING_ADJACENCY_FORMATION:
|
2023-01-21 02:08:45 +01:00
|
|
|
vty_out(vty, PROTO_NAME
|
2023-01-26 18:29:51 +01:00
|
|
|
" hello padding during-adjacency-formation\n");
|
2023-01-21 02:08:45 +01:00
|
|
|
write++;
|
|
|
|
break;
|
|
|
|
case ISIS_HELLO_PADDING_ALWAYS:
|
|
|
|
break;
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-03-05 21:29:15 +01:00
|
|
|
if (circuit->disable_threeway_adj) {
|
|
|
|
vty_out(vty, " no isis three-way-handshake\n");
|
|
|
|
write++;
|
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* ISIS - Hello interval */
|
|
|
|
if (circuit->hello_interval[0]
|
|
|
|
== circuit->hello_interval[1]) {
|
|
|
|
if (circuit->hello_interval[0]
|
|
|
|
!= DEFAULT_HELLO_INTERVAL) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
2018-03-22 15:01:08 +01:00
|
|
|
" " PROTO_NAME " hello-interval %d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->hello_interval[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
if (circuit->hello_interval[i]
|
|
|
|
!= DEFAULT_HELLO_INTERVAL) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
2018-03-22 15:01:08 +01:00
|
|
|
" " PROTO_NAME " hello-interval %d level-%d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->hello_interval
|
|
|
|
[i],
|
|
|
|
i + 1);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* ISIS - Hello Multiplier */
|
|
|
|
if (circuit->hello_multiplier[0]
|
|
|
|
== circuit->hello_multiplier[1]) {
|
|
|
|
if (circuit->hello_multiplier[0]
|
|
|
|
!= DEFAULT_HELLO_MULTIPLIER) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
2018-03-22 15:01:08 +01:00
|
|
|
" " PROTO_NAME " hello-multiplier %d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->hello_multiplier[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
if (circuit->hello_multiplier[i]
|
|
|
|
!= DEFAULT_HELLO_MULTIPLIER) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
2018-03-22 15:01:08 +01:00
|
|
|
" " PROTO_NAME " hello-multiplier %d level-%d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->hello_multiplier
|
|
|
|
[i],
|
|
|
|
i + 1);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* ISIS - Priority */
|
|
|
|
if (circuit->priority[0] == circuit->priority[1]) {
|
|
|
|
if (circuit->priority[0] != DEFAULT_PRIORITY) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " " PROTO_NAME " priority %d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->priority[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
if (circuit->priority[i]
|
|
|
|
!= DEFAULT_PRIORITY) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
2018-03-22 15:01:08 +01:00
|
|
|
" " PROTO_NAME " priority %d level-%d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->priority[i],
|
|
|
|
i + 1);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
/* ISIS - Metric */
|
|
|
|
if (circuit->te_metric[0] == circuit->te_metric[1]) {
|
|
|
|
if (circuit->te_metric[0]
|
|
|
|
!= DEFAULT_CIRCUIT_METRIC) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " " PROTO_NAME " metric %d\n",
|
2017-07-13 17:49:13 +02:00
|
|
|
circuit->te_metric[0]);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
if (circuit->te_metric[i]
|
|
|
|
!= DEFAULT_CIRCUIT_METRIC) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
2018-03-22 15:01:08 +01:00
|
|
|
" " PROTO_NAME " metric %d level-%d\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->te_metric[i],
|
|
|
|
i + 1);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->passwd.type == ISIS_PASSWD_TYPE_HMAC_MD5) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " " PROTO_NAME " password md5 %s\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->passwd.passwd);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
} else if (circuit->passwd.type
|
|
|
|
== ISIS_PASSWD_TYPE_CLEARTXT) {
|
2018-03-22 15:01:08 +01:00
|
|
|
vty_out(vty, " " PROTO_NAME " password clear %s\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
circuit->passwd.passwd);
|
2012-03-24 16:35:20 +01:00
|
|
|
write++;
|
|
|
|
}
|
2021-05-06 13:44:05 +02:00
|
|
|
if (circuit->bfd_config.enabled) {
|
|
|
|
vty_out(vty, " " PROTO_NAME " bfd\n");
|
|
|
|
write++;
|
|
|
|
}
|
2018-10-12 16:45:32 +02:00
|
|
|
write += hook_call(isis_circuit_config_write,
|
|
|
|
circuit, vty);
|
2021-11-02 13:22:23 +01:00
|
|
|
} while (0);
|
2022-01-23 22:07:20 +01:00
|
|
|
if_vty_config_end(vty);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return write;
|
|
|
|
}
|
2018-11-14 14:50:53 +01:00
|
|
|
#endif /* ifdef FABRICD */
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2016-07-29 16:19:40 +02:00
|
|
|
void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
|
|
|
|
bool ipv6_router)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2016-07-29 16:19:40 +02:00
|
|
|
struct isis_area *area = circuit->area;
|
2020-06-10 14:29:02 +02:00
|
|
|
int old_ipr = circuit->ip_router;
|
|
|
|
int old_ipv6r = circuit->ipv6_router;
|
|
|
|
|
|
|
|
/* is there something to do? */
|
|
|
|
if (old_ipr == ip_router && old_ipv6r == ipv6_router)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-07-29 16:19:40 +02:00
|
|
|
circuit->ip_router = ip_router;
|
|
|
|
circuit->ipv6_router = ipv6_router;
|
2020-06-10 14:29:02 +02:00
|
|
|
circuit_update_nlpids(circuit);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
if (area) {
|
|
|
|
area->ip_circuits += ip_router - old_ipr;
|
|
|
|
area->ipv6_circuits += ipv6_router - old_ipv6r;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
if (ip_router || ipv6_router)
|
|
|
|
lsp_regenerate_schedule(area, circuit->is_type, 0);
|
|
|
|
}
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2016-03-31 17:18:14 +02:00
|
|
|
ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive)
|
2012-03-24 16:35:20 +01:00
|
|
|
{
|
2016-07-29 16:19:40 +02:00
|
|
|
if (circuit->is_passive == passive)
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_ok();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-11-16 16:01:03 +01:00
|
|
|
if (if_is_loopback(circuit->interface) && !passive)
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_cfg_invalid("loopback is always passive");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->state != C_STATE_UP) {
|
2016-07-29 16:19:40 +02:00
|
|
|
circuit->is_passive = passive;
|
2004-09-10 22:48:21 +02:00
|
|
|
} else {
|
2012-03-24 16:35:20 +01:00
|
|
|
struct isis_area *area = circuit->area;
|
|
|
|
isis_csm_state_change(ISIS_DISABLE, circuit, area);
|
2016-07-29 16:19:40 +02:00
|
|
|
circuit->is_passive = passive;
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_csm_state_change(ISIS_ENABLE, circuit, area);
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_ok();
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2016-03-31 17:18:14 +02:00
|
|
|
ferr_r isis_circuit_metric_set(struct isis_circuit *circuit, int level,
|
|
|
|
int metric)
|
2012-03-24 16:35:20 +01:00
|
|
|
{
|
2016-07-29 16:19:40 +02:00
|
|
|
assert(level == IS_LEVEL_1 || level == IS_LEVEL_2);
|
|
|
|
if (metric > MAX_WIDE_LINK_METRIC)
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_cfg_invalid("metric %d too large for wide metric",
|
|
|
|
metric);
|
2016-07-29 16:19:40 +02:00
|
|
|
if (circuit->area && circuit->area->oldmetric
|
|
|
|
&& metric > MAX_NARROW_LINK_METRIC)
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_cfg_invalid("metric %d too large for narrow metric",
|
|
|
|
metric);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-01-11 02:58:29 +01:00
|
|
|
/* Don't modify metric if advertise high metrics is configured */
|
|
|
|
if (circuit->area && circuit->area->advertise_high_metrics)
|
|
|
|
return ferr_ok();
|
|
|
|
|
2020-07-22 20:32:35 +02:00
|
|
|
/* inform ldp-sync of metric change
|
|
|
|
* if ldp-sync is running need to save metric
|
|
|
|
* and restore new values after ldp-sync completion.
|
|
|
|
*/
|
|
|
|
if (isis_ldp_sync_if_metric_config(circuit, level, metric)) {
|
|
|
|
circuit->te_metric[level - 1] = metric;
|
|
|
|
circuit->metric[level - 1] = metric;
|
|
|
|
if (circuit->area)
|
|
|
|
lsp_regenerate_schedule(circuit->area, level, 0);
|
|
|
|
}
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_ok();
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2016-03-31 17:18:14 +02:00
|
|
|
ferr_r isis_circuit_passwd_unset(struct isis_circuit *circuit)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2016-07-28 17:23:27 +02:00
|
|
|
memset(&circuit->passwd, 0, sizeof(circuit->passwd));
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_ok();
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
|
|
|
|
2019-02-26 20:48:12 +01:00
|
|
|
ferr_r isis_circuit_passwd_set(struct isis_circuit *circuit,
|
|
|
|
uint8_t passwd_type, const char *passwd)
|
2012-03-24 16:35:20 +01:00
|
|
|
{
|
|
|
|
int len;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2016-07-28 17:23:27 +02:00
|
|
|
if (!passwd)
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_code_bug("no circuit password given");
|
2016-07-28 17:23:27 +02:00
|
|
|
|
|
|
|
len = strlen(passwd);
|
2004-09-10 22:48:21 +02:00
|
|
|
if (len > 254)
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_code_bug(
|
|
|
|
"circuit password too long (max 254 chars)");
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2016-07-28 17:23:27 +02:00
|
|
|
circuit->passwd.len = len;
|
2019-02-26 20:48:12 +01:00
|
|
|
strlcpy((char *)circuit->passwd.passwd, passwd,
|
|
|
|
sizeof(circuit->passwd.passwd));
|
2016-07-28 17:23:27 +02:00
|
|
|
circuit->passwd.type = passwd_type;
|
2016-03-31 17:18:14 +02:00
|
|
|
return ferr_ok();
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2016-03-31 17:18:14 +02:00
|
|
|
ferr_r isis_circuit_passwd_cleartext_set(struct isis_circuit *circuit,
|
|
|
|
const char *passwd)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2016-07-28 17:23:27 +02:00
|
|
|
return isis_circuit_passwd_set(circuit, ISIS_PASSWD_TYPE_CLEARTXT,
|
|
|
|
passwd);
|
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2016-03-31 17:18:14 +02:00
|
|
|
ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit,
|
|
|
|
const char *passwd)
|
2016-07-28 17:23:27 +02:00
|
|
|
{
|
|
|
|
return isis_circuit_passwd_set(circuit, ISIS_PASSWD_TYPE_HMAC_MD5,
|
|
|
|
passwd);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
2016-03-31 17:18:14 +02:00
|
|
|
|
2018-11-14 14:35:43 +01:00
|
|
|
void isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type)
|
2012-03-24 16:35:20 +01:00
|
|
|
{
|
2016-03-31 17:18:14 +02:00
|
|
|
if (circuit->circ_type == circ_type)
|
2018-11-14 14:35:43 +01:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->state != C_STATE_UP) {
|
2016-07-29 16:19:40 +02:00
|
|
|
circuit->circ_type = circ_type;
|
|
|
|
circuit->circ_type_config = circ_type;
|
2012-03-24 16:35:20 +01:00
|
|
|
} else {
|
|
|
|
struct isis_area *area = circuit->area;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-07-29 16:19:40 +02:00
|
|
|
isis_csm_state_change(ISIS_DISABLE, circuit, area);
|
|
|
|
circuit->circ_type = circ_type;
|
|
|
|
circuit->circ_type_config = circ_type;
|
|
|
|
isis_csm_state_change(ISIS_ENABLE, circuit, area);
|
2012-03-24 16:35:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-27 13:56:35 +02:00
|
|
|
int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid,
|
|
|
|
bool enabled)
|
|
|
|
{
|
|
|
|
struct isis_circuit_mt_setting *setting;
|
|
|
|
|
|
|
|
setting = circuit_get_mt_setting(circuit, mtid);
|
|
|
|
if (setting->enabled != enabled) {
|
|
|
|
setting->enabled = enabled;
|
2021-04-28 00:57:21 +02:00
|
|
|
if (circuit->area)
|
|
|
|
lsp_regenerate_schedule(circuit->area,
|
|
|
|
IS_LEVEL_1 | IS_LEVEL_2, 0);
|
2017-04-27 13:56:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
int isis_if_new_hook(struct interface *ifp)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int isis_if_delete_hook(struct interface *ifp)
|
|
|
|
{
|
2021-04-28 00:57:21 +02:00
|
|
|
if (ifp->info)
|
|
|
|
isis_circuit_del(ifp->info);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-09-18 22:20:04 +02:00
|
|
|
static int isis_ifp_create(struct interface *ifp)
|
|
|
|
{
|
2021-04-28 00:57:21 +02:00
|
|
|
struct isis_circuit *circuit = ifp->info;
|
|
|
|
|
|
|
|
if (circuit)
|
|
|
|
isis_circuit_enable(circuit);
|
2020-08-18 09:26:51 +02:00
|
|
|
|
2019-09-19 04:26:55 +02:00
|
|
|
hook_call(isis_if_new_hook, ifp);
|
|
|
|
|
2019-09-18 22:20:04 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int isis_ifp_up(struct interface *ifp)
|
|
|
|
{
|
2021-04-28 00:57:21 +02:00
|
|
|
struct isis_circuit *circuit = ifp->info;
|
|
|
|
|
2022-05-20 15:29:21 +02:00
|
|
|
if (circuit) {
|
|
|
|
UNSET_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z);
|
2021-04-28 00:57:21 +02:00
|
|
|
isis_csm_state_change(IF_UP_FROM_Z, circuit, ifp);
|
2022-05-20 15:29:21 +02:00
|
|
|
}
|
2019-09-19 05:07:44 +02:00
|
|
|
|
2023-09-03 08:54:57 +02:00
|
|
|
/* Notify SRv6 that the interface went up */
|
|
|
|
isis_srv6_ifp_up_notify(ifp);
|
|
|
|
|
2019-09-18 22:20:04 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int isis_ifp_down(struct interface *ifp)
|
|
|
|
{
|
2022-05-20 15:28:59 +02:00
|
|
|
afi_t afi;
|
2021-04-28 00:57:21 +02:00
|
|
|
struct isis_circuit *circuit = ifp->info;
|
|
|
|
|
2022-04-13 10:19:18 +02:00
|
|
|
if (circuit &&
|
|
|
|
!CHECK_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z)) {
|
2022-05-20 15:29:21 +02:00
|
|
|
SET_FLAG(circuit->flags, ISIS_CIRCUIT_IF_DOWN_FROM_Z);
|
2022-05-20 15:28:59 +02:00
|
|
|
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
|
|
|
|
isis_circuit_switchover_routes(
|
|
|
|
circuit, afi == AFI_IP ? AF_INET : AF_INET6,
|
|
|
|
NULL, ifp->ifindex);
|
2021-04-28 00:57:21 +02:00
|
|
|
isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
|
2019-09-19 05:55:34 +02:00
|
|
|
|
|
|
|
SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
|
2021-04-28 00:57:21 +02:00
|
|
|
}
|
2019-09-19 05:55:34 +02:00
|
|
|
|
2019-09-18 22:20:04 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int isis_ifp_destroy(struct interface *ifp)
|
|
|
|
{
|
2021-04-28 00:57:21 +02:00
|
|
|
struct isis_circuit *circuit = ifp->info;
|
2019-09-19 15:40:57 +02:00
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
if (circuit)
|
|
|
|
isis_circuit_disable(circuit);
|
2019-09-19 15:40:57 +02:00
|
|
|
|
2019-09-18 22:20:04 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2025-03-05 11:18:36 +01:00
|
|
|
/* Reset IS hello timer after interval change */
|
|
|
|
void isis_reset_hello_timer(struct isis_circuit *circuit)
|
|
|
|
{
|
|
|
|
/* First send an immediate hello to prevent adjacency loss
|
|
|
|
* during longer hello interval transitions
|
|
|
|
*/
|
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
|
|
|
/* For broadcast circuits - need to handle both levels */
|
|
|
|
if (circuit->is_type & IS_LEVEL_1) {
|
|
|
|
/* send hello immediately */
|
|
|
|
send_hello(circuit, IS_LEVEL_1);
|
|
|
|
|
|
|
|
/* reset level-1 hello timer */
|
|
|
|
EVENT_OFF(circuit->u.bc.t_send_lan_hello[0]);
|
|
|
|
if (circuit->area && (circuit->area->is_type & IS_LEVEL_1))
|
|
|
|
send_hello_sched(circuit, IS_LEVEL_1,
|
|
|
|
isis_jitter(circuit->hello_interval[0],
|
|
|
|
IIH_JITTER));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (circuit->is_type & IS_LEVEL_2) {
|
|
|
|
/* send hello immediately */
|
|
|
|
send_hello(circuit, IS_LEVEL_2);
|
|
|
|
|
|
|
|
/* reset level-2 hello timer */
|
|
|
|
EVENT_OFF(circuit->u.bc.t_send_lan_hello[1]);
|
|
|
|
if (circuit->area && (circuit->area->is_type & IS_LEVEL_2))
|
|
|
|
send_hello_sched(circuit, IS_LEVEL_2,
|
|
|
|
isis_jitter(circuit->hello_interval[1],
|
|
|
|
IIH_JITTER));
|
|
|
|
}
|
|
|
|
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
|
|
|
|
/* For point-to-point circuits */
|
|
|
|
send_hello(circuit, IS_LEVEL_1);
|
|
|
|
|
|
|
|
/* reset hello timer */
|
|
|
|
EVENT_OFF(circuit->u.p2p.t_send_p2p_hello);
|
|
|
|
send_hello_sched(circuit, 0, isis_jitter(circuit->hello_interval[0], IIH_JITTER));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-24 10:12:36 +01:00
|
|
|
void isis_circuit_init(void)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
/* Initialize Zebra interface data structure */
|
2017-08-08 10:50:43 +02:00
|
|
|
hook_register_prio(if_add, 0, isis_if_new_hook);
|
|
|
|
hook_register_prio(if_del, 0, isis_if_delete_hook);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* Install interface node */
|
2021-10-13 17:30:06 +02:00
|
|
|
#ifdef FABRICD
|
2021-07-29 20:34:56 +02:00
|
|
|
if_cmd_init(isis_interface_config_write);
|
2021-10-13 17:30:06 +02:00
|
|
|
#else
|
|
|
|
if_cmd_init_default();
|
|
|
|
#endif
|
2023-11-02 21:49:28 +01:00
|
|
|
hook_register_prio(if_real, 0, isis_ifp_create);
|
|
|
|
hook_register_prio(if_up, 0, isis_ifp_up);
|
|
|
|
hook_register_prio(if_down, 0, isis_ifp_down);
|
|
|
|
hook_register_prio(if_unreal, 0, isis_ifp_destroy);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|