summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am10
-rw-r--r--bgpd/bgp_conditional_adv.c2
-rw-r--r--bgpd/bgp_evpn.c6
-rw-r--r--bgpd/bgp_filter.c83
-rw-r--r--bgpd/bgp_io.c9
-rw-r--r--bgpd/bgp_nb.c2
-rw-r--r--bgpd/bgp_nb_config.c2
-rw-r--r--bgpd/bgp_network.c2
-rw-r--r--bgpd/bgp_packet.c201
-rw-r--r--bgpd/bgp_pbr.c1
-rw-r--r--bgpd/bgp_routemap_nb.c2
-rw-r--r--bgpd/bgp_routemap_nb_config.c2
-rw-r--r--bgpd/bgp_trace.c2
-rw-r--r--bgpd/bgp_zebra.c2
-rw-r--r--bgpd/bgpd.h4
-rw-r--r--configure.ac2
-rw-r--r--doc/developer/building-frr-for-openbsd6.rst17
-rw-r--r--doc/developer/lists.rst10
-rw-r--r--doc/user/basic.rst6
-rw-r--r--doc/user/bgp.rst37
-rw-r--r--doc/user/isisd.rst9
-rw-r--r--doc/user/kernel.rst20
-rw-r--r--doc/user/pim.rst50
-rw-r--r--eigrpd/eigrp_metric.c2
-rw-r--r--eigrpd/eigrp_packet.c11
-rw-r--r--isisd/isis_circuit.c223
-rw-r--r--isisd/isis_circuit.h9
-rw-r--r--isisd/isis_cli.c453
-rw-r--r--isisd/isis_csm.c94
-rw-r--r--isisd/isis_ldp_sync.c315
-rw-r--r--isisd/isis_ldp_sync.h11
-rw-r--r--isisd/isis_lfa.c14
-rw-r--r--isisd/isis_nb.c19
-rw-r--r--isisd/isis_nb.h5
-rw-r--r--isisd/isis_nb_config.c445
-rw-r--r--isisd/isis_snmp.c74
-rw-r--r--isisd/isis_vty_fabricd.c12
-rw-r--r--isisd/isis_zebra.c4
-rw-r--r--isisd/isisd.c160
-rw-r--r--isisd/isisd.h16
-rw-r--r--ldpd/lde.c24
-rw-r--r--ldpd/lde.h1
-rw-r--r--ldpd/ldp_vty.h1
-rw-r--r--ldpd/ldp_vty_cmds.c11
-rw-r--r--ldpd/ldp_vty_conf.c16
-rw-r--r--ldpd/ldp_zebra.c14
-rw-r--r--ldpd/ldpd.c10
-rw-r--r--ldpd/ldpd.h3
-rw-r--r--lib/assert/assert.h98
-rw-r--r--lib/clippy.c14
-rw-r--r--lib/compiler.h6
-rw-r--r--lib/filter.c117
-rw-r--r--lib/filter.h7
-rw-r--r--lib/libfrr_trace.c2
-rw-r--r--lib/link_state.c2
-rw-r--r--lib/linklist.c17
-rw-r--r--lib/linklist.h13
-rw-r--r--lib/log.c11
-rw-r--r--lib/log.h2
-rw-r--r--lib/log_vty.c13
-rw-r--r--lib/plist.c75
-rw-r--r--lib/plist_int.h4
-rw-r--r--lib/printfrr.h2
-rw-r--r--lib/ringbuf.c35
-rw-r--r--lib/ringbuf.h11
-rw-r--r--lib/routemap_northbound.c11
-rw-r--r--lib/routing_nb.c2
-rw-r--r--lib/routing_nb_config.c2
-rw-r--r--lib/subdir.am5
-rw-r--r--lib/thread.c7
-rw-r--r--lib/typerb.h1
-rw-r--r--lib/typesafe.h71
-rw-r--r--lib/xref.h1
-rw-r--r--lib/zassert.h45
-rw-r--r--lib/zclient.c2
-rw-r--r--lib/zclient.h2
-rw-r--r--lib/zebra.h2
-rw-r--r--lib/zlog.c45
-rw-r--r--lib/zlog.h5
-rw-r--r--nhrpd/nhrp_cache.c2
-rw-r--r--nhrpd/zbuf.c4
-rw-r--r--nhrpd/zbuf.h1
-rw-r--r--ospf6d/ospf6_interface.c19
-rw-r--r--ospf6d/ospf6_route.c61
-rw-r--r--ospf6d/ospf6_routemap_nb.c2
-rw-r--r--ospf6d/ospf6_routemap_nb_config.c2
-rw-r--r--ospfd/ospf_asbr.c29
-rw-r--r--ospfd/ospf_routemap_nb.c2
-rw-r--r--ospfd/ospf_routemap_nb_config.c2
-rw-r--r--ospfd/ospf_te.c9
-rw-r--r--ospfd/ospf_vty.c25
-rw-r--r--pathd/path_cli.c2
-rw-r--r--pathd/path_debug.c2
-rw-r--r--pathd/path_pcep_config.c2
-rw-r--r--pathd/path_pcep_debug.c2
-rw-r--r--pathd/path_zebra.c2
-rw-r--r--pbrd/pbr_zebra.c4
-rw-r--r--pceplib/pcep_msg_messages.c4
-rw-r--r--pceplib/pcep_msg_messages_encoding.c4
-rw-r--r--pceplib/pcep_msg_object_error_types.c4
-rw-r--r--pceplib/pcep_msg_objects.c4
-rw-r--r--pceplib/pcep_msg_objects_encoding.c4
-rw-r--r--pceplib/pcep_msg_tlvs.c4
-rw-r--r--pceplib/pcep_msg_tools.c4
-rw-r--r--pceplib/pcep_session_logic.c4
-rw-r--r--pceplib/pcep_session_logic_counters.c4
-rw-r--r--pceplib/pcep_session_logic_loop.c4
-rw-r--r--pceplib/pcep_session_logic_states.c4
-rw-r--r--pceplib/pcep_socket_comm_loop.c4
-rw-r--r--pceplib/pcep_socket_comm_mock.c4
-rw-r--r--pceplib/pcep_timers.c4
-rw-r--r--pceplib/pcep_timers_event_loop.c4
-rw-r--r--pceplib/pcep_utils_double_linked_list.c4
-rw-r--r--pceplib/pcep_utils_logging.c4
-rw-r--r--pceplib/pcep_utils_memory.c4
-rw-r--r--pceplib/pcep_utils_ordered_list.c4
-rw-r--r--pceplib/pcep_utils_queue.c4
-rw-r--r--pceplib/test/pcep_msg_messages_test.c4
-rw-r--r--pceplib/test/pcep_msg_messages_tests.c4
-rw-r--r--pceplib/test/pcep_msg_object_error_types_test.c4
-rw-r--r--pceplib/test/pcep_msg_objects_test.c4
-rw-r--r--pceplib/test/pcep_msg_tools_test.c4
-rw-r--r--pceplib/test/pcep_pcc_api_test.c4
-rw-r--r--pceplib/test/pcep_pcc_api_tests.c4
-rw-r--r--pceplib/test/pcep_session_logic_loop_test.c4
-rw-r--r--pceplib/test/pcep_session_logic_states_test.c4
-rw-r--r--pceplib/test/pcep_session_logic_test.c4
-rw-r--r--pceplib/test/pcep_session_logic_tests.c4
-rw-r--r--pceplib/test/pcep_socket_comm_loop_test.c4
-rw-r--r--pceplib/test/pcep_socket_comm_test.c4
-rw-r--r--pceplib/test/pcep_socket_comm_tests.c4
-rw-r--r--pceplib/test/pcep_timers_event_loop_test.c4
-rw-r--r--pceplib/test/pcep_timers_test.c4
-rw-r--r--pceplib/test/pcep_timers_tests.c4
-rw-r--r--pceplib/test/pcep_utils_counters_test.c4
-rw-r--r--pceplib/test/pcep_utils_double_linked_list_test.c4
-rw-r--r--pceplib/test/pcep_utils_memory_test.c4
-rw-r--r--pceplib/test/pcep_utils_ordered_list_test.c4
-rw-r--r--pceplib/test/pcep_utils_queue_test.c4
-rw-r--r--pceplib/test/pcep_utils_tests.c4
-rw-r--r--pimd/pim_assert.c2
-rw-r--r--pimd/pim_bsm.c173
-rw-r--r--pimd/pim_bsm.h43
-rw-r--r--pimd/pim_cmd.c658
-rw-r--r--pimd/pim_hello.c8
-rw-r--r--pimd/pim_iface.c42
-rw-r--r--pimd/pim_ifchannel.c10
-rw-r--r--pimd/pim_igmp.c46
-rw-r--r--pimd/pim_igmpv2.c2
-rw-r--r--pimd/pim_igmpv3.c52
-rw-r--r--pimd/pim_join.c4
-rw-r--r--pimd/pim_msdp.c20
-rw-r--r--pimd/pim_msdp.h2
-rw-r--r--pimd/pim_nb_config.c28
-rw-r--r--pimd/pim_neighbor.c32
-rw-r--r--pimd/pim_oil.c4
-rw-r--r--pimd/pim_pim.c16
-rw-r--r--pimd/pim_rp.c2
-rw-r--r--pimd/pim_ssmpingd.c6
-rw-r--r--pimd/pim_time.c6
-rw-r--r--pimd/pim_tlv.c2
-rw-r--r--pimd/pim_vty.c1
-rw-r--r--pimd/pim_zebra.c4
-rw-r--r--pimd/pim_zlookup.c3
-rw-r--r--pimd/pimd.c2
-rw-r--r--python/firstheader.py92
-rw-r--r--qpb/subdir.am1
-rw-r--r--sharpd/sharp_vty.c4
-rw-r--r--staticd/static_nb.c2
-rw-r--r--staticd/static_nb_config.c2
-rw-r--r--tests/.gitignore3
-rw-r--r--tests/isisd/test_isis_spf.c1
-rw-r--r--tests/lib/cxxcompat.c1
-rw-r--r--tests/lib/test_assert.c64
-rw-r--r--tests/lib/test_assert.py56
-rw-r--r--tests/lib/test_ringbuf.c2
-rw-r--r--tests/lib/test_seqlock.c3
-rw-r--r--tests/lib/test_typelist.h126
-rw-r--r--tests/subdir.am8
-rw-r--r--tests/topotests/Dockerfile1
-rw-r--r--tests/topotests/all-protocol-startup/r1/show_ip_ospf_interface.ref2
-rw-r--r--tests/topotests/bgp-default-ipv4-ipv6-unicast/test_bgp-default-ipv4-ipv6-unicast.py2
-rw-r--r--tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py2
-rwxr-xr-xtests/topotests/conftest.py1
-rwxr-xr-xtests/topotests/isis-snmp/test_isis_snmp.py33
-rw-r--r--tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py6
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref2
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref2
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref2
-rw-r--r--tests/topotests/lib/pim.py60
-rw-r--r--tests/topotests/lib/topotest.py4
-rw-r--r--tools/subdir.am2
-rw-r--r--yang/frr-isisd.yang22
-rw-r--r--zebra/connected.c47
-rw-r--r--zebra/debug.c65
-rw-r--r--zebra/if_netlink.c5
-rw-r--r--zebra/interface.c13
-rw-r--r--zebra/interface.h2
-rw-r--r--zebra/redistribute.c12
-rw-r--r--zebra/rtadv.c13
-rw-r--r--zebra/zebra_evpn_mh.c13
-rw-r--r--zebra/zebra_mroute.c2
-rw-r--r--zebra/zebra_routemap_nb.c2
-rw-r--r--zebra/zebra_vxlan.c2
-rw-r--r--zebra/zserv.c1
205 files changed, 2640 insertions, 2613 deletions
diff --git a/Makefile.am b/Makefile.am
index e4149b62ed..a5101df2f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,11 +11,19 @@ AM_CFLAGS = \
$(SAN_FLAGS) \
$(WERROR) \
# end
-AM_CPPFLAGS = \
+
+# CPPFLAGS_BASE does not contain the include path for overriding assert.h,
+# therefore should be used in tools that do *not* link libfrr or do not want
+# assert() overridden
+CPPFLAGS_BASE = \
-I$(top_srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/lib \
-I$(top_builddir) \
$(LUA_INCLUDE) \
# end
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/lib/assert \
+ $(CPPFLAGS_BASE) \
+ # end
AM_LDFLAGS = \
-export-dynamic \
$(AC_LDFLAGS) \
diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c
index b9ea26e862..6e80765f86 100644
--- a/bgpd/bgp_conditional_adv.c
+++ b/bgpd/bgp_conditional_adv.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "bgpd/bgp_conditional_adv.h"
#include "bgpd/bgp_vty.h"
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index a9fceb6cde..047b9742ee 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -586,7 +586,7 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
uint8_t flags, uint32_t seq, esi_t *esi)
{
struct stream *s;
- int ipa_len;
+ uint16_t ipa_len;
static struct in_addr zero_remote_vtep_ip;
/* Check socket. */
@@ -614,11 +614,11 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
stream_put(s, &p->prefix.macip_addr.mac.octet, ETH_ALEN); /* Mac Addr */
/* IP address length and IP address, if any. */
if (is_evpn_prefix_ipaddr_none(p))
- stream_putl(s, 0);
+ stream_putw(s, 0);
else {
ipa_len = is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BYTELEN
: IPV6_MAX_BYTELEN;
- stream_putl(s, ipa_len);
+ stream_putw(s, ipa_len);
stream_put(s, &p->prefix.macip_addr.ip.ip.addr, ipa_len);
}
/* If the ESI is valid that becomes the nexthop; tape out the
diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c
index 5d1a7a98d7..8d6691945f 100644
--- a/bgpd/bgp_filter.c
+++ b/bgpd/bgp_filter.c
@@ -40,9 +40,6 @@ struct as_list_list {
/* AS path filter master. */
struct as_list_master {
- /* List of access_list which name is number. */
- struct as_list_list num;
-
/* List of access_list which name is string. */
struct as_list_list str;
@@ -71,8 +68,6 @@ struct as_filter {
struct as_list {
char *name;
- enum access_type type;
-
struct as_list *next;
struct as_list *prev;
@@ -115,7 +110,6 @@ static struct as_filter *bgp_aslist_seq_check(struct as_list *list, int64_t seq)
/* as-path access-list 10 permit AS1. */
static struct as_list_master as_list_master = {{NULL, NULL},
- {NULL, NULL},
NULL,
NULL};
@@ -237,10 +231,6 @@ struct as_list *as_list_lookup(const char *name)
if (name == NULL)
return NULL;
- for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
- if (strcmp(aslist->name, name) == 0)
- return aslist;
-
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
if (strcmp(aslist->name, name) == 0)
return aslist;
@@ -263,8 +253,6 @@ static void as_list_free(struct as_list *aslist)
the name. */
static struct as_list *as_list_insert(const char *name)
{
- size_t i;
- long number;
struct as_list *aslist;
struct as_list *point;
struct as_list_list *list;
@@ -274,36 +262,13 @@ static struct as_list *as_list_insert(const char *name)
aslist->name = XSTRDUP(MTYPE_AS_STR, name);
assert(aslist->name);
- /* If name is made by all digit character. We treat it as
- number. */
- for (number = 0, i = 0; i < strlen(name); i++) {
- if (isdigit((unsigned char)name[i]))
- number = (number * 10) + (name[i] - '0');
- else
- break;
- }
-
- /* In case of name is all digit character */
- if (i == strlen(name)) {
- aslist->type = ACCESS_TYPE_NUMBER;
-
- /* Set access_list to number list. */
- list = &as_list_master.num;
-
- for (point = list->head; point; point = point->next)
- if (atol(point->name) >= number)
- break;
- } else {
- aslist->type = ACCESS_TYPE_STRING;
-
- /* Set access_list to string list. */
- list = &as_list_master.str;
+ /* Set access_list to string list. */
+ list = &as_list_master.str;
- /* Set point to insertion point. */
- for (point = list->head; point; point = point->next)
- if (strcmp(point->name, name) >= 0)
- break;
- }
+ /* Set point to insertion point. */
+ for (point = list->head; point; point = point->next)
+ if (strcmp(point->name, name) >= 0)
+ break;
/* In case of this is the first element of master. */
if (list->head == NULL) {
@@ -371,10 +336,7 @@ static void as_list_delete(struct as_list *aslist)
as_filter_free(filter);
}
- if (aslist->type == ACCESS_TYPE_NUMBER)
- list = &as_list_master.num;
- else
- list = &as_list_master.str;
+ list = &as_list_master.str;
if (aslist->next)
aslist->next->prev = aslist->prev;
@@ -667,17 +629,6 @@ static void as_list_show_all(struct vty *vty)
struct as_list *aslist;
struct as_filter *asfilter;
- for (aslist = as_list_master.num.head; aslist; aslist = aslist->next) {
- vty_out(vty, "AS path access list %s\n", aslist->name);
-
- for (asfilter = aslist->head; asfilter;
- asfilter = asfilter->next) {
- vty_out(vty, " %s %s\n",
- filter_type_str(asfilter->type),
- asfilter->reg_str);
- }
- }
-
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next) {
vty_out(vty, "AS path access list %s\n", aslist->name);
@@ -740,18 +691,6 @@ static int config_write_as_list(struct vty *vty)
struct as_filter *asfilter;
int write = 0;
- for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
- for (asfilter = aslist->head; asfilter;
- asfilter = asfilter->next) {
- vty_out(vty,
- "bgp as-path access-list %s seq %" PRId64
- " %s %s\n",
- aslist->name, asfilter->seq,
- filter_type_str(asfilter->type),
- asfilter->reg_str);
- write++;
- }
-
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
@@ -794,19 +733,11 @@ void bgp_filter_reset(void)
struct as_list *aslist;
struct as_list *next;
- for (aslist = as_list_master.num.head; aslist; aslist = next) {
- next = aslist->next;
- as_list_delete(aslist);
- }
-
for (aslist = as_list_master.str.head; aslist; aslist = next) {
next = aslist->next;
as_list_delete(aslist);
}
- assert(as_list_master.num.head == NULL);
- assert(as_list_master.num.tail == NULL);
-
assert(as_list_master.str.head == NULL);
assert(as_list_master.str.tail == NULL);
}
diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c
index c2d8cae580..e9b0f9e46a 100644
--- a/bgpd/bgp_io.c
+++ b/bgpd/bgp_io.c
@@ -32,7 +32,6 @@
#include "stream.h" // for stream_get_endp, stream_getw_from, str...
#include "ringbuf.h" // for ringbuf_remain, ringbuf_peek, ringbuf_...
#include "thread.h" // for THREAD_OFF, THREAD_ARG, thread...
-#include "zassert.h" // for assert
#include "bgpd/bgp_io.h"
#include "bgpd/bgp_debug.h" // for bgp_debug_neighbor_events, bgp_type_str
@@ -462,10 +461,13 @@ done : {
*/
static uint16_t bgp_read(struct peer *peer, int *code_p)
{
+ size_t readsize; // how many bytes we want to read
ssize_t nbytes; // how many bytes we actually read
uint16_t status = 0;
- nbytes = ringbuf_read(peer->ibuf_work, peer->fd);
+ readsize =
+ MIN(ringbuf_space(peer->ibuf_work), sizeof(peer->ibuf_scratch));
+ nbytes = read(peer->fd, peer->ibuf_scratch, readsize);
/* EAGAIN or EWOULDBLOCK; come back later */
if (nbytes < 0 && ERRNO_IO_RETRY(errno)) {
@@ -493,6 +495,9 @@ static uint16_t bgp_read(struct peer *peer, int *code_p)
*code_p = TCP_connection_closed;
SET_FLAG(status, BGP_IO_FATAL_ERR);
+ } else {
+ assert(ringbuf_put(peer->ibuf_work, peer->ibuf_scratch, nbytes)
+ == (size_t)nbytes);
}
return status;
diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c
index 2547439499..21810b634d 100644
--- a/bgpd/bgp_nb.c
+++ b/bgpd/bgp_nb.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "northbound.h"
#include "libfrr.h"
#include "bgpd/bgp_nb.h"
diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c
index 307fa4e9bc..ff2c8ce93e 100644
--- a/bgpd/bgp_nb_config.c
+++ b/bgpd/bgp_nb_config.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "northbound.h"
#include "libfrr.h"
#include "log.h"
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 8d9024e07c..55d7a29d98 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -376,7 +376,6 @@ static int bgp_accept(struct thread *thread)
accept_sock);
return -1;
}
- listener->thread = NULL;
thread_add_read(bm->master, bgp_accept, listener, accept_sock,
&listener->thread);
@@ -838,7 +837,6 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
listener->bgp = bgp;
memcpy(&listener->su, sa, salen);
- listener->thread = NULL;
thread_add_read(bm->master, bgp_accept, listener, sock,
&listener->thread);
listnode_add(bm->listen_sockets, listener);
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 24df324633..d79621a749 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1000,98 +1000,90 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id)
{
struct peer *peer;
- /* Upon receipt of an OPEN message, the local system must examine
- all of its connections that are in the OpenConfirm state. A BGP
- speaker may also examine connections in an OpenSent state if it
- knows the BGP Identifier of the peer by means outside of the
- protocol. If among these connections there is a connection to a
- remote BGP speaker whose BGP Identifier equals the one in the
- OPEN message, then the local system performs the following
- collision resolution procedure: */
-
- if ((peer = new->doppelganger) != NULL) {
- /* Do not accept the new connection in Established or Clearing
- * states.
- * Note that a peer GR is handled by closing the existing
- * connection
- * upon receipt of new one.
+ /*
+ * Upon receipt of an OPEN message, the local system must examine
+ * all of its connections that are in the OpenConfirm state. A BGP
+ * speaker may also examine connections in an OpenSent state if it
+ * knows the BGP Identifier of the peer by means outside of the
+ * protocol. If among these connections there is a connection to a
+ * remote BGP speaker whose BGP Identifier equals the one in the
+ * OPEN message, then the local system performs the following
+ * collision resolution procedure:
+ */
+ peer = new->doppelganger;
+ if (peer == NULL)
+ return 0;
+
+ /*
+ * Do not accept the new connection in Established or Clearing
+ * states. Note that a peer GR is handled by closing the existing
+ * connection upon receipt of new one.
+ */
+ if (peer->status == Established || peer->status == Clearing) {
+ bgp_notify_send(new, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
+ return -1;
+ }
+
+ if ((peer->status != OpenConfirm) && (peer->status != OpenSent))
+ return 0;
+
+ /*
+ * 1. The BGP Identifier of the local system is
+ * compared to the BGP Identifier of the remote
+ * system (as specified in the OPEN message).
+ *
+ * If the BGP Identifiers of the peers
+ * involved in the connection collision
+ * are identical, then the connection
+ * initiated by the BGP speaker with the
+ * larger AS number is preserved.
+ */
+ if (ntohl(peer->local_id.s_addr) < ntohl(remote_id.s_addr)
+ || (ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)
+ && peer->local_as < peer->as))
+ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) {
+ /*
+ * 2. If the value of the local BGP
+ * Identifier is less than the remote one,
+ * the local system closes BGP connection
+ * that already exists (the one that is
+ * already in the OpenConfirm state),
+ * and accepts BGP connection initiated by
+ * the remote system.
+ */
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
+ return 1;
+ } else {
+ bgp_notify_send(new, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
+ return -1;
+ }
+ else {
+ if (ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr)
+ && peer->local_as == peer->as)
+ flog_err(EC_BGP_ROUTER_ID_SAME,
+ "Peer's router-id %pI4 is the same as ours",
+ &remote_id);
+
+ /*
+ * 3. Otherwise, the local system closes newly
+ * created BGP connection (the one associated with the
+ * newly received OPEN message), and continues to use
+ * the existing one (the one that is already in the
+ * OpenConfirm state).
*/
- if (peer->status == Established || peer->status == Clearing) {
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) {
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
+ return 1;
+ } else {
bgp_notify_send(new, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
return -1;
- } else if ((peer->status == OpenConfirm)
- || (peer->status == OpenSent)) {
- /* 1. The BGP Identifier of the local system is
- * compared to the BGP Identifier of the remote
- * system (as specified in the OPEN message).
- *
- * If the BGP Identifiers of the peers
- * involved in the connection collision
- * are identical, then the connection
- * initiated by the BGP speaker with the
- * larger AS number is preserved.
- */
- if (ntohl(peer->local_id.s_addr)
- < ntohl(remote_id.s_addr)
- || (ntohl(peer->local_id.s_addr)
- == ntohl(remote_id.s_addr)
- && peer->local_as < peer->as))
- if (!CHECK_FLAG(peer->sflags,
- PEER_STATUS_ACCEPT_PEER)) {
- /* 2. If the value of the local BGP
- Identifier is less
- than the remote one, the local system
- closes BGP
- connection that already exists (the
- one that is
- already in the OpenConfirm state),
- and accepts BGP
- connection initiated by the remote
- system. */
- bgp_notify_send(
- peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
- return 1;
- } else {
- bgp_notify_send(
- new, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
- return -1;
- }
- else {
- if (ntohl(peer->local_id.s_addr)
- == ntohl(remote_id.s_addr)
- && peer->local_as == peer->as)
- flog_err(
- EC_BGP_ROUTER_ID_SAME,
- "Peer's router-id %pI4 is the same as ours",
- &remote_id);
-
- /* 3. Otherwise, the local system closes newly
- created
- BGP connection (the one associated with the
- newly
- received OPEN message), and continues to use
- the
- existing one (the one that is already in the
- OpenConfirm state). */
- if (CHECK_FLAG(peer->sflags,
- PEER_STATUS_ACCEPT_PEER)) {
- bgp_notify_send(
- peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
- return 1;
- } else {
- bgp_notify_send(
- new, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
- return -1;
- }
- }
}
}
- return 0;
}
/* Packet processing routines ---------------------------------------------- */
@@ -1269,9 +1261,6 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
return BGP_Stop;
}
- /* Set remote router-id */
- peer->remote_id = remote_id;
-
/* Peer BGP version check. */
if (version != BGP_VERSION_4) {
uint16_t maxver = htons(BGP_VERSION_4);
@@ -1331,6 +1320,25 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
return BGP_Stop;
}
+ /*
+ * When collision is detected and this peer is closed.
+ * Return immediately.
+ */
+ ret = bgp_collision_detect(peer, remote_id);
+ if (ret < 0)
+ return BGP_Stop;
+
+ /* Get sockname. */
+ if (bgp_getsockname(peer) < 0) {
+ flog_err_sys(EC_LIB_SOCKET,
+ "%s: bgp_getsockname() failed for peer: %s",
+ __func__, peer->host);
+ return BGP_Stop;
+ }
+
+ /* Set remote router-id */
+ peer->remote_id = remote_id;
+
/* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
calculate the value of the Hold Timer by using the smaller of its
configured Hold Time and the Hold Time received in the OPEN message.
@@ -1411,21 +1419,6 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
peer->afc[AFI_IP6][SAFI_FLOWSPEC];
}
- /* When collision is detected and this peer is closed.
- * Return immediately.
- */
- ret = bgp_collision_detect(peer, remote_id);
- if (ret < 0)
- return BGP_Stop;
-
- /* Get sockname. */
- if (bgp_getsockname(peer) < 0) {
- flog_err_sys(EC_LIB_SOCKET,
- "%s: bgp_getsockname() failed for peer: %s",
- __func__, peer->host);
- return BGP_Stop;
- }
-
/* Verify valid local address present based on negotiated
* address-families. */
if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index 2c6c2c3861..8b27b39c46 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -2684,6 +2684,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
struct bgp_pbr_or_filter bpof;
struct bgp_pbr_val_mask bpvm;
+ memset(&range, 0, sizeof(range));
memset(&nh, 0, sizeof(struct nexthop));
memset(&bpf, 0, sizeof(struct bgp_pbr_filter));
memset(&bpof, 0, sizeof(struct bgp_pbr_or_filter));
diff --git a/bgpd/bgp_routemap_nb.c b/bgpd/bgp_routemap_nb.c
index fc59122184..b165c5d0ee 100644
--- a/bgpd/bgp_routemap_nb.c
+++ b/bgpd/bgp_routemap_nb.c
@@ -18,6 +18,8 @@
*/
+#include <zebra.h>
+
#include "lib/command.h"
#include "lib/log.h"
#include "lib/northbound.h"
diff --git a/bgpd/bgp_routemap_nb_config.c b/bgpd/bgp_routemap_nb_config.c
index ec6284273e..ff08c16a82 100644
--- a/bgpd/bgp_routemap_nb_config.c
+++ b/bgpd/bgp_routemap_nb_config.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "lib/command.h"
#include "lib/log.h"
#include "lib/northbound.h"
diff --git a/bgpd/bgp_trace.c b/bgpd/bgp_trace.c
index 2ebc63b6b5..02afbeb46f 100644
--- a/bgpd/bgp_trace.c
+++ b/bgpd/bgp_trace.c
@@ -1,4 +1,6 @@
#define TRACEPOINT_CREATE_PROBES
#define TRACEPOINT_DEFINE
+#include <zebra.h>
+
#include "bgp_trace.h"
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index ae0bf7fe92..288c2851b3 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1975,7 +1975,7 @@ void bgp_zebra_instance_deregister(struct bgp *bgp)
void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer)
{
- int ra_interval = BGP_UNNUM_DEFAULT_RA_INTERVAL;
+ uint32_t ra_interval = BGP_UNNUM_DEFAULT_RA_INTERVAL;
/* Don't try to initiate if we're not connected to Zebra */
if (zclient->sock < 0)
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 51134dc8c5..88588952ba 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -44,6 +44,7 @@
#include "bgp_addpath_types.h"
#include "bgp_nexthop.h"
#include "bgp_damp.h"
+#include "bgp_io.h"
#include "lib/bfd.h"
@@ -1047,6 +1048,9 @@ struct peer {
struct stream_fifo *ibuf; // packets waiting to be processed
struct stream_fifo *obuf; // packets waiting to be written
+ /* used as a block to deposit raw wire data to */
+ uint8_t ibuf_scratch[BGP_MAX_EXTENDED_MESSAGE_PACKET_SIZE
+ * BGP_READ_PACKET_MAX];
struct ringbuf *ibuf_work; // WiP buffer used by bgp_read() only
struct stream *obuf_work; // WiP buffer used to construct packets
diff --git a/configure.ac b/configure.ac
index f9fa8e0713..c082a9e527 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1866,7 +1866,7 @@ AC_SUBST([SNMP_CFLAGS])
dnl ---------------
dnl libyang
dnl ---------------
-PKG_CHECK_MODULES([LIBYANG], [libyang >= 1.0.184], , [
+PKG_CHECK_MODULES([LIBYANG], [libyang >= 1.0.184 libyang < 2.0], , [
AC_MSG_ERROR([libyang (>= 1.0.184) was not found on your system.])
])
ac_cflags_save="$CFLAGS"
diff --git a/doc/developer/building-frr-for-openbsd6.rst b/doc/developer/building-frr-for-openbsd6.rst
index f307cacdfc..88446685e0 100644
--- a/doc/developer/building-frr-for-openbsd6.rst
+++ b/doc/developer/building-frr-for-openbsd6.rst
@@ -14,6 +14,7 @@ Add packages:
::
+ pkg_add clang libcares python3
pkg_add git autoconf-2.69p2 automake-1.15.1 libtool bison
pkg_add gmake json-c py-test py-sphinx libexecinfo
@@ -47,6 +48,19 @@ Download Source, configure and compile it
(You may prefer different options on configure statement. These are just
an example)
+.. warning::
+
+ In openbsd the proper links for the libyang library may not have been created.
+
+::
+
+ ln -s /usr/lib/libyang.so.1.10.17 /usr/lib/libyang.so
+
+.. warning::
+
+ ``openbsd`` since version 6.2 has ``clang`` as the default compiler so to
+ build frr, clang must be used (the included gcc version is very old).
+
::
git clone https://github.com/frrouting/frr.git frr
@@ -67,7 +81,8 @@ an example)
--enable-logfile-mask=0640 \
--enable-fpm \
--with-pkg-git-version \
- --with-pkg-extra-version=-MyOwnFRRVersion
+ --with-pkg-extra-version=-MyOwnFRRVersion \
+ CC=clang
gmake
gmake check
doas gmake install
diff --git a/doc/developer/lists.rst b/doc/developer/lists.rst
index 86db788c0e..553bd1f596 100644
--- a/doc/developer/lists.rst
+++ b/doc/developer/lists.rst
@@ -108,6 +108,8 @@ Functions provided:
| _first, _next, _next_safe, | yes | yes | yes | yes | yes |
| _const_first, _const_next | | | | | |
+------------------------------------+------+------+------+---------+------------+
+| _swap_all | yes | yes | yes | yes | yes |
++------------------------------------+------+------+------+---------+------------+
| _add_head, _add_tail, _add_after | yes | -- | -- | -- | -- |
+------------------------------------+------+------+------+---------+------------+
| _add | -- | yes | yes | yes | yes |
@@ -322,6 +324,14 @@ The following documentation assumes that a list has been defined using
return ``item``. The function may also call ``assert()`` (but most
don't.)
+.. c:function:: itemtype *Z_swap_all(struct Z_head *, struct Z_head *)
+
+ Swap the contents of 2 containers (of identical type). This exchanges the
+ contents of the two head structures and updates pointers if necessary for
+ the particular data structure. Fast for all structures.
+
+ (Not currently available on atomic containers.)
+
.. todo::
``Z_del_after()`` / ``Z_del_hint()``?
diff --git a/doc/user/basic.rst b/doc/user/basic.rst
index 519f30d5e6..2def835f0b 100644
--- a/doc/user/basic.rst
+++ b/doc/user/basic.rst
@@ -188,6 +188,12 @@ Basic Config Commands
This command clears all current filters in the log-filter table. Can be
daemon independent.
+
+.. clicmd:: log immediate-mode
+
+ Use unbuffered output for log and debug messages; normally there is
+ some internal buffering.
+
.. clicmd:: service password-encryption
Encrypt password.
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 1da9e3ba73..87710e98c6 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -2567,6 +2567,24 @@ address-family:
Ethernet Virtual Network - EVPN
-------------------------------
+Note: When using EVPN features and if you have a large number of hosts, make
+sure to adjust the size of the arp neighbor cache to avoid neighbor table
+overflow and/or excessive garbage collection. On Linux, the size of the table
+and garbage collection frequency can be controlled via the following
+sysctl configurations:
+
+.. code-block:: shell
+
+ net.ipv4.neigh.default.gc_thresh1
+ net.ipv4.neigh.default.gc_thresh2
+ net.ipv4.neigh.default.gc_thresh3
+
+ net.ipv6.neigh.default.gc_thresh1
+ net.ipv6.neigh.default.gc_thresh2
+ net.ipv6.neigh.default.gc_thresh3
+
+For more information, see ``man 7 arp``.
+
.. _bgp-evpn-advertise-pip:
EVPN advertise-PIP
@@ -2592,10 +2610,10 @@ other EVPN routes.
To support this feature there needs to have ability to co-exist a
(system-MAC, system-IP) pair with a (anycast-MAC, anycast-IP) pair with the
ability to terminate VxLAN-encapsulated packets received for either pair on
-the same L3VNI (i.e associated VLAN). This capability is need per tenant
+the same L3VNI (i.e associated VLAN). This capability is needed per tenant
VRF instance.
-To derive the system-MAC and the anycast MAC, there needs to have a
+To derive the system-MAC and the anycast MAC, there must be a
separate/additional MAC-VLAN interface corresponding to L3VNI’s SVI.
The SVI interface’s MAC address can be interpreted as system-MAC
and MAC-VLAN interface's MAC as anycast MAC.
@@ -2607,7 +2625,7 @@ User has an option to configure the system-IP and/or system-MAC value if the
auto derived value is not preferred.
Note: By default, advertise-pip feature is enabled and user has an option to
-disable the feature via configuration CLI. Once the feature is disable under
+disable the feature via configuration CLI. Once the feature is disabled under
bgp vrf instance or MAC-VLAN interface is not configured, all the routes follow
the same behavior of using same next-hop and RMAC values.
@@ -2616,6 +2634,19 @@ the same behavior of using same next-hop and RMAC values.
Enables or disables advertise-pip feature, specifiy system-IP and/or system-MAC
parameters.
+EVPN advertise-svi-ip
+^^^^^^^^^^^^^^^^^^^^^
+Typically, the SVI IP address is reused on VTEPs across multiple racks. However,
+if you have unique SVI IP addresses that you want to be reachable you can use the
+advertise-svi-ip option. This option advertises the SVI IP/MAC address as a type-2
+route and eliminates the need for any flooding over VXLAN to reach the IP from a
+remote VTEP.
+
+.. clicmd:: advertise-svi-ip
+
+Note that you should not enable both the advertise-svi-ip and the advertise-default-gw
+at the same time.
+
EVPN Multihoming
^^^^^^^^^^^^^^^^
diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst
index ef2bf16166..66f8fd5678 100644
--- a/doc/user/isisd.rst
+++ b/doc/user/isisd.rst
@@ -77,7 +77,7 @@ writing, *isisd* does not support multiple ISIS processes.
- transition
Send and accept both styles of TLVs during transition
- wide
- Use new style of TLVs to carry wider metric
+ Use new style of TLVs to carry wider metric. FRR uses this as a default value
.. clicmd:: set-overload-bit
@@ -172,7 +172,7 @@ ISIS interface
.. _ip-router-isis-word:
-.. clicmd:: <ip|ipv6> router isis WORD [vrf NAME]
+.. clicmd:: <ip|ipv6> router isis WORD
Activate ISIS adjacency on this interface. Note that the name of ISIS
instance must be the same as the one used to configure the ISIS process (see
@@ -261,10 +261,11 @@ ISIS interface
Limit Remote LFA PQ node selection within the specified metric.
-.. clicmd:: isis fast-reroute ti-lfa [level-1|level-2] [node-protection]
+.. clicmd:: isis fast-reroute ti-lfa [level-1|level-2] [node-protection [link-fallback]]
Enable per-prefix TI-LFA fast reroute link or node protection.
-
+ When node protection is used, option link-fallback enables the computation and use of
+ link-protecting LFAs for destinations unprotected by node protection.
.. _showing-isis-information:
diff --git a/doc/user/kernel.rst b/doc/user/kernel.rst
index 4c2c7a5008..210ede7e91 100644
--- a/doc/user/kernel.rst
+++ b/doc/user/kernel.rst
@@ -6,6 +6,9 @@ Kernel Interface
There are several different methods for reading kernel routing table
information, updating kernel routing tables, and for looking up interfaces.
+FRR relies heavily on the Netlink (``man 7 netlink``) interface to
+communicate with the Kernel. However, other interfaces are still used
+in some parts of the code.
- ioctl
This method is a very traditional way for reading or writing kernel
@@ -27,16 +30,7 @@ information, updating kernel routing tables, and for looking up interfaces.
kernel information.
- routing socket / Netlink
- On recent Linux kernels (2.0.x and 2.2.x), there is a kernel/user
- communication support called `Netlink`. It makes asynchronous communication
- between kernel and FRR possible, similar to a routing socket on BSD systems.
-
- Before you use this feature, be sure to select (in kernel configuration) the
- kernel/Netlink support option 'Kernel/User network link driver' and 'Routing
- messages'.
-
- Today, the :file:`/dev/route` special device file is obsolete. Netlink
- communication is done by reading/writing over Netlink socket.
-
- After the kernel configuration, please reconfigure and rebuild FRR. You can
- use Netlink as a dynamic routing update channel between FRR and the kernel.
+ Netlink first appeard in Linux kernel 2.0. It makes asynchronous
+ communication between the kernel and FRR possible, similar to a routing
+ socket on BSD systems. Netlink communication is done by reading/writing
+ over Netlink socket.
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index 6b7cae2c5d..103760933c 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -154,20 +154,6 @@ Certain signals have special meanings to *pimd*.
urib-only
Lookup in the Unicast Rib only.
-.. clicmd:: ip msdp mesh-group [WORD]
-
- Create or Delete a multicast source discovery protocol mesh-group using
- [WORD] as the group name.
-
-.. clicmd:: ip msdp mesh-group WORD member A.B.C.D
-
- Attach or Delete A.B.C.D to the MSDP mesh group WORD specified.
-
-.. clicmd:: ip msdp mesh-group WORD source A.B.C.D
-
- For the address specified A.B.C.D use that as the source address for
- mesh group packets being sent.
-
.. clicmd:: ip igmp generate-query-once [version (2-3)]
Generate IGMP query (v2/v3) on user requirement. This will not depend on
@@ -308,27 +294,43 @@ caution. Most of the time this will not be necessary.
Multicast Source Discovery Protocol (MSDP) Configuration
========================================================
-.. clicmd:: ip msdp mesh-group [WORD] member A.B.C.D
+MSDP can be setup in different ways:
- Include a MSDP peer as a member of a MSDP mesh-group.
+* MSDP meshed-group: where all peers are connected with each other creating
+ a fully meshed network. SAs (source active) messages are not forwarded in
+ this mode because the origin is able to send SAs to all members.
-.. clicmd:: ip msdp mesh-group [WORD] source A.B.C.D
+ This setup is commonly used with anycast.
- Create a MSDP mesh-group, defining a name for it and an associated local source
- address.
+* MSDP peering: when there is one or more peers that are not fully meshed. SAs
+ may be forwarded depending on the result of filtering and RPF checks.
-.. clicmd:: ip msdp peer A.B.C.D source A.B.C.D
+ This setup is commonly consistent with BGP peerings (for RPF checks).
- Establish a MSDP connection with a peer.
+* MSDP default peer: there is only one peer and all SAs will be forwarded
+ there.
+.. note::
- Remove a MSDP peer member from a MSDP mesh-group.
+ MSDP default peer and SA filtering is not implemented.
- Delete a MSDP mesh-group.
+Commands available for MSDP:
+
+
+.. clicmd:: ip msdp mesh-group WORD member A.B.C.D
+
+ Create or update a mesh group to include the specified MSDP peer.
+
+.. clicmd:: ip msdp mesh-group WORD source A.B.C.D
+
+ Create or update a mesh group to set the source address used to connect to
+ peers.
+
+.. clicmd:: ip msdp peer A.B.C.D source A.B.C.D
+ Create a regular MSDP session with peer using the specified source address.
- Delete a MSDP peer connection.
.. _show-pim-information:
diff --git a/eigrpd/eigrp_metric.c b/eigrpd/eigrp_metric.c
index 2b05db71d5..ea62f9d1be 100644
--- a/eigrpd/eigrp_metric.c
+++ b/eigrpd/eigrp_metric.c
@@ -21,6 +21,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "eigrpd/eigrp_structs.h"
#include "eigrpd/eigrpd.h"
#include "eigrpd/eigrp_types.h"
diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c
index 0b37733990..39e384c121 100644
--- a/eigrpd/eigrp_packet.c
+++ b/eigrpd/eigrp_packet.c
@@ -572,9 +572,14 @@ int eigrp_read(struct thread *thread)
&& IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL))
eigrp_header_dump(eigrph);
- // if (MSG_OK != eigrp_packet_examin(eigrph, stream_get_endp(ibuf) -
- // stream_get_getp(ibuf)))
- // return -1;
+ if (ntohs(eigrph->ASNumber) != eigrp->AS) {
+ if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
+ zlog_debug(
+ "ignoring packet from router %u sent to %pI4, wrong AS Number received: %u",
+ ntohs(eigrph->vrid), &iph->ip_dst,
+ ntohs(eigrph->ASNumber));
+ return 0;
+ }
/* If incoming interface is passive one, ignore it. */
if (eigrp_if_is_passive(ei)) {
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index a637429e84..7fd9c07ed2 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -73,61 +73,42 @@ DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp));
int isis_if_new_hook(struct interface *);
int isis_if_delete_hook(struct interface *);
-static int isis_circuit_smmp_id_gen(struct isis_circuit *circuit)
-{
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
- struct isis *isis = NULL;
- uint32_t id;
- uint32_t i;
-
- isis = isis_lookup_by_vrfid(vrf->vrf_id);
- if (isis == NULL)
- return 0;
-
- id = isis->snmp_circuit_id_last;
- id++;
+DEFINE_HOOK(isis_circuit_new_hook, (struct isis_circuit *circuit), (circuit));
+DEFINE_HOOK(isis_circuit_del_hook, (struct isis_circuit *circuit), (circuit));
- /* find next unused entry */
- for (i = 0; i < SNMP_CIRCUITS_MAX; i++) {
- if (id >= SNMP_CIRCUITS_MAX) {
- id = 0;
- continue;
- }
-
- if (id == 0)
- continue;
+static void isis_circuit_enable(struct isis_circuit *circuit)
+{
+ struct isis_area *area;
+ struct interface *ifp = circuit->interface;
- if (isis->snmp_circuits[id] == NULL)
- break;
+ area = isis_area_lookup(circuit->tag, ifp->vrf_id);
+ if (area)
+ isis_area_add_circuit(area, circuit);
- id++;
- }
+ if (if_is_operative(ifp))
+ isis_csm_state_change(IF_UP_FROM_Z, circuit, ifp);
+}
- if (i == SNMP_CIRCUITS_MAX) {
- zlog_warn("Could not allocate a smmp-circuit-id");
- return 0;
- }
+static void isis_circuit_disable(struct isis_circuit *circuit)
+{
+ struct isis_area *area = circuit->area;
+ struct interface *ifp = circuit->interface;
- isis->snmp_circuits[id] = circuit;
- isis->snmp_circuit_id_last = id;
- circuit->snmp_id = id;
+ if (if_is_operative(ifp))
+ isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
- return 1;
+ if (area)
+ isis_area_del_circuit(area, circuit);
}
-struct isis_circuit *isis_circuit_new(struct isis *isis)
+struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag)
{
struct isis_circuit *circuit;
int i;
circuit = XCALLOC(MTYPE_ISIS_CIRCUIT, sizeof(struct isis_circuit));
- circuit->isis = isis;
- /*
- * Note: if snmp-id generation failed circuit will fail
- * up operation
- */
- isis_circuit_smmp_id_gen(circuit);
+ circuit->tag = XSTRDUP(MTYPE_ISIS_CIRCUIT, tag);
/*
* Default values
@@ -193,31 +174,39 @@ struct isis_circuit *isis_circuit_new(struct isis *isis)
isis_lfa_excluded_ifaces_init(circuit, ISIS_LEVEL1);
isis_lfa_excluded_ifaces_init(circuit, ISIS_LEVEL2);
+ circuit->ldp_sync_info = ldp_sync_info_create();
+ circuit->ldp_sync_info->enabled = LDP_IGP_SYNC_ENABLED;
+
QOBJ_REG(circuit, isis_circuit);
+ isis_circuit_if_bind(circuit, ifp);
+
+ if (ifp->ifindex != IFINDEX_INTERNAL)
+ isis_circuit_enable(circuit);
+
return circuit;
}
void isis_circuit_del(struct isis_circuit *circuit)
{
- struct isis *isis = NULL;
-
if (!circuit)
return;
- QOBJ_UNREG(circuit);
-
- if (circuit->interface) {
- isis = isis_lookup_by_vrfid(circuit->interface->vrf_id);
- isis->snmp_circuits[circuit->snmp_id] = NULL;
- }
+ if (circuit->interface->ifindex != IFINDEX_INTERNAL)
+ isis_circuit_disable(circuit);
isis_circuit_if_unbind(circuit, circuit->interface);
+ QOBJ_UNREG(circuit);
+
+ ldp_sync_info_free(&circuit->ldp_sync_info);
+
circuit_mt_finish(circuit);
isis_lfa_excluded_ifaces_clear(circuit, ISIS_LEVEL1);
isis_lfa_excluded_ifaces_clear(circuit, ISIS_LEVEL2);
+ XFREE(MTYPE_ISIS_CIRCUIT, circuit->tag);
+
/* and lastly the circuit itself */
XFREE(MTYPE_ISIS_CIRCUIT, circuit);
@@ -228,6 +217,7 @@ void isis_circuit_configure(struct isis_circuit *circuit,
struct isis_area *area)
{
assert(area);
+ circuit->isis = area->isis;
circuit->area = area;
/*
@@ -247,12 +237,16 @@ void isis_circuit_configure(struct isis_circuit *circuit,
circuit->idx = flags_get_index(&area->flags);
+ hook_call(isis_circuit_new_hook, circuit);
+
return;
}
void isis_circuit_deconfigure(struct isis_circuit *circuit,
struct isis_area *area)
{
+ hook_call(isis_circuit_del_hook, circuit);
+
/* Free the index of SRM and SSN flags */
flags_free_index(&area->flags, circuit->idx);
circuit->idx = 0;
@@ -260,6 +254,7 @@ void isis_circuit_deconfigure(struct isis_circuit *circuit,
assert(circuit->area == area);
listnode_delete(area->circuit_list, circuit);
circuit->area = NULL;
+ circuit->isis = NULL;
return;
}
@@ -284,29 +279,7 @@ struct isis_circuit *circuit_lookup_by_ifp(struct interface *ifp,
struct isis_circuit *circuit_scan_by_ifp(struct interface *ifp)
{
- struct isis_area *area;
- struct listnode *node;
- struct isis_circuit *circuit;
- struct isis *isis = NULL;
-
- if (ifp->info)
- return (struct isis_circuit *)ifp->info;
-
- isis = isis_lookup_by_vrfid(ifp->vrf_id);
- if (isis == NULL) {
- zlog_warn(" %s : ISIS routing instance not found", __func__);
- return NULL;
- }
-
- if (isis->area_list) {
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
- circuit =
- circuit_lookup_by_ifp(ifp, area->circuit_list);
- if (circuit)
- return circuit;
- }
- }
- return circuit_lookup_by_ifp(ifp, isis->init_circ_list);
+ return (struct isis_circuit *)ifp->info;
}
DEFINE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit),
@@ -516,8 +489,6 @@ void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp)
struct listnode *node, *nnode;
struct connected *conn;
- isis_circuit_if_bind(circuit, ifp);
-
if (if_is_broadcast(ifp)) {
if (fabricd || circuit->circ_type_config == CIRCUIT_T_P2P)
circuit->circ_type = CIRCUIT_T_P2P;
@@ -681,13 +652,6 @@ int isis_circuit_up(struct isis_circuit *circuit)
return ISIS_OK;
}
- if (circuit->snmp_id == 0) {
- /* We cannot bring circuit up if does not have snmp-id */
- flog_err(EC_ISIS_CONFIG,
- "No snnmp-id: there are too many circuits:");
- return ISIS_ERROR;
- }
-
if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) {
flog_err(
EC_ISIS_CONFIG,
@@ -789,6 +753,11 @@ int isis_circuit_up(struct isis_circuit *circuit)
circuit->last_uptime = time(NULL);
+ if (circuit->area->mta && circuit->area->mta->status)
+ isis_link_params_update(circuit, circuit->interface);
+
+ isis_if_ldp_sync_enable(circuit);
+
#ifndef FABRICD
/* send northbound notification */
isis_notif_if_state_change(circuit, false);
@@ -804,6 +773,8 @@ void isis_circuit_down(struct isis_circuit *circuit)
isis_notif_if_state_change(circuit, true);
#endif /* ifndef FABRICD */
+ isis_if_ldp_sync_disable(circuit);
+
/* log adjacency changes if configured to do so */
if (circuit->area->log_adj_changes) {
struct isis_adjacency *adj = NULL;
@@ -1345,23 +1316,6 @@ static int isis_interface_config_write(struct vty *vty)
}
#endif /* ifdef FABRICD */
-struct isis_circuit *isis_circuit_create(struct isis_area *area,
- struct interface *ifp)
-{
- struct isis_circuit *circuit = circuit_scan_by_ifp(ifp);
-
- if (circuit && circuit->area)
- return NULL;
- circuit = isis_csm_state_change(ISIS_ENABLE, circuit, area);
- if (circuit->state != C_STATE_CONF && circuit->state != C_STATE_UP)
- return circuit;
- isis_circuit_if_bind(circuit, ifp);
- if (circuit->area->mta && circuit->area->mta->status)
- isis_link_params_update(circuit, ifp);
-
- return circuit;
-}
-
void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
bool ipv6_router)
{
@@ -1377,24 +1331,13 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
circuit->ipv6_router = ipv6_router;
circuit_update_nlpids(circuit);
- /* the area should always be there if we get here, but in the past
- * there were corner cases where the area was NULL (e.g. because the
- * circuit was deconfigured following a validation error). Do not
- * segfault if this happens again.
- */
- if (!area) {
- zlog_err("%s: NULL area for circuit %u", __func__,
- circuit->circuit_id);
- return;
- }
-
- area->ip_circuits += ip_router - old_ipr;
- area->ipv6_circuits += ipv6_router - old_ipv6r;
+ if (area) {
+ area->ip_circuits += ip_router - old_ipr;
+ area->ipv6_circuits += ipv6_router - old_ipv6r;
- if (!ip_router && !ipv6_router)
- isis_csm_state_change(ISIS_DISABLE, circuit, area);
- else
- lsp_regenerate_schedule(area, circuit->is_type, 0);
+ if (ip_router || ipv6_router)
+ lsp_regenerate_schedule(area, circuit->is_type, 0);
+ }
}
ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive)
@@ -1516,8 +1459,9 @@ int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid,
setting = circuit_get_mt_setting(circuit, mtid);
if (setting->enabled != enabled) {
setting->enabled = enabled;
- lsp_regenerate_schedule(circuit->area, IS_LEVEL_1 | IS_LEVEL_2,
- 0);
+ if (circuit->area)
+ lsp_regenerate_schedule(circuit->area,
+ IS_LEVEL_1 | IS_LEVEL_2, 0);
}
return CMD_SUCCESS;
@@ -1530,27 +1474,19 @@ int isis_if_new_hook(struct interface *ifp)
int isis_if_delete_hook(struct interface *ifp)
{
- struct isis_circuit *circuit;
- /* Clean up the circuit data */
- if (ifp && ifp->info) {
- circuit = ifp->info;
- isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
- }
+ if (ifp->info)
+ isis_circuit_del(ifp->info);
return 0;
}
static int isis_ifp_create(struct interface *ifp)
{
- struct vrf *vrf = NULL;
+ struct isis_circuit *circuit = ifp->info;
+
+ if (circuit)
+ isis_circuit_enable(circuit);
- if (if_is_operative(ifp)) {
- vrf = vrf_lookup_by_id(ifp->vrf_id);
- if (vrf)
- isis_global_instance_create(vrf->name);
- isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp),
- ifp);
- }
hook_call(isis_if_new_hook, ifp);
return 0;
@@ -1558,34 +1494,33 @@ static int isis_ifp_create(struct interface *ifp)
static int isis_ifp_up(struct interface *ifp)
{
- isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
+ struct isis_circuit *circuit = ifp->info;
+
+ if (circuit)
+ isis_csm_state_change(IF_UP_FROM_Z, circuit, ifp);
return 0;
}
static int isis_ifp_down(struct interface *ifp)
{
- struct isis_circuit *circuit;
+ struct isis_circuit *circuit = ifp->info;
+
+ if (circuit) {
+ isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
- circuit = isis_csm_state_change(IF_DOWN_FROM_Z,
- circuit_scan_by_ifp(ifp), ifp);
- if (circuit)
SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
+ }
return 0;
}
static int isis_ifp_destroy(struct interface *ifp)
{
- if (if_is_operative(ifp))
- zlog_warn("Zebra: got delete of %s, but interface is still up",
- ifp->name);
-
- isis_csm_state_change(IF_DOWN_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
+ struct isis_circuit *circuit = ifp->info;
- /* Cannot call if_delete because we should retain the pseudo interface
- in case there is configuration info attached to it. */
- if_delete_retain(ifp);
+ if (circuit)
+ isis_circuit_disable(circuit);
return 0;
}
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index d4c7baea1a..84c3ca3ff2 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -122,6 +122,7 @@ struct isis_circuit {
/*
* Configurables
*/
+ char *tag; /* area tag */
struct isis_passwd passwd; /* Circuit rx/tx password */
int is_type; /* circuit is type == level of circuit
* differentiated from circuit type (media) */
@@ -151,6 +152,7 @@ struct isis_circuit {
struct hash *lfa_excluded_ifaces[ISIS_LEVELS];
bool tilfa_protection[ISIS_LEVELS];
bool tilfa_node_protection[ISIS_LEVELS];
+ bool tilfa_link_fallback[ISIS_LEVELS];
/*
* Counters as in 10589--11.2.5.9
*/
@@ -180,7 +182,7 @@ struct isis_circuit {
DECLARE_QOBJ_TYPE(isis_circuit);
void isis_circuit_init(void);
-struct isis_circuit *isis_circuit_new(struct isis *isis);
+struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag);
void isis_circuit_del(struct isis_circuit *circuit);
struct isis_circuit *circuit_lookup_by_ifp(struct interface *ifp,
struct list *list);
@@ -207,8 +209,6 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
size_t isis_circuit_pdu_size(struct isis_circuit *circuit);
void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream);
-struct isis_circuit *isis_circuit_create(struct isis_area *area,
- struct interface *ifp);
void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
bool ipv6_router);
ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive);
@@ -238,4 +238,7 @@ DECLARE_HOOK(isis_circuit_config_write,
DECLARE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit),
(circuit));
+DECLARE_HOOK(isis_circuit_new_hook, (struct isis_circuit *circuit), (circuit));
+DECLARE_HOOK(isis_circuit_del_hook, (struct isis_circuit *circuit), (circuit));
+
#endif /* _ZEBRA_ISIS_CIRCUIT_H */
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index b108210686..f316e0279c 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -62,19 +62,7 @@ DEFPY_YANG_NOSH(router_isis, router_isis_cmd,
"/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
vrf_name);
nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
- /* default value in yang for is-type is level-1, but in FRR
- * the first instance is assigned is-type level-1-2. We
- * need to make sure to set it in the yang model so that it
- * is consistent with what FRR sees.
- */
-
- if (!im) {
- return CMD_SUCCESS;
- }
- if (listcount(im->isis) == 0)
- nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY,
- "level-1-2");
ret = nb_cli_apply_changes(vty, base_xpath);
if (ret == CMD_SUCCESS)
VTY_PUSH_XPATH(ISIS_NODE, base_xpath);
@@ -82,16 +70,42 @@ DEFPY_YANG_NOSH(router_isis, router_isis_cmd,
return ret;
}
+struct if_iter {
+ struct vty *vty;
+ const char *tag;
+};
+
+static int if_iter_cb(const struct lyd_node *dnode, void *arg)
+{
+ struct if_iter *iter = arg;
+ const char *tag;
+
+ if (!yang_dnode_exists(dnode, "frr-isisd:isis/area-tag"))
+ return YANG_ITER_CONTINUE;
+
+ tag = yang_dnode_get_string(dnode, "frr-isisd:isis/area-tag");
+ if (strmatch(tag, iter->tag)) {
+ char xpath[XPATH_MAXLEN];
+ const char *name = yang_dnode_get_string(dnode, "name");
+ const char *vrf = yang_dnode_get_string(dnode, "vrf");
+
+ snprintf(
+ xpath, XPATH_MAXLEN,
+ "/frr-interface:lib/interface[name='%s'][vrf='%s']/frr-isisd:isis",
+ name, vrf);
+ nb_cli_enqueue_change(iter->vty, xpath, NB_OP_DESTROY, NULL);
+ }
+
+ return YANG_ITER_CONTINUE;
+}
+
DEFPY_YANG(no_router_isis, no_router_isis_cmd,
"no router isis WORD$tag [vrf NAME$vrf_name]",
NO_STR ROUTER_STR
"ISO IS-IS\n"
"ISO Routing area tag\n" VRF_CMD_HELP_STR)
{
- char temp_xpath[XPATH_MAXLEN];
- struct listnode *node, *nnode;
- struct isis_circuit *circuit = NULL;
- struct isis_area *area = NULL;
+ struct if_iter iter;
if (!vrf_name)
vrf_name = VRF_DEFAULT_NAME;
@@ -104,24 +118,13 @@ DEFPY_YANG(no_router_isis, no_router_isis_cmd,
return CMD_ERR_NOTHING_TODO;
}
+ iter.vty = vty;
+ iter.tag = tag;
+
+ yang_dnode_iterate(if_iter_cb, &iter, vty->candidate_config->dnode,
+ "/frr-interface:lib/interface[vrf='%s']", vrf_name);
+
nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
- area = isis_area_lookup_by_vrf(tag, vrf_name);
- if (area && area->circuit_list && listcount(area->circuit_list)) {
- for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
- circuit)) {
- /* add callbacks to delete each of the circuits listed
- */
- const char *vrf_name =
- vrf_lookup_by_id(circuit->interface->vrf_id)
- ->name;
- snprintf(
- temp_xpath, XPATH_MAXLEN,
- "/frr-interface:lib/interface[name='%s'][vrf='%s']/frr-isisd:isis",
- circuit->interface->name, vrf_name);
- nb_cli_enqueue_change(vty, temp_xpath, NB_OP_DESTROY,
- NULL);
- }
- }
return nb_cli_apply_changes(
vty, "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
@@ -150,95 +153,48 @@ void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode,
* XPath: /frr-isisd:isis/instance
*/
DEFPY_YANG(ip_router_isis, ip_router_isis_cmd,
- "ip router isis WORD$tag [vrf NAME$vrf_name]",
+ "ip router isis WORD$tag",
"Interface Internet Protocol config commands\n"
"IP router interface commands\n"
"IS-IS routing protocol\n"
- "Routing process tag\n" VRF_CMD_HELP_STR)
+ "Routing process tag\n")
{
- char temp_xpath[XPATH_MAXLEN];
- const char *circ_type;
- struct isis_area *area = NULL;
+ char inst_xpath[XPATH_MAXLEN];
+ struct lyd_node *if_dnode, *inst_dnode;
+ const char *circ_type = NULL;
+ const char *vrf_name;
struct interface *ifp;
- struct vrf *vrf;
-
- /* area will be created if it is not present. make sure the yang model
- * is synced with FRR and call the appropriate NB cb.
- */
- if (!im) {
- return CMD_SUCCESS;
- }
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (!vrf_name) {
- if (ifp) {
- if (ifp->vrf_id == VRF_DEFAULT)
- vrf_name = VRF_DEFAULT_NAME;
- else {
- vrf = vrf_lookup_by_id(ifp->vrf_id);
- if (vrf && !vrf_name)
- vrf_name = vrf->name;
- }
- } else
- vrf_name = VRF_DEFAULT_NAME;
+ if_dnode = yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!if_dnode) {
+ vty_out(vty, "%% Failed to get iface dnode in candidate DB\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
- area = isis_area_lookup_by_vrf(tag, vrf_name);
- if (!area) {
- isis_global_instance_create(vrf_name);
- snprintf(temp_xpath, XPATH_MAXLEN,
- "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']",
- tag, vrf_name);
- nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag);
- snprintf(
- temp_xpath, XPATH_MAXLEN,
- "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']/is-type",
- tag, vrf_name);
- nb_cli_enqueue_change(vty, temp_xpath, NB_OP_MODIFY,
- listcount(im->isis) == 0 ? "level-1-2"
- : NULL);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
- NULL);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
- NB_OP_MODIFY, tag);
+ vrf_name = yang_dnode_get_string(if_dnode, "vrf");
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/vrf", NB_OP_MODIFY,
- vrf_name);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
- NB_OP_MODIFY, "true");
- nb_cli_enqueue_change(
- vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
- listcount(im->isis) == 0 ? "level-1-2" : "level-1");
- } else {
- /* area exists, circuit type defaults to its area's is_type */
- switch (area->is_type) {
- case IS_LEVEL_1:
- circ_type = "level-1";
- break;
- case IS_LEVEL_2:
- circ_type = "level-2";
- break;
- case IS_LEVEL_1_AND_2:
- circ_type = "level-1-2";
- break;
- default:
- /* just to silence compiler warnings */
- return CMD_WARNING_CONFIG_FAILED;
- }
- nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
- NULL);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
- NB_OP_MODIFY, tag);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/vrf", NB_OP_MODIFY,
- vrf_name);
+ snprintf(inst_xpath, XPATH_MAXLEN,
+ "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
+ vrf_name);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
- NB_OP_MODIFY, "true");
+ /* if instance exists then inherit its type, create it otherwise */
+ inst_dnode = yang_dnode_get(vty->candidate_config->dnode, inst_xpath);
+ if (inst_dnode)
+ circ_type = yang_dnode_get_string(inst_dnode, "is-type");
+ else
+ nb_cli_enqueue_change(vty, inst_xpath, NB_OP_CREATE, NULL);
+
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE, NULL);
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag", NB_OP_MODIFY,
+ tag);
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
+ NB_OP_MODIFY, "true");
+ if (circ_type)
nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
NB_OP_MODIFY, circ_type);
- }
/* check if the interface is a loopback and if so set it as passive */
+ ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (ifp && if_is_loopback(ifp))
nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
NB_OP_MODIFY, "true");
@@ -246,95 +202,56 @@ DEFPY_YANG(ip_router_isis, ip_router_isis_cmd,
return nb_cli_apply_changes(vty, NULL);
}
+ALIAS_HIDDEN(ip_router_isis, ip_router_isis_vrf_cmd,
+ "ip router isis WORD$tag vrf NAME$vrf_name",
+ "Interface Internet Protocol config commands\n"
+ "IP router interface commands\n"
+ "IS-IS routing protocol\n"
+ "Routing process tag\n" VRF_CMD_HELP_STR)
+
DEFPY_YANG(ip6_router_isis, ip6_router_isis_cmd,
- "ipv6 router isis WORD$tag [vrf NAME$vrf_name]",
+ "ipv6 router isis WORD$tag",
"Interface Internet Protocol config commands\n"
"IP router interface commands\n"
"IS-IS routing protocol\n"
- "Routing process tag\n" VRF_CMD_HELP_STR)
+ "Routing process tag\n")
{
- char temp_xpath[XPATH_MAXLEN];
- const char *circ_type;
+ char inst_xpath[XPATH_MAXLEN];
+ struct lyd_node *if_dnode, *inst_dnode;
+ const char *circ_type = NULL;
+ const char *vrf_name;
struct interface *ifp;
- struct isis_area *area;
- struct vrf *vrf;
- /* area will be created if it is not present. make sure the yang model
- * is synced with FRR and call the appropriate NB cb.
- */
-
- if (!im)
- return CMD_SUCCESS;
-
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (!vrf_name) {
- if (ifp) {
- if (ifp->vrf_id == VRF_DEFAULT)
- vrf_name = VRF_DEFAULT_NAME;
- else {
- vrf = vrf_lookup_by_id(ifp->vrf_id);
- if (vrf && !vrf_name)
- vrf_name = vrf->name;
- }
- } else
- vrf_name = VRF_DEFAULT_NAME;
+ if_dnode = yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!if_dnode) {
+ vty_out(vty, "%% Failed to get iface dnode in candidate DB\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
- area = isis_area_lookup_by_vrf(tag, vrf_name);
- if (!area) {
- isis_global_instance_create(vrf_name);
- snprintf(temp_xpath, XPATH_MAXLEN,
- "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']",
- tag, vrf_name);
- nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, tag);
- snprintf(
- temp_xpath, XPATH_MAXLEN,
- "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']/is-type",
- tag, vrf_name);
- nb_cli_enqueue_change(vty, temp_xpath, NB_OP_MODIFY,
- listcount(im->isis) == 0 ? "level-1-2"
- : NULL);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
- NULL);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
- NB_OP_MODIFY, tag);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/vrf", NB_OP_MODIFY,
- vrf_name);
+ vrf_name = yang_dnode_get_string(if_dnode, "vrf");
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
- NB_OP_MODIFY, "true");
- nb_cli_enqueue_change(
- vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
- listcount(im->isis) == 0 ? "level-1-2" : "level-1");
- } else {
- /* area exists, circuit type defaults to its area's is_type */
- switch (area->is_type) {
- case IS_LEVEL_1:
- circ_type = "level-1";
- break;
- case IS_LEVEL_2:
- circ_type = "level-2";
- break;
- case IS_LEVEL_1_AND_2:
- circ_type = "level-1-2";
- break;
- default:
- /* just to silence compiler warnings */
- return CMD_WARNING_CONFIG_FAILED;
- }
- nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
- NULL);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
- NB_OP_MODIFY, tag);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/vrf", NB_OP_MODIFY,
- vrf_name);
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
- NB_OP_MODIFY, "true");
+ snprintf(inst_xpath, XPATH_MAXLEN,
+ "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
+ vrf_name);
+
+ /* if instance exists then inherit its type, create it otherwise */
+ inst_dnode = yang_dnode_get(vty->candidate_config->dnode, inst_xpath);
+ if (inst_dnode)
+ circ_type = yang_dnode_get_string(inst_dnode, "is-type");
+ else
+ nb_cli_enqueue_change(vty, inst_xpath, NB_OP_CREATE, NULL);
+
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE, NULL);
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag", NB_OP_MODIFY,
+ tag);
+ nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
+ NB_OP_MODIFY, "true");
+ if (circ_type)
nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
NB_OP_MODIFY, circ_type);
- }
/* check if the interface is a loopback and if so set it as passive */
+ ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (ifp && if_is_loopback(ifp))
nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
NB_OP_MODIFY, "true");
@@ -342,15 +259,21 @@ DEFPY_YANG(ip6_router_isis, ip6_router_isis_cmd,
return nb_cli_apply_changes(vty, NULL);
}
+ALIAS_HIDDEN(ip6_router_isis, ip6_router_isis_vrf_cmd,
+ "ipv6 router isis WORD$tag vrf NAME$vrf_name",
+ "Interface Internet Protocol config commands\n"
+ "IP router interface commands\n"
+ "IS-IS routing protocol\n"
+ "Routing process tag\n" VRF_CMD_HELP_STR)
+
DEFPY_YANG(no_ip_router_isis, no_ip_router_isis_cmd,
- "no <ip|ipv6>$ip router isis [WORD]$tag [vrf NAME$vrf_name]",
+ "no <ip|ipv6>$ip router isis [WORD]$tag",
NO_STR
"Interface Internet Protocol config commands\n"
"IP router interface commands\n"
"IP router interface commands\n"
"IS-IS routing protocol\n"
- "Routing process tag\n"
- VRF_CMD_HELP_STR)
+ "Routing process tag\n")
{
const struct lyd_node *dnode;
@@ -383,36 +306,32 @@ DEFPY_YANG(no_ip_router_isis, no_ip_router_isis_cmd,
return nb_cli_apply_changes(vty, NULL);
}
+ALIAS_HIDDEN(no_ip_router_isis, no_ip_router_isis_vrf_cmd,
+ "no <ip|ipv6>$ip router isis WORD$tag vrf NAME$vrf_name",
+ NO_STR
+ "Interface Internet Protocol config commands\n"
+ "IP router interface commands\n"
+ "IP router interface commands\n"
+ "IS-IS routing protocol\n"
+ "Routing process tag\n"
+ VRF_CMD_HELP_STR)
+
void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
- const char *vrf;
-
- vrf = yang_dnode_get_string(dnode, "../vrf");
-
if (!yang_dnode_get_bool(dnode, NULL))
vty_out(vty, " no");
- vty_out(vty, " ip router isis %s",
+ vty_out(vty, " ip router isis %s\n",
yang_dnode_get_string(dnode, "../area-tag"));
- if (!strmatch(vrf, VRF_DEFAULT_NAME))
- vty_out(vty, " vrf %s", vrf);
- vty_out(vty, "\n");
}
void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
- const char *vrf;
-
- vrf = yang_dnode_get_string(dnode, "../vrf");
-
if (!yang_dnode_get_bool(dnode, NULL))
vty_out(vty, " no");
- vty_out(vty, " ipv6 router isis %s",
+ vty_out(vty, " ipv6 router isis %s\n",
yang_dnode_get_string(dnode, "../area-tag"));
- if (!strmatch(vrf, VRF_DEFAULT_NAME))
- vty_out(vty, " vrf %s", vrf);
- vty_out(vty, "\n");
}
/*
@@ -2584,50 +2503,41 @@ DEFPY_YANG(no_isis_circuit_type, no_isis_circuit_type_cmd,
"Level-1-2 adjacencies are formed\n"
"Level-2 only adjacencies are formed\n")
{
- struct interface *ifp;
- struct isis_circuit *circuit;
- int is_type;
- const char *circ_type;
+ char inst_xpath[XPATH_MAXLEN];
+ struct lyd_node *if_dnode, *inst_dnode;
+ const char *vrf_name;
+ const char *tag;
+ const char *circ_type = NULL;
/*
* Default value depends on whether the circuit is part of an area,
* and the is-type of the area if there is one. So we need to do this
* here.
*/
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (!ifp)
- goto def_val;
+ if_dnode = yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!if_dnode) {
+ vty_out(vty, "%% Failed to get iface dnode in candidate DB\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- circuit = circuit_scan_by_ifp(ifp);
- if (!circuit)
- goto def_val;
+ if (!yang_dnode_exists(if_dnode, "frr-isisd:isis/area-tag")) {
+ vty_out(vty, "%% ISIS is not configured on the interface\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (circuit->state == C_STATE_UP)
- is_type = circuit->area->is_type;
- else
- goto def_val;
+ vrf_name = yang_dnode_get_string(if_dnode, "vrf");
+ tag = yang_dnode_get_string(if_dnode, "frr-isisd:isis/area-tag");
- switch (is_type) {
- case IS_LEVEL_1:
- circ_type = "level-1";
- break;
- case IS_LEVEL_2:
- circ_type = "level-2";
- break;
- case IS_LEVEL_1_AND_2:
- circ_type = "level-1-2";
- break;
- default:
- return CMD_ERR_NO_MATCH;
- }
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
- NB_OP_MODIFY, circ_type);
+ snprintf(inst_xpath, XPATH_MAXLEN,
+ "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
+ vrf_name);
- return nb_cli_apply_changes(vty, NULL);
+ inst_dnode = yang_dnode_get(vty->candidate_config->dnode, inst_xpath);
+ if (inst_dnode)
+ circ_type = yang_dnode_get_string(inst_dnode, "is-type");
-def_val:
nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
- NB_OP_MODIFY, NULL);
+ NB_OP_MODIFY, circ_type);
return nb_cli_apply_changes(vty, NULL);
}
@@ -2737,6 +2647,7 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode,
{
bool l1_enabled, l2_enabled;
bool l1_node_protection, l2_node_protection;
+ bool l1_link_fallback, l2_link_fallback;
/* Classic LFA */
l1_enabled = yang_dnode_get_bool(dnode, "./level-1/lfa/enable");
@@ -2782,13 +2693,21 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode,
yang_dnode_get_bool(dnode, "./level-1/ti-lfa/node-protection");
l2_node_protection =
yang_dnode_get_bool(dnode, "./level-2/ti-lfa/node-protection");
+ l1_link_fallback =
+ yang_dnode_get_bool(dnode, "./level-1/ti-lfa/link-fallback");
+ l2_link_fallback =
+ yang_dnode_get_bool(dnode, "./level-2/ti-lfa/link-fallback");
+
if (l1_enabled || l2_enabled) {
if (l1_enabled == l2_enabled
- && l1_node_protection == l2_node_protection) {
+ && l1_node_protection == l2_node_protection
+ && l1_link_fallback == l2_link_fallback) {
vty_out(vty, " isis fast-reroute ti-lfa");
if (l1_node_protection)
vty_out(vty, " node-protection");
+ if (l1_link_fallback)
+ vty_out(vty, " link-fallback");
vty_out(vty, "\n");
} else {
if (l1_enabled) {
@@ -2796,6 +2715,8 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode,
" isis fast-reroute ti-lfa level-1");
if (l1_node_protection)
vty_out(vty, " node-protection");
+ if (l1_link_fallback)
+ vty_out(vty, " link-fallback");
vty_out(vty, "\n");
}
if (l2_enabled) {
@@ -2803,6 +2724,8 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode,
" isis fast-reroute ti-lfa level-2");
if (l2_node_protection)
vty_out(vty, " node-protection");
+ if (l2_link_fallback)
+ vty_out(vty, " link-fallback");
vty_out(vty, "\n");
}
}
@@ -3007,14 +2930,15 @@ void cli_show_frr_remote_lfa_max_metric(struct vty *vty, struct lyd_node *dnode,
* XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/ti-lfa/enable
*/
DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
- "[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection]",
+ "[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection [link-fallback$link_fallback]]",
NO_STR
"IS-IS routing protocol\n"
"Interface IP Fast-reroute configuration\n"
"Enable TI-LFA computation\n"
"Enable TI-LFA computation for Level 1 only\n"
"Enable TI-LFA computation for Level 2 only\n"
- "Protect against node failures\n")
+ "Protect against node failures\n"
+ "Enable link-protection fallback\n")
{
if (!level || strmatch(level, "level-1")) {
if (no) {
@@ -3026,6 +2950,10 @@ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
vty,
"./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection",
NB_OP_MODIFY, "false");
+ nb_cli_enqueue_change(
+ vty,
+ "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback",
+ NB_OP_MODIFY, "false");
} else {
nb_cli_enqueue_change(
vty,
@@ -3036,6 +2964,10 @@ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
"./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection",
NB_OP_MODIFY,
node_protection ? "true" : "false");
+ nb_cli_enqueue_change(
+ vty,
+ "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback",
+ NB_OP_MODIFY, link_fallback ? "true" : "false");
}
}
if (!level || strmatch(level, "level-2")) {
@@ -3048,6 +2980,10 @@ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
vty,
"./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection",
NB_OP_MODIFY, "false");
+ nb_cli_enqueue_change(
+ vty,
+ "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback",
+ NB_OP_MODIFY, "false");
} else {
nb_cli_enqueue_change(
vty,
@@ -3058,6 +2994,10 @@ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
"./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection",
NB_OP_MODIFY,
node_protection ? "true" : "false");
+ nb_cli_enqueue_change(
+ vty,
+ "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback",
+ NB_OP_MODIFY, link_fallback ? "true" : "false");
}
}
@@ -3147,7 +3087,6 @@ DEFPY(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd,
NO_STR "IS-IS routing protocol\n" MPLS_STR MPLS_LDP_SYNC_STR)
{
const struct lyd_node *dnode;
- struct interface *ifp;
dnode = yang_dnode_get(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH);
@@ -3156,17 +3095,6 @@ DEFPY(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd,
return CMD_SUCCESS;
}
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (if_is_loopback(ifp)) {
- vty_out(vty, "ldp-sync does not run on loopback interface\n");
- return CMD_SUCCESS;
- }
-
- if (ifp->vrf_id != VRF_DEFAULT) {
- vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n");
- return CMD_SUCCESS;
- }
-
nb_cli_enqueue_change(vty, "./frr-isisd:isis/mpls/ldp-sync",
NB_OP_MODIFY, no ? "false" : "true");
@@ -3190,7 +3118,6 @@ DEFPY(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd,
"Time in seconds\n")
{
const struct lyd_node *dnode;
- struct interface *ifp;
dnode = yang_dnode_get(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH);
@@ -3199,17 +3126,6 @@ DEFPY(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd,
return CMD_SUCCESS;
}
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (if_is_loopback(ifp)) {
- vty_out(vty, "ldp-sync does not run on loopback interface\n");
- return CMD_SUCCESS;
- }
-
- if (ifp->vrf_id != VRF_DEFAULT) {
- vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n");
- return CMD_SUCCESS;
- }
-
nb_cli_enqueue_change(vty, "./frr-isisd:isis/mpls/holddown",
NB_OP_MODIFY, holddown_str);
@@ -3222,7 +3138,6 @@ DEFPY(no_isis_mpls_if_ldp_sync_holddown, no_isis_mpls_if_ldp_sync_holddown_cmd,
NO_MPLS_LDP_SYNC_HOLDDOWN_STR "Time in seconds\n")
{
const struct lyd_node *dnode;
- struct interface *ifp;
dnode = yang_dnode_get(vty->candidate_config->dnode,
"%s/frr-isisd:isis", VTY_CURR_XPATH);
@@ -3231,17 +3146,6 @@ DEFPY(no_isis_mpls_if_ldp_sync_holddown, no_isis_mpls_if_ldp_sync_holddown_cmd,
return CMD_SUCCESS;
}
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (if_is_loopback(ifp)) {
- vty_out(vty, "ldp-sync does not run on loopback interface\n");
- return CMD_SUCCESS;
- }
-
- if (ifp->vrf_id != VRF_DEFAULT) {
- vty_out(vty, "ldp-sync only runs on DEFAULT VRF\n");
- return CMD_SUCCESS;
- }
-
nb_cli_enqueue_change(vty, "./frr-isisd:isis/mpls/holddown",
NB_OP_DESTROY, NULL);
@@ -3262,8 +3166,11 @@ void isis_cli_init(void)
install_element(CONFIG_NODE, &no_router_isis_cmd);
install_element(INTERFACE_NODE, &ip_router_isis_cmd);
+ install_element(INTERFACE_NODE, &ip_router_isis_vrf_cmd);
install_element(INTERFACE_NODE, &ip6_router_isis_cmd);
+ install_element(INTERFACE_NODE, &ip6_router_isis_vrf_cmd);
install_element(INTERFACE_NODE, &no_ip_router_isis_cmd);
+ install_element(INTERFACE_NODE, &no_ip_router_isis_vrf_cmd);
install_element(INTERFACE_NODE, &isis_bfd_cmd);
install_element(INTERFACE_NODE, &isis_bfd_profile_cmd);
diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c
index ebb68ba3f0..0a29dcd09a 100644
--- a/isisd/isis_csm.c
+++ b/isisd/isis_csm.c
@@ -65,70 +65,56 @@ struct isis_circuit *isis_csm_state_change(enum isis_circuit_event event,
void *arg)
{
enum isis_circuit_state old_state;
- struct isis *isis = NULL;
struct isis_area *area = NULL;
struct interface *ifp;
- old_state = circuit ? circuit->state : C_STATE_NA;
+ assert(circuit);
+
+ old_state = circuit->state;
if (IS_DEBUG_EVENTS)
- zlog_debug("CSM_EVENT: %s", EVENT2STR(event));
+ zlog_debug("CSM_EVENT for %s: %s", circuit->interface->name,
+ EVENT2STR(event));
switch (old_state) {
case C_STATE_NA:
- if (circuit)
- zlog_warn("Non-null circuit while state C_STATE_NA");
- assert(circuit == NULL);
switch (event) {
case ISIS_ENABLE:
area = arg;
- circuit = isis_circuit_new(area->isis);
isis_circuit_configure(circuit, area);
circuit->state = C_STATE_CONF;
break;
case IF_UP_FROM_Z:
ifp = arg;
- isis = isis_lookup_by_vrfid(ifp->vrf_id);
- if (isis == NULL) {
- if (IS_DEBUG_EVENTS)
- zlog_debug(
- " %s : ISIS routing instance not found when attempting to apply against interface %s",
- __func__, ifp->name);
- break;
- }
- circuit = isis_circuit_new(isis);
+
isis_circuit_if_add(circuit, ifp);
- listnode_add(isis->init_circ_list, circuit);
circuit->state = C_STATE_INIT;
break;
case ISIS_DISABLE:
if (IS_DEBUG_EVENTS)
- zlog_debug(
- "circuit disable event passed for a non existent circuit");
+ zlog_debug("circuit %s already disabled",
+ circuit->interface->name);
break;
case IF_DOWN_FROM_Z:
if (IS_DEBUG_EVENTS)
- zlog_debug(
- "circuit disconnect event passed for a non existent circuit");
+ zlog_debug("circuit %s already disconnected",
+ circuit->interface->name);
break;
}
break;
case C_STATE_INIT:
- assert(circuit);
switch (event) {
case ISIS_ENABLE:
- isis_circuit_configure(circuit,
- (struct isis_area *)arg);
+ area = arg;
+
+ isis_circuit_configure(circuit, area);
if (isis_circuit_up(circuit) != ISIS_OK) {
- isis_circuit_deconfigure(
- circuit, (struct isis_area *)arg);
+ isis_circuit_deconfigure(circuit, area);
break;
}
circuit->state = C_STATE_UP;
isis_event_circuit_state_change(circuit, circuit->area,
1);
- listnode_delete(circuit->isis->init_circ_list,
- circuit);
break;
case IF_UP_FROM_Z:
if (IS_DEBUG_EVENTS)
@@ -141,26 +127,26 @@ struct isis_circuit *isis_csm_state_change(enum isis_circuit_event event,
circuit->interface->name);
break;
case IF_DOWN_FROM_Z:
- isis_circuit_if_del(circuit, (struct interface *)arg);
- listnode_delete(circuit->isis->init_circ_list,
- circuit);
- isis_circuit_del(circuit);
- circuit = NULL;
+ ifp = arg;
+
+ isis_circuit_if_del(circuit, ifp);
+ circuit->state = C_STATE_NA;
break;
}
break;
case C_STATE_CONF:
- assert(circuit);
switch (event) {
case ISIS_ENABLE:
if (IS_DEBUG_EVENTS)
- zlog_debug("circuit %p is already enabled",
- circuit);
+ zlog_debug("circuit %s is already enabled",
+ circuit->interface->name);
break;
case IF_UP_FROM_Z:
- isis_circuit_if_add(circuit, (struct interface *)arg);
+ ifp = arg;
+
+ isis_circuit_if_add(circuit, ifp);
if (isis_circuit_up(circuit) != ISIS_OK) {
- isis_circuit_if_del(circuit, (struct interface *)arg);
+ isis_circuit_if_del(circuit, ifp);
flog_err(
EC_ISIS_CONFIG,
"Could not bring up %s because of invalid config.",
@@ -172,24 +158,23 @@ struct isis_circuit *isis_csm_state_change(enum isis_circuit_event event,
1);
break;
case ISIS_DISABLE:
- isis_circuit_deconfigure(circuit,
- (struct isis_area *)arg);
- isis_circuit_del(circuit);
- circuit = NULL;
+ area = arg;
+
+ isis_circuit_deconfigure(circuit, area);
+ circuit->state = C_STATE_NA;
break;
case IF_DOWN_FROM_Z:
if (IS_DEBUG_EVENTS)
- zlog_debug("circuit %p already disconnected",
- circuit);
+ zlog_debug("circuit %s already disconnected",
+ circuit->interface->name);
break;
}
break;
case C_STATE_UP:
- assert(circuit);
switch (event) {
case ISIS_ENABLE:
if (IS_DEBUG_EVENTS)
- zlog_debug("circuit %s already configured",
+ zlog_debug("circuit %s already enabled",
circuit->interface->name);
break;
case IF_UP_FROM_Z:
@@ -198,18 +183,18 @@ struct isis_circuit *isis_csm_state_change(enum isis_circuit_event event,
circuit->interface->name);
break;
case ISIS_DISABLE:
- isis = circuit->isis;
+ area = arg;
+
isis_circuit_down(circuit);
- isis_circuit_deconfigure(circuit,
- (struct isis_area *)arg);
+ isis_circuit_deconfigure(circuit, area);
circuit->state = C_STATE_INIT;
- isis_event_circuit_state_change(
- circuit, (struct isis_area *)arg, 0);
- listnode_add(isis->init_circ_list, circuit);
+ isis_event_circuit_state_change(circuit, area, 0);
break;
case IF_DOWN_FROM_Z:
+ ifp = arg;
+
isis_circuit_down(circuit);
- isis_circuit_if_del(circuit, (struct interface *)arg);
+ isis_circuit_if_del(circuit, ifp);
circuit->state = C_STATE_CONF;
isis_event_circuit_state_change(circuit, circuit->area,
0);
@@ -220,8 +205,7 @@ struct isis_circuit *isis_csm_state_change(enum isis_circuit_event event,
if (IS_DEBUG_EVENTS)
zlog_debug("CSM_STATE_CHANGE: %s -> %s ", STATE2STR(old_state),
- circuit ? STATE2STR(circuit->state)
- : STATE2STR(C_STATE_NA));
+ STATE2STR(circuit->state));
return circuit;
}
diff --git a/isisd/isis_ldp_sync.c b/isisd/isis_ldp_sync.c
index 585f769806..62d8b8334a 100644
--- a/isisd/isis_ldp_sync.c
+++ b/isisd/isis_ldp_sync.c
@@ -65,28 +65,20 @@ int isis_ldp_sync_state_update(struct ldp_igp_sync_if_state state)
struct interface *ifp;
struct isis_circuit *circuit = NULL;
struct isis_area *area;
- struct listnode *node;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
-
- /* if isis is not enabled or LDP-SYNC is not configured ignore */
- if (!isis ||
- !CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
- return 0;
/* lookup circuit */
ifp = if_lookup_by_index(state.ifindex, VRF_DEFAULT);
if (ifp == NULL)
return 0;
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
- circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
- if (circuit != NULL)
- break;
- }
+ circuit = ifp->info;
+ if (circuit == NULL)
+ return 0;
/* if isis is not enabled or LDP-SYNC is not configured ignore */
- if (circuit == NULL ||
- !CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ area = circuit->area;
+ if (area == NULL
+ || !CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
return 0;
/* received ldp-sync interface state from LDP */
@@ -103,15 +95,12 @@ int isis_ldp_sync_state_update(struct ldp_igp_sync_if_state state)
int isis_ldp_sync_announce_update(struct ldp_igp_sync_announce announce)
{
struct isis_area *area;
- struct listnode *node;
- struct vrf *vrf;
- struct interface *ifp;
+ struct listnode *anode, *cnode;
struct isis_circuit *circuit;
struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
- /* if isis is not enabled or LDP-SYNC is not configured ignore */
- if (!isis ||
- !CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ /* if isis is not enabled ignore */
+ if (!isis)
return 0;
if (announce.proto != ZEBRA_ROUTE_LDP)
@@ -123,15 +112,12 @@ int isis_ldp_sync_announce_update(struct ldp_igp_sync_announce announce)
* set cost to LSInfinity
* send request to LDP for LDP-SYNC state for each interface
*/
- vrf = vrf_lookup_by_id(VRF_DEFAULT);
- FOR_ALL_INTERFACES (vrf, ifp) {
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
- circuit = circuit_lookup_by_ifp(ifp,
- area->circuit_list);
- if (circuit == NULL)
- continue;
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
+ if (!CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit))
isis_ldp_sync_if_start(circuit, true);
- }
}
return 0;
@@ -157,32 +143,6 @@ void isis_ldp_sync_state_req_msg(struct isis_circuit *circuit)
/*
* LDP-SYNC general interface routines
*/
-void isis_ldp_sync_if_init(struct isis_circuit *circuit, struct isis *isis)
-{
- struct ldp_sync_info *ldp_sync_info;
- struct interface *ifp = circuit->interface;
-
- /* called when ISIS is configured on an interface
- * if LDP-IGP Sync is configured globally set state
- * and if ptop interface LDP LDP-SYNC is enabled
- */
- ils_debug("ldp_sync: init if %s ", ifp->name);
- if (circuit->ldp_sync_info == NULL)
- circuit->ldp_sync_info = ldp_sync_info_create();
- ldp_sync_info = circuit->ldp_sync_info;
-
- /* specifed on interface overrides global config. */
- if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN))
- ldp_sync_info->holddown = isis->ldp_sync_cmd.holddown;
-
- if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG))
- ldp_sync_info->enabled = LDP_IGP_SYNC_ENABLED;
-
- if ((circuit->circ_type == CIRCUIT_T_P2P || if_is_pointopoint(ifp)) &&
- ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED)
- ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
-}
-
void isis_ldp_sync_if_start(struct isis_circuit *circuit,
bool send_state_req)
{
@@ -251,49 +211,17 @@ void isis_ldp_sync_ldp_fail(struct isis_circuit *circuit)
}
}
-void isis_ldp_sync_if_remove(struct isis_circuit *circuit, bool remove)
-{
- struct ldp_sync_info *ldp_sync_info;
-
- if (circuit->ldp_sync_info == NULL)
- return;
-
- ldp_sync_info = circuit->ldp_sync_info;
-
- /* Stop LDP-SYNC on this interface:
- * if holddown timer is running stop it
- * delete ldp instance on interface
- * restore metric
- */
- ils_debug("ldp_sync: remove if %s", circuit->interface
- ? circuit->interface->name : "");
-
- THREAD_OFF(ldp_sync_info->t_holddown);
- ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
- isis_ldp_sync_set_if_metric(circuit, true);
- if (remove) {
- /* ISIS instance being removed free ldp-sync info */
- ldp_sync_info_free((struct ldp_sync_info **)&(ldp_sync_info));
- circuit->ldp_sync_info = NULL;
- }
-}
-
static int isis_ldp_sync_adj_state_change(struct isis_adjacency *adj)
{
struct isis_circuit *circuit = adj->circuit;
- struct ldp_sync_info *ldp_sync_info;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+ struct ldp_sync_info *ldp_sync_info = circuit->ldp_sync_info;
+ struct isis_area *area = circuit->area;
- if (!isis ||
- !CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE) ||
- circuit->interface->vrf_id != VRF_DEFAULT ||
- if_is_loopback(circuit->interface))
+ if (!CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)
+ || circuit->interface->vrf_id != VRF_DEFAULT
+ || if_is_loopback(circuit->interface))
return 0;
- if (circuit->ldp_sync_info == NULL)
- isis_ldp_sync_if_init(circuit, isis);
- ldp_sync_info = circuit->ldp_sync_info;
-
if (ldp_sync_info->enabled != LDP_IGP_SYNC_ENABLED)
return 0;
@@ -329,16 +257,15 @@ bool isis_ldp_sync_if_metric_config(struct isis_circuit *circuit, int level,
int metric)
{
struct ldp_sync_info *ldp_sync_info = circuit->ldp_sync_info;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+ struct isis_area *area = circuit->area;
/* configured interface metric has been changed:
* if LDP-IGP Sync is running and metric has been set to LSInfinity
* change saved value so when ldp-sync completes proper metric is
* restored
*/
- if (isis &&
- CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE) &&
- ldp_sync_info != NULL) {
+ if (area && CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)
+ && ldp_sync_info != NULL) {
if (CHECK_FLAG(ldp_sync_info->flags,
LDP_SYNC_FLAG_SET_METRIC)) {
@@ -471,15 +398,12 @@ void isis_ldp_sync_holddown_timer_add(struct isis_circuit *circuit)
void isis_ldp_sync_handle_client_close(struct zapi_client_close_info *info)
{
struct isis_area *area;
- struct listnode *node;
+ struct listnode *anode, *cnode;
struct isis_circuit *circuit;
- struct interface *ifp;
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
- /* if isis is not enabled or LDP-SYNC is not configured ignore */
- if (!isis
- || !CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ /* if isis is not enabled ignore */
+ if (!isis)
return;
/* Check if the LDP main client session closed */
@@ -492,14 +416,12 @@ void isis_ldp_sync_handle_client_close(struct zapi_client_close_info *info)
*/
zlog_err("ldp_sync: LDP down");
- FOR_ALL_INTERFACES (vrf, ifp) {
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
- circuit =
- circuit_lookup_by_ifp(ifp, area->circuit_list);
- if (circuit == NULL)
- continue;
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
+ if (!CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit))
isis_ldp_sync_ldp_fail(circuit);
- }
}
}
@@ -507,110 +429,130 @@ void isis_ldp_sync_handle_client_close(struct zapi_client_close_info *info)
* LDP-SYNC routes used by set commands.
*/
-void isis_if_set_ldp_sync_enable(struct isis_circuit *circuit)
+void isis_area_ldp_sync_enable(struct isis_area *area)
{
- struct ldp_sync_info *ldp_sync_info;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+ struct isis_circuit *circuit;
+ struct listnode *node;
+
+ if (!CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) {
+ SET_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE);
+
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
+ isis_if_ldp_sync_enable(circuit);
+ }
+}
+
+void isis_area_ldp_sync_disable(struct isis_area *area)
+{
+ struct isis_circuit *circuit;
+ struct listnode *node;
+
+ if (CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) {
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
+ isis_if_ldp_sync_disable(circuit);
+
+ UNSET_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE);
+
+ UNSET_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN);
+ area->ldp_sync_cmd.holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
+ }
+}
+
+void isis_area_ldp_sync_set_holddown(struct isis_area *area, uint16_t holddown)
+{
+ struct isis_circuit *circuit;
+ struct listnode *node;
+
+ if (holddown == LDP_IGP_SYNC_HOLDDOWN_DEFAULT)
+ UNSET_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN);
+ else
+ SET_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN);
+
+ area->ldp_sync_cmd.holddown = holddown;
+
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
+ isis_if_set_ldp_sync_holddown(circuit);
+}
+
+void isis_if_ldp_sync_enable(struct isis_circuit *circuit)
+{
+ struct ldp_sync_info *ldp_sync_info = circuit->ldp_sync_info;
+ struct isis_area *area = circuit->area;
/* called when setting LDP-SYNC at the global level:
* specifed on interface overrides global config
* if ptop link send msg to LDP indicating ldp-sync enabled
*/
- if (!isis || if_is_loopback(circuit->interface))
+ if (if_is_loopback(circuit->interface))
return;
- if (CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) {
- if (circuit->ldp_sync_info == NULL)
- isis_ldp_sync_if_init(circuit, isis);
- ldp_sync_info = circuit->ldp_sync_info;
+ ils_debug("ldp_sync: enable if %s", circuit->interface->name);
- /* config on interface, overrides global config. */
- if (CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG))
- if (ldp_sync_info->enabled != LDP_IGP_SYNC_ENABLED)
- return;
+ if (!CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ return;
- ldp_sync_info->enabled = LDP_IGP_SYNC_ENABLED;
- ils_debug("ldp_sync: enable if %s", circuit->interface->name);
+ /* config on interface, overrides global config. */
+ if (CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG))
+ if (ldp_sync_info->enabled != LDP_IGP_SYNC_ENABLED)
+ return;
- /* send message to LDP if ptop link */
- if (circuit->circ_type == CIRCUIT_T_P2P ||
- if_is_pointopoint(circuit->interface)) {
- ldp_sync_info->state =
- LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
- isis_ldp_sync_state_req_msg(circuit);
- } else {
- ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
- zlog_debug("ldp_sync: Sync only runs on P2P links %s",
- circuit->interface->name);
- }
- } else
- /* delete LDP sync even if configured on an interface */
- isis_ldp_sync_if_remove(circuit, false);
+ if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN))
+ ldp_sync_info->holddown = area->ldp_sync_cmd.holddown;
+
+ if (circuit->circ_type == CIRCUIT_T_P2P
+ || if_is_pointopoint(circuit->interface)) {
+ ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
+ isis_ldp_sync_state_req_msg(circuit);
+ } else {
+ ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
+ ils_debug("ldp_sync: Sync only runs on P2P links %s",
+ circuit->interface->name);
+ }
+}
+
+void isis_if_ldp_sync_disable(struct isis_circuit *circuit)
+{
+ struct ldp_sync_info *ldp_sync_info = circuit->ldp_sync_info;
+ struct isis_area *area = circuit->area;
+
+ /* Stop LDP-SYNC on this interface:
+ * if holddown timer is running stop it
+ * delete ldp instance on interface
+ * restore metric
+ */
+ if (if_is_loopback(circuit->interface))
+ return;
+
+ ils_debug("ldp_sync: remove if %s", circuit->interface->name);
+
+ if (!CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
+ return;
+
+ THREAD_OFF(ldp_sync_info->t_holddown);
+ ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
+ isis_ldp_sync_set_if_metric(circuit, true);
}
void isis_if_set_ldp_sync_holddown(struct isis_circuit *circuit)
{
- struct ldp_sync_info *ldp_sync_info;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+ struct ldp_sync_info *ldp_sync_info = circuit->ldp_sync_info;
+ struct isis_area *area = circuit->area;
/* called when setting LDP-SYNC at the global level:
* specifed on interface overrides global config.
*/
- if (!isis || if_is_loopback(circuit->interface))
+ if (if_is_loopback(circuit->interface))
return;
- if (circuit->ldp_sync_info == NULL)
- isis_ldp_sync_if_init(circuit, isis);
- ldp_sync_info = circuit->ldp_sync_info;
-
/* config on interface, overrides global config. */
if (CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN))
return;
- if (CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN))
- ldp_sync_info->holddown = isis->ldp_sync_cmd.holddown;
+ if (CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN))
+ ldp_sync_info->holddown = area->ldp_sync_cmd.holddown;
else
ldp_sync_info->holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
}
-void isis_ldp_sync_gbl_exit(bool remove)
-{
- struct isis_area *area;
- struct listnode *node;
- struct isis_circuit *circuit;
- struct interface *ifp;
- struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
-
- /* if you delete LDP-SYNC at a gobal level is clears all LDP-SYNC
- * configuration, even interface configuration
- */
- if (isis &&
- CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) {
- /* register with opaque client to recv LDP-IGP Sync msgs */
- zclient_unregister_opaque(zclient,
- LDP_IGP_SYNC_IF_STATE_UPDATE);
- zclient_unregister_opaque(zclient,
- LDP_IGP_SYNC_ANNOUNCE_UPDATE);
-
- /* disable LDP-SYNC globally */
- UNSET_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE);
- UNSET_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN);
- isis->ldp_sync_cmd.holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
-
- /* remove LDP-SYNC on all ISIS interfaces */
- FOR_ALL_INTERFACES (vrf, ifp) {
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
- area)) {
- circuit = circuit_lookup_by_ifp(ifp,
- area->circuit_list);
- if (circuit == NULL)
- continue;
- isis_ldp_sync_if_remove(circuit, remove);
- }
- }
- }
-}
-
/*
* LDP-SYNC routines used by show commands.
*/
@@ -693,11 +635,6 @@ DEFUN (show_isis_mpls_ldp_interface,
return CMD_SUCCESS;
}
- if (!CHECK_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) {
- vty_out(vty, "LDP-sync is disabled\n");
- return CMD_SUCCESS;
- }
-
if (argv_find(argv, argc, "INTERFACE", &idx_intf))
ifname = argv[idx_intf]->arg;
diff --git a/isisd/isis_ldp_sync.h b/isisd/isis_ldp_sync.h
index 977c5ba0de..69a1800007 100644
--- a/isisd/isis_ldp_sync.h
+++ b/isisd/isis_ldp_sync.h
@@ -29,13 +29,15 @@
zlog_debug(__VA_ARGS__); \
} while (0)
-extern void isis_if_set_ldp_sync_enable(struct isis_circuit *circuit);
+extern void isis_area_ldp_sync_enable(struct isis_area *area);
+extern void isis_area_ldp_sync_disable(struct isis_area *area);
+extern void isis_area_ldp_sync_set_holddown(struct isis_area *area,
+ uint16_t holddown);
+extern void isis_if_ldp_sync_enable(struct isis_circuit *circuit);
+extern void isis_if_ldp_sync_disable(struct isis_circuit *circuit);
extern void isis_if_set_ldp_sync_holddown(struct isis_circuit *circuit);
-extern void isis_ldp_sync_if_init(struct isis_circuit *circuit,
- struct isis *isis);
extern void isis_ldp_sync_if_start(struct isis_circuit *circuit,
bool send_state_req);
-extern void isis_ldp_sync_if_remove(struct isis_circuit *circuit, bool remove);
extern void isis_ldp_sync_if_complete(struct isis_circuit *circuit);
extern void isis_ldp_sync_holddown_timer_add(struct isis_circuit *circuit);
extern void
@@ -49,5 +51,4 @@ extern void isis_ldp_sync_set_if_metric(struct isis_circuit *circuit,
extern bool isis_ldp_sync_if_metric_config(struct isis_circuit *circuit,
int level, int metric);
extern void isis_ldp_sync_init(void);
-extern void isis_ldp_sync_gbl_exit(bool remove);
#endif /* _ZEBRA_ISIS_LDP_SYNC_H */
diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c
index 085177b943..e033c28fef 100644
--- a/isisd/isis_lfa.c
+++ b/isisd/isis_lfa.c
@@ -1148,10 +1148,13 @@ static void lfa_calc_pq_spaces(struct isis_spftree *spftree_pc,
/*
* Compute the reverse SPF in the behalf of the node
- * adjacent to the failure.
+ * adjacent to the failure, if we haven't done that
+ * before
*/
- adj_node->lfa.spftree_reverse =
- isis_spf_reverse_run(adj_node->lfa.spftree);
+ if (!adj_node->lfa.spftree_reverse)
+ adj_node->lfa.spftree_reverse =
+ isis_spf_reverse_run(
+ adj_node->lfa.spftree);
lfa_calc_reach_nodes(adj_node->lfa.spftree_reverse,
spftree_reverse, adj_nodes, false,
@@ -2255,6 +2258,11 @@ static void isis_spf_run_tilfa(struct isis_area *area,
spftree_pc_node = isis_tilfa_compute(area, spftree,
spftree_reverse, resource);
isis_spftree_del(spftree_pc_node);
+
+ /* don't do link protection unless link-fallback is configured
+ */
+ if (!circuit->tilfa_link_fallback[spftree->level - 1])
+ return;
}
/* Compute link protecting repair paths. */
diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c
index 227724934b..ecad16229c 100644
--- a/isisd/isis_nb.c
+++ b/isisd/isis_nb.c
@@ -686,13 +686,6 @@ const struct frr_yang_module_info frr_isisd_info = {
},
},
{
- .xpath = "/frr-interface:lib/interface/frr-isisd:isis/vrf",
- .cbs = {
- .modify = lib_interface_isis_vrf_modify,
- },
- },
-
- {
.xpath = "/frr-interface:lib/interface/frr-isisd:isis/circuit-type",
.cbs = {
.cli_show = cli_show_ip_isis_circ_type,
@@ -985,6 +978,12 @@ const struct frr_yang_module_info frr_isisd_info = {
}
},
{
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback",
+ .cbs = {
+ .modify = lib_interface_isis_fast_reroute_level_1_ti_lfa_link_fallback_modify,
+ }
+ },
+ {
.xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/lfa/enable",
.cbs = {
.modify = lib_interface_isis_fast_reroute_level_2_lfa_enable_modify,
@@ -1025,6 +1024,12 @@ const struct frr_yang_module_info frr_isisd_info = {
}
},
{
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback",
+ .cbs = {
+ .modify = lib_interface_isis_fast_reroute_level_2_ti_lfa_link_fallback_modify,
+ }
+ },
+ {
.xpath = "/frr-interface:lib/interface/state/frr-isisd:isis",
.cbs = {
.get_elem = lib_interface_state_isis_get_elem,
diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h
index a6841b9fd4..0c2f7b6b7e 100644
--- a/isisd/isis_nb.h
+++ b/isisd/isis_nb.h
@@ -214,7 +214,6 @@ int isis_instance_mpls_te_router_address_destroy(
int lib_interface_isis_create(struct nb_cb_create_args *args);
int lib_interface_isis_destroy(struct nb_cb_destroy_args *args);
int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args);
-int lib_interface_isis_vrf_modify(struct nb_cb_modify_args *args);
int lib_interface_isis_ipv4_routing_modify(struct nb_cb_modify_args *args);
int lib_interface_isis_ipv6_routing_modify(struct nb_cb_modify_args *args);
int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args);
@@ -320,6 +319,8 @@ int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify(
struct nb_cb_modify_args *args);
int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify(
struct nb_cb_modify_args *args);
+int lib_interface_isis_fast_reroute_level_1_ti_lfa_link_fallback_modify(
+ struct nb_cb_modify_args *args);
int lib_interface_isis_fast_reroute_level_2_lfa_enable_modify(
struct nb_cb_modify_args *args);
int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_create(
@@ -336,6 +337,8 @@ int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify(
struct nb_cb_modify_args *args);
int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify(
struct nb_cb_modify_args *args);
+int lib_interface_isis_fast_reroute_level_2_ti_lfa_link_fallback_modify(
+ struct nb_cb_modify_args *args);
struct yang_data *
lib_interface_state_isis_get_elem(struct nb_cb_get_elem_args *args);
const void *lib_interface_state_isis_adjacencies_adjacency_get_next(
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index c8ad816b58..5ca2329dd3 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -32,7 +32,6 @@
#include "spf_backoff.h"
#include "lib_errors.h"
#include "vrf.h"
-#include "zclient.h"
#include "ldp_sync.h"
#include "isisd/isisd.h"
@@ -56,8 +55,6 @@
DEFINE_MTYPE_STATIC(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters");
DEFINE_MTYPE_STATIC(ISISD, ISIS_PLIST_NAME, "ISIS prefix-list name");
-extern struct zclient *zclient;
-
/*
* XPath: /frr-isisd:isis/instance
*/
@@ -87,16 +84,10 @@ int isis_instance_create(struct nb_cb_create_args *args)
int isis_instance_destroy(struct nb_cb_destroy_args *args)
{
struct isis_area *area;
- vrf_id_t vrf_id;
if (args->event != NB_EV_APPLY)
return NB_OK;
area = nb_running_unset_entry(args->dnode);
- vrf_id = area->isis->vrf_id;
-
- /* remove ldp-sync config */
- if (vrf_id == VRF_DEFAULT)
- isis_ldp_sync_gbl_exit(true);
isis_area_destroy(area);
return NB_OK;
@@ -2369,11 +2360,6 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args)
{
struct isis_area *area;
- struct listnode *node;
- struct isis_circuit *circuit;
- struct interface *ifp;
- struct vrf *vrf;
- struct isis *isis;
switch (args->event) {
case NB_EV_VALIDATE:
@@ -2392,30 +2378,7 @@ int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args)
break;
case NB_EV_APPLY:
area = nb_running_get_entry(args->dnode, NULL, true);
- isis = area->isis;
- vrf = vrf_lookup_by_id(isis->vrf_id);
-
- /* register with opaque client to recv LDP-IGP Sync msgs */
- zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE);
- zclient_register_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE);
-
- if (!CHECK_FLAG(isis->ldp_sync_cmd.flags,
- LDP_SYNC_FLAG_ENABLE)) {
- SET_FLAG(isis->ldp_sync_cmd.flags,
- LDP_SYNC_FLAG_ENABLE);
-
- /* turn on LDP-IGP Sync on all ptop ISIS interfaces */
- FOR_ALL_INTERFACES (vrf, ifp) {
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
- area)) {
- circuit = circuit_lookup_by_ifp(
- ifp, area->circuit_list);
- if (circuit == NULL)
- continue;
- isis_if_set_ldp_sync_enable(circuit);
- }
- }
- }
+ isis_area_ldp_sync_enable(area);
break;
}
return NB_OK;
@@ -2423,11 +2386,13 @@ int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args)
int isis_instance_mpls_ldp_sync_destroy(struct nb_cb_destroy_args *args)
{
+ struct isis_area *area;
+
if (args->event != NB_EV_APPLY)
return NB_OK;
- /* remove ldp-sync config */
- isis_ldp_sync_gbl_exit(false);
+ area = nb_running_get_entry(args->dnode, NULL, true);
+ isis_area_ldp_sync_disable(area);
return NB_OK;
}
@@ -2438,12 +2403,7 @@ int isis_instance_mpls_ldp_sync_destroy(struct nb_cb_destroy_args *args)
int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args)
{
struct isis_area *area;
- struct listnode *node;
- struct isis_circuit *circuit;
- struct interface *ifp;
- struct vrf *vrf;
- uint16_t holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
- struct isis *isis;
+ uint16_t holddown;
switch (args->event) {
case NB_EV_VALIDATE:
@@ -2462,29 +2422,8 @@ int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args)
break;
case NB_EV_APPLY:
area = nb_running_get_entry(args->dnode, NULL, true);
- isis = area->isis;
- vrf = vrf_lookup_by_id(isis->vrf_id);
holddown = yang_dnode_get_uint16(args->dnode, NULL);
-
- if (holddown == LDP_IGP_SYNC_HOLDDOWN_DEFAULT)
- UNSET_FLAG(isis->ldp_sync_cmd.flags,
- LDP_SYNC_FLAG_HOLDDOWN);
- else
- SET_FLAG(isis->ldp_sync_cmd.flags,
- LDP_SYNC_FLAG_HOLDDOWN);
- isis->ldp_sync_cmd.holddown = holddown;
-
- /* set holddown time on all ISIS interfaces */
- FOR_ALL_INTERFACES (vrf, ifp) {
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
- area)) {
- circuit = circuit_lookup_by_ifp(ifp,
- area->circuit_list);
- if (circuit == NULL)
- continue;
- isis_if_set_ldp_sync_holddown(circuit);
- }
- }
+ isis_area_ldp_sync_set_holddown(area, holddown);
break;
}
return NB_OK;
@@ -2498,9 +2437,7 @@ int lib_interface_isis_create(struct nb_cb_create_args *args)
struct isis_area *area = NULL;
struct interface *ifp;
struct isis_circuit *circuit = NULL;
- struct vrf *vrf;
const char *area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
- const char *vrf_name = yang_dnode_get_string(args->dnode, "./vrf");
uint32_t min_mtu, actual_mtu;
switch (args->event) {
@@ -2515,14 +2452,6 @@ int lib_interface_isis_create(struct nb_cb_create_args *args)
/* zebra might not know yet about the MTU - nothing we can do */
if (!ifp || ifp->mtu == 0)
break;
- vrf = vrf_lookup_by_id(ifp->vrf_id);
- if (ifp->vrf_id != VRF_DEFAULT && vrf
- && strcmp(vrf->name, vrf_name) != 0) {
- snprintf(args->errmsg, args->errmsg_len,
- "interface %s not in vrf %s\n", ifp->name,
- vrf_name);
- return NB_ERR_VALIDATION;
- }
actual_mtu =
if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
@@ -2544,24 +2473,8 @@ int lib_interface_isis_create(struct nb_cb_create_args *args)
}
break;
case NB_EV_APPLY:
- area = isis_area_lookup_by_vrf(area_tag, vrf_name);
- /* The area should have already be created. We are
- * setting the priority of the global isis area creation
- * slightly lower, so it should be executed first, but I
- * cannot rely on that so here I have to check.
- */
- if (!area) {
- flog_err(
- EC_LIB_NB_CB_CONFIG_APPLY,
- "%s: attempt to create circuit for area %s before the area has been created",
- __func__, area_tag);
- abort();
- }
ifp = nb_running_get_entry(args->dnode, NULL, true);
- circuit = isis_circuit_create(area, ifp);
- assert(circuit
- && (circuit->state == C_STATE_CONF
- || circuit->state == C_STATE_UP));
+ circuit = isis_circuit_new(ifp, area_tag);
nb_running_set_entry(args->dnode, circuit);
break;
}
@@ -2577,18 +2490,9 @@ int lib_interface_isis_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
circuit = nb_running_unset_entry(args->dnode);
- if (!circuit)
- return NB_ERR_INCONSISTENCY;
- /* remove ldp-sync config */
- isis_ldp_sync_if_remove(circuit, true);
+ isis_circuit_del(circuit);
- /* disable both AFs for this circuit. this will also update the
- * CSM state by sending an ISIS_DISABLED signal. If there is no
- * area associated to the circuit there is nothing to do
- */
- if (circuit->area)
- isis_circuit_af_set(circuit, false, false);
return NB_OK;
}
@@ -2631,44 +2535,6 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
}
/*
- * XPath: /frr-interface:lib/interface/frr-isisd:isis/vrf
- */
-int lib_interface_isis_vrf_modify(struct nb_cb_modify_args *args)
-{
- struct interface *ifp;
- struct vrf *vrf;
- const char *ifname, *vrfname, *vrf_name;
- struct isis_circuit *circuit;
-
- if (args->event == NB_EV_VALIDATE) {
- /* libyang doesn't like relative paths across module boundaries
- */
- ifname = yang_dnode_get_string(args->dnode->parent->parent,
- "./name");
- vrfname = yang_dnode_get_string(args->dnode->parent->parent,
- "./vrf");
- vrf = vrf_lookup_by_name(vrfname);
- assert(vrf);
- ifp = if_lookup_by_name(ifname, vrf->vrf_id);
-
- if (!ifp)
- return NB_OK;
-
- vrf_name = yang_dnode_get_string(args->dnode, NULL);
- circuit = circuit_scan_by_ifp(ifp);
- if (circuit && circuit->area && circuit->isis
- && strcmp(circuit->isis->name, vrf_name)) {
- snprintf(args->errmsg, args->errmsg_len,
- "ISIS circuit is already defined on vrf %s",
- circuit->isis->name);
- return NB_ERR_VALIDATION;
- }
- }
-
- return NB_OK;
-}
-
-/*
* XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type
*/
int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
@@ -2678,7 +2544,6 @@ int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
struct interface *ifp;
struct vrf *vrf;
const char *ifname, *vrfname;
- struct isis *isis = NULL;
switch (args->event) {
case NB_EV_VALIDATE:
@@ -2694,11 +2559,7 @@ int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
if (!ifp)
break;
- isis = isis_lookup_by_vrfid(ifp->vrf_id);
- if (isis == NULL)
- return NB_ERR_VALIDATION;
-
- circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
+ circuit = circuit_scan_by_ifp(ifp);
if (circuit && circuit->state == C_STATE_UP
&& circuit->area->is_type != IS_LEVEL_1_AND_2
&& circuit->area->is_type != circ_type) {
@@ -3085,7 +2946,6 @@ int lib_interface_isis_network_type_modify(struct nb_cb_modify_args *args)
int lib_interface_isis_passive_modify(struct nb_cb_modify_args *args)
{
struct isis_circuit *circuit;
- struct isis_area *area;
struct interface *ifp;
bool passive = yang_dnode_get_bool(args->dnode, NULL);
@@ -3108,14 +2968,7 @@ int lib_interface_isis_passive_modify(struct nb_cb_modify_args *args)
return NB_OK;
circuit = nb_running_get_entry(args->dnode, NULL, true);
- if (circuit->state != C_STATE_UP) {
- circuit->is_passive = passive;
- } else {
- area = circuit->area;
- isis_csm_state_change(ISIS_DISABLE, circuit, area);
- circuit->is_passive = passive;
- isis_csm_state_change(ISIS_ENABLE, circuit, area);
- }
+ isis_circuit_passive_set(circuit, passive);
return NB_OK;
}
@@ -3318,13 +3171,23 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args)
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
bool ldp_sync_enable;
- struct isis *isis;
+ struct interface *ifp;
switch (args->event) {
case NB_EV_VALIDATE:
+ ifp = nb_running_get_entry(args->dnode->parent->parent->parent,
+ NULL, false);
+ if (ifp == NULL)
+ return NB_ERR_VALIDATION;
+ if (if_is_loopback(ifp)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "LDP-Sync does not run on loopback interface");
+ return NB_ERR_VALIDATION;
+ }
+
circuit = nb_running_get_entry(args->dnode, NULL, false);
if (circuit == NULL || circuit->area == NULL)
- return NB_ERR_VALIDATION;
+ break;
if (circuit->isis->vrf_id != VRF_DEFAULT) {
snprintf(args->errmsg, args->errmsg_len,
@@ -3338,39 +3201,17 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args)
case NB_EV_APPLY:
circuit = nb_running_get_entry(args->dnode, NULL, true);
ldp_sync_enable = yang_dnode_get_bool(args->dnode, NULL);
- isis = circuit->isis;
- if (circuit->ldp_sync_info == NULL)
- isis_ldp_sync_if_init(circuit, isis);
- assert(circuit->ldp_sync_info != NULL);
ldp_sync_info = circuit->ldp_sync_info;
- if (ldp_sync_enable) {
- /* enable LDP-SYNC on an interface
- * if ptop interface send message to LDP to get state
- */
- SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG);
- ldp_sync_info->enabled = LDP_IGP_SYNC_ENABLED;
- if (circuit->circ_type == CIRCUIT_T_P2P) {
- ldp_sync_info->state =
- LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
- isis_ldp_sync_state_req_msg(circuit);
- } else {
- zlog_debug("ldp_sync: only runs on P2P links %s",
- circuit->interface->name);
- ldp_sync_info->state =
- LDP_IGP_SYNC_STATE_NOT_REQUIRED;
- }
- } else {
- /* disable LDP-SYNC on an interface
- * stop holddown timer if running
- * restore isis metric
- */
- SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG);
- ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT;
- ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
- THREAD_OFF(ldp_sync_info->t_holddown);
- isis_ldp_sync_set_if_metric(circuit, true);
+ SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG);
+ ldp_sync_info->enabled = ldp_sync_enable;
+
+ if (circuit->area) {
+ if (ldp_sync_enable)
+ isis_if_ldp_sync_enable(circuit);
+ else
+ isis_if_ldp_sync_disable(circuit);
}
break;
}
@@ -3385,13 +3226,23 @@ int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args)
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
uint16_t holddown;
- struct isis *isis;
+ struct interface *ifp;
switch (args->event) {
case NB_EV_VALIDATE:
+ ifp = nb_running_get_entry(args->dnode->parent->parent->parent,
+ NULL, false);
+ if (ifp == NULL)
+ return NB_ERR_VALIDATION;
+ if (if_is_loopback(ifp)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "LDP-Sync does not run on loopback interface");
+ return NB_ERR_VALIDATION;
+ }
+
circuit = nb_running_get_entry(args->dnode, NULL, false);
if (circuit == NULL || circuit->area == NULL)
- return NB_ERR_VALIDATION;
+ break;
if (circuit->isis->vrf_id != VRF_DEFAULT) {
snprintf(args->errmsg, args->errmsg_len,
@@ -3405,11 +3256,7 @@ int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args)
case NB_EV_APPLY:
circuit = nb_running_get_entry(args->dnode, NULL, true);
holddown = yang_dnode_get_uint16(args->dnode, NULL);
- isis = circuit->isis;
- if (circuit->ldp_sync_info == NULL)
- isis_ldp_sync_if_init(circuit, isis);
- assert(circuit->ldp_sync_info != NULL);
ldp_sync_info = circuit->ldp_sync_info;
SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN);
@@ -3423,14 +3270,23 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args)
{
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
- struct isis *isis;
+ struct interface *ifp;
switch (args->event) {
case NB_EV_VALIDATE:
- circuit = nb_running_get_entry(args->dnode, NULL, false);
- if (circuit == NULL || circuit->ldp_sync_info == NULL
- || circuit->area == NULL)
+ ifp = nb_running_get_entry(args->dnode->parent->parent->parent,
+ NULL, false);
+ if (ifp == NULL)
+ return NB_ERR_VALIDATION;
+ if (if_is_loopback(ifp)) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "LDP-Sync does not run on loopback interface");
return NB_ERR_VALIDATION;
+ }
+
+ circuit = nb_running_get_entry(args->dnode, NULL, false);
+ if (circuit == NULL || circuit->area == NULL)
+ break;
if (circuit->isis->vrf_id != VRF_DEFAULT) {
snprintf(args->errmsg, args->errmsg_len,
@@ -3443,15 +3299,12 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args)
break;
case NB_EV_APPLY:
circuit = nb_running_get_entry(args->dnode, NULL, true);
- isis = circuit->isis;
ldp_sync_info = circuit->ldp_sync_info;
+
UNSET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN);
- if (CHECK_FLAG(isis->ldp_sync_cmd.flags,
- LDP_SYNC_FLAG_HOLDDOWN))
- ldp_sync_info->holddown = isis->ldp_sync_cmd.holddown;
- else
- ldp_sync_info->holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
+ if (circuit->area)
+ isis_if_set_ldp_sync_holddown(circuit);
break;
}
@@ -3473,15 +3326,18 @@ int lib_interface_isis_fast_reroute_level_1_lfa_enable_modify(
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->lfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->lfa_protection[0])
- circuit->area->lfa_protected_links[0]++;
- else {
- assert(circuit->area->lfa_protected_links[0] > 0);
- circuit->area->lfa_protected_links[0]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->lfa_protection[0])
+ area->lfa_protected_links[0]++;
+ else {
+ assert(area->lfa_protected_links[0] > 0);
+ area->lfa_protected_links[0]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
@@ -3505,7 +3361,8 @@ int lib_interface_isis_fast_reroute_level_1_lfa_exclude_interface_create(
isis_lfa_excluded_iface_add(circuit, ISIS_LEVEL1, exclude_ifname);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3525,7 +3382,8 @@ int lib_interface_isis_fast_reroute_level_1_lfa_exclude_interface_destroy(
isis_lfa_excluded_iface_delete(circuit, ISIS_LEVEL1, exclude_ifname);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3545,15 +3403,18 @@ int lib_interface_isis_fast_reroute_level_1_remote_lfa_enable_modify(
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->rlfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->rlfa_protection[0])
- circuit->area->rlfa_protected_links[0]++;
- else {
- assert(circuit->area->rlfa_protected_links[0] > 0);
- circuit->area->rlfa_protected_links[0]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->rlfa_protection[0])
+ area->rlfa_protected_links[0]++;
+ else {
+ assert(area->rlfa_protected_links[0] > 0);
+ area->rlfa_protected_links[0]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
@@ -3575,7 +3436,8 @@ int lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_modify(
circuit->rlfa_max_metric[0] = yang_dnode_get_uint32(args->dnode, NULL);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3593,7 +3455,8 @@ int lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_destroy(
circuit->rlfa_max_metric[0] = 0;
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3613,15 +3476,18 @@ int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify(
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->tilfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->tilfa_protection[0])
- circuit->area->tilfa_protected_links[0]++;
- else {
- assert(circuit->area->tilfa_protected_links[0] > 0);
- circuit->area->tilfa_protected_links[0]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->tilfa_protection[0])
+ area->tilfa_protected_links[0]++;
+ else {
+ assert(area->tilfa_protected_links[0] > 0);
+ area->tilfa_protected_links[0]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
@@ -3644,7 +3510,32 @@ int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify(
yang_dnode_get_bool(args->dnode, NULL);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
+
+ return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/link-fallback
+ */
+int lib_interface_isis_fast_reroute_level_1_ti_lfa_link_fallback_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct isis_area *area;
+ struct isis_circuit *circuit;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ circuit = nb_running_get_entry(args->dnode, NULL, true);
+ circuit->tilfa_link_fallback[0] =
+ yang_dnode_get_bool(args->dnode, NULL);
+
+ area = circuit->area;
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3664,15 +3555,18 @@ int lib_interface_isis_fast_reroute_level_2_lfa_enable_modify(
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->lfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->lfa_protection[1])
- circuit->area->lfa_protected_links[1]++;
- else {
- assert(circuit->area->lfa_protected_links[1] > 0);
- circuit->area->lfa_protected_links[1]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->lfa_protection[1])
+ area->lfa_protected_links[1]++;
+ else {
+ assert(area->lfa_protected_links[1] > 0);
+ area->lfa_protected_links[1]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
@@ -3696,7 +3590,8 @@ int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_create(
isis_lfa_excluded_iface_add(circuit, ISIS_LEVEL2, exclude_ifname);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3716,7 +3611,8 @@ int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_destroy(
isis_lfa_excluded_iface_delete(circuit, ISIS_LEVEL2, exclude_ifname);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3736,15 +3632,18 @@ int lib_interface_isis_fast_reroute_level_2_remote_lfa_enable_modify(
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->rlfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->rlfa_protection[1])
- circuit->area->rlfa_protected_links[1]++;
- else {
- assert(circuit->area->rlfa_protected_links[1] > 0);
- circuit->area->rlfa_protected_links[1]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->rlfa_protection[1])
+ area->rlfa_protected_links[1]++;
+ else {
+ assert(area->rlfa_protected_links[1] > 0);
+ area->rlfa_protected_links[1]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
@@ -3766,7 +3665,8 @@ int lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_modify(
circuit->rlfa_max_metric[1] = yang_dnode_get_uint32(args->dnode, NULL);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3784,7 +3684,8 @@ int lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_destroy(
circuit->rlfa_max_metric[1] = 0;
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
@@ -3804,15 +3705,18 @@ int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify(
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->tilfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->tilfa_protection[1])
- circuit->area->tilfa_protected_links[1]++;
- else {
- assert(circuit->area->tilfa_protected_links[1] > 0);
- circuit->area->tilfa_protected_links[1]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->tilfa_protection[1])
+ area->tilfa_protected_links[1]++;
+ else {
+ assert(area->tilfa_protected_links[1] > 0);
+ area->tilfa_protected_links[1]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
@@ -3835,7 +3739,32 @@ int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify(
yang_dnode_get_bool(args->dnode, NULL);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
+
+ return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/link-fallback
+ */
+int lib_interface_isis_fast_reroute_level_2_ti_lfa_link_fallback_modify(
+ struct nb_cb_modify_args *args)
+{
+ struct isis_area *area;
+ struct isis_circuit *circuit;
+
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ circuit = nb_running_get_entry(args->dnode, NULL, true);
+ circuit->tilfa_link_fallback[1] =
+ yang_dnode_get_bool(args->dnode, NULL);
+
+ area = circuit->area;
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
diff --git a/isisd/isis_snmp.c b/isisd/isis_snmp.c
index 1efe9f3bfb..6337faab1c 100644
--- a/isisd/isis_snmp.c
+++ b/isisd/isis_snmp.c
@@ -629,6 +629,54 @@ static uint8_t isis_null_sysid[ISIS_SYS_ID_LEN];
/* Protocols supported value */
static uint8_t isis_snmp_protocols_supported = 0x7; /* All: iso, ipv4, ipv6 */
+#define SNMP_CIRCUITS_MAX (512)
+
+static struct isis_circuit *snmp_circuits[SNMP_CIRCUITS_MAX];
+static uint32_t snmp_circuit_id_last;
+
+static int isis_circuit_snmp_id_gen(struct isis_circuit *circuit)
+{
+ uint32_t id;
+ uint32_t i;
+
+ id = snmp_circuit_id_last;
+ id++;
+
+ /* find next unused entry */
+ for (i = 0; i < SNMP_CIRCUITS_MAX; i++) {
+ if (id >= SNMP_CIRCUITS_MAX) {
+ id = 0;
+ continue;
+ }
+
+ if (id == 0)
+ continue;
+
+ if (snmp_circuits[id] == NULL)
+ break;
+
+ id++;
+ }
+
+ if (i == SNMP_CIRCUITS_MAX) {
+ zlog_warn("Could not allocate a smmp-circuit-id");
+ return 0;
+ }
+
+ snmp_circuits[id] = circuit;
+ snmp_circuit_id_last = id;
+ circuit->snmp_id = id;
+
+ return 0;
+}
+
+static int isis_circuit_snmp_id_free(struct isis_circuit *circuit)
+{
+ snmp_circuits[circuit->snmp_id] = NULL;
+ circuit->snmp_id = 0;
+ return 0;
+}
+
/*
* Convenience function to move to the next circuit,
*/
@@ -636,10 +684,6 @@ static struct isis_circuit *isis_snmp_circuit_next(struct isis_circuit *circuit)
{
uint32_t start;
uint32_t off;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
-
- if (isis == NULL)
- return NULL;
start = 1;
@@ -647,7 +691,7 @@ static struct isis_circuit *isis_snmp_circuit_next(struct isis_circuit *circuit)
start = circuit->snmp_id + 1;
for (off = start; off < SNMP_CIRCUITS_MAX; off++) {
- circuit = isis->snmp_circuits[off];
+ circuit = snmp_circuits[off];
if (circuit != NULL)
return circuit;
@@ -912,16 +956,12 @@ static int isis_snmp_circuit_lookup_exact(oid *oid_idx, size_t oid_idx_len,
struct isis_circuit **ret_circuit)
{
struct isis_circuit *circuit;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
-
- if (isis == NULL)
- return 0;
if (oid_idx == NULL || oid_idx_len < 1
|| oid_idx[0] > SNMP_CIRCUITS_MAX)
return 0;
- circuit = isis->snmp_circuits[oid_idx[0]];
+ circuit = snmp_circuits[oid_idx[0]];
if (circuit == NULL)
return 0;
@@ -937,10 +977,6 @@ static int isis_snmp_circuit_lookup_next(oid *oid_idx, size_t oid_idx_len,
oid off;
oid start;
struct isis_circuit *circuit;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
-
- if (isis == NULL)
- return 0;
start = 0;
@@ -952,7 +988,7 @@ static int isis_snmp_circuit_lookup_next(oid *oid_idx, size_t oid_idx_len,
}
for (off = start; off < SNMP_CIRCUITS_MAX; ++off) {
- circuit = isis->snmp_circuits[off];
+ circuit = snmp_circuits[off];
if (circuit != NULL && off > start) {
if (ret_circuit != NULL)
@@ -1011,10 +1047,6 @@ static int isis_snmp_circuit_level_lookup_next(
oid start;
struct isis_circuit *circuit;
int level;
- struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
-
- if (isis == NULL)
- return 0;
start = 0;
@@ -1026,7 +1058,7 @@ static int isis_snmp_circuit_level_lookup_next(
}
for (off = start; off < SNMP_CIRCUITS_MAX; off++) {
- circuit = isis->snmp_circuits[off];
+ circuit = snmp_circuits[off];
if (circuit == NULL)
continue;
@@ -3449,6 +3481,8 @@ static int isis_snmp_module_init(void)
hook_register(isis_hook_adj_state_change,
isis_snmp_adj_state_change_update);
hook_register(isis_hook_lsp_error, isis_snmp_lsp_error_update);
+ hook_register(isis_circuit_new_hook, isis_circuit_snmp_id_gen);
+ hook_register(isis_circuit_del_hook, isis_circuit_snmp_id_free);
hook_register(frr_late_init, isis_snmp_init);
return 0;
diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c
index 6055984195..7020b6efeb 100644
--- a/isisd/isis_vty_fabricd.c
+++ b/isisd/isis_vty_fabricd.c
@@ -229,10 +229,10 @@ DEFUN (ip_router_isis,
area = isis_area_lookup(area_tag, VRF_DEFAULT);
if (!area)
- area = isis_area_create(area_tag, VRF_DEFAULT_NAME);
+ isis_area_create(area_tag, VRF_DEFAULT_NAME);
- if (!circuit || !circuit->area) {
- circuit = isis_circuit_create(area, ifp);
+ if (!circuit) {
+ circuit = isis_circuit_new(ifp, area_tag);
if (circuit->state != C_STATE_CONF
&& circuit->state != C_STATE_UP) {
@@ -288,7 +288,7 @@ DEFUN (no_ip_router_isis,
return CMD_ERR_NO_MATCH;
}
- circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
+ circuit = circuit_scan_by_ifp(ifp);
if (!circuit) {
vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
return CMD_ERR_NO_MATCH;
@@ -301,6 +301,10 @@ DEFUN (no_ip_router_isis,
ip = false;
isis_circuit_af_set(circuit, ip, ipv6);
+
+ if (!ip && !ipv6)
+ isis_circuit_del(circuit);
+
return CMD_SUCCESS;
}
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index cb4dd2569d..90959eb98c 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -728,6 +728,8 @@ static void isis_zebra_connected(struct zclient *zclient)
{
zclient_send_reg_requests(zclient, VRF_DEFAULT);
zclient_register_opaque(zclient, LDP_RLFA_LABELS);
+ zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE);
+ zclient_register_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE);
}
/*
@@ -818,6 +820,8 @@ void isis_zebra_init(struct thread_master *master, int instance)
void isis_zebra_stop(void)
{
zclient_unregister_opaque(zclient, LDP_RLFA_LABELS);
+ zclient_unregister_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE);
+ zclient_unregister_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE);
zclient_stop(zclient_sync);
zclient_free(zclient_sync);
zclient_stop(zclient);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 714961c177..37416fc1a4 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -114,16 +114,6 @@ int show_isis_neighbor_common(struct vty *, const char *id, char,
int clear_isis_neighbor_common(struct vty *, const char *id, const char *vrf_name,
bool all_vrf);
-static void isis_add(struct isis *isis)
-{
- listnode_add(im->isis, isis);
-}
-
-static void isis_delete(struct isis *isis)
-{
- listnode_delete(im->isis, isis);
-}
-
/* Link ISIS instance to VRF. */
void isis_vrf_link(struct isis *isis, struct vrf *vrf)
{
@@ -189,10 +179,8 @@ void isis_global_instance_create(const char *vrf_name)
struct isis *isis;
isis = isis_lookup_by_vrfname(vrf_name);
- if (isis == NULL) {
- isis = isis_new(vrf_name);
- isis_add(isis);
- }
+ if (isis == NULL)
+ isis_new(vrf_name);
}
struct isis *isis_new(const char *vrf_name)
@@ -201,16 +189,15 @@ struct isis *isis_new(const char *vrf_name)
struct isis *isis;
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
+
+ isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf_name);
+
vrf = vrf_lookup_by_name(vrf_name);
- if (vrf) {
- isis->vrf_id = vrf->vrf_id;
+ if (vrf)
isis_vrf_link(isis, vrf);
- isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf->name);
- } else {
+ else
isis->vrf_id = VRF_UNKNOWN;
- isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf_name);
- }
if (IS_DEBUG_EVENTS)
zlog_debug(
@@ -224,43 +211,81 @@ struct isis *isis_new(const char *vrf_name)
isis->process_id = getpid();
isis->router_id = 0;
isis->area_list = list_new();
- isis->init_circ_list = list_new();
isis->uptime = time(NULL);
isis->snmp_notifications = 1;
dyn_cache_init(isis);
+ listnode_add(im->isis, isis);
+
return isis;
}
+void isis_finish(struct isis *isis)
+{
+ struct vrf *vrf = NULL;
+
+ listnode_delete(im->isis, isis);
+
+ vrf = vrf_lookup_by_name(isis->name);
+ if (vrf)
+ isis_vrf_unlink(isis, vrf);
+ XFREE(MTYPE_ISIS_NAME, isis->name);
+
+ isis_redist_free(isis);
+ list_delete(&isis->area_list);
+ XFREE(MTYPE_ISIS, isis);
+}
+
+void isis_area_add_circuit(struct isis_area *area, struct isis_circuit *circuit)
+{
+ isis_csm_state_change(ISIS_ENABLE, circuit, area);
+
+ area->ip_circuits += circuit->ip_router;
+ area->ipv6_circuits += circuit->ipv6_router;
+
+ area->lfa_protected_links[0] += circuit->lfa_protection[0];
+ area->rlfa_protected_links[0] += circuit->rlfa_protection[0];
+ area->tilfa_protected_links[0] += circuit->tilfa_protection[0];
+
+ area->lfa_protected_links[1] += circuit->lfa_protection[1];
+ area->rlfa_protected_links[1] += circuit->rlfa_protection[1];
+ area->tilfa_protected_links[1] += circuit->tilfa_protection[1];
+}
+
+void isis_area_del_circuit(struct isis_area *area, struct isis_circuit *circuit)
+{
+ area->ip_circuits -= circuit->ip_router;
+ area->ipv6_circuits -= circuit->ipv6_router;
+
+ area->lfa_protected_links[0] -= circuit->lfa_protection[0];
+ area->rlfa_protected_links[0] -= circuit->rlfa_protection[0];
+ area->tilfa_protected_links[0] -= circuit->tilfa_protection[0];
+
+ area->lfa_protected_links[1] -= circuit->lfa_protection[1];
+ area->rlfa_protected_links[1] -= circuit->rlfa_protection[1];
+ area->tilfa_protected_links[1] -= circuit->tilfa_protection[1];
+
+ isis_csm_state_change(ISIS_DISABLE, circuit, area);
+}
+
struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
{
struct isis_area *area;
struct isis *isis = NULL;
struct vrf *vrf = NULL;
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
- if (vrf_name) {
- vrf = vrf_lookup_by_name(vrf_name);
- if (vrf) {
- isis = isis_lookup_by_vrfid(vrf->vrf_id);
- if (isis == NULL) {
- isis = isis_new(vrf_name);
- isis_add(isis);
- }
- } else {
- isis = isis_lookup_by_vrfid(VRF_UNKNOWN);
- if (isis == NULL) {
- isis = isis_new(vrf_name);
- isis_add(isis);
- }
- }
- } else {
- isis = isis_lookup_by_vrfid(VRF_DEFAULT);
- if (isis == NULL) {
- isis = isis_new(VRF_DEFAULT_NAME);
- isis_add(isis);
- }
- }
+ if (!vrf_name)
+ vrf_name = VRF_DEFAULT_NAME;
+
+ vrf = vrf_lookup_by_name(vrf_name);
+ isis = isis_lookup_by_vrfname(vrf_name);
+
+ if (isis == NULL)
+ isis = isis_new(vrf_name);
listnode_add(isis->area_list, area);
area->isis = isis;
@@ -373,9 +398,19 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
area->bfd_signalled_down = false;
area->bfd_force_spf_refresh = false;
-
QOBJ_REG(area, isis_area);
+ if (vrf) {
+ FOR_ALL_INTERFACES (vrf, ifp) {
+ if (ifp->ifindex == IFINDEX_INTERNAL)
+ continue;
+
+ circuit = ifp->info;
+ if (circuit)
+ isis_area_add_circuit(area, circuit);
+ }
+ }
+
return area;
}
@@ -470,11 +505,9 @@ void isis_area_destroy(struct isis_area *area)
if (area->circuit_list) {
for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
- circuit)) {
- circuit->ip_router = 0;
- circuit->ipv6_router = 0;
- isis_csm_state_change(ISIS_DISABLE, circuit, area);
- }
+ circuit))
+ isis_area_del_circuit(area, circuit);
+
list_delete(&area->circuit_list);
}
list_delete(&area->adjacency_list);
@@ -572,10 +605,6 @@ static int isis_vrf_enable(struct vrf *vrf)
isis = isis_lookup_by_vrfname(vrf->name);
if (isis) {
- if (isis->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) {
- XFREE(MTYPE_ISIS_NAME, isis->name);
- isis->name = NULL;
- }
old_vrf_id = isis->vrf_id;
/* We have instance configured, link to VRF and make it "up". */
isis_vrf_link(isis, vrf);
@@ -630,28 +659,6 @@ void isis_vrf_init(void)
isis_vrf_delete, isis_vrf_enable);
}
-void isis_finish(struct isis *isis)
-{
- struct vrf *vrf = NULL;
-
- isis_delete(isis);
- if (isis->name) {
- vrf = vrf_lookup_by_name(isis->name);
- if (vrf)
- isis_vrf_unlink(isis, vrf);
- XFREE(MTYPE_ISIS_NAME, isis->name);
- } else {
- vrf = vrf_lookup_by_id(VRF_DEFAULT);
- if (vrf)
- isis_vrf_unlink(isis, vrf);
- }
-
- isis_redist_free(isis);
- list_delete(&isis->area_list);
- list_delete(&isis->init_circ_list);
- XFREE(MTYPE_ISIS, isis);
-}
-
void isis_terminate()
{
struct isis *isis;
@@ -1369,6 +1376,9 @@ DEFUN_NOSH (show_debugging,
print_debug(vty, DEBUG_BFD, 1);
if (IS_DEBUG_LDP_SYNC)
print_debug(vty, DEBUG_LDP_SYNC, 1);
+ if (IS_DEBUG_LFA)
+ print_debug(vty, DEBUG_LFA, 1);
+
return CMD_SUCCESS;
}
diff --git a/isisd/isisd.h b/isisd/isisd.h
index a2e821ad2f..9d0b57e9f6 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -65,8 +65,6 @@ extern void isis_cli_init(void);
all_vrf = strmatch(vrf_name, "all"); \
}
-#define SNMP_CIRCUITS_MAX (512)
-
extern struct zebra_privs_t isisd_privs;
/* uncomment if you are a developer in bug hunt */
@@ -91,18 +89,14 @@ struct isis {
uint8_t sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */
uint32_t router_id; /* Router ID from zebra */
struct list *area_list; /* list of IS-IS areas */
- struct list *init_circ_list;
uint8_t max_area_addrs; /* maximumAreaAdresses */
struct area_addr *man_area_addrs; /* manualAreaAddresses */
time_t uptime; /* when did we start */
struct thread *t_dync_clean; /* dynamic hostname cache cleanup thread */
uint32_t circuit_ids_used[8]; /* 256 bits to track circuit ids 1 through 255 */
- struct isis_circuit *snmp_circuits[SNMP_CIRCUITS_MAX];
- uint32_t snmp_circuit_id_last;
int snmp_notifications;
struct route_table *ext_info[REDIST_PROTOCOL_COUNT];
- struct ldp_sync_info_cmd ldp_sync_cmd; /* MPLS LDP-IGP Sync */
};
extern struct isis_master *im;
@@ -214,6 +208,8 @@ struct isis_area {
struct prefix_list *rlfa_plist[ISIS_LEVELS];
size_t rlfa_protected_links[ISIS_LEVELS];
size_t tilfa_protected_links[ISIS_LEVELS];
+ /* MPLS LDP-IGP Sync */
+ struct ldp_sync_info_cmd ldp_sync_cmd;
/* Counters */
uint32_t circuit_state_changes;
struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT]
@@ -248,7 +244,6 @@ DECLARE_MTYPE(ISIS_AREA_ADDR); /* isis_area->area_addrs */
DECLARE_HOOK(isis_area_overload_bit_update, (struct isis_area * area), (area));
void isis_terminate(void);
-void isis_finish(struct isis *isis);
void isis_master_init(struct thread_master *master);
void isis_vrf_link(struct isis *isis, struct vrf *vrf);
void isis_vrf_unlink(struct isis *isis, struct vrf *vrf);
@@ -261,6 +256,13 @@ void isis_init(void);
void isis_vrf_init(void);
struct isis *isis_new(const char *vrf_name);
+void isis_finish(struct isis *isis);
+
+void isis_area_add_circuit(struct isis_area *area,
+ struct isis_circuit *circuit);
+void isis_area_del_circuit(struct isis_area *area,
+ struct isis_circuit *circuit);
+
struct isis_area *isis_area_create(const char *, const char *);
struct isis_area *isis_area_lookup(const char *, vrf_id_t vrf_id);
struct isis_area *isis_area_lookup_by_vrf(const char *area_tag,
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 02dcec750b..724e83adb2 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -1630,6 +1630,30 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
}
}
+void
+lde_allow_broken_lsp_update(int new_config)
+{
+ struct fec_node *fn;
+ struct fec_nh *fnh;
+ struct fec *f;
+
+ RB_FOREACH(f, fec_tree, &ft) {
+ fn = (struct fec_node *)f;
+
+ LIST_FOREACH(fnh, &fn->nexthops, entry) {
+ /* allow-broken-lsp config is changing so
+ * we need to reprogram labeled routes to
+ * have proper top-level label
+ */
+ if (!(new_config & F_LDPD_ALLOW_BROKEN_LSP))
+ lde_send_delete_klabel(fn, fnh);
+
+ if (fn->local_label != NO_LABEL)
+ lde_send_change_klabel(fn, fnh);
+ }
+ }
+}
+
static __inline int
lde_map_compare(const struct lde_map *a, const struct lde_map *b)
{
diff --git a/ldpd/lde.h b/ldpd/lde.h
index e09be01ece..dee6f3fcb9 100644
--- a/ldpd/lde.h
+++ b/ldpd/lde.h
@@ -200,6 +200,7 @@ void lde_route_update_release(struct iface *, int);
void lde_route_update_release_all(int);
struct lde_addr *lde_address_find(struct lde_nbr *, int,
union ldpd_addr *);
+void lde_allow_broken_lsp_update(int new_config);
/* lde_lib.c */
void fec_init(struct fec_tree *);
diff --git a/ldpd/ldp_vty.h b/ldpd/ldp_vty.h
index 882874f1be..d788fa0687 100644
--- a/ldpd/ldp_vty.h
+++ b/ldpd/ldp_vty.h
@@ -34,6 +34,7 @@ extern struct cmd_node ldp_debug_node;
union ldpd_addr;
int ldp_get_address(const char *, int *, union ldpd_addr *);
int ldp_vty_mpls_ldp (struct vty *, const char *);
+int ldp_vty_allow_broken_lsp(struct vty *, const char *);
int ldp_vty_address_family (struct vty *, const char *, const char *);
int ldp_vty_disc_holdtime(struct vty *, const char *, enum hello_type, long);
int ldp_vty_disc_interval(struct vty *, const char *, enum hello_type, long);
diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c
index 1f102f86fa..b65ebf6f55 100644
--- a/ldpd/ldp_vty_cmds.c
+++ b/ldpd/ldp_vty_cmds.c
@@ -241,6 +241,16 @@ DEFPY (ldp_wait_for_sync,
}
+DEFPY (ldp_allow_broken_lsps,
+ ldp_allow_broken_lsps_cmd,
+ "[no] install allow-broken-lsps",
+ NO_STR
+ "install lsps\n"
+ "if no remote-label install with imp-null")
+{
+ return (ldp_vty_allow_broken_lsp(vty, no));
+}
+
DEFPY (ldp_discovery_targeted_hello_accept,
ldp_discovery_targeted_hello_accept_cmd,
"[no] discovery targeted-hello accept [from <(1-199)|(1300-2699)|WORD>$from_acl]",
@@ -844,6 +854,7 @@ ldp_vty_init (void)
install_element(LDP_NODE, &ldp_router_id_cmd);
install_element(LDP_NODE, &ldp_ordered_control_cmd);
install_element(LDP_NODE, &ldp_wait_for_sync_cmd);
+ install_element(LDP_NODE, &ldp_allow_broken_lsps_cmd);
install_element(LDP_IPV4_NODE, &ldp_discovery_link_holdtime_cmd);
install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_holdtime_cmd);
diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c
index 6e925d1410..b35d3dfa00 100644
--- a/ldpd/ldp_vty_conf.c
+++ b/ldpd/ldp_vty_conf.c
@@ -290,6 +290,9 @@ ldp_config_write(struct vty *vty)
vty_out (vty, " wait-for-sync %u\n",
ldpd_conf->wait_for_sync_interval);
+ if (ldpd_conf->flags & F_LDPD_ALLOW_BROKEN_LSP)
+ vty_out(vty, " install allow-broken-lsp\n");
+
RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) {
if (nbrp->flags & F_NBRP_KEEPALIVE)
vty_out (vty, " neighbor %pI4 session holdtime %u\n",
@@ -1040,6 +1043,19 @@ int ldp_vty_wait_for_sync_interval(struct vty *vty, const char *negate,
}
int
+ldp_vty_allow_broken_lsp(struct vty *vty, const char *negate)
+{
+ if (negate)
+ vty_conf->flags &= ~F_LDPD_ALLOW_BROKEN_LSP;
+ else
+ vty_conf->flags |= F_LDPD_ALLOW_BROKEN_LSP;
+
+ ldp_config_apply(vty, vty_conf);
+
+ return (CMD_SUCCESS);
+}
+
+int
ldp_vty_ds_cisco_interop(struct vty *vty, const char * negate)
{
if (negate)
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 92e329c389..2d90412d17 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -246,12 +246,17 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
zl.route.instance = kr->route_instance;
}
- /*
- * For broken LSPs, instruct the forwarding plane to pop the top-level
+ /* If allow-broken-lsps is enabled then if an lsp is received with
+ * no remote label, instruct the forwarding plane to pop the top-level
* label and forward packets normally. This is a best-effort attempt
* to deliver labeled IP packets to their final destination (instead of
* dropping them).
*/
+ if (kr->remote_label == NO_LABEL
+ && !(ldpd_conf->flags & F_LDPD_ALLOW_BROKEN_LSP)
+ && cmd == ZEBRA_MPLS_LABELS_ADD)
+ return 0;
+
if (kr->remote_label == NO_LABEL)
kr->remote_label = MPLS_LABEL_IMPLICIT_NULL;
@@ -679,9 +684,8 @@ ldp_zebra_filter_update(struct access_list *access)
if (access && access->name[0] != '\0') {
strlcpy(laccess.name, access->name, sizeof(laccess.name));
- laccess.type = access->type;
- debug_evt("%s ACL update filter name %s type %d", __func__,
- access->name, access->type);
+ debug_evt("%s ACL update filter name %s", __func__,
+ access->name);
main_imsg_compose_both(IMSG_FILTER_UPDATE, &laccess,
sizeof(laccess));
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index d69a4dcd3c..800b954d65 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -1365,6 +1365,16 @@ merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
ldpe_reset_ds_nbrs();
}
+ /*
+ * Configuration of allow-broken-lsp requires reprograming all
+ * labeled routes
+ */
+ if ((conf->flags & F_LDPD_ALLOW_BROKEN_LSP) !=
+ (xconf->flags & F_LDPD_ALLOW_BROKEN_LSP)) {
+ if (ldpd_process == PROC_LDE_ENGINE)
+ lde_allow_broken_lsp_update(xconf->flags);
+ }
+
if (ldpd_process == PROC_LDP_ENGINE)
ldpe_set_config_change_time();
diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h
index 7e70aa3a44..616c390e50 100644
--- a/ldpd/ldpd.h
+++ b/ldpd/ldpd.h
@@ -174,7 +174,6 @@ struct ldpd_init {
struct ldp_access {
char name[ACL_NAMSIZ];
- enum access_type type;
};
union ldpd_addr {
@@ -591,7 +590,7 @@ DECLARE_QOBJ_TYPE(ldpd_conf);
#define F_LDPD_DS_CISCO_INTEROP 0x0002
#define F_LDPD_ENABLED 0x0004
#define F_LDPD_ORDERED_CONTROL 0x0008
-
+#define F_LDPD_ALLOW_BROKEN_LSP 0x0010
struct ldpd_af_global {
struct thread *disc_ev;
diff --git a/lib/assert/assert.h b/lib/assert/assert.h
new file mode 100644
index 0000000000..fbdbd52ce8
--- /dev/null
+++ b/lib/assert/assert.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2021 David Lamparter, for NetDEF, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* WARNING: this file is "special" in that it overrides the system-provided
+ * assert.h by being on the include path before it. That means it should
+ * provide the functional equivalent.
+ *
+ * This is intentional because FRR extends assert() to write to the log and
+ * add backtraces. Overriding the entire file is the simplest and most
+ * reliable way to get this to work; there were problems previously with the
+ * system assert.h getting included afterwards and redefining assert() back to
+ * the system variant.
+ */
+
+#ifndef _FRR_ASSERT_H
+#define _FRR_ASSERT_H
+
+#include "xref.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __cplusplus
+/* C++ has this built-in, but C provides it in assert.h for >=C11. Since we
+ * replace assert.h entirely, we need to provide it here too.
+ */
+#define static_assert _Static_assert
+#endif
+
+struct xref_assert {
+ struct xref xref;
+
+ const char *expr;
+ const char *extra, *args;
+};
+
+extern void _zlog_assert_failed(const struct xref_assert *xref,
+ const char *extra, ...) PRINTFRR(2, 3)
+ __attribute__((noreturn));
+
+/* the "do { } while (expr_)" is there to get a warning for assignments inside
+ * the assert expression aka "assert(x = 1)". The (necessary) braces around
+ * expr_ in the if () statement would suppress these warnings. Since
+ * _zlog_assert_failed() is noreturn, the while condition will never be
+ * checked.
+ */
+#define assert(expr_) \
+ ({ \
+ static const struct xref_assert _xref __attribute__( \
+ (used)) = { \
+ .xref = XREF_INIT(XREFT_ASSERT, NULL, __func__), \
+ .expr = #expr_, \
+ }; \
+ XREF_LINK(_xref.xref); \
+ if (__builtin_expect((expr_) ? 0 : 1, 0)) \
+ do { \
+ _zlog_assert_failed(&_xref, NULL); \
+ } while (expr_); \
+ })
+
+#define assertf(expr_, extra_, ...) \
+ ({ \
+ static const struct xref_assert _xref __attribute__( \
+ (used)) = { \
+ .xref = XREF_INIT(XREFT_ASSERT, NULL, __func__), \
+ .expr = #expr_, \
+ .extra = extra_, \
+ .args = #__VA_ARGS__, \
+ }; \
+ XREF_LINK(_xref.xref); \
+ if (__builtin_expect((expr_) ? 0 : 1, 0)) \
+ do { \
+ _zlog_assert_failed(&_xref, extra_, \
+ ##__VA_ARGS__); \
+ } while (expr_); \
+ })
+
+#define zassert assert
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FRR_ASSERT_H */
diff --git a/lib/clippy.c b/lib/clippy.c
index 6223697ae9..7ca99c9a94 100644
--- a/lib/clippy.c
+++ b/lib/clippy.c
@@ -106,12 +106,7 @@ int main(int argc, char **argv)
/* and now for the ugly part... provide simplified logging functions so we
* don't need to link libzebra (which would be a circular build dep) */
-#ifdef __ASSERT_FUNCTION
-#undef __ASSERT_FUNCTION
-#endif
-
#include "log.h"
-#include "zassert.h"
void vzlogx(const struct xref_logmsg *xref, int prio,
const char *format, va_list args)
@@ -120,15 +115,6 @@ void vzlogx(const struct xref_logmsg *xref, int prio,
fputs("\n", stderr);
}
-void _zlog_assert_failed(const char *assertion, const char *file,
- unsigned int line, const char *function)
-{
- fprintf(stderr,
- "Assertion `%s' failed in file %s, line %u, function %s",
- assertion, file, line, (function ? function : "?"));
- abort();
-}
-
void memory_oom(size_t size, const char *name)
{
abort();
diff --git a/lib/compiler.h b/lib/compiler.h
index b7a142bdee..86cf347e01 100644
--- a/lib/compiler.h
+++ b/lib/compiler.h
@@ -373,6 +373,10 @@ CPP_NOTICE("time to remove this CONFDATE block")
#else /* !_FRR_ATTRIBUTE_PRINTFRR */
#define PRINTFRR(a, b) __attribute__((format(printf, a, b)))
+/* frr-format plugin is C-only for now, so no point in doing these shenanigans
+ * for C++... (also they can break some C++ stuff...)
+ */
+#ifndef __cplusplus
/* these should be typedefs, but might also be #define */
#ifdef uint64_t
#undef uint64_t
@@ -400,6 +404,8 @@ _Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8,
#define PRIu64 "llu"
#define PRId64 "lld"
#define PRIx64 "llx"
+
+#endif /* !__cplusplus */
#endif /* !_FRR_ATTRIBUTE_PRINTFRR */
#ifdef __cplusplus
diff --git a/lib/filter.c b/lib/filter.c
index ba8a3086af..b7a935d076 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -38,7 +38,6 @@ DEFINE_MTYPE_STATIC(LIB, ACCESS_FILTER, "Access Filter");
/* Static structure for mac access_list's master. */
static struct access_master access_master_mac = {
{NULL, NULL},
- {NULL, NULL},
NULL,
NULL,
};
@@ -46,7 +45,6 @@ static struct access_master access_master_mac = {
/* Static structure for IPv4 access_list's master. */
static struct access_master access_master_ipv4 = {
{NULL, NULL},
- {NULL, NULL},
NULL,
NULL,
};
@@ -54,7 +52,6 @@ static struct access_master access_master_ipv4 = {
/* Static structure for IPv6 access_list's master. */
static struct access_master access_master_ipv6 = {
{NULL, NULL},
- {NULL, NULL},
NULL,
NULL,
};
@@ -166,10 +163,7 @@ void access_list_delete(struct access_list *access)
master = access->master;
- if (access->type == ACCESS_TYPE_NUMBER)
- list = &master->num;
- else
- list = &master->str;
+ list = &master->str;
if (access->next)
access->next->prev = access->prev;
@@ -197,8 +191,6 @@ void access_list_delete(struct access_list *access)
is sorted by the name. */
static struct access_list *access_list_insert(afi_t afi, const char *name)
{
- unsigned int i;
- long number;
struct access_list *access;
struct access_list *point;
struct access_list_list *alist;
@@ -213,36 +205,13 @@ static struct access_list *access_list_insert(afi_t afi, const char *name)
access->name = XSTRDUP(MTYPE_ACCESS_LIST_STR, name);
access->master = master;
- /* If name is made by all digit character. We treat it as
- number. */
- for (number = 0, i = 0; i < strlen(name); i++) {
- if (isdigit((unsigned char)name[i]))
- number = (number * 10) + (name[i] - '0');
- else
- break;
- }
-
- /* In case of name is all digit character */
- if (i == strlen(name)) {
- access->type = ACCESS_TYPE_NUMBER;
-
- /* Set access_list to number list. */
- alist = &master->num;
-
- for (point = alist->head; point; point = point->next)
- if (atol(point->name) >= number)
- break;
- } else {
- access->type = ACCESS_TYPE_STRING;
-
- /* Set access_list to string list. */
- alist = &master->str;
+ /* Set access_list to string list. */
+ alist = &master->str;
- /* Set point to insertion point. */
- for (point = alist->head; point; point = point->next)
- if (strcmp(point->name, name) >= 0)
- break;
- }
+ /* Set point to insertion point. */
+ for (point = alist->head; point; point = point->next)
+ if (strcmp(point->name, name) >= 0)
+ break;
/* In case of this is the first element of master. */
if (alist->head == NULL) {
@@ -290,10 +259,6 @@ struct access_list *access_list_lookup(afi_t afi, const char *name)
if (master == NULL)
return NULL;
- for (access = master->num.head; access; access = access->next)
- if (strcmp(access->name, name) == 0)
- return access;
-
for (access = master->str.head; access; access = access->next)
if (strcmp(access->name, name) == 0)
return access;
@@ -493,53 +458,6 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
/* Print the name of the protocol */
vty_out(vty, "%s:\n", frr_protoname);
- for (access = master->num.head; access; access = access->next) {
- if (name && strcmp(access->name, name) != 0)
- continue;
-
- write = 1;
-
- for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
- filter = &mfilter->u.cfilter;
-
- if (write) {
- vty_out(vty, "%s %s access list %s\n",
- mfilter->cisco ? (filter->extended
- ? "Extended"
- : "Standard")
- : "Zebra",
- (afi == AFI_IP)
- ? ("IP")
- : ((afi == AFI_IP6) ? ("IPv6 ")
- : ("MAC ")),
- access->name);
- write = 0;
- }
-
- vty_out(vty, " seq %" PRId64, mfilter->seq);
- vty_out(vty, " %s%s", filter_type_str(mfilter),
- mfilter->type == FILTER_DENY ? " " : "");
-
- if (!mfilter->cisco)
- config_write_access_zebra(vty, mfilter);
- else if (filter->extended)
- config_write_access_cisco(vty, mfilter);
- else {
- if (filter->addr_mask.s_addr == 0xffffffff)
- vty_out(vty, " any\n");
- else {
- vty_out(vty, " %pI4", &filter->addr);
- if (filter->addr_mask.s_addr
- != INADDR_ANY)
- vty_out(vty,
- ", wildcard bits %pI4",
- &filter->addr_mask);
- vty_out(vty, "\n");
- }
- }
- }
- }
-
for (access = master->str.head; access; access = access->next) {
if (name && strcmp(access->name, name) != 0)
continue;
@@ -739,18 +657,11 @@ static void access_list_reset_mac(void)
if (master == NULL)
return;
- for (access = master->num.head; access; access = next) {
- next = access->next;
- access_list_delete(access);
- }
for (access = master->str.head; access; access = next) {
next = access->next;
access_list_delete(access);
}
- assert(master->num.head == NULL);
- assert(master->num.tail == NULL);
-
assert(master->str.head == NULL);
assert(master->str.tail == NULL);
}
@@ -797,18 +708,11 @@ static void access_list_reset_ipv4(void)
if (master == NULL)
return;
- for (access = master->num.head; access; access = next) {
- next = access->next;
- access_list_delete(access);
- }
for (access = master->str.head; access; access = next) {
next = access->next;
access_list_delete(access);
}
- assert(master->num.head == NULL);
- assert(master->num.tail == NULL);
-
assert(master->str.head == NULL);
assert(master->str.tail == NULL);
}
@@ -838,18 +742,11 @@ static void access_list_reset_ipv6(void)
if (master == NULL)
return;
- for (access = master->num.head; access; access = next) {
- next = access->next;
- access_list_delete(access);
- }
for (access = master->str.head; access; access = next) {
next = access->next;
access_list_delete(access);
}
- assert(master->num.head == NULL);
- assert(master->num.tail == NULL);
-
assert(master->str.head == NULL);
assert(master->str.tail == NULL);
}
diff --git a/lib/filter.h b/lib/filter.h
index ade68a4567..941fabd38b 100644
--- a/lib/filter.h
+++ b/lib/filter.h
@@ -50,8 +50,6 @@ extern "C" {
/* Filter type is made by `permit', `deny' and `dynamic'. */
enum filter_type { FILTER_DENY, FILTER_PERMIT, FILTER_DYNAMIC };
-enum access_type { ACCESS_TYPE_STRING, ACCESS_TYPE_NUMBER };
-
struct filter_cisco {
/* Cisco access-list */
int extended;
@@ -103,8 +101,6 @@ struct access_list {
struct access_master *master;
- enum access_type type;
-
struct access_list *next;
struct access_list *prev;
@@ -120,9 +116,6 @@ struct access_list_list {
/* Master structure of access_list. */
struct access_master {
- /* List of access_list which name is number. */
- struct access_list_list num;
-
/* List of access_list which name is string. */
struct access_list_list str;
diff --git a/lib/libfrr_trace.c b/lib/libfrr_trace.c
index 2f300e6ee1..59320322ca 100644
--- a/lib/libfrr_trace.c
+++ b/lib/libfrr_trace.c
@@ -1,4 +1,6 @@
#define TRACEPOINT_CREATE_PROBES
#define TRACEPOINT_DEFINE
+#include <zebra.h>
+
#include "libfrr_trace.h"
diff --git a/lib/link_state.c b/lib/link_state.c
index 8606f8eb09..afeb89c592 100644
--- a/lib/link_state.c
+++ b/lib/link_state.c
@@ -22,6 +22,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "if.h"
#include "linklist.h"
#include "log.h"
diff --git a/lib/linklist.c b/lib/linklist.c
index 5de6c8a817..8137b68d84 100644
--- a/lib/linklist.c
+++ b/lib/linklist.c
@@ -320,23 +320,6 @@ void list_delete_all_node(struct list *list)
list->count = 0;
}
-void list_filter_out_nodes(struct list *list, bool (*cond)(void *data))
-{
- struct listnode *node;
- struct listnode *next;
- void *data;
-
- assert(list);
-
- for (ALL_LIST_ELEMENTS(list, node, next, data)) {
- if ((cond && cond(data)) || (!cond)) {
- if (*list->del)
- (*list->del)(data);
- list_delete_node(list, node);
- }
- }
-}
-
void list_delete(struct list **list)
{
assert(*list);
diff --git a/lib/linklist.h b/lib/linklist.h
index d8820c924d..1452145218 100644
--- a/lib/linklist.h
+++ b/lib/linklist.h
@@ -295,19 +295,6 @@ extern void list_delete_all_node(struct list *list);
extern void list_delete_node(struct list *list, struct listnode *node);
/*
- * Delete all nodes which satisfy a condition from a list.
- * Deletes the node if cond function returns true for the node.
- * If function ptr passed is NULL, it deletes all nodes
- *
- * list
- * list to operate on
- * cond
- * function pointer which takes node data as input and return true or false
- */
-
-extern void list_filter_out_nodes(struct list *list, bool (*cond)(void *data));
-
-/*
* Insert a new element into a list with insertion sort if there is no
* duplicate element present in the list. This assumes the input list is
* sorted. If unsorted, it will check for duplicate until it finds out
diff --git a/lib/log.c b/lib/log.c
index ca2f501686..15fdfd4b0a 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -311,17 +311,6 @@ void zlog_thread_info(int log_level)
zlog(log_level, "Current thread not known/applicable");
}
-void _zlog_assert_failed(const char *assertion, const char *file,
- unsigned int line, const char *function)
-{
- zlog(LOG_CRIT, "Assertion `%s' failed in file %s, line %u, function %s",
- assertion, file, line, (function ? function : "?"));
- zlog_backtrace(LOG_CRIT);
- zlog_thread_info(LOG_CRIT);
- log_memstats(stderr, "log");
- abort();
-}
-
void memory_oom(size_t size, const char *name)
{
zlog(LOG_CRIT,
diff --git a/lib/log.h b/lib/log.h
index 7147253644..59f1742d01 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -22,8 +22,6 @@
#ifndef _ZEBRA_LOG_H
#define _ZEBRA_LOG_H
-#include "zassert.h"
-
#include <syslog.h>
#include <stdint.h>
#include <stdbool.h>
diff --git a/lib/log_vty.c b/lib/log_vty.c
index c6788dd35a..9dbf216d31 100644
--- a/lib/log_vty.c
+++ b/lib/log_vty.c
@@ -647,6 +647,18 @@ DEFPY (show_log_filter,
return CMD_SUCCESS;
}
+/* Enable/disable 'immediate' mode, with no output buffering */
+DEFPY (log_immediate_mode,
+ log_immediate_mode_cmd,
+ "[no] log immediate-mode",
+ NO_STR
+ "Logging control"
+ "Output immediately, without buffering")
+{
+ zlog_set_immediate(!no);
+ return CMD_SUCCESS;
+}
+
void log_config_write(struct vty *vty)
{
bool show_cmdline_hint = false;
@@ -775,4 +787,5 @@ void log_cmd_init(void)
install_element(CONFIG_NODE, &log_filter_clear_cmd);
install_element(CONFIG_NODE, &config_log_filterfile_cmd);
install_element(CONFIG_NODE, &no_config_log_filterfile_cmd);
+ install_element(CONFIG_NODE, &log_immediate_mode_cmd);
}
diff --git a/lib/plist.c b/lib/plist.c
index 0663ac5aec..0ee02f8a0b 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -66,9 +66,6 @@ struct prefix_list_list {
/* Master structure of prefix_list. */
struct prefix_master {
- /* List of prefix_list which name is number. */
- struct prefix_list_list num;
-
/* List of prefix_list which name is string. */
struct prefix_list_list str;
@@ -87,22 +84,22 @@ struct prefix_master {
/* Static structure of IPv4 prefix_list's master. */
static struct prefix_master prefix_master_ipv4 = {
- {NULL, NULL}, {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV4,
+ {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV4,
};
/* Static structure of IPv6 prefix-list's master. */
static struct prefix_master prefix_master_ipv6 = {
- {NULL, NULL}, {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV6,
+ {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV6,
};
/* Static structure of BGP ORF prefix_list's master. */
static struct prefix_master prefix_master_orf_v4 = {
- {NULL, NULL}, {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV4,
+ {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV4,
};
/* Static structure of BGP ORF prefix_list's master. */
static struct prefix_master prefix_master_orf_v6 = {
- {NULL, NULL}, {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV6,
+ {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV6,
};
static struct prefix_master *prefix_master_get(afi_t afi, int orf)
@@ -141,10 +138,6 @@ static struct prefix_list *prefix_list_lookup_do(afi_t afi, int orf,
if (master == NULL)
return NULL;
- for (plist = master->num.head; plist; plist = plist->next)
- if (strcmp(plist->name, name) == 0)
- return plist;
-
for (plist = master->str.head; plist; plist = plist->next)
if (strcmp(plist->name, name) == 0)
return plist;
@@ -194,8 +187,6 @@ void prefix_list_entry_free(struct prefix_list_entry *pentry)
static struct prefix_list *prefix_list_insert(afi_t afi, int orf,
const char *name)
{
- unsigned int i;
- long number;
struct prefix_list *plist;
struct prefix_list *point;
struct prefix_list_list *list;
@@ -212,36 +203,13 @@ static struct prefix_list *prefix_list_insert(afi_t afi, int orf,
plist->trie =
XCALLOC(MTYPE_PREFIX_LIST_TRIE, sizeof(struct pltrie_table));
- /* If name is made by all digit character. We treat it as
- number. */
- for (number = 0, i = 0; i < strlen(name); i++) {
- if (isdigit((unsigned char)name[i]))
- number = (number * 10) + (name[i] - '0');
- else
- break;
- }
-
- /* In case of name is all digit character */
- if (i == strlen(name)) {
- plist->type = PREFIX_TYPE_NUMBER;
+ /* Set prefix_list to string list. */
+ list = &master->str;
- /* Set prefix_list to number list. */
- list = &master->num;
-
- for (point = list->head; point; point = point->next)
- if (atol(point->name) >= number)
- break;
- } else {
- plist->type = PREFIX_TYPE_STRING;
-
- /* Set prefix_list to string list. */
- list = &master->str;
-
- /* Set point to insertion point. */
- for (point = list->head; point; point = point->next)
- if (strcmp(point->name, name) >= 0)
- break;
- }
+ /* Set point to insertion point. */
+ for (point = list->head; point; point = point->next)
+ if (strcmp(point->name, name) >= 0)
+ break;
/* In case of this is the first element of master. */
if (list->head == NULL) {
@@ -310,10 +278,7 @@ void prefix_list_delete(struct prefix_list *plist)
master = plist->master;
- if (plist->type == PREFIX_TYPE_NUMBER)
- list = &master->num;
- else
- list = &master->str;
+ list = &master->str;
if (plist->next)
plist->next->prev = plist->prev;
@@ -1056,10 +1021,6 @@ static int vty_show_prefix_list(struct vty *vty, afi_t afi, const char *name,
master->recent->name);
}
- for (plist = master->num.head; plist; plist = plist->next)
- vty_show_prefix_entry(vty, afi, plist, master, dtype,
- seqnum);
-
for (plist = master->str.head; plist; plist = plist->next)
vty_show_prefix_entry(vty, afi, plist, master, dtype,
seqnum);
@@ -1148,11 +1109,6 @@ static int vty_clear_prefix_list(struct vty *vty, afi_t afi, const char *name,
return CMD_WARNING;
if (name == NULL && prefix == NULL) {
- for (plist = master->num.head; plist; plist = plist->next)
- for (pentry = plist->head; pentry;
- pentry = pentry->next)
- pentry->hitcnt = 0;
-
for (plist = master->str.head; plist; plist = plist->next)
for (pentry = plist->head; pentry;
pentry = pentry->next)
@@ -1509,18 +1465,11 @@ static void prefix_list_reset_afi(afi_t afi, int orf)
if (master == NULL)
return;
- for (plist = master->num.head; plist; plist = next) {
- next = plist->next;
- prefix_list_delete(plist);
- }
for (plist = master->str.head; plist; plist = next) {
next = plist->next;
prefix_list_delete(plist);
}
- assert(master->num.head == NULL);
- assert(master->num.tail == NULL);
-
assert(master->str.head == NULL);
assert(master->str.tail == NULL);
@@ -1546,8 +1495,6 @@ static void plist_autocomplete_afi(afi_t afi, vector comps,
for (plist = master->str.head; plist; plist = plist->next)
vector_set(comps, XSTRDUP(MTYPE_COMPLETION, plist->name));
- for (plist = master->num.head; plist; plist = plist->next)
- vector_set(comps, XSTRDUP(MTYPE_COMPLETION, plist->name));
}
static void plist_autocomplete(vector comps, struct cmd_token *token)
diff --git a/lib/plist_int.h b/lib/plist_int.h
index 5e0beabbc6..571978a517 100644
--- a/lib/plist_int.h
+++ b/lib/plist_int.h
@@ -26,8 +26,6 @@
extern "C" {
#endif
-enum prefix_name_type { PREFIX_TYPE_STRING, PREFIX_TYPE_NUMBER };
-
struct pltrie_table;
struct prefix_list {
@@ -36,8 +34,6 @@ struct prefix_list {
struct prefix_master *master;
- enum prefix_name_type type;
-
int count;
int rangecount;
diff --git a/lib/printfrr.h b/lib/printfrr.h
index 4338ac3a2f..37f1f9c8cd 100644
--- a/lib/printfrr.h
+++ b/lib/printfrr.h
@@ -305,8 +305,8 @@ struct va_format {
#define FMT_NSTD(expr) \
({ \
- typeof(expr) _v; \
FMT_NSTD_BEGIN \
+ typeof(expr) _v; \
_v = expr; \
FMT_NSTD_END \
_v; \
diff --git a/lib/ringbuf.c b/lib/ringbuf.c
index 49221e7cb3..6efa8077c2 100644
--- a/lib/ringbuf.c
+++ b/lib/ringbuf.c
@@ -131,38 +131,3 @@ void ringbuf_wipe(struct ringbuf *buf)
memset(buf->data, 0x00, buf->size);
ringbuf_reset(buf);
}
-
-ssize_t ringbuf_read(struct ringbuf *buf, int sock)
-{
- size_t to_read = ringbuf_space(buf);
- size_t bytes_to_end = buf->size - buf->end;
- ssize_t bytes_read;
- struct iovec iov[2] = {};
-
- /* Calculate amount of read blocks. */
- if (to_read > bytes_to_end) {
- iov[0].iov_base = buf->data + buf->end;
- iov[0].iov_len = bytes_to_end;
- iov[1].iov_base = buf->data;
- iov[1].iov_len = to_read - bytes_to_end;
- } else {
- iov[0].iov_base = buf->data + buf->end;
- iov[0].iov_len = to_read;
- }
-
- /* Do the system call. */
- bytes_read = readv(sock, iov, 2);
- if (bytes_read <= 0)
- return bytes_read;
-
- /* Calculate the new end. */
- if ((size_t)bytes_read > bytes_to_end)
- buf->end = bytes_read - bytes_to_end;
- else
- buf->end += bytes_read;
-
- /* Set emptiness state. */
- buf->empty = (buf->start == buf->end) && (buf->empty && !bytes_read);
-
- return bytes_read;
-}
diff --git a/lib/ringbuf.h b/lib/ringbuf.h
index 209687512b..b8f4d9798d 100644
--- a/lib/ringbuf.h
+++ b/lib/ringbuf.h
@@ -126,17 +126,6 @@ void ringbuf_reset(struct ringbuf *buf);
*/
void ringbuf_wipe(struct ringbuf *buf);
-/**
- * Perform a socket/file `read()` in to the ring buffer.
- *
- * \param buf the ring buffer pointer.
- * \param sock the file descriptor.
- * \returns the number of bytes read, `0` on connection close or `-1` with
- * `errno` pointing the error (see `readv()` man page for more
- * information.)
- */
-ssize_t ringbuf_read(struct ringbuf *buf, int sock);
-
#ifdef __cplusplus
}
#endif
diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
index db06e9caac..3473ca2aea 100644
--- a/lib/routemap_northbound.c
+++ b/lib/routemap_northbound.c
@@ -271,6 +271,7 @@ lib_route_map_entry_description_destroy(struct nb_cb_destroy_args *args)
static int lib_route_map_entry_action_modify(struct nb_cb_modify_args *args)
{
struct route_map_index *rmi;
+ struct route_map *map;
switch (args->event) {
case NB_EV_VALIDATE:
@@ -281,7 +282,15 @@ static int lib_route_map_entry_action_modify(struct nb_cb_modify_args *args)
case NB_EV_APPLY:
rmi = nb_running_get_entry(args->dnode, NULL, true);
rmi->type = yang_dnode_get_enum(args->dnode, NULL);
- /* TODO: notify? */
+ map = rmi->map;
+
+ /* Execute event hook. */
+ if (route_map_master.event_hook) {
+ (*route_map_master.event_hook)(map->name);
+ route_map_notify_dependencies(map->name,
+ RMAP_EVENT_CALL_ADDED);
+ }
+
break;
}
diff --git a/lib/routing_nb.c b/lib/routing_nb.c
index 0160354a7e..6238fb055d 100644
--- a/lib/routing_nb.c
+++ b/lib/routing_nb.c
@@ -16,6 +16,8 @@
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "northbound.h"
#include "libfrr.h"
#include "routing_nb.h"
diff --git a/lib/routing_nb_config.c b/lib/routing_nb_config.c
index f66f32015d..594ad6c9e8 100644
--- a/lib/routing_nb_config.c
+++ b/lib/routing_nb_config.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "northbound.h"
#include "libfrr.h"
#include "vrf.h"
diff --git a/lib/subdir.am b/lib/subdir.am
index 98ba1cf24c..480c2938d0 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -278,13 +278,14 @@ pkginclude_HEADERS += \
lib/yang.h \
lib/yang_translator.h \
lib/yang_wrappers.h \
- lib/zassert.h \
lib/zclient.h \
lib/zebra.h \
lib/zlog.h \
lib/zlog_targets.h \
lib/pbr.h \
lib/routing_nb.h \
+ \
+ lib/assert/assert.h \
# end
@@ -413,7 +414,7 @@ lib_grammar_sandbox_SOURCES = \
lib_grammar_sandbox_LDADD = \
lib/libfrr.la
-lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY
+lib_clippy_CPPFLAGS = $(CPPFLAGS_BASE) -D_GNU_SOURCE -DBUILDING_CLIPPY
lib_clippy_CFLAGS = $(AC_CFLAGS) $(PYTHON_CFLAGS)
lib_clippy_LDADD = $(PYTHON_LIBS) $(UST_LIBS) -lelf
lib_clippy_LDFLAGS = -export-dynamic
diff --git a/lib/thread.c b/lib/thread.c
index 3d8b544678..3af89fad5a 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -664,7 +664,7 @@ static int time_hhmmss(char *buf, int buf_size, long sec)
long mm;
int wr;
- zassert(buf_size >= 8);
+ assert(buf_size >= 8);
hh = sec / 3600;
sec %= 3600;
@@ -862,7 +862,10 @@ struct thread *_thread_add_read_write(const struct xref_threadsched *xref,
xref->funcname, xref->xref.file, xref->xref.line,
t_ptr, fd, 0, arg, 0);
- assert(fd >= 0 && fd < m->fd_limit);
+ assert(fd >= 0);
+ if (fd >= m->fd_limit)
+ assert(!"Number of FD's open is greater than FRR currently configured to handle, aborting");
+
frr_with_mutex(&m->mtx) {
if (t_ptr && *t_ptr)
// thread is already scheduled; don't reschedule
diff --git a/lib/typerb.h b/lib/typerb.h
index 60e6d09016..cbed8d4893 100644
--- a/lib/typerb.h
+++ b/lib/typerb.h
@@ -117,6 +117,7 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \
typed_rb_remove(&h->rr, re); \
return container_of(re, type, field.re); \
} \
+TYPESAFE_SWAP_ALL_SIMPLE(prefix) \
macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \
{ \
const struct typed_rb_entry *re; \
diff --git a/lib/typesafe.h b/lib/typesafe.h
index 27e7be1286..ecac1a4381 100644
--- a/lib/typesafe.h
+++ b/lib/typesafe.h
@@ -78,6 +78,19 @@ macro_inline type *prefix ## _find_gteq(struct prefix##_head *h, \
} \
/* ... */
+/* SWAP_ALL_SIMPLE = for containers where the items don't point back to the
+ * head *AND* the head doesn'T points to itself (= everything except LIST,
+ * DLIST and SKIPLIST), just switch out the entire head
+ */
+#define TYPESAFE_SWAP_ALL_SIMPLE(prefix) \
+macro_inline void prefix ## _swap_all(struct prefix##_head *a, \
+ struct prefix##_head *b) \
+{ \
+ struct prefix##_head tmp = *a; \
+ *a = *b; \
+ *b = tmp; \
+} \
+/* ... */
/* single-linked list, unsorted/arbitrary.
* can be used as queue with add_tail / pop
@@ -169,6 +182,17 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \
h->sh.last_next = &h->sh.first; \
return container_of(sitem, type, field.si); \
} \
+macro_inline void prefix ## _swap_all(struct prefix##_head *a, \
+ struct prefix##_head *b) \
+{ \
+ struct prefix##_head tmp = *a; \
+ *a = *b; \
+ *b = tmp; \
+ if (a->sh.last_next == &b->sh.first) \
+ a->sh.last_next = &a->sh.first; \
+ if (b->sh.last_next == &a->sh.first) \
+ b->sh.last_next = &b->sh.first; \
+} \
macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \
{ \
return container_of_null(h->sh.first, type, field.si); \
@@ -215,6 +239,34 @@ static inline void typesafe_dlist_add(struct dlist_head *head,
head->count++;
}
+static inline void typesafe_dlist_swap_all(struct dlist_head *a,
+ struct dlist_head *b)
+{
+ struct dlist_head tmp = *a;
+
+ a->count = b->count;
+ if (a->count) {
+ a->hitem.next = b->hitem.next;
+ a->hitem.prev = b->hitem.prev;
+ a->hitem.next->prev = &a->hitem;
+ a->hitem.prev->next = &a->hitem;
+ } else {
+ a->hitem.next = &a->hitem;
+ a->hitem.prev = &a->hitem;
+ }
+
+ b->count = tmp.count;
+ if (b->count) {
+ b->hitem.next = tmp.hitem.next;
+ b->hitem.prev = tmp.hitem.prev;
+ b->hitem.next->prev = &b->hitem;
+ b->hitem.prev->next = &b->hitem;
+ } else {
+ b->hitem.next = &b->hitem;
+ b->hitem.prev = &b->hitem;
+ }
+}
+
/* double-linked list, for fast item deletion
*/
#define PREDECL_DLIST(prefix) \
@@ -271,6 +323,11 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \
h->dh.count--; \
return container_of(ditem, type, field.di); \
} \
+macro_inline void prefix ## _swap_all(struct prefix##_head *a, \
+ struct prefix##_head *b) \
+{ \
+ typesafe_dlist_swap_all(&a->dh, &b->dh); \
+} \
macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \
{ \
const struct dlist_item *ditem = h->dh.hitem.next; \
@@ -380,6 +437,7 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \
typesafe_heap_resize(&h->hh, false); \
return container_of(hitem, type, field.hi); \
} \
+TYPESAFE_SWAP_ALL_SIMPLE(prefix) \
macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \
{ \
if (h->hh.count == 0) \
@@ -518,6 +576,7 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \
h->sh.first = sitem->next; \
return container_of(sitem, type, field.si); \
} \
+TYPESAFE_SWAP_ALL_SIMPLE(prefix) \
macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \
{ \
return container_of_null(h->sh.first, type, field.si); \
@@ -708,6 +767,7 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \
} \
return NULL; \
} \
+TYPESAFE_SWAP_ALL_SIMPLE(prefix) \
macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \
{ \
uint32_t i; \
@@ -824,6 +884,17 @@ macro_inline type *prefix ## _pop(struct prefix##_head *h) \
struct sskip_item *sitem = typesafe_skiplist_pop(&h->sh); \
return container_of_null(sitem, type, field.si); \
} \
+macro_inline void prefix ## _swap_all(struct prefix##_head *a, \
+ struct prefix##_head *b) \
+{ \
+ struct prefix##_head tmp = *a; \
+ *a = *b; \
+ *b = tmp; \
+ a->sh.hitem.next[SKIPLIST_OVERFLOW] = (struct sskip_item *) \
+ ((uintptr_t)a->sh.overflow | 1); \
+ b->sh.hitem.next[SKIPLIST_OVERFLOW] = (struct sskip_item *) \
+ ((uintptr_t)b->sh.overflow | 1); \
+} \
macro_pure const type *prefix ## _const_first(const struct prefix##_head *h) \
{ \
const struct sskip_item *first = h->sh.hitem.next[0]; \
diff --git a/lib/xref.h b/lib/xref.h
index 63166b069a..949458b313 100644
--- a/lib/xref.h
+++ b/lib/xref.h
@@ -33,6 +33,7 @@ enum xref_type {
XREFT_THREADSCHED = 0x100,
XREFT_LOGMSG = 0x200,
+ XREFT_ASSERT = 0x280,
XREFT_DEFUN = 0x300,
XREFT_INSTALL_ELEMENT = 0x301,
diff --git a/lib/zassert.h b/lib/zassert.h
deleted file mode 100644
index 527282c4f2..0000000000
--- a/lib/zassert.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of Quagga.
- *
- * Quagga is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * Quagga is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _QUAGGA_ASSERT_H
-#define _QUAGGA_ASSERT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void _zlog_assert_failed(const char *assertion, const char *file,
- unsigned int line, const char *function)
- __attribute__((noreturn));
-
-#undef __ASSERT_FUNCTION
-#define __ASSERT_FUNCTION __func__
-
-#define zassert(EX) \
- ((void)((EX) ? 0 : (_zlog_assert_failed(#EX, __FILE__, __LINE__, \
- __ASSERT_FUNCTION), \
- 0)))
-
-#undef assert
-#define assert(EX) zassert(EX)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _QUAGGA_ASSERT_H */
diff --git a/lib/zclient.c b/lib/zclient.c
index d613906d82..b1aea55afa 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -587,7 +587,7 @@ zclient_send_router_id_update(struct zclient *zclient,
enum zclient_send_status
zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
struct interface *ifp, int enable,
- int ra_interval)
+ uint32_t ra_interval)
{
struct stream *s;
diff --git a/lib/zclient.h b/lib/zclient.h
index 26fa73fc0a..e8fff4b881 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -911,7 +911,7 @@ zclient_send_router_id_update(struct zclient *zclient,
extern enum zclient_send_status
zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
struct interface *ifp, int enable,
- int ra_interval);
+ uint32_t ra_interval);
extern enum zclient_send_status
zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
struct interface *ifp, bool down);
diff --git a/lib/zebra.h b/lib/zebra.h
index 26c0fe05b5..3b624117de 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -206,7 +206,7 @@
#define __attribute__(x)
#endif /* !__GNUC__ || VTYSH_EXTRACT_PL */
-#include "zassert.h"
+#include <assert.h>
/*
* Add explicit static cast only when using a C++ compiler.
diff --git a/lib/zlog.c b/lib/zlog.c
index 24800c6e64..89ab9265d1 100644
--- a/lib/zlog.c
+++ b/lib/zlog.c
@@ -81,6 +81,11 @@ static gid_t zlog_gid = -1;
DECLARE_ATOMLIST(zlog_targets, struct zlog_target, head);
static struct zlog_targets_head zlog_targets;
+/* Global setting for buffered vs immediate output. The default is
+ * per-pthread buffering.
+ */
+static bool default_immediate;
+
/* cf. zlog.h for additional comments on this struct.
*
* Note: you MUST NOT pass the format string + va_list to non-FRR format
@@ -395,7 +400,7 @@ static void vzlog_tls(struct zlog_tls *zlog_tls, const struct xref_logmsg *xref,
struct zlog_msg *msg;
char *buf;
bool ignoremsg = true;
- bool immediate = false;
+ bool immediate = default_immediate;
/* avoid further processing cost if no target wants this message */
rcu_read_lock();
@@ -521,6 +526,36 @@ void zlog_sigsafe(const char *text, size_t len)
}
}
+void _zlog_assert_failed(const struct xref_assert *xref, const char *extra, ...)
+{
+ va_list ap;
+ static bool assert_in_assert; /* "global-ish" variable, init to 0 */
+
+ if (assert_in_assert)
+ abort();
+ assert_in_assert = true;
+
+ if (extra) {
+ struct va_format vaf;
+
+ va_start(ap, extra);
+ vaf.fmt = extra;
+ vaf.va = &ap;
+
+ zlog(LOG_CRIT,
+ "%s:%d: %s(): assertion (%s) failed, extra info: %pVA",
+ xref->xref.file, xref->xref.line, xref->xref.func,
+ xref->expr, &vaf);
+
+ va_end(ap);
+ } else
+ zlog(LOG_CRIT, "%s:%d: %s(): assertion (%s) failed",
+ xref->xref.file, xref->xref.line, xref->xref.func,
+ xref->expr);
+
+ /* abort() prints backtrace & memstats in SIGABRT handler */
+ abort();
+}
int zlog_msg_prio(struct zlog_msg *msg)
{
@@ -714,6 +749,14 @@ struct zlog_target *zlog_target_replace(struct zlog_target *oldzt,
return oldzt;
}
+/*
+ * Enable or disable 'immediate' output - default is to buffer
+ * each pthread's messages.
+ */
+void zlog_set_immediate(bool set_p)
+{
+ default_immediate = set_p;
+}
/* common init */
diff --git a/lib/zlog.h b/lib/zlog.h
index 66d8f1e5d7..c421c16f38 100644
--- a/lib/zlog.h
+++ b/lib/zlog.h
@@ -25,6 +25,8 @@
#include <unistd.h>
#include <sys/uio.h>
+#include <assert.h>
+
#include "atomlist.h"
#include "frrcu.h"
#include "memory.h"
@@ -249,6 +251,9 @@ extern void zlog_tls_buffer_init(void);
extern void zlog_tls_buffer_flush(void);
extern void zlog_tls_buffer_fini(void);
+/* Enable or disable 'immediate' output - default is to buffer messages. */
+extern void zlog_set_immediate(bool set_p);
+
#ifdef __cplusplus
}
#endif
diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c
index bcf0e2168c..c358baecb2 100644
--- a/nhrpd/nhrp_cache.c
+++ b/nhrpd/nhrp_cache.c
@@ -72,7 +72,7 @@ static void nhrp_cache_free(struct nhrp_cache *c)
debugf(NHRP_DEBUG_COMMON, "Deleting cache entry");
nhrp_cache_counts[c->cur.type]--;
notifier_call(&c->notifier_list, NOTIFY_CACHE_DELETE);
- zassert(!notifier_active(&c->notifier_list));
+ assert(!notifier_active(&c->notifier_list));
hash_release(nifp->cache_hash, c);
THREAD_OFF(c->t_timeout);
THREAD_OFF(c->t_auth);
diff --git a/nhrpd/zbuf.c b/nhrpd/zbuf.c
index 43ce974817..e191a90f2d 100644
--- a/nhrpd/zbuf.c
+++ b/nhrpd/zbuf.c
@@ -14,7 +14,7 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
-#include "zassert.h"
+#include <assert.h>
#include "zbuf.h"
#include "memory.h"
#include "nhrpd.h"
@@ -59,7 +59,7 @@ void zbuf_reset(struct zbuf *zb)
void zbuf_reset_head(struct zbuf *zb, void *ptr)
{
- zassert((void *)zb->buf <= ptr && ptr <= (void *)zb->tail);
+ assert((void *)zb->buf <= ptr && ptr <= (void *)zb->tail);
zb->head = ptr;
}
diff --git a/nhrpd/zbuf.h b/nhrpd/zbuf.h
index d4a7c15a95..2741860bfd 100644
--- a/nhrpd/zbuf.h
+++ b/nhrpd/zbuf.h
@@ -15,7 +15,6 @@
#include <endian.h>
#include <sys/types.h>
-#include "zassert.h"
#include "list.h"
struct zbuf {
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index f3af8b308f..a2ddba65e9 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -474,8 +474,8 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
}
-static void ospf6_interface_state_change(uint8_t next_state,
- struct ospf6_interface *oi)
+static int ospf6_interface_state_change(uint8_t next_state,
+ struct ospf6_interface *oi)
{
uint8_t prev_state;
struct ospf6 *ospf6;
@@ -484,7 +484,7 @@ static void ospf6_interface_state_change(uint8_t next_state,
oi->state = next_state;
if (prev_state == next_state)
- return;
+ return -1;
/* log */
if (IS_OSPF6_DEBUG_INTERFACE) {
@@ -525,6 +525,8 @@ static void ospf6_interface_state_change(uint8_t next_state,
}
hook_call(ospf6_interface_change, oi, next_state, prev_state);
+
+ return 0;
}
@@ -1902,10 +1904,13 @@ DEFUN (ipv6_ospf6_priority,
? OSPF6_INTERFACE_PRIORITY
: strtoul(argv[idx_number]->arg, NULL, 10);
- if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER
- || oi->state == OSPF6_INTERFACE_BDR
- || oi->state == OSPF6_INTERFACE_DR))
- ospf6_interface_state_change(dr_election(oi), oi);
+ if (oi->area
+ && (oi->state == OSPF6_INTERFACE_DROTHER
+ || oi->state == OSPF6_INTERFACE_BDR
+ || oi->state == OSPF6_INTERFACE_DR)) {
+ if (ospf6_interface_state_change(dr_election(oi), oi) == -1)
+ OSPF6_LINK_LSA_SCHEDULE(oi);
+ }
return CMD_SUCCESS;
}
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 9770dd0444..2daf119c52 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -1039,7 +1039,7 @@ void ospf6_route_table_delete(struct ospf6_route_table *table)
/* VTY commands */
void ospf6_route_show(struct vty *vty, struct ospf6_route *route,
- json_object *json_array_routes, bool use_json)
+ json_object *json_routes, bool use_json)
{
int i;
char destination[PREFIX2STR_BUFFER], nexthop[64];
@@ -1072,7 +1072,6 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route,
if (use_json) {
json_route = json_object_new_object();
- json_object_string_add(json_route, "destination", destination);
json_object_boolean_add(json_route, "isBestRoute",
ospf6_route_is_best(route));
json_object_string_add(json_route, "destinationType",
@@ -1121,12 +1120,12 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route,
if (use_json) {
json_object_object_add(json_route, "nextHops",
json_array_next_hops);
- json_object_array_add(json_array_routes, json_route);
+ json_object_object_add(json_routes, destination, json_route);
}
}
void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route,
- json_object *json_array_routes, bool use_json)
+ json_object *json_routes, bool use_json)
{
char destination[PREFIX2STR_BUFFER], nexthop[64];
char area_id[16], id[16], adv_router[16], capa[16], options[16];
@@ -1158,7 +1157,6 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route,
if (use_json) {
json_route = json_object_new_object();
- json_object_string_add(json_route, "destination", destination);
json_object_string_add(json_route, "destinationType",
OSPF6_DEST_TYPE_NAME(route->type));
} else {
@@ -1311,7 +1309,7 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route,
if (use_json) {
json_object_object_add(json_route, "nextHops",
json_array_next_hops);
- json_object_array_add(json_array_routes, json_route);
+ json_object_object_add(json_routes, destination, json_route);
} else
vty_out(vty, "\n");
}
@@ -1377,24 +1375,23 @@ static void ospf6_route_show_table_prefix(struct vty *vty,
json_object *json, bool use_json)
{
struct ospf6_route *route;
- json_object *json_array_routes = NULL;
+ json_object *json_routes = NULL;
route = ospf6_route_lookup(prefix, table);
if (route == NULL)
return;
if (use_json)
- json_array_routes = json_object_new_array();
+ json_routes = json_object_new_object();
ospf6_route_lock(route);
while (route && ospf6_route_is_prefix(prefix, route)) {
/* Specifying a prefix will always display details */
- ospf6_route_show_detail(vty, route, json_array_routes,
- use_json);
+ ospf6_route_show_detail(vty, route, json_routes, use_json);
route = ospf6_route_next(route);
}
if (use_json)
- json_object_object_add(json, "routes", json_array_routes);
+ json_object_object_add(json, "routes", json_routes);
if (route)
ospf6_route_unlock(route);
}
@@ -1405,24 +1402,23 @@ static void ospf6_route_show_table_address(struct vty *vty,
json_object *json, bool use_json)
{
struct ospf6_route *route;
- json_object *json_array_routes = NULL;
+ json_object *json_routes = NULL;
route = ospf6_route_lookup_bestmatch(prefix, table);
if (route == NULL)
return;
if (use_json)
- json_array_routes = json_object_new_array();
+ json_routes = json_object_new_object();
prefix = &route->prefix;
ospf6_route_lock(route);
while (route && ospf6_route_is_prefix(prefix, route)) {
/* Specifying a prefix will always display details */
- ospf6_route_show_detail(vty, route, json_array_routes,
- use_json);
+ ospf6_route_show_detail(vty, route, json_routes, use_json);
route = ospf6_route_next(route);
}
if (use_json)
- json_object_object_add(json, "routes", json_array_routes);
+ json_object_object_add(json, "routes", json_routes);
if (route)
ospf6_route_unlock(route);
}
@@ -1433,24 +1429,23 @@ static void ospf6_route_show_table_match(struct vty *vty, int detail,
json_object *json, bool use_json)
{
struct ospf6_route *route;
- json_object *json_array_routes = NULL;
+ json_object *json_routes = NULL;
assert(prefix->family);
route = ospf6_route_match_head(prefix, table);
if (use_json)
- json_array_routes = json_object_new_array();
+ json_routes = json_object_new_object();
while (route) {
if (detail)
- ospf6_route_show_detail(vty, route, json_array_routes,
+ ospf6_route_show_detail(vty, route, json_routes,
use_json);
else
- ospf6_route_show(vty, route, json_array_routes,
- use_json);
+ ospf6_route_show(vty, route, json_routes, use_json);
route = ospf6_route_match_next(prefix, route);
}
if (use_json)
- json_object_object_add(json, "routes", json_array_routes);
+ json_object_object_add(json, "routes", json_routes);
}
static void ospf6_route_show_table_type(struct vty *vty, int detail,
@@ -1459,25 +1454,24 @@ static void ospf6_route_show_table_type(struct vty *vty, int detail,
json_object *json, bool use_json)
{
struct ospf6_route *route;
- json_object *json_array_routes = NULL;
+ json_object *json_routes = NULL;
route = ospf6_route_head(table);
if (use_json)
- json_array_routes = json_object_new_array();
+ json_routes = json_object_new_object();
while (route) {
if (route->path.type == type) {
if (detail)
- ospf6_route_show_detail(vty, route,
- json_array_routes,
+ ospf6_route_show_detail(vty, route, json_routes,
use_json);
else
- ospf6_route_show(vty, route, json_array_routes,
+ ospf6_route_show(vty, route, json_routes,
use_json);
}
route = ospf6_route_next(route);
}
if (use_json)
- json_object_object_add(json, "routes", json_array_routes);
+ json_object_object_add(json, "routes", json_routes);
}
static void ospf6_route_show_table(struct vty *vty, int detail,
@@ -1485,22 +1479,21 @@ static void ospf6_route_show_table(struct vty *vty, int detail,
json_object *json, bool use_json)
{
struct ospf6_route *route;
- json_object *json_array_routes = NULL;
+ json_object *json_routes = NULL;
route = ospf6_route_head(table);
if (use_json)
- json_array_routes = json_object_new_array();
+ json_routes = json_object_new_object();
while (route) {
if (detail)
- ospf6_route_show_detail(vty, route, json_array_routes,
+ ospf6_route_show_detail(vty, route, json_routes,
use_json);
else
- ospf6_route_show(vty, route, json_array_routes,
- use_json);
+ ospf6_route_show(vty, route, json_routes, use_json);
route = ospf6_route_next(route);
}
if (use_json)
- json_object_object_add(json, "routes", json_array_routes);
+ json_object_object_add(json, "routes", json_routes);
}
int ospf6_route_table_show(struct vty *vty, int argc_start, int argc,
diff --git a/ospf6d/ospf6_routemap_nb.c b/ospf6d/ospf6_routemap_nb.c
index b710fefbdf..faa992e026 100644
--- a/ospf6d/ospf6_routemap_nb.c
+++ b/ospf6d/ospf6_routemap_nb.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "lib/northbound.h"
#include "lib/routemap.h"
#include "ospf6_routemap_nb.h"
diff --git a/ospf6d/ospf6_routemap_nb_config.c b/ospf6d/ospf6_routemap_nb_config.c
index 3c7741e473..cd0a3260d5 100644
--- a/ospf6d/ospf6_routemap_nb_config.c
+++ b/ospf6d/ospf6_routemap_nb_config.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "lib/command.h"
#include "lib/log.h"
#include "lib/northbound.h"
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 6d80725ae6..e01cfe3e03 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -332,20 +332,29 @@ void ospf_redistribute_withdraw(struct ospf *ospf, uint8_t type,
if (EXTERNAL_INFO(ext))
for (rn = route_top(EXTERNAL_INFO(ext)); rn;
rn = route_next(rn))
- if ((ei = rn->info))
- if (ospf_external_info_find_lsa(ospf, &ei->p)) {
- if (is_prefix_default(&ei->p)
- && ospf->default_originate
- != DEFAULT_ORIGINATE_NONE)
- continue;
+ if ((ei = rn->info)) {
+ struct ospf_external_aggr_rt *aggr;
+
+ if (is_prefix_default(&ei->p)
+ && ospf->default_originate
+ != DEFAULT_ORIGINATE_NONE)
+ continue;
+
+ aggr = ei->aggr_route;
+
+ if (aggr)
+ ospf_unlink_ei_from_aggr(ospf, aggr,
+ ei);
+ else if (ospf_external_info_find_lsa(ospf,
+ &ei->p))
ospf_external_lsa_flush(
ospf, type, &ei->p,
ei->ifindex /*, ei->nexthop */);
- ospf_external_info_free(ei);
- route_unlock_node(rn);
- rn->info = NULL;
- }
+ ospf_external_info_free(ei);
+ route_unlock_node(rn);
+ rn->info = NULL;
+ }
}
/* External Route Aggregator Handlers */
diff --git a/ospfd/ospf_routemap_nb.c b/ospfd/ospf_routemap_nb.c
index 1f6b0ef78c..e53d009a55 100644
--- a/ospfd/ospf_routemap_nb.c
+++ b/ospfd/ospf_routemap_nb.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "lib/northbound.h"
#include "lib/routemap.h"
#include "ospf_routemap_nb.h"
diff --git a/ospfd/ospf_routemap_nb_config.c b/ospfd/ospf_routemap_nb_config.c
index bfb18c5e08..9026795425 100644
--- a/ospfd/ospf_routemap_nb_config.c
+++ b/ospfd/ospf_routemap_nb_config.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "lib/command.h"
#include "lib/log.h"
#include "lib/northbound.h"
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index f2842538a5..1929e3dea4 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -2153,6 +2153,13 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa)
/* Initialize TLV browsing */
tlvh = TLV_HDR_TOP(lsa->data);
+ uint32_t total_len = TLV_BODY_SIZE(lsa->data) - OSPF_LSA_HEADER_SIZE;
+
+ /* If TE Router-ID is only TLV we are done */
+ if (ntohs(tlvh->type) == TE_TLV_ROUTER_ADDR
+ && total_len == sizeof(struct te_tlv_router_addr))
+ return 0;
+
/* Skip TE Router-ID if present */
if (ntohs(tlvh->type) == TE_TLV_ROUTER_ADDR)
tlvh = TLV_HDR_NEXT(tlvh);
@@ -2756,7 +2763,7 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)
&lsa->data->id, &edge->attributes->standard.local);
/* Initialize TLV browsing */
- len = TLV_BODY_SIZE(&ext->header);
+ len = TLV_BODY_SIZE(&ext->header) - EXT_TLV_LINK_SIZE;
tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE
+ EXT_TLV_LINK_SIZE);
for (; sum < len; tlvh = TLV_HDR_NEXT(tlvh)) {
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 69a3e45878..57ef6029ad 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3737,6 +3737,31 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
vty_out(vty,
" No backup designated router on this network\n");
} else {
+ nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi));
+ if (nbr) {
+ if (use_json) {
+ json_object_string_add(
+ json_interface_sub, "drId",
+ inet_ntop(AF_INET,
+ &nbr->router_id, buf,
+ sizeof(buf)));
+ json_object_string_add(
+ json_interface_sub, "drAddress",
+ inet_ntop(
+ AF_INET,
+ &nbr->address.u.prefix4,
+ buf, sizeof(buf)));
+ } else {
+ vty_out(vty,
+ " Designated Router (ID) %pI4",
+ &nbr->router_id);
+ vty_out(vty,
+ " Interface Address %pFX\n",
+ &nbr->address);
+ }
+ }
+ nbr = NULL;
+
nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &BDR(oi));
if (nbr == NULL) {
if (!use_json)
diff --git a/pathd/path_cli.c b/pathd/path_cli.c
index cf14aa8c61..ecb667f985 100644
--- a/pathd/path_cli.c
+++ b/pathd/path_cli.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include <float.h>
#include <math.h>
#include <zebra.h>
diff --git a/pathd/path_debug.c b/pathd/path_debug.c
index df0550715a..eec5707396 100644
--- a/pathd/path_debug.c
+++ b/pathd/path_debug.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include <string.h>
#include <stdbool.h>
#include <time.h>
diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c
index 107475bec9..aacbca4ae9 100644
--- a/pathd/path_pcep_config.c
+++ b/pathd/path_pcep_config.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include <northbound.h>
#include <yang.h>
#include <printfrr.h>
diff --git a/pathd/path_pcep_debug.c b/pathd/path_pcep_debug.c
index d222371bbb..370484dc1b 100644
--- a/pathd/path_pcep_debug.c
+++ b/pathd/path_pcep_debug.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include <string.h>
#include <stdbool.h>
#include <time.h>
diff --git a/pathd/path_zebra.c b/pathd/path_zebra.c
index 276bc9289c..8c9357460f 100644
--- a/pathd/path_zebra.c
+++ b/pathd/path_zebra.c
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "thread.h"
#include "log.h"
#include "lib_errors.h"
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index 4b73e13c27..eb41bf6043 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -50,8 +50,8 @@ struct pbr_interface *pbr_if_new(struct interface *ifp)
{
struct pbr_interface *pbr_ifp;
- zassert(ifp);
- zassert(!ifp->info);
+ assert(ifp);
+ assert(!ifp->info);
pbr_ifp = XCALLOC(MTYPE_PBR_INTERFACE, sizeof(*pbr_ifp));
diff --git a/pceplib/pcep_msg_messages.c b/pceplib/pcep_msg_messages.c
index ec2a237f30..9bbfc5372b 100644
--- a/pceplib/pcep_msg_messages.c
+++ b/pceplib/pcep_msg_messages.c
@@ -25,6 +25,10 @@
* This is the implementation of a High Level PCEP message API.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <string.h>
#include <arpa/inet.h>
#include <stdarg.h>
diff --git a/pceplib/pcep_msg_messages_encoding.c b/pceplib/pcep_msg_messages_encoding.c
index 7c8e1b3a1f..e90ca1cfd8 100644
--- a/pceplib/pcep_msg_messages_encoding.c
+++ b/pceplib/pcep_msg_messages_encoding.c
@@ -25,6 +25,10 @@
* Encoding and decoding for PCEP messages.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
diff --git a/pceplib/pcep_msg_object_error_types.c b/pceplib/pcep_msg_object_error_types.c
index a4fd8151cd..c72dfd7061 100644
--- a/pceplib/pcep_msg_object_error_types.c
+++ b/pceplib/pcep_msg_object_error_types.c
@@ -19,6 +19,10 @@
* Author : Brady Johnson <brady@voltanet.io>
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include "pcep_msg_object_error_types.h"
diff --git a/pceplib/pcep_msg_objects.c b/pceplib/pcep_msg_objects.c
index 6c943ddc2a..e253fcc540 100644
--- a/pceplib/pcep_msg_objects.c
+++ b/pceplib/pcep_msg_objects.c
@@ -25,6 +25,10 @@
* This is the implementation of a High Level PCEP message object API.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <string.h>
#include <arpa/inet.h>
#include <stdarg.h>
diff --git a/pceplib/pcep_msg_objects_encoding.c b/pceplib/pcep_msg_objects_encoding.c
index c4089ba5ec..9ab96f7bce 100644
--- a/pceplib/pcep_msg_objects_encoding.c
+++ b/pceplib/pcep_msg_objects_encoding.c
@@ -25,6 +25,10 @@
* Encoding and decoding for PCEP Objects.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
diff --git a/pceplib/pcep_msg_tlvs.c b/pceplib/pcep_msg_tlvs.c
index 9c84e71ee1..6298ed4b8d 100644
--- a/pceplib/pcep_msg_tlvs.c
+++ b/pceplib/pcep_msg_tlvs.c
@@ -25,6 +25,10 @@
* This is the implementation of a High Level PCEP message object TLV API.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
diff --git a/pceplib/pcep_msg_tools.c b/pceplib/pcep_msg_tools.c
index e190d2a850..8f32f2c537 100644
--- a/pceplib/pcep_msg_tools.c
+++ b/pceplib/pcep_msg_tools.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <errno.h>
#include <stdio.h>
#include <string.h>
diff --git a/pceplib/pcep_session_logic.c b/pceplib/pcep_session_logic.c
index 52655914c6..2ec2fd72a8 100644
--- a/pceplib/pcep_session_logic.c
+++ b/pceplib/pcep_session_logic.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <errno.h>
#include <limits.h>
#include <pthread.h>
diff --git a/pceplib/pcep_session_logic_counters.c b/pceplib/pcep_session_logic_counters.c
index a6bd41b4f1..fceb15af76 100644
--- a/pceplib/pcep_session_logic_counters.c
+++ b/pceplib/pcep_session_logic_counters.c
@@ -25,6 +25,10 @@
* PCEP session logic counters configuration.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <time.h>
diff --git a/pceplib/pcep_session_logic_loop.c b/pceplib/pcep_session_logic_loop.c
index 269aa1e07e..4b855c06cd 100644
--- a/pceplib/pcep_session_logic_loop.c
+++ b/pceplib/pcep_session_logic_loop.c
@@ -20,6 +20,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
diff --git a/pceplib/pcep_session_logic_states.c b/pceplib/pcep_session_logic_states.c
index 3beceefad0..3e9c701a62 100644
--- a/pceplib/pcep_session_logic_states.c
+++ b/pceplib/pcep_session_logic_states.c
@@ -20,6 +20,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
diff --git a/pceplib/pcep_socket_comm_loop.c b/pceplib/pcep_socket_comm_loop.c
index d58409c4f3..d9a6b9ae48 100644
--- a/pceplib/pcep_socket_comm_loop.c
+++ b/pceplib/pcep_socket_comm_loop.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
diff --git a/pceplib/pcep_socket_comm_mock.c b/pceplib/pcep_socket_comm_mock.c
index 069d0cf998..7a9511e315 100644
--- a/pceplib/pcep_socket_comm_mock.c
+++ b/pceplib/pcep_socket_comm_mock.c
@@ -27,6 +27,10 @@
* created.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <netinet/in.h>
#include <stdbool.h>
#include <stdlib.h>
diff --git a/pceplib/pcep_timers.c b/pceplib/pcep_timers.c
index d0a2349d05..4c06d2b3f7 100644
--- a/pceplib/pcep_timers.c
+++ b/pceplib/pcep_timers.c
@@ -25,6 +25,10 @@
* Implementation of public API timer functions.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <limits.h>
#include <pthread.h>
#include <stddef.h>
diff --git a/pceplib/pcep_timers_event_loop.c b/pceplib/pcep_timers_event_loop.c
index 932a53eb2a..8984496717 100644
--- a/pceplib/pcep_timers_event_loop.c
+++ b/pceplib/pcep_timers_event_loop.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <errno.h>
#include <stddef.h>
#include <stdbool.h>
diff --git a/pceplib/pcep_utils_double_linked_list.c b/pceplib/pcep_utils_double_linked_list.c
index acdcee0598..696e46632a 100644
--- a/pceplib/pcep_utils_double_linked_list.c
+++ b/pceplib/pcep_utils_double_linked_list.c
@@ -20,6 +20,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stddef.h>
#include <string.h>
diff --git a/pceplib/pcep_utils_logging.c b/pceplib/pcep_utils_logging.c
index 65e1abbc03..0286c23078 100644
--- a/pceplib/pcep_utils_logging.c
+++ b/pceplib/pcep_utils_logging.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdarg.h>
#include <stdio.h>
#include "pcep_utils_logging.h"
diff --git a/pceplib/pcep_utils_memory.c b/pceplib/pcep_utils_memory.c
index 7362e3433b..c564705f66 100644
--- a/pceplib/pcep_utils_memory.c
+++ b/pceplib/pcep_utils_memory.c
@@ -20,6 +20,10 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
diff --git a/pceplib/pcep_utils_ordered_list.c b/pceplib/pcep_utils_ordered_list.c
index f5c7f70240..81eb614494 100644
--- a/pceplib/pcep_utils_ordered_list.c
+++ b/pceplib/pcep_utils_ordered_list.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <string.h>
diff --git a/pceplib/pcep_utils_queue.c b/pceplib/pcep_utils_queue.c
index e8c3f2be0e..627533d01b 100644
--- a/pceplib/pcep_utils_queue.c
+++ b/pceplib/pcep_utils_queue.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
diff --git a/pceplib/test/pcep_msg_messages_test.c b/pceplib/test/pcep_msg_messages_test.c
index b8984a42bc..61fa94047b 100644
--- a/pceplib/test/pcep_msg_messages_test.c
+++ b/pceplib/test/pcep_msg_messages_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <CUnit/CUnit.h>
diff --git a/pceplib/test/pcep_msg_messages_tests.c b/pceplib/test/pcep_msg_messages_tests.c
index bd85a16530..f24a797f77 100644
--- a/pceplib/test/pcep_msg_messages_tests.c
+++ b/pceplib/test/pcep_msg_messages_tests.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/Basic.h>
#include <CUnit/CUnit.h>
#include <CUnit/TestDB.h>
diff --git a/pceplib/test/pcep_msg_object_error_types_test.c b/pceplib/test/pcep_msg_object_error_types_test.c
index 7275eaf098..b1463751d6 100644
--- a/pceplib/test/pcep_msg_object_error_types_test.c
+++ b/pceplib/test/pcep_msg_object_error_types_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <CUnit/CUnit.h>
diff --git a/pceplib/test/pcep_msg_objects_test.c b/pceplib/test/pcep_msg_objects_test.c
index a4c069945c..e0814de543 100644
--- a/pceplib/test/pcep_msg_objects_test.c
+++ b/pceplib/test/pcep_msg_objects_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <CUnit/CUnit.h>
diff --git a/pceplib/test/pcep_msg_tools_test.c b/pceplib/test/pcep_msg_tools_test.c
index ff5fc62390..787df2fd7a 100644
--- a/pceplib/test/pcep_msg_tools_test.c
+++ b/pceplib/test/pcep_msg_tools_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
diff --git a/pceplib/test/pcep_pcc_api_test.c b/pceplib/test/pcep_pcc_api_test.c
index c227dc1a3d..4adbb6374e 100644
--- a/pceplib/test/pcep_pcc_api_test.c
+++ b/pceplib/test/pcep_pcc_api_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <netdb.h> // gethostbyname
#include <pthread.h>
#include <stdlib.h>
diff --git a/pceplib/test/pcep_pcc_api_tests.c b/pceplib/test/pcep_pcc_api_tests.c
index 04895d6340..5d9e92c1d3 100644
--- a/pceplib/test/pcep_pcc_api_tests.c
+++ b/pceplib/test/pcep_pcc_api_tests.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/Basic.h>
#include <CUnit/CUnit.h>
#include <CUnit/TestDB.h>
diff --git a/pceplib/test/pcep_session_logic_loop_test.c b/pceplib/test/pcep_session_logic_loop_test.c
index 3a40f59bb9..d68b200549 100644
--- a/pceplib/test/pcep_session_logic_loop_test.c
+++ b/pceplib/test/pcep_session_logic_loop_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
diff --git a/pceplib/test/pcep_session_logic_states_test.c b/pceplib/test/pcep_session_logic_states_test.c
index f75c16e397..24741fa345 100644
--- a/pceplib/test/pcep_session_logic_states_test.c
+++ b/pceplib/test/pcep_session_logic_states_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
diff --git a/pceplib/test/pcep_session_logic_test.c b/pceplib/test/pcep_session_logic_test.c
index 66db4fbaea..503e77c20e 100644
--- a/pceplib/test/pcep_session_logic_test.c
+++ b/pceplib/test/pcep_session_logic_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <time.h>
diff --git a/pceplib/test/pcep_session_logic_tests.c b/pceplib/test/pcep_session_logic_tests.c
index 67bf6e22ef..9a15390c1b 100644
--- a/pceplib/test/pcep_session_logic_tests.c
+++ b/pceplib/test/pcep_session_logic_tests.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/Basic.h>
#include <CUnit/CUnit.h>
#include <CUnit/TestDB.h>
diff --git a/pceplib/test/pcep_socket_comm_loop_test.c b/pceplib/test/pcep_socket_comm_loop_test.c
index 94f0983ca7..748cf433e6 100644
--- a/pceplib/test/pcep_socket_comm_loop_test.c
+++ b/pceplib/test/pcep_socket_comm_loop_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <pthread.h>
#include <stdlib.h>
diff --git a/pceplib/test/pcep_socket_comm_test.c b/pceplib/test/pcep_socket_comm_test.c
index 35afbcbb13..0ab38bf96e 100644
--- a/pceplib/test/pcep_socket_comm_test.c
+++ b/pceplib/test/pcep_socket_comm_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <netinet/in.h>
#include <CUnit/CUnit.h>
diff --git a/pceplib/test/pcep_socket_comm_tests.c b/pceplib/test/pcep_socket_comm_tests.c
index 293678f1a7..6a5839d3d0 100644
--- a/pceplib/test/pcep_socket_comm_tests.c
+++ b/pceplib/test/pcep_socket_comm_tests.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/Basic.h>
#include <CUnit/CUnit.h>
#include <CUnit/TestDB.h>
diff --git a/pceplib/test/pcep_timers_event_loop_test.c b/pceplib/test/pcep_timers_event_loop_test.c
index ae63601df2..79ed84bfeb 100644
--- a/pceplib/test/pcep_timers_event_loop_test.c
+++ b/pceplib/test/pcep_timers_event_loop_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <CUnit/CUnit.h>
diff --git a/pceplib/test/pcep_timers_test.c b/pceplib/test/pcep_timers_test.c
index 9d9e0f6c1b..e5be90a8ed 100644
--- a/pceplib/test/pcep_timers_test.c
+++ b/pceplib/test/pcep_timers_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdbool.h>
#include <CUnit/CUnit.h>
diff --git a/pceplib/test/pcep_timers_tests.c b/pceplib/test/pcep_timers_tests.c
index adfea17e29..f3aa8307a7 100644
--- a/pceplib/test/pcep_timers_tests.c
+++ b/pceplib/test/pcep_timers_tests.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/Basic.h>
#include <CUnit/CUnit.h>
#include <CUnit/TestDB.h>
diff --git a/pceplib/test/pcep_utils_counters_test.c b/pceplib/test/pcep_utils_counters_test.c
index 6f53e4d400..bcdce36188 100644
--- a/pceplib/test/pcep_utils_counters_test.c
+++ b/pceplib/test/pcep_utils_counters_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <CUnit/CUnit.h>
diff --git a/pceplib/test/pcep_utils_double_linked_list_test.c b/pceplib/test/pcep_utils_double_linked_list_test.c
index d2600e66c4..4eb85816b9 100644
--- a/pceplib/test/pcep_utils_double_linked_list_test.c
+++ b/pceplib/test/pcep_utils_double_linked_list_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/CUnit.h>
#include "pcep_utils_double_linked_list.h"
diff --git a/pceplib/test/pcep_utils_memory_test.c b/pceplib/test/pcep_utils_memory_test.c
index b0b528f084..0958626a0c 100644
--- a/pceplib/test/pcep_utils_memory_test.c
+++ b/pceplib/test/pcep_utils_memory_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdint.h>
diff --git a/pceplib/test/pcep_utils_ordered_list_test.c b/pceplib/test/pcep_utils_ordered_list_test.c
index fe9ee58825..d20f5e68af 100644
--- a/pceplib/test/pcep_utils_ordered_list_test.c
+++ b/pceplib/test/pcep_utils_ordered_list_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/CUnit.h>
#include "pcep_utils_ordered_list.h"
diff --git a/pceplib/test/pcep_utils_queue_test.c b/pceplib/test/pcep_utils_queue_test.c
index 1731457789..061dfbf37b 100644
--- a/pceplib/test/pcep_utils_queue_test.c
+++ b/pceplib/test/pcep_utils_queue_test.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/CUnit.h>
#include "pcep_utils_queue.h"
diff --git a/pceplib/test/pcep_utils_tests.c b/pceplib/test/pcep_utils_tests.c
index 452b9fa09c..ad9f76933a 100644
--- a/pceplib/test/pcep_utils_tests.c
+++ b/pceplib/test/pcep_utils_tests.c
@@ -21,6 +21,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <CUnit/Basic.h>
#include <CUnit/CUnit.h>
#include <CUnit/TestDB.h>
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c
index 957f904714..0988938701 100644
--- a/pimd/pim_assert.c
+++ b/pimd/pim_assert.c
@@ -304,7 +304,7 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
msg_metric.ip_address = src_addr;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
++pim_ifp->pim_ifstat_assert_recv;
return dispatch_assert(ifp, msg_source_addr.u.prefix4, sg.grp,
diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c
index f43a31fde2..3fbe3317ba 100644
--- a/pimd/pim_bsm.c
+++ b/pimd/pim_bsm.c
@@ -43,8 +43,8 @@ static inline void pim_g2rp_timer_restart(struct bsm_rpinfo *bsrp,
/* Memory Types */
DEFINE_MTYPE_STATIC(PIMD, PIM_BSGRP_NODE, "PIM BSR advertised grp info");
-DEFINE_MTYPE_STATIC(PIMD, PIM_BSRP_NODE, "PIM BSR advertised RP info");
-DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_INFO, "PIM BSM Info");
+DEFINE_MTYPE_STATIC(PIMD, PIM_BSRP_INFO, "PIM BSR advertised RP info");
+DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_FRAG, "PIM BSM fragment");
DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_PKT_VAR_MEM, "PIM BSM Packet");
/* All bsm packets forwarded shall be fit within ip mtu less iphdr(max) */
@@ -63,12 +63,24 @@ void pim_bsm_write_config(struct vty *vty, struct interface *ifp)
}
}
+static void pim_bsm_rpinfo_free(struct bsm_rpinfo *bsrp_info)
+{
+ THREAD_OFF(bsrp_info->g2rp_timer);
+ XFREE(MTYPE_PIM_BSRP_INFO, bsrp_info);
+}
+
+void pim_bsm_rpinfos_free(struct bsm_rpinfos_head *head)
+{
+ struct bsm_rpinfo *bsrp_info;
+
+ while ((bsrp_info = bsm_rpinfos_pop(head)))
+ pim_bsm_rpinfo_free(bsrp_info);
+}
+
void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node)
{
- if (bsgrp_node->bsrp_list)
- list_delete(&bsgrp_node->bsrp_list);
- if (bsgrp_node->partial_bsrp_list)
- list_delete(&bsgrp_node->partial_bsrp_list);
+ pim_bsm_rpinfos_free(bsgrp_node->bsrp_list);
+ pim_bsm_rpinfos_free(bsgrp_node->partial_bsrp_list);
XFREE(MTYPE_PIM_BSGRP_NODE, bsgrp_node);
}
@@ -84,14 +96,21 @@ void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp)
}
}
-static void pim_bsm_node_free(struct bsm_info *bsm)
+static void pim_bsm_frag_free(struct bsm_frag *bsfrag)
{
- XFREE(MTYPE_PIM_BSM_PKT_VAR_MEM, bsm->bsm);
- XFREE(MTYPE_PIM_BSM_INFO, bsm);
+ XFREE(MTYPE_PIM_BSM_FRAG, bsfrag);
}
-static int pim_g2rp_list_compare(struct bsm_rpinfo *node1,
- struct bsm_rpinfo *node2)
+void pim_bsm_frags_free(struct bsm_scope *scope)
+{
+ struct bsm_frag *bsfrag;
+
+ while ((bsfrag = bsm_frags_pop(scope->bsm_frags)))
+ pim_bsm_frag_free(bsfrag);
+}
+
+int pim_bsm_rpinfo_cmp(const struct bsm_rpinfo *node1,
+ const struct bsm_rpinfo *node2)
{
/* RP election Algo :
* Step-1 : Loweset Rp priority will have higher precedance.
@@ -115,27 +134,6 @@ static int pim_g2rp_list_compare(struct bsm_rpinfo *node1,
return 0;
}
-static void pim_free_bsrp_node(struct bsm_rpinfo *bsrp_info)
-{
- THREAD_OFF(bsrp_info->g2rp_timer);
- XFREE(MTYPE_PIM_BSRP_NODE, bsrp_info);
-}
-
-static struct list *pim_alloc_bsrp_list(void)
-{
- struct list *new_list = NULL;
-
- new_list = list_new();
-
- if (!new_list)
- return NULL;
-
- new_list->cmp = (int (*)(void *, void *))pim_g2rp_list_compare;
- new_list->del = (void (*)(void *))pim_free_bsrp_node;
-
- return new_list;
-}
-
static struct bsgrp_node *pim_bsm_new_bsgrp_node(struct route_table *rt,
struct prefix *grp)
{
@@ -150,14 +148,8 @@ static struct bsgrp_node *pim_bsm_new_bsgrp_node(struct route_table *rt,
bsgrp = XCALLOC(MTYPE_PIM_BSGRP_NODE, sizeof(struct bsgrp_node));
rn->info = bsgrp;
- bsgrp->bsrp_list = pim_alloc_bsrp_list();
- bsgrp->partial_bsrp_list = pim_alloc_bsrp_list();
-
- if ((!bsgrp->bsrp_list) || (!bsgrp->partial_bsrp_list)) {
- route_unlock_node(rn);
- pim_free_bsgrp_data(bsgrp);
- return NULL;
- }
+ bsm_rpinfos_init(bsgrp->bsrp_list);
+ bsm_rpinfos_init(bsgrp->partial_bsrp_list);
prefix_copy(&bsgrp->group, grp);
return bsgrp;
@@ -197,7 +189,7 @@ static int pim_on_bs_timer(struct thread *t)
scope->current_bsr_first_ts = 0;
scope->current_bsr_last_ts = 0;
scope->bsm_frag_tag = 0;
- list_delete_all_node(scope->bsm_list);
+ pim_bsm_frags_free(scope);
for (rn = route_top(scope->bsrp_table); rn; rn = route_next(rn)) {
@@ -208,16 +200,13 @@ static int pim_on_bs_timer(struct thread *t)
continue;
}
/* Give grace time for rp to continue for another hold time */
- if ((bsgrp_node->bsrp_list) && (bsgrp_node->bsrp_list->count)) {
- bsrp = listnode_head(bsgrp_node->bsrp_list);
+ bsrp = bsm_rpinfos_first(bsgrp_node->bsrp_list);
+ if (bsrp)
pim_g2rp_timer_restart(bsrp, bsrp->rp_holdtime);
- }
+
/* clear pending list */
- if ((bsgrp_node->partial_bsrp_list)
- && (bsgrp_node->partial_bsrp_list->count)) {
- list_delete_all_node(bsgrp_node->partial_bsrp_list);
- bsgrp_node->pend_rp_cnt = 0;
- }
+ pim_bsm_rpinfos_free(bsgrp_node->partial_bsrp_list);
+ bsgrp_node->pend_rp_cnt = 0;
}
return 0;
}
@@ -260,8 +249,7 @@ void pim_bsm_proc_init(struct pim_instance *pim)
pim->global_scope.accept_nofwd_bsm = true;
pim->global_scope.state = NO_INFO;
pim->global_scope.pim = pim;
- pim->global_scope.bsm_list = list_new();
- pim->global_scope.bsm_list->del = (void (*)(void *))pim_bsm_node_free;
+ bsm_frags_init(pim->global_scope.bsm_frags);
pim_bs_timer_start(&pim->global_scope, PIM_BS_TIME);
}
@@ -271,9 +259,7 @@ void pim_bsm_proc_free(struct pim_instance *pim)
struct bsgrp_node *bsgrp;
pim_bs_timer_stop(&pim->global_scope);
-
- if (pim->global_scope.bsm_list)
- list_delete(&pim->global_scope.bsm_list);
+ pim_bsm_frags_free(&pim->global_scope);
for (rn = route_top(pim->global_scope.bsrp_table); rn;
rn = route_next(rn)) {
@@ -303,7 +289,6 @@ static int pim_on_g2rp_timer(struct thread *t)
struct bsm_rpinfo *bsrp;
struct bsm_rpinfo *bsrp_node;
struct bsgrp_node *bsgrp_node;
- struct listnode *bsrp_ln;
struct pim_instance *pim;
struct rp_info *rp_info;
struct route_node *rn;
@@ -319,14 +304,17 @@ static int pim_on_g2rp_timer(struct thread *t)
bsrp_addr = bsrp->rp_address;
/* update elapse for all bsrp nodes */
- for (ALL_LIST_ELEMENTS_RO(bsgrp_node->bsrp_list, bsrp_ln, bsrp_node))
+ frr_each_safe (bsm_rpinfos, bsgrp_node->bsrp_list, bsrp_node) {
bsrp_node->elapse_time += elapse;
- /* remove the expired nodes from the list */
- list_filter_out_nodes(bsgrp_node->bsrp_list, is_hold_time_elapsed);
+ if (is_hold_time_elapsed(bsrp_node)) {
+ bsm_rpinfos_del(bsgrp_node->bsrp_list, bsrp_node);
+ pim_bsm_rpinfo_free(bsrp_node);
+ }
+ }
/* Get the next elected rp node */
- bsrp = listnode_head(bsgrp_node->bsrp_list);
+ bsrp = bsm_rpinfos_first(bsgrp_node->bsrp_list);
pim = bsgrp_node->scope->pim;
rn = route_node_lookup(pim->rp_table, &bsgrp_node->group);
@@ -356,8 +344,8 @@ static int pim_on_g2rp_timer(struct thread *t)
}
}
- if ((!bsgrp_node->bsrp_list->count)
- && (!bsgrp_node->partial_bsrp_list->count)) {
+ if (!bsm_rpinfos_count(bsgrp_node->bsrp_list)
+ && !bsm_rpinfos_count(bsgrp_node->partial_bsrp_list)) {
pim_free_bsgrp_node(pim->global_scope.bsrp_table,
&bsgrp_node->group);
pim_free_bsgrp_data(bsgrp_node);
@@ -420,7 +408,6 @@ static void pim_instate_pend_list(struct bsgrp_node *bsgrp_node)
{
struct bsm_rpinfo *active;
struct bsm_rpinfo *pend;
- struct list *temp;
struct rp_info *rp_info;
struct route_node *rn;
struct pim_instance *pim;
@@ -429,11 +416,14 @@ static void pim_instate_pend_list(struct bsgrp_node *bsgrp_node)
bool had_rp_node = true;
pim = bsgrp_node->scope->pim;
- active = listnode_head(bsgrp_node->bsrp_list);
+ active = bsm_rpinfos_first(bsgrp_node->bsrp_list);
/* Remove nodes with hold time 0 & check if list still has a head */
- list_filter_out_nodes(bsgrp_node->partial_bsrp_list, is_hold_time_zero);
- pend = listnode_head(bsgrp_node->partial_bsrp_list);
+ frr_each_safe (bsm_rpinfos, bsgrp_node->partial_bsrp_list, pend)
+ if (is_hold_time_zero(pend))
+ bsm_rpinfos_del(bsgrp_node->partial_bsrp_list, pend);
+
+ pend = bsm_rpinfos_first(bsgrp_node->partial_bsrp_list);
if (!str2prefix("224.0.0.0/4", &group_all))
return;
@@ -541,14 +531,12 @@ static void pim_instate_pend_list(struct bsgrp_node *bsgrp_node)
* pend is head of bsrp list
* So check appriate head after swap and clean the new partial list
*/
- temp = bsgrp_node->bsrp_list;
- bsgrp_node->bsrp_list = bsgrp_node->partial_bsrp_list;
- bsgrp_node->partial_bsrp_list = temp;
+ bsm_rpinfos_swap_all(bsgrp_node->bsrp_list,
+ bsgrp_node->partial_bsrp_list);
- if (active) {
+ if (active)
pim_g2rp_timer_stop(active);
- list_delete_all_node(bsgrp_node->partial_bsrp_list);
- }
+ pim_bsm_rpinfos_free(bsgrp_node->partial_bsrp_list);
}
static bool pim_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr,
@@ -896,8 +884,7 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
struct in_addr dst_addr;
struct pim_interface *pim_ifp;
struct bsm_scope *scope;
- struct listnode *bsm_ln;
- struct bsm_info *bsminfo;
+ struct bsm_frag *bsfrag;
char neigh_src_str[INET_ADDRSTRLEN];
uint32_t pim_mtu;
bool no_fwd = true;
@@ -929,7 +916,7 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
scope = &pim_ifp->pim->global_scope;
- if (!scope->bsm_list->count) {
+ if (!bsm_frags_count(scope->bsm_frags)) {
if (PIM_DEBUG_BSM)
zlog_debug("%s: BSM list for the scope is empty",
__func__);
@@ -950,10 +937,10 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
pim_mtu = ifp->mtu - MAX_IP_HDR_LEN;
pim_hello_require(ifp);
- for (ALL_LIST_ELEMENTS_RO(scope->bsm_list, bsm_ln, bsminfo)) {
- if (pim_mtu < bsminfo->size) {
- ret = pim_bsm_frag_send(bsminfo->bsm, bsminfo->size,
- ifp, pim_mtu, dst_addr, no_fwd);
+ frr_each (bsm_frags, scope->bsm_frags, bsfrag) {
+ if (pim_mtu < bsfrag->size) {
+ ret = pim_bsm_frag_send(bsfrag->data, bsfrag->size, ifp,
+ pim_mtu, dst_addr, no_fwd);
if (!ret) {
if (PIM_DEBUG_BSM)
zlog_debug(
@@ -962,10 +949,10 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
}
} else {
/* Pim header needs to be constructed */
- pim_msg_build_header(bsminfo->bsm, bsminfo->size,
+ pim_msg_build_header(bsfrag->data, bsfrag->size,
PIM_MSG_TYPE_BOOTSTRAP, no_fwd);
- ret = pim_bsm_send_intf(bsminfo->bsm, bsminfo->size,
- ifp, dst_addr);
+ ret = pim_bsm_send_intf(bsfrag->data, bsfrag->size, ifp,
+ dst_addr);
if (!ret) {
if (PIM_DEBUG_BSM)
zlog_debug(
@@ -1035,7 +1022,7 @@ static bool pim_install_bsm_grp_rp(struct pim_instance *pim,
uint8_t hashMask_len = pim->global_scope.hashMasklen;
/*memory allocation for bsm_rpinfo */
- bsm_rpinfo = XCALLOC(MTYPE_PIM_BSRP_NODE, sizeof(*bsm_rpinfo));
+ bsm_rpinfo = XCALLOC(MTYPE_PIM_BSRP_INFO, sizeof(*bsm_rpinfo));
bsm_rpinfo->rp_prio = rp->rp_pri;
bsm_rpinfo->rp_holdtime = rp->rp_holdtime;
@@ -1049,7 +1036,7 @@ static bool pim_install_bsm_grp_rp(struct pim_instance *pim,
/* update hash for this rp node */
bsm_rpinfo->hash = hash_calc_on_grp_rp(grpnode->group, rp->rpaddr.addr,
hashMask_len);
- if (listnode_add_sort_nodup(grpnode->partial_bsrp_list, bsm_rpinfo)) {
+ if (bsm_rpinfos_add(grpnode->partial_bsrp_list, bsm_rpinfo) == NULL) {
if (PIM_DEBUG_BSM)
zlog_debug(
"%s, bs_rpinfo node added to the partial bs_rplist.",
@@ -1060,7 +1047,7 @@ static bool pim_install_bsm_grp_rp(struct pim_instance *pim,
if (PIM_DEBUG_BSM)
zlog_debug("%s: list node not added", __func__);
- XFREE(MTYPE_PIM_BSRP_NODE, bsm_rpinfo);
+ XFREE(MTYPE_PIM_BSRP_INFO, bsm_rpinfo);
return false;
}
@@ -1078,7 +1065,7 @@ static void pim_update_pending_rp_cnt(struct bsm_scope *sz,
zlog_debug(
"%s,Received a new BSM ,so clear the pending bs_rpinfo list.",
__func__);
- list_delete_all_node(bsgrp->partial_bsrp_list);
+ pim_bsm_rpinfos_free(bsgrp->partial_bsrp_list);
bsgrp->pend_rp_cnt = total_rp_count;
}
} else
@@ -1227,7 +1214,7 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
int sz = PIM_GBL_SZ_ID;
struct bsmmsg_grpinfo *msg_grp;
struct pim_interface *pim_ifp = NULL;
- struct bsm_info *bsminfo;
+ struct bsm_frag *bsfrag;
struct pim_instance *pim;
char bsr_str[INET_ADDRSTRLEN];
uint16_t frag_tag;
@@ -1383,7 +1370,7 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
pim_ifp->pim->global_scope.bsm_frag_tag,
frag_tag);
}
- list_delete_all_node(pim_ifp->pim->global_scope.bsm_list);
+ pim_bsm_frags_free(&pim_ifp->pim->global_scope);
pim_ifp->pim->global_scope.bsm_frag_tag = frag_tag;
}
@@ -1392,13 +1379,13 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
if (!no_fwd) {
pim_bsm_fwd_whole_sz(pim_ifp->pim, buf, buf_size, sz);
- bsminfo = XCALLOC(MTYPE_PIM_BSM_INFO, sizeof(struct bsm_info));
-
- bsminfo->bsm = XCALLOC(MTYPE_PIM_BSM_PKT_VAR_MEM, buf_size);
+ bsfrag = XCALLOC(MTYPE_PIM_BSM_FRAG,
+ sizeof(struct bsm_frag) + buf_size);
- bsminfo->size = buf_size;
- memcpy(bsminfo->bsm, buf, buf_size);
- listnode_add(pim_ifp->pim->global_scope.bsm_list, bsminfo);
+ bsfrag->size = buf_size;
+ memcpy(bsfrag->data, buf, buf_size);
+ bsm_frags_add_tail(pim_ifp->pim->global_scope.bsm_frags,
+ bsfrag);
}
return 0;
diff --git a/pimd/pim_bsm.h b/pimd/pim_bsm.h
index 2829c1e05a..dbfeeceec8 100644
--- a/pimd/pim_bsm.h
+++ b/pimd/pim_bsm.h
@@ -25,7 +25,7 @@
#include "if.h"
#include "vty.h"
-#include "linklist.h"
+#include "typesafe.h"
#include "table.h"
#include "pim_rp.h"
#include "pim_msg.h"
@@ -54,6 +54,8 @@ enum ncbsr_state {
ACCEPT_PREFERRED
};
+PREDECL_DLIST(bsm_frags);
+
/* BSM scope - bsm processing is per scope */
struct bsm_scope {
int sz_id; /* scope zone id */
@@ -66,36 +68,49 @@ struct bsm_scope {
uint16_t bsm_frag_tag; /* Last received frag tag from E-BSR */
uint8_t hashMasklen; /* Mask in hash calc RFC 7761 4.7.2 */
struct pim_instance *pim; /* Back pointer to pim instance */
- struct list *bsm_list; /* list of bsm frag for frowarding */
+
+ /* current set of fragments for forwarding */
+ struct bsm_frags_head bsm_frags[1];
+
struct route_table *bsrp_table; /* group2rp mapping rcvd from BSR */
struct thread *bs_timer; /* Boot strap timer */
- struct thread *sz_timer;
};
-/* BSM packet - this is stored as list in bsm_list inside scope
+/* BSM packet (= fragment) - this is stored as list in bsm_frags inside scope
* This is used for forwarding to new neighbors or restarting mcast routers
*/
-struct bsm_info {
- uint32_t size; /* size of the packet */
- unsigned char *bsm; /* Actual packet */
+struct bsm_frag {
+ struct bsm_frags_item item;
+
+ uint32_t size; /* size of the packet */
+ uint8_t data[0]; /* Actual packet (dyn size) */
};
+DECLARE_DLIST(bsm_frags, struct bsm_frag, item);
+
+PREDECL_SORTLIST_UNIQ(bsm_rpinfos);
+
/* This is the group node of the bsrp table in scope.
* this node maintains the list of rp for the group.
*/
struct bsgrp_node {
struct prefix group; /* Group range */
struct bsm_scope *scope; /* Back ptr to scope */
- struct list *bsrp_list; /* list of RPs adv by BSR */
- struct list *partial_bsrp_list; /* maintained until all RPs received */
+
+ /* RPs advertised by BSR, and temporary list while receiving new set */
+ struct bsm_rpinfos_head bsrp_list[1];
+ struct bsm_rpinfos_head partial_bsrp_list[1];
+
int pend_rp_cnt; /* Total RP - Received RP */
uint16_t frag_tag; /* frag tag to identify the fragment */
};
-/* This is the list node of bsrp_list and partial bsrp list in
- * bsgrp_node. Hold info of each RP received for the group
+/* Items on [partial_]bsrp_list above.
+ * Holds info of each candidate RP received for the bsgrp_node's prefix.
*/
struct bsm_rpinfo {
+ struct bsm_rpinfos_item item;
+
uint32_t hash; /* Hash Value as per RFC 7761 4.7.2 */
uint32_t elapse_time; /* upd at expiry of elected RP node */
uint16_t rp_prio; /* RP priority */
@@ -105,6 +120,10 @@ struct bsm_rpinfo {
struct thread *g2rp_timer; /* Run only for elected RP node */
};
+extern int pim_bsm_rpinfo_cmp(const struct bsm_rpinfo *a,
+ const struct bsm_rpinfo *b);
+DECLARE_SORTLIST_UNIQ(bsm_rpinfos, struct bsm_rpinfo, item, pim_bsm_rpinfo_cmp);
+
/* Structures to extract Bootstrap Message header and Grp to RP Mappings
* =====================================================================
* BSM Format:
@@ -196,6 +215,8 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp);
struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
struct prefix *grp);
void pim_bs_timer_stop(struct bsm_scope *scope);
+void pim_bsm_frags_free(struct bsm_scope *scope);
+void pim_bsm_rpinfos_free(struct bsm_rpinfos_head *head);
void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node);
void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp);
#endif
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index c01cfec88e..d2f7dad820 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -3000,15 +3000,14 @@ static void pim_show_nexthop(struct pim_instance *pim, struct vty *vty)
/* Display the bsm database details */
static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
{
- struct listnode *bsmnode;
int count = 0;
int fragment = 1;
- struct bsm_info *bsm;
+ struct bsm_frag *bsfrag;
json_object *json = NULL;
json_object *json_group = NULL;
json_object *json_row = NULL;
- count = pim->global_scope.bsm_list->count;
+ count = bsm_frags_count(pim->global_scope.bsm_frags);
if (uj) {
json = json_object_new_object();
@@ -3019,7 +3018,7 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
vty_out(vty, "\n");
}
- for (ALL_LIST_ELEMENTS_RO(pim->global_scope.bsm_list, bsmnode, bsm)) {
+ frr_each (bsm_frags, pim->global_scope.bsm_frags, bsfrag) {
char grp_str[PREFIX_STRLEN];
char rp_str[INET_ADDRSTRLEN];
char bsr_str[INET_ADDRSTRLEN];
@@ -3032,8 +3031,8 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
uint32_t len = 0;
uint32_t frag_rp_cnt = 0;
- buf = bsm->bsm;
- len = bsm->size;
+ buf = bsfrag->data;
+ len = bsfrag->size;
/* skip pim header */
buf += PIM_MSG_HEADER_LEN;
@@ -3160,7 +3159,6 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
struct vty *vty, bool uj)
{
struct bsgrp_node *bsgrp;
- struct listnode *rpnode;
struct bsm_rpinfo *bsm_rp;
struct route_node *rn;
char bsr_str[INET_ADDRSTRLEN];
@@ -3209,42 +3207,33 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
vty_out(vty, "(ACTIVE)\n");
}
- if (bsgrp->bsrp_list) {
- for (ALL_LIST_ELEMENTS_RO(bsgrp->bsrp_list, rpnode,
- bsm_rp)) {
- char rp_str[INET_ADDRSTRLEN];
+ frr_each (bsm_rpinfos, bsgrp->bsrp_list, bsm_rp) {
+ char rp_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<Rp Address?>",
- bsm_rp->rp_address, rp_str,
- sizeof(rp_str));
+ pim_inet4_dump("<Rp Address?>", bsm_rp->rp_address,
+ rp_str, sizeof(rp_str));
- if (uj) {
- json_row = json_object_new_object();
- json_object_string_add(
- json_row, "Rp Address", rp_str);
- json_object_int_add(
- json_row, "Rp HoldTime",
- bsm_rp->rp_holdtime);
- json_object_int_add(json_row,
- "Rp Priority",
- bsm_rp->rp_prio);
- json_object_int_add(json_row,
- "Hash Val",
- bsm_rp->hash);
- json_object_object_add(
- json_group, rp_str, json_row);
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "Rp Address",
+ rp_str);
+ json_object_int_add(json_row, "Rp HoldTime",
+ bsm_rp->rp_holdtime);
+ json_object_int_add(json_row, "Rp Priority",
+ bsm_rp->rp_prio);
+ json_object_int_add(json_row, "Hash Val",
+ bsm_rp->hash);
+ json_object_object_add(json_group, rp_str,
+ json_row);
- } else {
- vty_out(vty,
- "%-15s %-15u %-15u %-15u\n",
- rp_str, bsm_rp->rp_prio,
- bsm_rp->rp_holdtime,
- bsm_rp->hash);
- }
+ } else {
+ vty_out(vty, "%-15s %-15u %-15u %-15u\n",
+ rp_str, bsm_rp->rp_prio,
+ bsm_rp->rp_holdtime, bsm_rp->hash);
}
- if (!bsgrp->bsrp_list->count && !uj)
- vty_out(vty, "Active List is empty.\n");
}
+ if (!bsm_rpinfos_count(bsgrp->bsrp_list) && !uj)
+ vty_out(vty, "Active List is empty.\n");
if (uj) {
json_object_int_add(json_group, "Pending RP count",
@@ -3259,40 +3248,32 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
"Hash");
}
- if (bsgrp->partial_bsrp_list) {
- for (ALL_LIST_ELEMENTS_RO(bsgrp->partial_bsrp_list,
- rpnode, bsm_rp)) {
- char rp_str[INET_ADDRSTRLEN];
+ frr_each (bsm_rpinfos, bsgrp->partial_bsrp_list, bsm_rp) {
+ char rp_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address,
- rp_str, sizeof(rp_str));
+ pim_inet4_dump("<Rp Addr?>", bsm_rp->rp_address, rp_str,
+ sizeof(rp_str));
- if (uj) {
- json_row = json_object_new_object();
- json_object_string_add(
- json_row, "Rp Address", rp_str);
- json_object_int_add(
- json_row, "Rp HoldTime",
- bsm_rp->rp_holdtime);
- json_object_int_add(json_row,
- "Rp Priority",
- bsm_rp->rp_prio);
- json_object_int_add(json_row,
- "Hash Val",
- bsm_rp->hash);
- json_object_object_add(
- json_group, rp_str, json_row);
- } else {
- vty_out(vty,
- "%-15s %-15u %-15u %-15u\n",
- rp_str, bsm_rp->rp_prio,
- bsm_rp->rp_holdtime,
- bsm_rp->hash);
- }
+ if (uj) {
+ json_row = json_object_new_object();
+ json_object_string_add(json_row, "Rp Address",
+ rp_str);
+ json_object_int_add(json_row, "Rp HoldTime",
+ bsm_rp->rp_holdtime);
+ json_object_int_add(json_row, "Rp Priority",
+ bsm_rp->rp_prio);
+ json_object_int_add(json_row, "Hash Val",
+ bsm_rp->hash);
+ json_object_object_add(json_group, rp_str,
+ json_row);
+ } else {
+ vty_out(vty, "%-15s %-15u %-15u %-15u\n",
+ rp_str, bsm_rp->rp_prio,
+ bsm_rp->rp_holdtime, bsm_rp->hash);
}
- if (!bsgrp->partial_bsrp_list->count && !uj)
- vty_out(vty, "Partial List is empty\n");
}
+ if (!bsm_rpinfos_count(bsgrp->partial_bsrp_list) && !uj)
+ vty_out(vty, "Partial List is empty\n");
if (!uj)
vty_out(vty, "\n");
@@ -3847,6 +3828,31 @@ static void clear_interfaces(struct pim_instance *pim)
return CMD_WARNING_CONFIG_FAILED; \
}
+/**
+ * Get current node VRF name.
+ *
+ * NOTE:
+ * In case of failure it will print error message to user.
+ *
+ * \returns name or NULL if failed to get VRF.
+ */
+static const char *pim_cli_get_vrf_name(struct vty *vty)
+{
+ const struct lyd_node *vrf_node;
+
+ /* Not inside any VRF context. */
+ if (vty->xpath_index == 0)
+ return VRF_DEFAULT_NAME;
+
+ vrf_node = yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (vrf_node == NULL) {
+ vty_out(vty, "%% Failed to get vrf dnode in configuration\n");
+ return NULL;
+ }
+
+ return yang_dnode_get_string(vrf_node, "./name");
+}
+
DEFUN (clear_ip_interfaces,
clear_ip_interfaces_cmd,
"clear ip interfaces [vrf NAME]",
@@ -4083,7 +4089,7 @@ static void clear_pim_bsr_db(struct pim_instance *pim)
pim->global_scope.current_bsr_first_ts = 0;
pim->global_scope.current_bsr_last_ts = 0;
pim->global_scope.bsm_frag_tag = 0;
- list_delete_all_node(pim->global_scope.bsm_list);
+ pim_bsm_frags_free(&pim->global_scope);
pim_bs_timer_stop(&pim->global_scope);
@@ -6925,25 +6931,13 @@ DEFUN (ip_pim_spt_switchover_infinity,
"SPT-Switchover\n"
"Never switch to SPT Tree\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char spt_plist_xpath[XPATH_MAXLEN];
char spt_action_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
-
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(spt_plist_xpath, sizeof(spt_plist_xpath),
FRR_PIM_AF_XPATH, "frr-pim:pimd", "pim", vrfname,
@@ -6976,25 +6970,13 @@ DEFUN (ip_pim_spt_switchover_infinity_plist,
"Prefix-List to control which groups to switch\n"
"Prefix-List name\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char spt_plist_xpath[XPATH_MAXLEN];
char spt_action_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
-
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(spt_plist_xpath, sizeof(spt_plist_xpath),
FRR_PIM_AF_XPATH, "frr-pim:pimd", "pim", vrfname,
@@ -7025,25 +7007,13 @@ DEFUN (no_ip_pim_spt_switchover_infinity,
"SPT_Switchover\n"
"Never switch to SPT Tree\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char spt_plist_xpath[XPATH_MAXLEN];
char spt_action_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
-
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(spt_plist_xpath, sizeof(spt_plist_xpath),
FRR_PIM_AF_XPATH, "frr-pim:pimd", "pim", vrfname,
@@ -7075,25 +7045,13 @@ DEFUN (no_ip_pim_spt_switchover_infinity_plist,
"Prefix-List to control which groups to switch\n"
"Prefix-List name\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char spt_plist_xpath[XPATH_MAXLEN];
char spt_action_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
-
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(spt_plist_xpath, sizeof(spt_plist_xpath),
FRR_PIM_AF_XPATH, "frr-pim:pimd", "pim", vrfname,
@@ -7123,22 +7081,12 @@ DEFPY (pim_register_accept_list,
"Only accept registers from a specific source prefix list\n"
"Prefix-List name\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char reg_alist_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(reg_alist_xpath, sizeof(reg_alist_xpath),
FRR_PIM_AF_XPATH, "frr-pim:pimd", "pim", vrfname,
@@ -7233,22 +7181,12 @@ DEFUN (ip_pim_rp_keep_alive,
"Keep alive Timer\n"
"Seconds\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char rp_ka_timer_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_ka_timer_xpath, sizeof(rp_ka_timer_xpath),
FRR_PIM_XPATH, "frr-pim:pimd", "pim", vrfname);
@@ -7271,26 +7209,15 @@ DEFUN (no_ip_pim_rp_keep_alive,
"Keep alive Timer\n"
"Seconds\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char rp_ka_timer[5];
char rp_ka_timer_xpath[XPATH_MAXLEN];
snprintf(rp_ka_timer, sizeof(rp_ka_timer), "%d", PIM_KEEPALIVE_PERIOD);
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
-
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_ka_timer_xpath, sizeof(rp_ka_timer_xpath),
FRR_PIM_XPATH, "frr-pim:pimd", "pim", vrfname);
@@ -7311,22 +7238,12 @@ DEFUN (ip_pim_keep_alive,
"Keep alive Timer\n"
"Seconds\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ka_timer_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), FRR_PIM_XPATH,
"frr-pim:pimd", "pim", vrfname);
@@ -7347,25 +7264,15 @@ DEFUN (no_ip_pim_keep_alive,
"Keep alive Timer\n"
"Seconds\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ka_timer[5];
char ka_timer_xpath[XPATH_MAXLEN];
snprintf(ka_timer, sizeof(ka_timer), "%d", PIM_KEEPALIVE_PERIOD);
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), FRR_PIM_XPATH,
"frr-pim:pimd", "pim", vrfname);
@@ -7447,22 +7354,12 @@ DEFUN (ip_pim_v6_secondary,
"pim multicast routing\n"
"Send v6 secondary addresses\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char send_v6_secondary_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
FRR_PIM_AF_XPATH,
@@ -7484,22 +7381,12 @@ DEFUN (no_ip_pim_v6_secondary,
"pim multicast routing\n"
"Send v6 secondary addresses\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char send_v6_secondary_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath),
FRR_PIM_AF_XPATH,
@@ -7522,7 +7409,6 @@ DEFUN (ip_pim_rp,
"ip address of RP\n"
"Group Address range to cover\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
int idx_rp = 3, idx_group = 4;
char rp_group_xpath[XPATH_MAXLEN];
@@ -7558,20 +7444,9 @@ DEFUN (ip_pim_rp,
return CMD_WARNING_CONFIG_FAILED;
}
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
-
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_group_xpath, sizeof(rp_group_xpath),
FRR_PIM_STATIC_RP_XPATH,
@@ -7595,24 +7470,12 @@ DEFUN (ip_pim_rp_prefix_list,
"Name of a prefix-list\n")
{
int idx_rp = 3, idx_plist = 5;
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char rp_plist_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
-
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_plist_xpath, sizeof(rp_plist_xpath),
FRR_PIM_STATIC_RP_XPATH,
@@ -7642,24 +7505,12 @@ DEFUN (no_ip_pim_rp,
char group_list_xpath[XPATH_MAXLEN + 32];
char group_xpath[XPATH_MAXLEN + 64];
char rp_xpath[XPATH_MAXLEN];
- const struct lyd_node *vrf_dnode;
const char *vrfname;
const struct lyd_node *group_dnode;
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
-
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4",
@@ -7702,23 +7553,13 @@ DEFUN (no_ip_pim_rp_prefix_list,
int idx_plist = 6;
char rp_xpath[XPATH_MAXLEN];
char plist_xpath[XPATH_MAXLEN];
- const struct lyd_node *vrf_dnode;
const char *vrfname;
const struct lyd_node *plist_dnode;
const char *plist;
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4",
@@ -7755,22 +7596,12 @@ DEFUN (ip_pim_ssm_prefix_list,
"group range prefix-list filter\n"
"Name of a prefix-list\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ssm_plist_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), FRR_PIM_AF_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
@@ -7790,22 +7621,12 @@ DEFUN (no_ip_pim_ssm_prefix_list,
"Source Specific Multicast\n"
"group range prefix-list filter\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ssm_plist_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
FRR_PIM_AF_XPATH,
@@ -7827,27 +7648,14 @@ DEFUN (no_ip_pim_ssm_prefix_list_name,
"group range prefix-list filter\n"
"Name of a prefix-list\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
const struct lyd_node *ssm_plist_dnode;
char ssm_plist_xpath[XPATH_MAXLEN];
const char *ssm_plist_name;
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
-
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
-
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath),
FRR_PIM_AF_XPATH,
@@ -8001,22 +7809,12 @@ DEFUN (ip_ssmpingd,
{
int idx_ipv4 = 2;
const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ssmpingd_ip_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
FRR_PIM_AF_XPATH,
@@ -8038,24 +7836,14 @@ DEFUN (no_ip_ssmpingd,
CONF_SSMPINGD_STR
"Source address\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
int idx_ipv4 = 3;
const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
char ssmpingd_ip_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
FRR_PIM_AF_XPATH,
@@ -8076,22 +7864,12 @@ DEFUN (ip_pim_ecmp,
"pim multicast routing\n"
"Enable PIM ECMP \n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ecmp_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_XPATH,
"frr-pim:pimd", "pim", vrfname);
@@ -8109,22 +7887,12 @@ DEFUN (no_ip_pim_ecmp,
"pim multicast routing\n"
"Disable PIM ECMP \n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ecmp_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_XPATH,
"frr-pim:pimd", "pim", vrfname);
@@ -8143,23 +7911,13 @@ DEFUN (ip_pim_ecmp_rebalance,
"Enable PIM ECMP \n"
"Enable PIM ECMP Rebalance\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ecmp_xpath[XPATH_MAXLEN];
char ecmp_rebalance_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_XPATH,
"frr-pim:pimd", "pim", vrfname);
@@ -8185,22 +7943,12 @@ DEFUN (no_ip_pim_ecmp_rebalance,
"Disable PIM ECMP \n"
"Disable PIM ECMP Rebalance\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char ecmp_rebalance_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath),
FRR_PIM_XPATH,
@@ -9882,23 +9630,13 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
"Source address for TCP connection\n"
"local ip address\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char temp_xpath[XPATH_MAXLEN];
char msdp_peer_source_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
FRR_PIM_AF_XPATH,
@@ -9924,23 +9662,13 @@ DEFUN (no_ip_msdp_peer,
"Delete MSDP peer\n"
"peer ip address\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char msdp_peer_xpath[XPATH_MAXLEN];
char temp_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
FRR_PIM_AF_XPATH,
@@ -9966,23 +9694,13 @@ DEFUN (ip_msdp_mesh_group_member,
"mesh group member\n"
"peer ip address\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char msdp_mesh_group_name_xpath[XPATH_MAXLEN];
char msdp_mesh_group_member_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(msdp_mesh_group_name_xpath, sizeof(msdp_mesh_group_name_xpath),
FRR_PIM_AF_XPATH,
@@ -10015,7 +9733,6 @@ DEFUN (no_ip_msdp_mesh_group_member,
"mesh group member\n"
"peer ip address\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char pim_af_xpath[XPATH_MAXLEN];
char mesh_group_xpath[XPATH_MAXLEN + 32];
@@ -10026,18 +9743,9 @@ DEFUN (no_ip_msdp_mesh_group_member,
const char *mesh_group_name;
const struct lyd_node *member_dnode;
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(pim_af_xpath, sizeof(pim_af_xpath), FRR_PIM_AF_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
@@ -10103,23 +9811,13 @@ DEFUN (ip_msdp_mesh_group_source,
"mesh group local address\n"
"source ip address for the TCP connection\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char msdp_mesh_source_ip_xpath[XPATH_MAXLEN];
char msdp_mesh_group_name_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(msdp_mesh_group_name_xpath, sizeof(msdp_mesh_group_name_xpath),
FRR_PIM_AF_XPATH,
@@ -10152,7 +9850,6 @@ DEFUN (no_ip_msdp_mesh_group_source,
"mesh group source\n"
"mesh group local address\n")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
char msdp_mesh_xpath[XPATH_MAXLEN];
char source_xpath[XPATH_MAXLEN];
@@ -10160,18 +9857,9 @@ DEFUN (no_ip_msdp_mesh_group_source,
char mesh_group_name_xpath[XPATH_MAXLEN];
const char *mesh_group_name;
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
snprintf(msdp_mesh_xpath, sizeof(msdp_mesh_xpath),
FRR_PIM_AF_XPATH,
@@ -10226,24 +9914,14 @@ DEFUN (no_ip_msdp_mesh_group,
"Delete MSDP mesh-group\n"
"mesh group name")
{
- const struct lyd_node *vrf_dnode;
const char *vrfname;
const char *mesh_group_name;
char xpath[XPATH_MAXLEN];
char msdp_mesh_xpath[XPATH_MAXLEN];
- if (vty->xpath_index) {
- vrf_dnode =
- yang_dnode_get(vty->candidate_config->dnode,
- VTY_CURR_XPATH);
- if (!vrf_dnode) {
- vty_out(vty,
- "%% Failed to get vrf dnode in candidate db\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- vrfname = yang_dnode_get_string(vrf_dnode, "./name");
- } else
- vrfname = VRF_DEFAULT_NAME;
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
if (argc == 5) {
snprintf(xpath, sizeof(xpath), FRR_PIM_AF_XPATH, "frr-pim:pimd",
diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c
index 6f5c4174e2..e48a4bdd4d 100644
--- a/pimd/pim_hello.c
+++ b/pimd/pim_hello.c
@@ -141,14 +141,14 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
on_trace(__func__, ifp, src_addr);
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
++pim_ifp->pim_ifstat_hello_recv;
/*
Parse PIM hello TLVs
*/
- zassert(tlv_buf_size >= 0);
+ assert(tlv_buf_size >= 0);
tlv_curr = tlv_buf;
tlv_pastend = tlv_buf + tlv_buf_size;
@@ -539,11 +539,11 @@ void pim_hello_require(struct interface *ifp)
{
struct pim_interface *pim_ifp;
- zassert(ifp);
+ assert(ifp);
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
if (pim_ifp->pim_ifstat_hello_sent)
return;
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 62d19f7619..834399053b 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -115,8 +115,8 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
{
struct pim_interface *pim_ifp;
- zassert(ifp);
- zassert(!ifp->info);
+ assert(ifp);
+ assert(!ifp->info);
pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
@@ -145,8 +145,8 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
The number of seconds represented by the [Query Response Interval]
must be less than the [Query Interval].
*/
- zassert(pim_ifp->igmp_query_max_response_time_dsec
- < pim_ifp->igmp_default_query_interval);
+ assert(pim_ifp->igmp_query_max_response_time_dsec
+ < pim_ifp->igmp_default_query_interval);
if (pim)
PIM_IF_DO_PIM(pim_ifp->options);
@@ -198,9 +198,9 @@ void pim_if_delete(struct interface *ifp)
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
- zassert(ifp);
+ assert(ifp);
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
if (pim_ifp->igmp_join_list) {
pim_if_igmp_join_del_all(ifp);
@@ -238,7 +238,7 @@ void pim_if_update_could_assert(struct interface *ifp)
struct pim_ifchannel *ch;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
pim_ifchannel_update_could_assert(ch);
@@ -251,7 +251,7 @@ static void pim_if_update_my_assert_metric(struct interface *ifp)
struct pim_ifchannel *ch;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
pim_ifchannel_update_my_assert_metric(ch);
@@ -263,7 +263,7 @@ static void pim_addr_change(struct interface *ifp)
struct pim_interface *pim_ifp;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
pim_if_dr_election(ifp); /* router's own DR Priority (addr) changes --
Done TODO T30 */
@@ -507,10 +507,10 @@ void pim_if_addr_add(struct connected *ifc)
struct in_addr ifaddr;
bool vxlan_term;
- zassert(ifc);
+ assert(ifc);
ifp = ifc->ifp;
- zassert(ifp);
+ assert(ifp);
pim_ifp = ifp->info;
if (!pim_ifp)
return;
@@ -708,9 +708,9 @@ void pim_if_addr_del(struct connected *ifc, int force_prim_as_any)
{
struct interface *ifp;
- zassert(ifc);
+ assert(ifc);
ifp = ifc->ifp;
- zassert(ifp);
+ assert(ifp);
if (PIM_DEBUG_ZEBRA)
zlog_debug("%s: %s ifindex=%d disconnected IP address %pFX %s",
@@ -945,7 +945,7 @@ int pim_if_add_vif(struct interface *ifp, bool ispimreg, bool is_vxlan_term)
struct in_addr ifaddr;
unsigned char flags = 0;
- zassert(pim_ifp);
+ assert(pim_ifp);
if (pim_ifp->mroute_vif_index > 0) {
zlog_warn("%s: vif_index=%d > 0 on interface %s ifindex=%d",
@@ -1063,8 +1063,8 @@ int pim_if_lan_delay_enabled(struct interface *ifp)
struct pim_interface *pim_ifp;
pim_ifp = ifp->info;
- zassert(pim_ifp);
- zassert(pim_ifp->pim_number_of_nonlandelay_neighbors >= 0);
+ assert(pim_ifp);
+ assert(pim_ifp->pim_number_of_nonlandelay_neighbors >= 0);
return pim_ifp->pim_number_of_nonlandelay_neighbors == 0;
}
@@ -1128,7 +1128,7 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
struct pim_interface *pim_ifp;
struct prefix p;
- zassert(ifp);
+ assert(ifp);
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -1171,7 +1171,7 @@ long pim_if_t_suppressed_msec(struct interface *ifp)
uint32_t ramount = 0;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
/* join suppression disabled ? */
if (PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options))
@@ -1196,7 +1196,7 @@ static struct igmp_join *igmp_join_find(struct list *join_list,
struct listnode *node;
struct igmp_join *ij;
- zassert(join_list);
+ assert(join_list);
for (ALL_LIST_ELEMENTS_RO(join_list, node, ij)) {
if ((group_addr.s_addr == ij->group_addr.s_addr)
@@ -1245,7 +1245,7 @@ static struct igmp_join *igmp_join_new(struct interface *ifp,
int join_fd;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
join_fd = igmp_join_sock(ifp->name, ifp->ifindex, group_addr,
source_addr);
@@ -1416,7 +1416,7 @@ void pim_if_assert_on_neighbor_down(struct interface *ifp,
struct pim_ifchannel *ch;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
/* Is (S,G,I) assert loser ? */
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index cdaf7bcdd4..579824c88d 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -498,7 +498,7 @@ void pim_ifchannel_membership_clear(struct interface *ifp)
struct pim_ifchannel *ch;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
RB_FOREACH (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb)
ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
@@ -510,7 +510,7 @@ void pim_ifchannel_delete_on_noinfo(struct interface *ifp)
struct pim_ifchannel *ch, *ch_tmp;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
RB_FOREACH_SAFE (ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb, ch_tmp)
delete_on_noinfo(ch);
@@ -825,7 +825,7 @@ static int nonlocal_upstream(int is_join, struct interface *recv_ifp,
int is_local; /* boolean */
recv_pim_ifp = recv_ifp->info;
- zassert(recv_pim_ifp);
+ assert(recv_pim_ifp);
is_local = (upstream.s_addr == recv_pim_ifp->primary_address.s_addr);
@@ -913,7 +913,7 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
}
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
switch (ch->ifjoin_state) {
case PIM_IFJOIN_NOINFO:
@@ -939,7 +939,7 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
}
break;
case PIM_IFJOIN_JOIN:
- zassert(!ch->t_ifjoin_prune_pending_timer);
+ assert(!ch->t_ifjoin_prune_pending_timer);
/*
In the JOIN state ch->t_ifjoin_expiry_timer may be NULL due to
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 73e42e9d83..f2b909e268 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -159,7 +159,7 @@ static int pim_igmp_other_querier_expire(struct thread *t)
igmp = THREAD_ARG(t);
- zassert(!igmp->t_igmp_query_timer);
+ assert(!igmp->t_igmp_query_timer);
if (PIM_DEBUG_IGMP_TRACE) {
char ifaddr_str[INET_ADDRSTRLEN];
@@ -185,9 +185,9 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
long other_querier_present_interval_msec;
struct pim_interface *pim_ifp;
- zassert(igmp);
- zassert(igmp->interface);
- zassert(igmp->interface->info);
+ assert(igmp);
+ assert(igmp->interface);
+ assert(igmp->interface->info);
pim_ifp = igmp->interface->info;
@@ -218,7 +218,7 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
Since this socket is starting the other-querier-present timer,
there should not be periodic query timer for this socket.
*/
- zassert(!igmp->t_igmp_query_timer);
+ assert(!igmp->t_igmp_query_timer);
/*
RFC 3376: 8.5. Other Querier Present Interval
@@ -255,7 +255,7 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
void pim_igmp_other_querier_timer_off(struct igmp_sock *igmp)
{
- zassert(igmp);
+ assert(igmp);
if (PIM_DEBUG_IGMP_TRACE) {
if (igmp->t_other_querier_timer) {
@@ -589,9 +589,9 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp)
Since this socket is starting as querier,
there should not exist a timer for other-querier-present.
*/
- zassert(!igmp->t_other_querier_timer);
+ assert(!igmp->t_other_querier_timer);
pim_ifp = igmp->interface->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
/*
RFC 3376: 8.6. Startup Query Interval
@@ -638,7 +638,7 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp)
void pim_igmp_general_query_off(struct igmp_sock *igmp)
{
- zassert(igmp);
+ assert(igmp);
if (PIM_DEBUG_IGMP_TRACE) {
if (igmp->t_igmp_query_timer) {
@@ -664,8 +664,8 @@ static int pim_igmp_general_query(struct thread *t)
igmp = THREAD_ARG(t);
- zassert(igmp->interface);
- zassert(igmp->interface->info);
+ assert(igmp->interface);
+ assert(igmp->interface->info);
pim_ifp = igmp->interface->info;
@@ -835,19 +835,19 @@ void igmp_group_delete(struct igmp_group *group)
void igmp_group_delete_empty_include(struct igmp_group *group)
{
- zassert(!group->group_filtermode_isexcl);
- zassert(!listcount(group->group_source_list));
+ assert(!group->group_filtermode_isexcl);
+ assert(!listcount(group->group_source_list));
igmp_group_delete(group);
}
void igmp_sock_free(struct igmp_sock *igmp)
{
- zassert(!igmp->t_igmp_read);
- zassert(!igmp->t_igmp_query_timer);
- zassert(!igmp->t_other_querier_timer);
- zassert(igmp->igmp_group_list);
- zassert(!listcount(igmp->igmp_group_list));
+ assert(!igmp->t_igmp_read);
+ assert(!igmp->t_igmp_query_timer);
+ assert(!igmp->t_other_querier_timer);
+ assert(igmp->igmp_group_list);
+ assert(!listcount(igmp->igmp_group_list));
list_delete(&igmp->igmp_group_list);
hash_free(igmp->igmp_group_hash);
@@ -1076,7 +1076,7 @@ static int igmp_group_timer(struct thread *t)
group_str, group->group_igmp_sock->interface->name);
}
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
group->group_filtermode_isexcl = 0;
@@ -1085,7 +1085,7 @@ static int igmp_group_timer(struct thread *t)
igmp_source_delete_expired(group->group_source_list);
- zassert(!group->group_filtermode_isexcl);
+ assert(!group->group_filtermode_isexcl);
/*
RFC 3376: 6.2.2. Definition of Group Timers
@@ -1137,7 +1137,7 @@ void igmp_group_timer_on(struct igmp_group *group, long interval_msec,
it represents the time for the *filter-mode* of the group to
expire and switch to INCLUDE mode.
*/
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
thread_add_timer_msec(router->master, igmp_group_timer, group,
interval_msec, &group->t_group_timer);
@@ -1228,8 +1228,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
it represents the time for the *filter-mode* of the group to
expire and switch to INCLUDE mode.
*/
- zassert(!group->group_filtermode_isexcl); /* INCLUDE mode */
- zassert(!group->t_group_timer); /* group timer == 0 */
+ assert(!group->group_filtermode_isexcl); /* INCLUDE mode */
+ assert(!group->t_group_timer); /* group timer == 0 */
/* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
igmp_anysource_forward_stop(group);
diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c
index 7f3c7a0f8c..6eadf87c83 100644
--- a/pimd/pim_igmpv2.c
+++ b/pimd/pim_igmpv2.c
@@ -54,7 +54,7 @@ void igmp_v2_send_query(struct igmp_group *group, int fd, const char *ifname,
/* max_resp_code must be non-zero else this will look like an IGMP v1
* query */
max_resp_code = igmp_msg_encode16to8(query_max_response_time_dsec);
- zassert(max_resp_code > 0);
+ assert(max_resp_code > 0);
query_buf[0] = PIM_IGMP_MEMBERSHIP_QUERY;
query_buf[1] = max_resp_code;
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 425adfe166..3ae7744eb0 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -103,7 +103,7 @@ void igmp_group_reset_gmi(struct igmp_group *group)
it represents the time for the *filter-mode* of the group to
expire and switch to INCLUDE mode.
*/
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
igmp_group_timer_on(group, group_membership_interval_msec, ifp->name);
}
@@ -314,7 +314,7 @@ static void group_exclude_fwd_anysrc_ifempty(struct igmp_group *group)
{
struct pim_interface *pim_ifp = group->group_igmp_sock->interface->info;
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
if (listcount(group->group_source_list) < 1) {
igmp_anysource_forward_start(pim_ifp->pim, group);
@@ -324,7 +324,7 @@ static void group_exclude_fwd_anysrc_ifempty(struct igmp_group *group)
void igmp_source_free(struct igmp_source *source)
{
/* make sure there is no source timer running */
- zassert(!source->t_source_timer);
+ assert(!source->t_source_timer);
XFREE(MTYPE_PIM_IGMP_GROUP_SOURCE, source);
}
@@ -557,7 +557,7 @@ static void isex_excl(struct igmp_group *group, int num_sources,
int i;
/* EXCLUDE mode */
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
/* E.1: set deletion flag for known sources (X,Y) */
source_mark_delete_flag(group);
@@ -577,10 +577,10 @@ static void isex_excl(struct igmp_group *group, int num_sources,
/* E.4: if not found, create source with timer=GMI:
* (A-X-Y) */
source = source_new(group, *src_addr);
- zassert(!source->t_source_timer); /* timer == 0 */
+ assert(!source->t_source_timer); /* timer == 0 */
igmp_source_reset_gmi(group->group_igmp_sock, group,
source);
- zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
+ assert(source->t_source_timer); /* (A-X-Y) timer > 0 */
}
} /* scan received sources */
@@ -610,7 +610,7 @@ static void isex_incl(struct igmp_group *group, int num_sources,
int i;
/* INCLUDE mode */
- zassert(!group->group_filtermode_isexcl);
+ assert(!group->group_filtermode_isexcl);
/* I.1: set deletion flag for known sources (A) */
source_mark_delete_flag(group);
@@ -631,7 +631,7 @@ static void isex_incl(struct igmp_group *group, int num_sources,
/* I.4: if not found, create source with timer=0 (B-A)
*/
source = source_new(group, *src_addr);
- zassert(!source->t_source_timer); /* (B-A) timer=0 */
+ assert(!source->t_source_timer); /* (B-A) timer=0 */
}
} /* scan received sources */
@@ -641,7 +641,7 @@ static void isex_incl(struct igmp_group *group, int num_sources,
group->group_filtermode_isexcl = 1; /* boolean=true */
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
group_exclude_fwd_anysrc_ifempty(group);
}
@@ -675,10 +675,10 @@ void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
} else {
/* INCLUDE mode */
isex_incl(group, num_sources, sources);
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
}
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
igmp_group_reset_gmi(group);
}
@@ -807,7 +807,7 @@ static void toex_incl(struct igmp_group *group, int num_sources,
int num_sources_tosend = 0;
int i;
- zassert(!group->group_filtermode_isexcl);
+ assert(!group->group_filtermode_isexcl);
/* Set DELETE flag for all known sources (A) */
source_mark_delete_flag(group);
@@ -834,7 +834,7 @@ static void toex_incl(struct igmp_group *group, int num_sources,
/* If source not found, create source with timer=0:
* (B-A)=0 */
source = source_new(group, *src_addr);
- zassert(!source->t_source_timer); /* (B-A) timer=0 */
+ assert(!source->t_source_timer); /* (B-A) timer=0 */
}
} /* Scan received sources (B) */
@@ -849,7 +849,7 @@ static void toex_incl(struct igmp_group *group, int num_sources,
source_query_send_by_flag(group, num_sources_tosend);
}
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
group_exclude_fwd_anysrc_ifempty(group);
}
@@ -894,17 +894,17 @@ static void toex_excl(struct igmp_group *group, int num_sources,
long group_timer_msec;
source = source_new(group, *src_addr);
- zassert(!source->t_source_timer); /* timer == 0 */
+ assert(!source->t_source_timer); /* timer == 0 */
group_timer_msec = igmp_group_timer_remain_msec(group);
igmp_source_timer_on(group, source, group_timer_msec);
- zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
+ assert(source->t_source_timer); /* (A-X-Y) timer > 0 */
/* make sure source is created with DELETE flag unset */
- zassert(!IGMP_SOURCE_TEST_DELETE(source->source_flags));
+ assert(!IGMP_SOURCE_TEST_DELETE(source->source_flags));
}
/* make sure reported source has DELETE flag unset */
- zassert(!IGMP_SOURCE_TEST_DELETE(source->source_flags));
+ assert(!IGMP_SOURCE_TEST_DELETE(source->source_flags));
if (source->t_source_timer) {
/* if source timer>0 mark SEND flag: Q(G,A-Y) */
@@ -948,9 +948,9 @@ void igmpv3_report_toex(struct igmp_sock *igmp, struct in_addr from,
} else {
/* INCLUDE mode */
toex_incl(group, num_sources, sources);
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
}
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
/* Group Timer=GMI */
igmp_group_reset_gmi(group);
@@ -1347,7 +1347,7 @@ static void source_query_send_by_flag(struct igmp_group *group,
long lmqi_msec; /* Last Member Query Interval */
long lmqt_msec; /* Last Member Query Time */
- zassert(num_sources_tosend > 0);
+ assert(num_sources_tosend > 0);
igmp = group->group_igmp_sock;
pim_ifp = igmp->interface->info;
@@ -1408,10 +1408,10 @@ static void block_excl(struct igmp_group *group, int num_sources,
long group_timer_msec;
source = source_new(group, *src_addr);
- zassert(!source->t_source_timer); /* timer == 0 */
+ assert(!source->t_source_timer); /* timer == 0 */
group_timer_msec = igmp_group_timer_remain_msec(group);
igmp_source_timer_on(group, source, group_timer_msec);
- zassert(source->t_source_timer); /* (A-X-Y) timer > 0 */
+ assert(source->t_source_timer); /* (A-X-Y) timer > 0 */
}
if (source->t_source_timer) {
@@ -1523,7 +1523,7 @@ void igmp_group_timer_lower_to_lmqt(struct igmp_group *group)
lmqt_msec);
}
- zassert(group->group_filtermode_isexcl);
+ assert(group->group_filtermode_isexcl);
igmp_group_timer_on(group, lmqt_msec, ifname);
}
@@ -1581,7 +1581,7 @@ void igmp_v3_send_query(struct igmp_group *group, int fd, const char *ifname,
socklen_t tolen;
uint16_t checksum;
- zassert(num_sources >= 0);
+ assert(num_sources >= 0);
msg_size = IGMP_V3_SOURCES_OFFSET + (num_sources << 2);
if (msg_size > query_buf_size) {
@@ -1593,7 +1593,7 @@ void igmp_v3_send_query(struct igmp_group *group, int fd, const char *ifname,
}
s_flag = PIM_FORCE_BOOLEAN(s_flag);
- zassert((s_flag == 0) || (s_flag == 1));
+ assert((s_flag == 0) || (s_flag == 1));
max_resp_code = igmp_msg_encode16to8(query_max_response_time_dsec);
qqic = igmp_msg_encode16to8(querier_query_interval);
diff --git a/pimd/pim_join.c b/pimd/pim_join.c
index 2766a6d2b5..c7a80ca8e0 100644
--- a/pimd/pim_join.c
+++ b/pimd/pim_join.c
@@ -71,7 +71,7 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
}
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
++pim_ifp->pim_ifstat_join_recv;
@@ -134,7 +134,7 @@ static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh,
}
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
++pim_ifp->pim_ifstat_prune_recv;
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 7336cdfef8..9cf73c38c3 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -1562,6 +1562,26 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
return count;
}
+bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim,
+ const char *spaces)
+{
+ struct pim_msdp_peer *mp;
+ struct listnode *node;
+ bool written = false;
+
+ for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, mp)) {
+ /* Non meshed peers have the group name set to 'default'. */
+ if (strcmp(mp->mesh_group_name, "default"))
+ continue;
+
+ vty_out(vty, "%sip msdp peer %pI4 source %pI4\n", spaces,
+ &mp->peer, &mp->local);
+ written = true;
+ }
+
+ return written;
+}
+
/* Enable feature including active/periodic timers etc. on the first peer
* config. Till then MSDP should just stay quiet. */
static void pim_msdp_enable(struct pim_instance *pim)
diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h
index 15a1041e21..4d01880fbf 100644
--- a/pimd/pim_msdp.h
+++ b/pimd/pim_msdp.h
@@ -234,6 +234,8 @@ char *pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size,
bool long_format);
int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
const char *spaces);
+bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim,
+ const char *spaces);
void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp);
void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
struct prefix_sg *sg, struct in_addr rp);
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index 8e6f2ec42b..da2daea7c3 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "pimd.h"
#include "pim_nb.h"
#include "lib/northbound_cli.h"
@@ -36,7 +38,7 @@ static void pim_if_membership_clear(struct interface *ifp)
struct pim_interface *pim_ifp;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
if (PIM_IF_TEST_PIM(pim_ifp->options)
&& PIM_IF_TEST_IGMP(pim_ifp->options)) {
@@ -62,7 +64,7 @@ static void pim_if_membership_refresh(struct interface *ifp)
struct igmp_sock *igmp;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
if (!PIM_IF_TEST_PIM(pim_ifp->options))
return;
@@ -576,7 +578,7 @@ static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
struct interface *ifp;
struct pim_interface *pim_ifp;
- zassert(igmp);
+ assert(igmp);
/* other querier present? */
@@ -585,8 +587,8 @@ static void igmp_sock_query_interval_reconfig(struct igmp_sock *igmp)
/* this is the querier */
- zassert(igmp->interface);
- zassert(igmp->interface->info);
+ assert(igmp->interface);
+ assert(igmp->interface->info);
ifp = igmp->interface;
pim_ifp = ifp->info;
@@ -616,25 +618,25 @@ static void igmp_sock_query_reschedule(struct igmp_sock *igmp)
if (igmp->t_igmp_query_timer) {
/* other querier present */
- zassert(igmp->t_igmp_query_timer);
- zassert(!igmp->t_other_querier_timer);
+ assert(igmp->t_igmp_query_timer);
+ assert(!igmp->t_other_querier_timer);
pim_igmp_general_query_off(igmp);
pim_igmp_general_query_on(igmp);
- zassert(igmp->t_igmp_query_timer);
- zassert(!igmp->t_other_querier_timer);
+ assert(igmp->t_igmp_query_timer);
+ assert(!igmp->t_other_querier_timer);
} else {
/* this is the querier */
- zassert(!igmp->t_igmp_query_timer);
- zassert(igmp->t_other_querier_timer);
+ assert(!igmp->t_igmp_query_timer);
+ assert(igmp->t_other_querier_timer);
pim_igmp_other_querier_timer_off(igmp);
pim_igmp_other_querier_timer_on(igmp);
- zassert(!igmp->t_igmp_query_timer);
- zassert(igmp->t_other_querier_timer);
+ assert(!igmp->t_igmp_query_timer);
+ assert(igmp->t_other_querier_timer);
}
}
diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c
index 19dc469091..48b1a30f2d 100644
--- a/pimd/pim_neighbor.c
+++ b/pimd/pim_neighbor.c
@@ -49,7 +49,7 @@ static void dr_election_by_addr(struct interface *ifp)
struct pim_neighbor *neigh;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
pim_ifp->pim_dr_addr = pim_ifp->primary_address;
@@ -73,7 +73,7 @@ static void dr_election_by_pri(struct interface *ifp)
uint32_t dr_pri;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
pim_ifp->pim_dr_addr = pim_ifp->primary_address;
dr_pri = pim_ifp->pim_dr_priority;
@@ -310,9 +310,9 @@ pim_neighbor_new(struct interface *ifp, struct in_addr source_addr,
struct pim_neighbor *neigh;
char src_str[INET_ADDRSTRLEN];
- zassert(ifp);
+ assert(ifp);
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
neigh = XCALLOC(MTYPE_PIM_NEIGHBOR, sizeof(*neigh));
@@ -412,7 +412,7 @@ static void delete_prefix_list(struct pim_neighbor *neigh)
void pim_neighbor_free(struct pim_neighbor *neigh)
{
- zassert(!neigh->t_expire_timer);
+ assert(!neigh->t_expire_timer);
delete_prefix_list(neigh);
@@ -503,7 +503,7 @@ pim_neighbor_add(struct interface *ifp, struct in_addr source_addr,
}
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
listnode_add(pim_ifp->pim_neighbor_list, neigh);
@@ -566,7 +566,7 @@ static uint16_t find_neighbors_next_highest_propagation_delay_msec(
uint16_t next_highest_delay_msec;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
next_highest_delay_msec = pim_ifp->pim_propagation_delay_msec;
@@ -590,7 +590,7 @@ static uint16_t find_neighbors_next_highest_override_interval_msec(
uint16_t next_highest_interval_msec;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
next_highest_interval_msec = pim_ifp->pim_override_interval_msec;
@@ -613,7 +613,7 @@ void pim_neighbor_delete(struct interface *ifp, struct pim_neighbor *neigh,
char src_str[INET_ADDRSTRLEN];
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
zlog_info("PIM NEIGHBOR DOWN: neighbor %s on interface %s: %s", src_str,
@@ -637,10 +637,10 @@ void pim_neighbor_delete(struct interface *ifp, struct pim_neighbor *neigh,
--pim_ifp->pim_dr_num_nondrpri_neighbors;
}
- zassert(neigh->propagation_delay_msec
- <= pim_ifp->pim_neighbors_highest_propagation_delay_msec);
- zassert(neigh->override_interval_msec
- <= pim_ifp->pim_neighbors_highest_override_interval_msec);
+ assert(neigh->propagation_delay_msec
+ <= pim_ifp->pim_neighbors_highest_propagation_delay_msec);
+ assert(neigh->override_interval_msec
+ <= pim_ifp->pim_neighbors_highest_override_interval_msec);
if (pim_if_lan_delay_enabled(ifp)) {
@@ -683,7 +683,7 @@ void pim_neighbor_delete_all(struct interface *ifp, const char *delete_message)
struct pim_neighbor *neigh;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list, neigh_node,
neigh_nextnode, neigh)) {
@@ -728,9 +728,9 @@ static void delete_from_neigh_addr(struct interface *ifp,
struct pim_interface *pim_ifp;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
- zassert(addr_list);
+ assert(addr_list);
/*
Scan secondary address list
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index 3ec0720fc4..0a4e3e1a6f 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -219,8 +219,8 @@ int pim_channel_del_oif(struct channel_oil *channel_oil, struct interface *oif,
{
struct pim_interface *pim_ifp;
- zassert(channel_oil);
- zassert(oif);
+ assert(channel_oil);
+ assert(oif);
pim_ifp = oif->info;
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index 2ccff8b84a..4ba08a19d8 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -407,8 +407,8 @@ static void pim_sock_read_on(struct interface *ifp)
{
struct pim_interface *pim_ifp;
- zassert(ifp);
- zassert(ifp->info);
+ assert(ifp);
+ assert(ifp->info);
pim_ifp = ifp->info;
@@ -444,7 +444,7 @@ void pim_ifstat_reset(struct interface *ifp)
{
struct pim_interface *pim_ifp;
- zassert(ifp);
+ assert(ifp);
pim_ifp = ifp->info;
if (!pim_ifp) {
@@ -462,8 +462,8 @@ void pim_sock_reset(struct interface *ifp)
{
struct pim_interface *pim_ifp;
- zassert(ifp);
- zassert(ifp->info);
+ assert(ifp);
+ assert(ifp->info);
pim_ifp = ifp->info;
@@ -671,8 +671,8 @@ static int hello_send(struct interface *ifp, uint16_t holdtime)
pim_msg_size = pim_tlv_size + PIM_PIM_MIN_LEN;
- zassert(pim_msg_size >= PIM_PIM_MIN_LEN);
- zassert(pim_msg_size <= PIM_PIM_BUFSIZE_WRITE);
+ assert(pim_msg_size >= PIM_PIM_MIN_LEN);
+ assert(pim_msg_size <= PIM_PIM_BUFSIZE_WRITE);
pim_msg_build_header(pim_msg, pim_msg_size, PIM_MSG_TYPE_HELLO, false);
@@ -846,7 +846,7 @@ int pim_sock_add(struct interface *ifp)
uint32_t old_genid;
pim_ifp = ifp->info;
- zassert(pim_ifp);
+ assert(pim_ifp);
if (pim_ifp->pim_sock_fd >= 0) {
if (PIM_DEBUG_PIM_PACKETS)
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index dbba6b66d8..feaeea929d 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -702,7 +702,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
bsgrp = pim_bsm_get_bsgrp_node(&pim->global_scope, &group);
if (bsgrp) {
- bsrp = listnode_head(bsgrp->bsrp_list);
+ bsrp = bsm_rpinfos_first(bsgrp->bsrp_list);
if (bsrp) {
if (PIM_DEBUG_PIM_TRACE) {
char bsrp_str[INET_ADDRSTRLEN];
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c
index f4d3547b3f..03e77de161 100644
--- a/pimd/pim_ssmpingd.c
+++ b/pimd/pim_ssmpingd.c
@@ -41,12 +41,12 @@ void pim_ssmpingd_init(struct pim_instance *pim)
{
int result;
- zassert(!pim->ssmpingd_list);
+ assert(!pim->ssmpingd_list);
result = inet_pton(AF_INET, PIM_SSMPINGD_REPLY_GROUP,
&pim->ssmpingd_group_addr);
- zassert(result > 0);
+ assert(result > 0);
}
void pim_ssmpingd_destroy(struct pim_instance *pim)
@@ -197,7 +197,7 @@ static int ssmpingd_socket(struct in_addr addr, int port, int mttl)
static void ssmpingd_delete(struct ssmpingd_sock *ss)
{
- zassert(ss);
+ assert(ss);
THREAD_OFF(ss->t_sock_read);
diff --git a/pimd/pim_time.c b/pimd/pim_time.c
index 9878fcf6b4..c88ee7554b 100644
--- a/pimd/pim_time.c
+++ b/pimd/pim_time.c
@@ -106,7 +106,7 @@ int pim_time_mmss(char *buf, int buf_size, long sec)
long mm;
int wr;
- zassert(buf_size >= 5);
+ assert(buf_size >= 5);
mm = sec / 60;
sec %= 60;
@@ -122,7 +122,7 @@ static int pim_time_hhmmss(char *buf, int buf_size, long sec)
long mm;
int wr;
- zassert(buf_size >= 8);
+ assert(buf_size >= 8);
hh = sec / 3600;
sec %= 3600;
@@ -156,7 +156,7 @@ void pim_time_timer_to_hhmmss(char *buf, int buf_size, struct thread *t_timer)
void pim_time_uptime(char *buf, int buf_size, int64_t uptime_sec)
{
- zassert(buf_size >= 8);
+ assert(buf_size >= 8);
pim_time_hhmmss(buf, buf_size, uptime_sec);
}
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index 633bb207bd..f21c369b8d 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -662,7 +662,7 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
const uint8_t *addr;
const uint8_t *pastend;
- zassert(hello_option_addr_list);
+ assert(hello_option_addr_list);
/*
Scan addr list
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 57a0c69166..76e9c3f0aa 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -176,6 +176,7 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
else
snprintf(spaces, sizeof(spaces), "%s", " ");
+ writes += pim_msdp_peer_config_write(vty, pim, spaces);
writes += pim_msdp_config_write(pim, vty, spaces);
if (!pim->send_v6_secondary) {
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index f0eae955cc..6f933e9e72 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -471,8 +471,8 @@ void igmp_anysource_forward_start(struct pim_instance *pim,
struct igmp_source *source;
struct in_addr src_addr = {.s_addr = 0};
/* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
- zassert(group->group_filtermode_isexcl);
- zassert(listcount(group->group_source_list) < 1);
+ assert(group->group_filtermode_isexcl);
+ assert(listcount(group->group_source_list) < 1);
source = source_new(group, src_addr);
if (!source) {
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index 05c9af8734..72505a6993 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -600,7 +600,8 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
}
stream_get(&lastused, s, sizeof(lastused));
- stream_getl(s);
+ /* signed success value from netlink_talk; currently unused */
+ (void)stream_getl(s);
c_oil->cc.lastused = lastused;
diff --git a/pimd/pimd.c b/pimd/pimd.c
index 811dc96b56..1679480794 100644
--- a/pimd/pimd.c
+++ b/pimd/pimd.c
@@ -126,7 +126,7 @@ void pim_init(void)
"%s %s: could not solve %s to group address: errno=%d: %s",
__FILE__, __func__, PIM_ALL_PIM_ROUTERS, errno,
safe_strerror(errno));
- zassert(0);
+ assert(0);
return;
}
diff --git a/python/firstheader.py b/python/firstheader.py
index bf50f33a33..892e9da8d6 100644
--- a/python/firstheader.py
+++ b/python/firstheader.py
@@ -1,30 +1,90 @@
-#
# check that the first header included in C files is either
# zebra.h or config.h
#
+# Copyright (C) 2020 David Lamparter for NetDEF, Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; see the file COPYING; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import sys, os, re, subprocess
+import sys
+import os
+import re
+import subprocess
+import argparse
+
+argp = argparse.ArgumentParser(description="include fixer")
+argp.add_argument("--autofix", action="store_const", const=True)
+argp.add_argument("--warn-empty", action="store_const", const=True)
+argp.add_argument("--pipe", action="store_const", const=True)
include_re = re.compile('^#\s*include\s+["<]([^ ">]+)[">]', re.M)
-errors = 0
+ignore = [
+ lambda fn: fn.startswith("tools/"),
+ lambda fn: fn
+ in [
+ "lib/elf_py.c",
+ ],
+]
+
+
+def run(args):
+ out = []
+
+ files = subprocess.check_output(["git", "ls-files"]).decode("ASCII")
+ for fn in files.splitlines():
+ if not fn.endswith(".c"):
+ continue
+ if max([i(fn) for i in ignore]):
+ continue
+
+ with open(fn, "r") as fd:
+ data = fd.read()
-files = subprocess.check_output(["git", "ls-files"]).decode("ASCII")
-for fn in files.splitlines():
- if not fn.endswith(".c"):
- continue
- if fn.startswith("tools/"):
- continue
- with open(fn, "r") as fd:
- data = fd.read()
m = include_re.search(data)
if m is None:
- # sys.stderr.write('no #include in %s?\n' % (fn))
+ if args.warn_empty:
+ sys.stderr.write("no #include in %s?\n" % (fn))
continue
if m.group(1) in ["config.h", "zebra.h", "lib/zebra.h"]:
continue
- sys.stderr.write("%s: %s\n" % (fn, m.group(0)))
- errors += 1
-if errors:
- sys.exit(1)
+ if args.autofix:
+ sys.stderr.write("%s: %s - fixing\n" % (fn, m.group(0)))
+ if fn.startswith("pceplib/"):
+ insert = '#ifdef HAVE_CONFIG_H\n#include "config.h"\n#endif\n\n'
+ else:
+ insert = "#include <zebra.h>\n\n"
+
+ pos = m.span()[0]
+
+ data = data[:pos] + insert + data[pos:]
+ with open(fn + ".new", "w") as fd:
+ fd.write(data)
+ os.rename(fn + ".new", fn)
+ else:
+ sys.stderr.write("%s: %s\n" % (fn, m.group(0)))
+ out.append(fn)
+
+ if len(out):
+ if args.pipe:
+ # for "vim `firstheader.py`"
+ print("\n".join(out))
+ return 1
+ return 0
+
+
+if __name__ == "__main__":
+ args = argp.parse_args()
+ sys.exit(run(args))
diff --git a/qpb/subdir.am b/qpb/subdir.am
index 4f826355d9..704efc5930 100644
--- a/qpb/subdir.am
+++ b/qpb/subdir.am
@@ -44,6 +44,7 @@ am__v_PROTOC_C_1 =
.proto.pb-c.c:
$(AM_V_PROTOC_C)$(PROTOC_C) -I$(top_srcdir) --c_out=$(top_builddir) $^
+ $(AM_V_GEN)$(SED) -e '1i#include "config.h"' -i $@
.pb-c.c.pb-c.h:
@/bin/true
diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c
index 002336616c..8306aca9ee 100644
--- a/sharpd/sharp_vty.c
+++ b/sharpd/sharp_vty.c
@@ -485,7 +485,7 @@ DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
(0-100000)$inlabel\
[nexthop-group NHGNAME$nhgname] \
[prefix A.B.C.D/M$pfx\
- " FRR_IP_REDIST_STR_SHARPD "$type_str [instance (0-255)$instance]]",
+ " FRR_IP_REDIST_STR_ZEBRA "$type_str [instance (0-255)$instance]]",
"Sharp Routing Protocol\n"
"Remove data\n"
"Remove an LSP\n"
@@ -494,7 +494,7 @@ DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
"The nexthop-group name\n"
"Specify a v4 prefix\n"
"The v4 prefix to label\n"
- FRR_IP_REDIST_HELP_STR_SHARPD
+ FRR_IP_REDIST_HELP_STR_ZEBRA
"Routing instance\n"
"Instance to use\n")
{
diff --git a/staticd/static_nb.c b/staticd/static_nb.c
index a2a14751cf..aa9076aa88 100644
--- a/staticd/static_nb.c
+++ b/staticd/static_nb.c
@@ -16,6 +16,8 @@
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "northbound.h"
#include "libfrr.h"
#include "static_nb.h"
diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c
index db154992f9..e78f5172a3 100644
--- a/staticd/static_nb_config.c
+++ b/staticd/static_nb_config.c
@@ -16,6 +16,8 @@
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "northbound.h"
#include "libfrr.h"
#include "log.h"
diff --git a/tests/.gitignore b/tests/.gitignore
index ca20b0ecac..0c938beab6 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -21,6 +21,7 @@
/lib/cli/test_commands_defun.c
/lib/northbound/test_oper_data
/lib/cxxcompat
+/lib/test_assert
/lib/test_atomlist
/lib/test_buffer
/lib/test_checksum
@@ -52,4 +53,4 @@
/lib/test_zmq
/ospf6d/test_lsdb
/ospf6d/test_lsdb_clippy.c
-/zebra/test_lm_plugin \ No newline at end of file
+/zebra/test_lm_plugin
diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c
index e06944a037..8fe1ad0b8a 100644
--- a/tests/isisd/test_isis_spf.c
+++ b/tests/isisd/test_isis_spf.c
@@ -556,7 +556,6 @@ int main(int argc, char **argv)
/* IS-IS inits. */
yang_module_load("frr-isisd");
isis = isis_new(VRF_DEFAULT_NAME);
- listnode_add(im->isis, isis);
SET_FLAG(im->options, F_ISIS_UNIT_TEST);
debug_spf_events |= DEBUG_SPF_EVENTS;
debug_lfa |= DEBUG_LFA;
diff --git a/tests/lib/cxxcompat.c b/tests/lib/cxxcompat.c
index fde0d6af52..2589fca614 100644
--- a/tests/lib/cxxcompat.c
+++ b/tests/lib/cxxcompat.c
@@ -104,7 +104,6 @@
#include "lib/yang.h"
#include "lib/yang_translator.h"
#include "lib/yang_wrappers.h"
-#include "lib/zassert.h"
#include "lib/zclient.h"
PREDECL_RBTREE_UNIQ(footree);
diff --git a/tests/lib/test_assert.c b/tests/lib/test_assert.c
new file mode 100644
index 0000000000..8f1f4f2bad
--- /dev/null
+++ b/tests/lib/test_assert.c
@@ -0,0 +1,64 @@
+/*
+ * Quick test for assert()
+ * Copyright (C) 2021 David Lamparter for NetDEF, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* make sure this works with assert.h & nothing else. also check the include
+ * shadowing, we don't want to pick up system assert.h
+ */
+#include <assert.h>
+
+__attribute__((noinline))
+void func_for_bt(int number)
+{
+ assert(number > 2);
+ assertf(number > 3, "(A) the number was %d", number);
+}
+
+#include <zebra.h>
+#include "lib/zlog.h"
+#include "lib/thread.h"
+#include "lib/sigevent.h"
+
+int main(int argc, char **argv)
+{
+ int number = 10;
+ struct thread_master *master;
+
+ zlog_aux_init("NONE: ", LOG_DEBUG);
+
+ if (argc > 1)
+ number = atoi(argv[1]);
+
+ assert(number > 0);
+ assertf(number > 1, "(B) the number was %d", number);
+
+ /* set up SIGABRT handler */
+ master = thread_master_create("test");
+ signal_init(master, 0, NULL);
+
+ func_for_bt(number);
+ assert(number > 4);
+ assertf(number > 5, "(C) the number was %d", number);
+
+ assertf(number > 10, "(D) the number was %d", number);
+ return 0;
+}
diff --git a/tests/lib/test_assert.py b/tests/lib/test_assert.py
new file mode 100644
index 0000000000..67c88e6220
--- /dev/null
+++ b/tests/lib/test_assert.py
@@ -0,0 +1,56 @@
+import frrtest
+import os
+import re
+import subprocess
+import inspect
+
+basedir = os.path.dirname(__file__)
+program = os.path.join(basedir, "test_assert")
+
+
+def check(number, rex=None):
+ proc = subprocess.Popen(
+ [frrtest.binpath(program), str(number)],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ out, err = proc.communicate()
+ exitcode = proc.wait()
+
+ if rex is None:
+ assert exitcode == 0
+ else:
+ assert exitcode != 0
+
+ text = out.decode("US-ASCII") + err.decode("US-ASCII")
+ rex = re.compile(rex, re.M | re.S)
+ m = rex.search(text)
+ assert m is not None, "non-matching output: %s" % text
+
+
+def test_assert_0():
+ check(0, r"test_assert\.c:\d+.*number > 0")
+
+
+def test_assert_1():
+ check(1, r"test_assert\.c:\d+.*number > 1.*\(B\) the number was 1")
+
+
+def test_assert_2():
+ check(2, r"test_assert\.c:\d+.*number > 2")
+
+
+def test_assert_3():
+ check(3, r"test_assert\.c:\d+.*number > 3.*\(A\) the number was 3")
+
+
+def test_assert_4():
+ check(4, r"test_assert\.c:\d+.*number > 4")
+
+
+def test_assert_10():
+ check(10, r"test_assert\.c:\d+.*number > 10.*\(D\) the number was 10")
+
+
+def test_assert_11():
+ check(11)
diff --git a/tests/lib/test_ringbuf.c b/tests/lib/test_ringbuf.c
index 7ba5a29b62..4ac62940b8 100644
--- a/tests/lib/test_ringbuf.c
+++ b/tests/lib/test_ringbuf.c
@@ -93,7 +93,7 @@ int main(int argc, char **argv)
assert(ringbuf_get(soil, &compost, BUFSIZ) == BUFSIZ);
validate_state(soil, BUFSIZ, 0);
- assert(soil->empty = true);
+ assert(soil->empty == true);
assert(soil->start == soil->end);
assert(soil->start == 15);
diff --git a/tests/lib/test_seqlock.c b/tests/lib/test_seqlock.c
index 639c2bdc2b..768307d56d 100644
--- a/tests/lib/test_seqlock.c
+++ b/tests/lib/test_seqlock.c
@@ -32,6 +32,7 @@
#include "monotime.h"
#include "seqlock.h"
+#include "printfrr.h"
static struct seqlock sqlo;
static pthread_t thr1;
@@ -43,7 +44,7 @@ static void writestr(const char *str)
char buf[32];
int64_t usec = monotime_since(&start, NULL);
- snprintf(buf, sizeof(buf), "[%02"PRId64"] ", usec / 100000);
+ snprintfrr(buf, sizeof(buf), "[%02" PRId64 "] ", usec / 100000);
iov[0].iov_base = buf;
iov[0].iov_len = strlen(buf);
diff --git a/tests/lib/test_typelist.h b/tests/lib/test_typelist.h
index 32331c14a0..379a2396b4 100644
--- a/tests/lib/test_typelist.h
+++ b/tests/lib/test_typelist.h
@@ -17,6 +17,7 @@
/* C++ called, they want their templates back */
#define item concat(item_, TYPE)
#define itm concat(itm_, TYPE)
+#define itmswap concat(itmswap_, TYPE)
#define head concat(head_, TYPE)
#define list concat(TYPE, )
#define list_head concat(TYPE, _head)
@@ -40,8 +41,9 @@
#define list_find_gteq concat(TYPE, _find_gteq)
#define list_del concat(TYPE, _del)
#define list_pop concat(TYPE, _pop)
+#define list_swap_all concat(TYPE, _swap_all)
-#define ts_hash concat(ts_hash_, TYPE)
+#define ts_hash_head concat(ts_hash_head_, TYPE)
#ifndef REALTYPE
#define REALTYPE TYPE
@@ -89,10 +91,12 @@ DECLARE(REALTYPE, list, struct item, itm);
#endif
#define NITEM 10000
-struct item itm[NITEM];
+#define NITEM_SWAP 100 /* other container for swap */
+struct item itm[NITEM], itmswap[NITEM_SWAP];
static struct list_head head = concat(INIT_, REALTYPE)(head);
-static void ts_hash(const char *text, const char *expect)
+static void ts_hash_head(struct list_head *h, const char *text,
+ const char *expect)
{
int64_t us = monotime_since(&ref, NULL);
SHA256_CTX ctx;
@@ -102,13 +106,13 @@ static void ts_hash(const char *text, const char *expect)
char hashtext[65];
uint32_t swap_count, count;
- count = list_count(&head);
+ count = list_count(h);
swap_count = htonl(count);
SHA256_Init(&ctx);
SHA256_Update(&ctx, &swap_count, sizeof(swap_count));
- frr_each (list, &head, item) {
+ frr_each (list, h, item) {
struct {
uint32_t val_upper, val_lower, index;
} hashitem = {
@@ -135,15 +139,20 @@ static void ts_hash(const char *text, const char *expect)
}
/* hashes will have different item ordering */
#if IS_HASH(REALTYPE) || IS_HEAP(REALTYPE)
-#define ts_hashx(pos, csum) ts_hash(pos, NULL)
+#define ts_hash(pos, csum) ts_hash_head(&head, pos, NULL)
+#define ts_hashx(pos, csum) ts_hash_head(&head, pos, NULL)
+#define ts_hash_headx(head, pos, csum) ts_hash_head(head, pos, NULL)
#else
-#define ts_hashx(pos, csum) ts_hash(pos, csum)
+#define ts_hash(pos, csum) ts_hash_head(&head, pos, csum)
+#define ts_hashx(pos, csum) ts_hash_head(&head, pos, csum)
+#define ts_hash_headx(head, pos, csum) ts_hash_head(head, pos, csum)
#endif
static void concat(test_, TYPE)(void)
{
size_t i, j, k, l;
struct prng *prng;
+ struct prng *prng_swap __attribute__((unused));
struct item *item, *prev __attribute__((unused));
struct item dummy __attribute__((unused));
@@ -151,6 +160,10 @@ static void concat(test_, TYPE)(void)
for (i = 0; i < NITEM; i++)
itm[i].val = i;
+ memset(itmswap, 0, sizeof(itmswap));
+ for (i = 0; i < NITEM_SWAP; i++)
+ itmswap[i].val = i;
+
printfrr("%s start\n", str(TYPE));
ts_start();
@@ -178,6 +191,56 @@ static void concat(test_, TYPE)(void)
assert(list_first(&head) != NULL);
ts_hashx("fill", "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");
+#if !IS_ATOMIC(REALTYPE)
+ struct list_head other;
+
+ list_init(&other);
+ list_swap_all(&head, &other);
+
+ assert(list_count(&head) == 0);
+ assert(!list_first(&head));
+ assert(list_count(&other) == k);
+ assert(list_first(&other) != NULL);
+ ts_hash_headx(
+ &other, "swap1",
+ "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");
+
+ prng_swap = prng_new(0x1234dead);
+ l = 0;
+ for (i = 0; i < NITEM_SWAP; i++) {
+ j = prng_rand(prng_swap) % NITEM_SWAP;
+ if (itmswap[j].scratchpad == 0) {
+ list_add(&head, &itmswap[j]);
+ itmswap[j].scratchpad = 1;
+ l++;
+ }
+#if !IS_HEAP(REALTYPE)
+ else {
+ struct item *rv = list_add(&head, &itmswap[j]);
+ assert(rv == &itmswap[j]);
+ }
+#endif
+ }
+ assert(list_count(&head) == l);
+ assert(list_first(&head) != NULL);
+ ts_hash_headx(
+ &head, "swap-fill",
+ "26df437174051cf305d1bbb62d779ee450ca764167a1e7a94be1aece420008e6");
+
+ list_swap_all(&head, &other);
+
+ assert(list_count(&other) == l);
+ assert(list_first(&other));
+ ts_hash_headx(
+ &other, "swap2a",
+ "26df437174051cf305d1bbb62d779ee450ca764167a1e7a94be1aece420008e6");
+ assert(list_count(&head) == k);
+ assert(list_first(&head) != NULL);
+ ts_hash_headx(
+ &head, "swap2b",
+ "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");
+#endif /* !IS_ATOMIC */
+
k = 0;
#if IS_ATOMIC(REALTYPE)
@@ -344,6 +407,50 @@ static void concat(test_, TYPE)(void)
assert(list_first(&head) != NULL);
ts_hash("fill / add_tail", "eabfcf1413936daaf20965abced95762f45110a6619b84aac7d38481bce4ea19");
+#if !IS_ATOMIC(REALTYPE)
+ struct list_head other;
+
+ list_init(&other);
+ list_swap_all(&head, &other);
+
+ assert(list_count(&head) == 0);
+ assert(!list_first(&head));
+ assert(list_count(&other) == k);
+ assert(list_first(&other) != NULL);
+ ts_hash_head(
+ &other, "swap1",
+ "eabfcf1413936daaf20965abced95762f45110a6619b84aac7d38481bce4ea19");
+
+ prng_swap = prng_new(0x1234dead);
+ l = 0;
+ for (i = 0; i < NITEM_SWAP; i++) {
+ j = prng_rand(prng_swap) % NITEM_SWAP;
+ if (itmswap[j].scratchpad == 0) {
+ list_add_tail(&head, &itmswap[j]);
+ itmswap[j].scratchpad = 1;
+ l++;
+ }
+ }
+ assert(list_count(&head) == l);
+ assert(list_first(&head) != NULL);
+ ts_hash_head(
+ &head, "swap-fill",
+ "833e6ae437e322dfbd36eda8cfc33a61109be735b43f15d256c05e52d1b01909");
+
+ list_swap_all(&head, &other);
+
+ assert(list_count(&other) == l);
+ assert(list_first(&other));
+ ts_hash_head(
+ &other, "swap2a",
+ "833e6ae437e322dfbd36eda8cfc33a61109be735b43f15d256c05e52d1b01909");
+ assert(list_count(&head) == k);
+ assert(list_first(&head) != NULL);
+ ts_hash_head(
+ &head, "swap2b",
+ "eabfcf1413936daaf20965abced95762f45110a6619b84aac7d38481bce4ea19");
+#endif
+
for (i = 0; i < NITEM / 2; i++) {
j = prng_rand(prng) % NITEM;
if (itm[j].scratchpad == 1) {
@@ -546,10 +653,14 @@ static void concat(test_, TYPE)(void)
printfrr("%s end\n", str(TYPE));
}
+#undef ts_hash
#undef ts_hashx
+#undef ts_hash_head
+#undef ts_hash_headx
#undef item
#undef itm
+#undef itmswap
#undef head
#undef list
#undef list_head
@@ -571,6 +682,7 @@ static void concat(test_, TYPE)(void)
#undef list_find_gteq
#undef list_del
#undef list_pop
+#undef list_swap_all
#undef REALTYPE
#undef TYPE
diff --git a/tests/subdir.am b/tests/subdir.am
index ec0a154a2d..139f4878c8 100644
--- a/tests/subdir.am
+++ b/tests/subdir.am
@@ -66,6 +66,7 @@ clippy_scan += \
check_PROGRAMS = \
tests/lib/cxxcompat \
+ tests/lib/test_assert \
tests/lib/test_atomlist \
tests/lib/test_buffer \
tests/lib/test_checksum \
@@ -249,6 +250,10 @@ tests_lib_northbound_test_oper_data_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_lib_northbound_test_oper_data_LDADD = $(ALL_TESTS_LDADD)
tests_lib_northbound_test_oper_data_SOURCES = tests/lib/northbound/test_oper_data.c
nodist_tests_lib_northbound_test_oper_data_SOURCES = yang/frr-test-module.yang.c
+tests_lib_test_assert_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_assert_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_assert_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_assert_SOURCES = tests/lib/test_assert.c
tests_lib_test_atomlist_CFLAGS = $(TESTS_CFLAGS)
tests_lib_test_atomlist_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_lib_test_atomlist_LDADD = $(ALL_TESTS_LDADD)
@@ -289,7 +294,7 @@ tests_lib_test_nexthop_iter_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_lib_test_nexthop_iter_LDADD = $(ALL_TESTS_LDADD)
tests_lib_test_nexthop_iter_SOURCES = tests/lib/test_nexthop_iter.c tests/helpers/c/prng.c
tests_lib_test_ntop_CFLAGS = $(TESTS_CFLAGS)
-tests_lib_test_ntop_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_ntop_CPPFLAGS = $(CPPFLAGS_BASE) # no assert override
tests_lib_test_ntop_LDADD = # none
tests_lib_test_ntop_SOURCES = tests/lib/test_ntop.c tests/helpers/c/prng.c
tests_lib_test_prefix2str_CFLAGS = $(TESTS_CFLAGS)
@@ -404,6 +409,7 @@ EXTRA_DIST += \
tests/lib/northbound/test_oper_data.in \
tests/lib/northbound/test_oper_data.py \
tests/lib/northbound/test_oper_data.refout \
+ tests/lib/test_assert.py \
tests/lib/test_atomlist.py \
tests/lib/test_nexthop_iter.py \
tests/lib/test_ntop.py \
diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile
index c9110d2db9..1503e67d31 100644
--- a/tests/topotests/Dockerfile
+++ b/tests/topotests/Dockerfile
@@ -44,6 +44,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \
xterm \
&& pip install \
exabgp==3.4.17 \
+ "scapy>=2.4.2" \
ipaddr \
pytest \
&& rm -rf /var/lib/apt/lists/*
diff --git a/tests/topotests/all-protocol-startup/r1/show_ip_ospf_interface.ref b/tests/topotests/all-protocol-startup/r1/show_ip_ospf_interface.ref
index 1e8f67f3f9..ff85679256 100644
--- a/tests/topotests/all-protocol-startup/r1/show_ip_ospf_interface.ref
+++ b/tests/topotests/all-protocol-startup/r1/show_ip_ospf_interface.ref
@@ -4,6 +4,7 @@ r1-eth0 is up
MTU mismatch detection: enabled
Router ID 192.168.0.1, Network Type BROADCAST, Cost: 10
Transmit Delay is 1 sec, State DR, Priority 1
+ Designated Router (ID) 192.168.0.1 Interface Address 192.168.0.1/24
No backup designated router on this network
Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
@@ -15,6 +16,7 @@ r1-eth3 is up
MTU mismatch detection: enabled
Router ID 192.168.0.1, Network Type BROADCAST, Cost: 10
Transmit Delay is 1 sec, State DR, Priority 1
+ Designated Router (ID) 192.168.0.1 Interface Address 192.168.3.1/26
No backup designated router on this network
Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
diff --git a/tests/topotests/bgp-default-ipv4-ipv6-unicast/test_bgp-default-ipv4-ipv6-unicast.py b/tests/topotests/bgp-default-ipv4-ipv6-unicast/test_bgp-default-ipv4-ipv6-unicast.py
index c1dbf0ebec..f9aa94fd14 100644
--- a/tests/topotests/bgp-default-ipv4-ipv6-unicast/test_bgp-default-ipv4-ipv6-unicast.py
+++ b/tests/topotests/bgp-default-ipv4-ipv6-unicast/test_bgp-default-ipv4-ipv6-unicast.py
@@ -34,6 +34,8 @@ import json
import pytest
import functools
+pytestmark = [pytest.mark.bgpd]
+
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))
diff --git a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py
index 19c4c5f87d..3b99065fe0 100644
--- a/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py
+++ b/tests/topotests/bgp-ebgp-common-subnet-nexthop-unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py
@@ -40,6 +40,8 @@ import time
import pytest
import functools
+pytestmark = [pytest.mark.bgpd]
+
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))
diff --git a/tests/topotests/conftest.py b/tests/topotests/conftest.py
index cf64956bfd..de5c584e91 100755
--- a/tests/topotests/conftest.py
+++ b/tests/topotests/conftest.py
@@ -62,6 +62,7 @@ def pytest_addoption(parser):
parser.addoption(
"--topology-only",
action="store_true",
+ default=False,
help="Only set up this topology, don't run tests",
)
diff --git a/tests/topotests/isis-snmp/test_isis_snmp.py b/tests/topotests/isis-snmp/test_isis_snmp.py
index 07f3335e23..04e043847d 100755
--- a/tests/topotests/isis-snmp/test_isis_snmp.py
+++ b/tests/topotests/isis-snmp/test_isis_snmp.py
@@ -243,15 +243,15 @@ def test_r1_scalar_snmp():
circtable_test = {
- "isisCircAdminState": ["on(1)", "on(1)", "on(1)"],
- "isisCircExistState": ["active(1)", "active(1)", "active(1)"],
- "isisCircType": ["broadcast(1)", "ptToPt(2)", "staticIn(3)"],
- "isisCircExtDomain": ["false(2)", "false(2)", "false(2)"],
- "isisCircLevelType": ["level1(1)", "level1(1)", "level1and2(3)"],
- "isisCircPassiveCircuit": ["false(2)", "false(2)", "true(1)"],
- "isisCircMeshGroupEnabled": ["inactive(1)", "inactive(1)", "inactive(1)"],
- "isisCircSmallHellos": ["false(2)", "false(2)", "false(2)"],
- "isisCirc3WayEnabled": ["false(2)", "false(2)", "false(2)"],
+ "isisCircAdminState": ["on(1)", "on(1)"],
+ "isisCircExistState": ["active(1)", "active(1)"],
+ "isisCircType": ["broadcast(1)", "ptToPt(2)"],
+ "isisCircExtDomain": ["false(2)", "false(2)"],
+ "isisCircLevelType": ["level1(1)", "level1(1)"],
+ "isisCircPassiveCircuit": ["false(2)", "false(2)"],
+ "isisCircMeshGroupEnabled": ["inactive(1)", "inactive(1)"],
+ "isisCircSmallHellos": ["false(2)", "false(2)"],
+ "isisCirc3WayEnabled": ["false(2)", "false(2)"],
}
@@ -266,7 +266,6 @@ def test_r1_isisCircTable():
oids = []
oids.append(generate_oid(1, 1, 0))
oids.append(generate_oid(1, 2, 0))
- oids.append(generate_oid(1, 3, 0))
# check items
for item in circtable_test.keys():
@@ -277,21 +276,17 @@ def test_r1_isisCircTable():
circleveltable_test = {
- "isisCircLevelMetric": ["10", "10", "10", "10"],
- "isisCircLevelWideMetric": ["10", "10", "0", "0"],
- "isisCircLevelISPriority": ["64", "64", "64", "64"],
- "isisCircLevelHelloMultiplier": ["10", "10", "10", "10"],
+ "isisCircLevelMetric": ["10", "10"],
+ "isisCircLevelWideMetric": ["10", "10"],
+ "isisCircLevelISPriority": ["64", "64"],
+ "isisCircLevelHelloMultiplier": ["10", "10"],
"isisCircLevelHelloTimer": [
"3000 milliseconds",
"3000 milliseconds",
- "3000 milliseconds",
- "3000 milliseconds",
],
"isisCircLevelMinLSPRetransInt": [
"1 seconds",
"1 seconds",
- "0 seconds",
- "0 seconds",
],
}
@@ -307,8 +302,6 @@ def test_r1_isislevelCircTable():
oids = []
oids.append(generate_oid(2, 1, "area"))
oids.append(generate_oid(2, 2, "area"))
- oids.append(generate_oid(2, 3, "area"))
- oids.append(generate_oid(2, 3, "domain"))
# check items
for item in circleveltable_test.keys():
diff --git a/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py b/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py
index 148a89474e..c22bd65d2d 100644
--- a/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py
+++ b/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py
@@ -1002,6 +1002,12 @@ def test_isis_adjacencies_step12():
tgen.net["rt4"].cmd(
'vtysh -c "conf t" -c "interface eth-rt5" -c "ipv6 router isis 1"'
)
+ tgen.net["rt4"].cmd(
+ 'vtysh -c "conf t" -c "interface eth-rt5" -c "isis network point-to-point"'
+ )
+ tgen.net["rt4"].cmd(
+ 'vtysh -c "conf t" -c "interface eth-rt5" -c "isis hello-multiplier 3"'
+ )
tgen.net["rt6"].cmd(
'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 23999"'
)
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref
index 9cb70a4758..7180f84d1a 100644
--- a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref
@@ -1,7 +1,7 @@
{
"r3-eth1":{
"ldpIgpSyncEnabled":false,
- "holdDownTimeInSec":50,
+ "holdDownTimeInSec":0,
"ldpIgpSyncState":"Sync not required"
},
"r3-eth2":{
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref
index 9cb70a4758..7180f84d1a 100644
--- a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref
@@ -1,7 +1,7 @@
{
"r3-eth1":{
"ldpIgpSyncEnabled":false,
- "holdDownTimeInSec":50,
+ "holdDownTimeInSec":0,
"ldpIgpSyncState":"Sync not required"
},
"r3-eth2":{
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref
index 9cb70a4758..7180f84d1a 100644
--- a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref
@@ -1,7 +1,7 @@
{
"r3-eth1":{
"ldpIgpSyncEnabled":false,
- "holdDownTimeInSec":50,
+ "holdDownTimeInSec":0,
"ldpIgpSyncState":"Sync not required"
},
"r3-eth2":{
diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py
index d07b58a774..61a5705a5d 100644
--- a/tests/topotests/lib/pim.py
+++ b/tests/topotests/lib/pim.py
@@ -384,50 +384,6 @@ def _enable_disable_pim(tgen, topo, input_dict, router, build=False):
return result
-def add_rp_interfaces_and_pim_config(tgen, topo, interface, rp, rp_mapping):
- """
- Add physical interfaces tp RP for all the RPs
-
- Parameters
- ----------
- * `tgen` : Topogen object
- * `topo` : json file data
- * `interface` : RP interface
- * `rp` : rp for given topology
- * `rp_mapping` : dictionary of all groups and RPs
-
- Returns
- -------
- True or False
- """
- result = False
- logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
-
- try:
- config_data = []
-
- for group, rp_list in rp_mapping.items():
- for _rp in rp_list:
- config_data.append("interface {}".format(interface))
- config_data.append("ip address {}".format(_rp))
- config_data.append("ip pim")
-
- result = create_common_configuration(
- tgen, rp, config_data, "interface_config"
- )
- if result is not True:
- return False
-
- except InvalidCLIError:
- # Traceback
- errormsg = traceback.format_exc()
- logger.error(errormsg)
- return errormsg
-
- logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
- return result
-
-
def find_rp_details(tgen, topo):
"""
Find who is RP in topology and returns list of RPs
@@ -1444,14 +1400,10 @@ def verify_pim_state(
errormsg = (
"[DUT %s]: Verifying pim state for group"
" %s, [FAILED]!! Expected: "
- "(iif: %s, oil: %s, installed: %s) ",
+ "(iif: %s, oil: %s, installed: %s) "
+ % (dut, grp_addr, iif, oil, "1"),
"Found: (iif: %s, oil: %s, installed: %s)"
% (
- dut,
- grp_addr,
- iif,
- oil,
- "1",
data["inboundInterface"],
data["outboundInterface"],
data["installed"],
@@ -2080,7 +2032,7 @@ def add_rp_interfaces_and_pim_config(tgen, topo, interface, rp, rp_mapping):
logger.error(errormsg)
return errormsg
- logger.debug("Exiting lib API: add_rp_interfaces_and_pim_config()")
+ logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
return result
@@ -2425,8 +2377,7 @@ def verify_ip_pim_upstream_rpf(tgen, topo, dut, interface, group_addresses, rp=N
if rp is None:
rp_details = find_rp_details(tgen, topo)
else:
- rp_details = {dut: ip}
- rp_details[dut] = rp
+ rp_details = {dut: rp}
if dut in rp_details:
pim_nh_intf_ip = topo["routers"][dut]["links"]["lo"]["ipv4"].split(
@@ -2732,7 +2683,7 @@ def verify_igmp_config(tgen, input_dict, stats_return=False):
if statistics and report:
show_ip_igmp_intf_json = run_frr_cmd(
- rnode, "{} json".format(cmd, interface), isjson=True
+ rnode, "{} json".format(cmd), isjson=True
)
intf_detail_json = show_ip_igmp_intf_json["global"]
else:
@@ -2808,7 +2759,6 @@ def verify_igmp_config(tgen, input_dict, stats_return=False):
dut,
interface,
value,
- intf_detail_json["reportV2"],
)
)
return errormsg
diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py
index 2a46115850..2a5bd17361 100644
--- a/tests/topotests/lib/topotest.py
+++ b/tests/topotests/lib/topotest.py
@@ -351,8 +351,8 @@ def run_and_expect(func, what, count=20, wait=3):
func_name = func.__name__
logger.info(
- "'{}' polling started (interval {} secs, maximum wait {} secs)".format(
- func_name, wait, int(wait * count)
+ "'{}' polling started (interval {} secs, maximum {} tries)".format(
+ func_name, wait, count
)
)
diff --git a/tools/subdir.am b/tools/subdir.am
index e159d82d4c..6a03a23baa 100644
--- a/tools/subdir.am
+++ b/tools/subdir.am
@@ -34,9 +34,11 @@ tools_gen_yang_deviations_SOURCES = tools/gen_yang_deviations.c
tools_gen_yang_deviations_LDADD = lib/libfrr.la $(LIBYANG_LIBS)
tools_ssd_SOURCES = tools/start-stop-daemon.c
+tools_ssd_CPPFLAGS =
# don't bother autoconf'ing these for a simple optional tool
llvm_version = $(shell echo __clang_major__ | $(CC) -xc -P -E -)
+tools_frr_llvm_cg_CPPFLAGS = $(CPPFLAGS_BASE)
tools_frr_llvm_cg_CFLAGS = $(AM_CFLAGS) `llvm-config-$(llvm_version) --cflags`
tools_frr_llvm_cg_LDFLAGS = `llvm-config-$(llvm_version) --ldflags --libs`
tools_frr_llvm_cg_SOURCES = \
diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang
index 7c820c9611..4653e6f009 100644
--- a/yang/frr-isisd.yang
+++ b/yang/frr-isisd.yang
@@ -493,6 +493,13 @@ module frr-isisd {
description
"Node protection is provided by the alternate.";
}
+ leaf link-fallback {
+ type boolean;
+ must ". = 'false' or ../enable = 'true'";
+ default false;
+ description
+ "Fallback to link protection.";
+ }
}
}
@@ -506,13 +513,6 @@ module frr-isisd {
"Area-tag associated to this circuit.";
}
- leaf vrf {
- type frr-vrf:vrf-ref;
- default "default";
- description
- "VRF NAME.";
- }
-
leaf ipv4-routing {
type boolean;
default "false";
@@ -791,10 +791,10 @@ module frr-isisd {
leaf holddown {
type uint16 {
range "0..10000";
- }
- units "seconds";
- description
- "Time to wait for LDP-Sync to occur before restoring interface metric.";
+ }
+ units "seconds";
+ description
+ "Time to wait for LDP-Sync to occur before restoring interface metric.";
}
}
diff --git a/zebra/connected.c b/zebra/connected.c
index 6f405ca1bb..1e03f8b639 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -208,6 +208,9 @@ void connected_up(struct interface *ifp, struct connected *ifc)
struct zebra_vrf *zvrf;
uint32_t metric;
uint32_t flags = 0;
+ uint32_t count = 0;
+ struct listnode *cnode;
+ struct connected *c;
zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
if (!zvrf) {
@@ -263,6 +266,27 @@ void connected_up(struct interface *ifp, struct connected *ifc)
if (zrouter.asic_offloaded)
flags |= ZEBRA_FLAG_OFFLOADED;
+ /*
+ * It's possible to add the same network and mask
+ * to an interface over and over. This would
+ * result in an equivalent number of connected
+ * routes. Just add one connected route in
+ * for all the addresses on an interface that
+ * resolve to the same network and mask
+ */
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ struct prefix cp;
+
+ PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
+ apply_mask(&cp);
+
+ if (prefix_same(&cp, &p))
+ count++;
+
+ if (count >= 2)
+ return;
+ }
+
rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
flags, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0);
@@ -358,6 +382,9 @@ void connected_down(struct interface *ifp, struct connected *ifc)
.vrf_id = ifp->vrf_id,
};
struct zebra_vrf *zvrf;
+ uint32_t count = 0;
+ struct listnode *cnode;
+ struct connected *c;
zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
if (!zvrf) {
@@ -397,6 +424,26 @@ void connected_down(struct interface *ifp, struct connected *ifc)
}
/*
+ * It's possible to have X number of addresses
+ * on a interface that all resolve to the same
+ * network and mask. Find them and just
+ * allow the deletion when are removing the last
+ * one.
+ */
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ struct prefix cp;
+
+ PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
+ apply_mask(&cp);
+
+ if (prefix_same(&p, &cp))
+ count++;
+
+ if (count >= 2)
+ return;
+ }
+
+ /*
* Same logic as for connected_up(): push the changes into the
* head.
*/
diff --git a/zebra/debug.c b/zebra/debug.c
index 05eed0d26e..a8ddf6ba64 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -241,12 +241,6 @@ DEFUN (debug_zebra_kernel,
{
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL);
- if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV)
- UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
-
- if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND)
- UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
-
return CMD_SUCCESS;
}
@@ -262,21 +256,11 @@ DEFUN (debug_zebra_kernel_msgdump,
{
int idx = 0;
- if (argv_find(argv, argc, "recv", &idx)) {
+ if (argv_find(argv, argc, "recv", &idx))
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
-
- if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND)
- UNSET_FLAG(zebra_debug_kernel,
- ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
-
- } else if (argv_find(argv, argc, "send", &idx)) {
+ else if (argv_find(argv, argc, "send", &idx))
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
-
- if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV)
- UNSET_FLAG(zebra_debug_kernel,
- ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
-
- } else {
+ else {
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
}
@@ -476,7 +460,8 @@ DEFUN (no_debug_zebra_kernel,
"Zebra configuration\n"
"Debug option set for zebra between kernel interface\n")
{
- zebra_debug_kernel = 0;
+ UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL);
+
return CMD_SUCCESS;
}
@@ -491,7 +476,17 @@ DEFUN (no_debug_zebra_kernel_msgdump,
"Dump raw netlink messages received\n"
"Dump raw netlink messages sent\n")
{
- zebra_debug_kernel = 0;
+ int idx = 0;
+
+ if (argv_find(argv, argc, "recv", &idx))
+ UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
+ else if (argv_find(argv, argc, "send", &idx))
+ UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
+ else {
+ UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV);
+ UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND);
+ }
+
return CMD_SUCCESS;
}
@@ -599,21 +594,21 @@ static int config_write_debug(struct vty *vty)
}
}
+ if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND
+ && IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
+ vty_out(vty, "debug zebra kernel msgdump\n");
+ write++;
+ } else if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
+ vty_out(vty, "debug zebra kernel msgdump recv\n");
+ write++;
+ } else if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) {
+ vty_out(vty, "debug zebra kernel msgdump send\n");
+ write++;
+ }
+
if (IS_ZEBRA_DEBUG_KERNEL) {
- if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND
- && IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
- vty_out(vty, "debug zebra kernel msgdump\n");
- write++;
- } else if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
- vty_out(vty, "debug zebra kernel msgdump recv\n");
- write++;
- } else if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) {
- vty_out(vty, "debug zebra kernel msgdump send\n");
- write++;
- } else {
- vty_out(vty, "debug zebra kernel\n");
- write++;
- }
+ vty_out(vty, "debug zebra kernel\n");
+ write++;
}
if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED)) {
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 6aaf9d94f3..e7d8b318e0 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -974,7 +974,7 @@ int interface_lookup_netlink(struct zebra_ns *zns)
return ret;
/* fixup linkages */
- zebra_if_update_all_links();
+ zebra_if_update_all_links(zns);
return 0;
}
@@ -1550,6 +1550,9 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
memcpy(old_hw_addr, ifp->hw_addr, INTERFACE_HWADDR_MAX);
+ /* Update link. */
+ zebra_if_update_link(ifp, link_ifindex, ns_id);
+
netlink_interface_update_hw_addr(tb, ifp);
if (if_is_no_ptm_operative(ifp)) {
diff --git a/zebra/interface.c b/zebra/interface.c
index 4b708496a1..e7357cb302 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -1074,6 +1074,9 @@ void if_up(struct interface *ifp)
if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
zebra_evpn_mh_uplink_oper_update(zif);
+
+ thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 0,
+ &zif->speed_update);
}
/* Interface goes down. We have to manage different behavior of based
@@ -1148,18 +1151,16 @@ void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
* during initial link dump kernel does not order lower devices before
* upper devices so we need to fixup link dependencies at the end of dump
*/
-void zebra_if_update_all_links(void)
+void zebra_if_update_all_links(struct zebra_ns *zns)
{
struct route_node *rn;
struct interface *ifp;
struct zebra_if *zif;
- struct zebra_ns *ns;
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_info("fixup link dependencies");
- ns = zebra_ns_lookup(NS_DEFAULT);
- for (rn = route_top(ns->if_table); rn; rn = route_next(rn)) {
+ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
ifp = (struct interface *)rn->info;
if (!ifp)
continue;
@@ -1177,8 +1178,8 @@ void zebra_if_update_all_links(void)
/* update SVI linkages */
if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
- zif->link = if_lookup_by_index_per_ns(ns,
- zif->link_ifindex);
+ zif->link = if_lookup_by_index_per_ns(
+ zns, zif->link_ifindex);
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("interface %s/%d's lower fixup to %s/%d",
ifp->name, ifp->ifindex,
diff --git a/zebra/interface.h b/zebra/interface.h
index 67eb1176b9..24bc70cb9b 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -482,7 +482,7 @@ extern int ipv6_address_configured(struct interface *ifp);
extern void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id);
extern void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
ns_id_t ns_id);
-extern void zebra_if_update_all_links(void);
+extern void zebra_if_update_all_links(struct zebra_ns *zns);
extern void zebra_if_set_protodown(struct interface *ifp, bool down);
extern int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
const char *label, struct prefix *pp);
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 6f24ec4225..7cb426359d 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -91,8 +91,7 @@ static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)
continue;
RNODE_FOREACH_RE (rn, newre) {
- if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED)
- && newre->distance != DISTANCE_INFINITY)
+ if (CHECK_FLAG(newre->flags, ZEBRA_FLAG_SELECTED))
zsend_redistribute_route(
ZEBRA_REDISTRIBUTE_ROUTE_ADD, client,
&rn->p, NULL, newre);
@@ -138,8 +137,6 @@ static void zebra_redistribute(struct zserv *client, int type,
&& (newre->type != type
|| newre->instance != instance)))
continue;
- if (newre->distance == DISTANCE_INFINITY)
- continue;
if (!zebra_check_addr(dst_p))
continue;
@@ -265,13 +262,6 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
new_re ? zebra_route_string(new_re->type) : "None");
}
- /* Add DISTANCE_INFINITY check. */
- if (old_re && (old_re->distance == DISTANCE_INFINITY)) {
- if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug(" Skipping due to Infinite Distance");
- return;
- }
-
afi = family2afi(p->family);
if (!afi) {
flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 8ffb3870fa..1e06b3e0e9 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -1063,22 +1063,13 @@ static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
ifindex_t ifindex;
struct interface *ifp;
struct zebra_if *zif;
- int ra_interval_rxd;
+ uint32_t ra_interval;
s = msg;
/* Get interface index and RA interval. */
STREAM_GETL(s, ifindex);
- STREAM_GETL(s, ra_interval_rxd);
-
- if (ra_interval_rxd < 0) {
- zlog_warn(
- "Requested RA interval %d is garbage; ignoring request",
- ra_interval_rxd);
- return;
- }
-
- unsigned int ra_interval = ra_interval_rxd;
+ STREAM_GETL(s, ra_interval);
if (IS_ZEBRA_DEBUG_EVENT) {
struct vrf *vrf = zvrf->vrf;
diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c
index cabba707a0..0038689e85 100644
--- a/zebra/zebra_evpn_mh.c
+++ b/zebra/zebra_evpn_mh.c
@@ -2484,8 +2484,8 @@ void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS)
memset(&esi, 0, sizeof(esi_t));
s = msg;
- stream_get(&esi, s, sizeof(esi_t));
- vtep_ip.s_addr = stream_get_ipv4(s);
+ STREAM_GET(&esi, s, sizeof(esi_t));
+ STREAM_GET(&vtep_ip.s_addr, s, sizeof(vtep_ip.s_addr));
if (hdr->command == ZEBRA_REMOTE_ES_VTEP_ADD) {
uint32_t zapi_flags;
@@ -2493,16 +2493,19 @@ void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS)
uint16_t df_pref;
bool esr_rxed;
- zapi_flags = stream_getl(s);
+ STREAM_GETL(s, zapi_flags);
esr_rxed = (zapi_flags & ZAPI_ES_VTEP_FLAG_ESR_RXED) ? true
: false;
- df_alg = stream_getc(s);
- df_pref = stream_getw(s);
+ STREAM_GETC(s, df_alg);
+ STREAM_GETW(s, df_pref);
zebra_evpn_remote_es_add(&esi, vtep_ip, esr_rxed, df_alg,
df_pref);
} else {
zebra_evpn_remote_es_del(&esi, vtep_ip);
}
+
+stream_failure:
+ return;
}
void zebra_evpn_es_mac_deref_entry(zebra_mac_t *mac)
diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c
index 3af805558d..ef0f2d8924 100644
--- a/zebra/zebra_mroute.c
+++ b/zebra/zebra_mroute.c
@@ -65,7 +65,7 @@ stream_failure:
stream_put_in_addr(s, &mroute.sg.src);
stream_put_in_addr(s, &mroute.sg.grp);
stream_put(s, &mroute.lastused, sizeof(mroute.lastused));
- stream_putl(s, suc);
+ stream_putl(s, (uint32_t)suc);
stream_putw_at(s, 0, stream_get_endp(s));
zserv_send_message(client, s);
diff --git a/zebra/zebra_routemap_nb.c b/zebra/zebra_routemap_nb.c
index c82c34dd53..9da4589501 100644
--- a/zebra/zebra_routemap_nb.c
+++ b/zebra/zebra_routemap_nb.c
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <zebra.h>
+
#include "northbound.h"
#include "libfrr.h"
#include "zebra_routemap_nb.h"
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 4cd3b60a0f..3ac7ee8f4f 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -3749,7 +3749,7 @@ zebra_vxlan_remote_macip_helper(bool add, struct stream *s, vni_t *vni,
memset(ip, 0, sizeof(*ip));
STREAM_GETL(s, *vni);
STREAM_GET(macaddr->octet, s, ETH_ALEN);
- STREAM_GETL(s, *ipa_len);
+ STREAM_GETW(s, *ipa_len);
if (*ipa_len) {
if (*ipa_len == IPV4_MAX_BYTELEN)
diff --git a/zebra/zserv.c b/zebra/zserv.c
index f89b6fe478..0bf4d8ece2 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -50,7 +50,6 @@
#include "lib/thread.h" /* for thread (ptr only), THREAD_ARG, ... */
#include "lib/vrf.h" /* for vrf_info_lookup, VRF_DEFAULT */
#include "lib/vty.h" /* for vty_out, vty (ptr only) */
-#include "lib/zassert.h" /* for assert */
#include "lib/zclient.h" /* for zmsghdr, ZEBRA_HEADER_SIZE, ZEBRA... */
#include "lib/frr_pthread.h" /* for frr_pthread_new, frr_pthread_stop... */
#include "lib/frratomic.h" /* for atomic_load_explicit, atomic_stor... */