summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am10
-rw-r--r--babeld/babeld.c94
-rw-r--r--bgpd/bgp_clist.c3
-rw-r--r--bgpd/bgp_conditional_adv.c2
-rw-r--r--bgpd/bgp_evpn.c5
-rw-r--r--bgpd/bgp_io.c1
-rw-r--r--bgpd/bgp_nb.c2
-rw-r--r--bgpd/bgp_nb_config.c2
-rw-r--r--bgpd/bgp_network.c11
-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_vty.c93
-rw-r--r--bgpd/bgpd.c23
-rw-r--r--bgpd/bgpd.h9
-rw-r--r--configure.ac2
-rw-r--r--doc/developer/lists.rst10
-rw-r--r--doc/user/basic.rst6
-rw-r--r--doc/user/bgp.rst178
-rw-r--r--doc/user/isisd.rst9
-rw-r--r--doc/user/kernel.rst20
-rw-r--r--doc/user/pim.rst50
-rw-r--r--doc/user/ripd.rst15
-rw-r--r--doc/user/ripngd.rst32
-rw-r--r--eigrpd/eigrp_main.c2
-rw-r--r--eigrpd/eigrp_metric.c2
-rw-r--r--eigrpd/eigrp_packet.c11
-rw-r--r--eigrpd/eigrp_routemap.c45
-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.c9
-rw-r--r--ldpd/ldpd.c10
-rw-r--r--ldpd/ldpd.h2
-rw-r--r--lib/assert/assert.h98
-rw-r--r--lib/clippy.c14
-rw-r--r--lib/compiler.h6
-rw-r--r--lib/distribute.c174
-rw-r--r--lib/distribute.h6
-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/routing_nb.c2
-rw-r--r--lib/routing_nb_config.c2
-rw-r--r--lib/sockopt.c36
-rw-r--r--lib/sockopt.h20
-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/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_message.c393
-rw-r--r--ospf6d/ospf6_message.h32
-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.c88
-rw-r--r--ospfd/ospf_routemap_nb.c2
-rw-r--r--ospfd/ospf_routemap_nb_config.c2
-rw-r--r--ospfd/ospf_sr.c3
-rw-r--r--ospfd/ospf_te.c9
-rw-r--r--ospfd/ospf_zebra.c437
-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/pimd.c2
-rw-r--r--python/firstheader.py92
-rw-r--r--qpb/subdir.am1
-rw-r--r--ripd/rip_cli.c45
-rw-r--r--ripd/ripd.c3
-rw-r--r--ripngd/ripng_cli.c47
-rw-r--r--ripngd/ripngd.c3
-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/bgp_tcp_mss/__init__.py0
-rw-r--r--tests/topotests/bgp_tcp_mss/r1/bgpd.conf6
-rw-r--r--tests/topotests/bgp_tcp_mss/r1/zebra.conf6
-rw-r--r--tests/topotests/bgp_tcp_mss/r2/bgpd.conf6
-rw-r--r--tests/topotests/bgp_tcp_mss/r2/zebra.conf6
-rw-r--r--tests/topotests/bgp_tcp_mss/test_bgp_tcp_mss.py178
-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--tools/subdir.am2
-rwxr-xr-xvtysh/extract.pl.in7
-rw-r--r--yang/frr-isisd.yang22
-rw-r--r--zebra/connected.c47
-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/zebra_routemap_nb.c2
-rw-r--r--zebra/zserv.c1
205 files changed, 3796 insertions, 2805 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/babeld/babeld.c b/babeld/babeld.c
index 72080bd7eb..4d4dd2e194 100644
--- a/babeld/babeld.c
+++ b/babeld/babeld.c
@@ -712,6 +712,92 @@ DEFUN (babel_set_smoothing_half_life,
return CMD_SUCCESS;
}
+DEFUN (babel_distribute_list,
+ babel_distribute_list_cmd,
+ "distribute-list [prefix] WORD <in|out> [WORD]",
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
+ argv[1 + prefix]->arg, ifname);
+}
+
+DEFUN (babel_no_distribute_list,
+ babel_no_distribute_list_cmd,
+ "no distribute-list [prefix] WORD <in|out> [WORD]",
+ NO_STR
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_no_parser(vty, prefix, true,
+ argv[3 + prefix]->text,
+ argv[2 + prefix]->arg, ifname);
+}
+
+DEFUN (babel_ipv6_distribute_list,
+ babel_ipv6_distribute_list_cmd,
+ "ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ "IPv6\n"
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_parser(prefix, false, argv[3 + prefix]->text,
+ argv[2 + prefix]->arg, ifname);
+}
+
+DEFUN (babel_no_ipv6_distribute_list,
+ babel_no_ipv6_distribute_list_cmd,
+ "no ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ NO_STR
+ "IPv6\n"
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_no_parser(vty, prefix, false,
+ argv[4 + prefix]->text,
+ argv[3 + prefix]->arg, ifname);
+}
+
void
babeld_quagga_init(void)
{
@@ -728,6 +814,11 @@ babeld_quagga_init(void)
install_element(BABEL_NODE, &babel_set_resend_delay_cmd);
install_element(BABEL_NODE, &babel_set_smoothing_half_life_cmd);
+ install_element(BABEL_NODE, &babel_distribute_list_cmd);
+ install_element(BABEL_NODE, &babel_no_distribute_list_cmd);
+ install_element(BABEL_NODE, &babel_ipv6_distribute_list_cmd);
+ install_element(BABEL_NODE, &babel_no_ipv6_distribute_list_cmd);
+
babel_if_init();
/* Access list install. */
@@ -739,9 +830,6 @@ babeld_quagga_init(void)
prefix_list_init ();
prefix_list_add_hook (babel_distribute_update_all);
prefix_list_delete_hook (babel_distribute_update_all);
-
- /* Distribute list install. */
- distribute_list_init(BABEL_NODE);
}
/* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index e17cce3ff6..50122ad7da 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -1117,9 +1117,6 @@ int lcommunity_list_set(struct community_list_handler *ch, const char *name,
}
if (str) {
- if (!lcommunity_list_valid(str, style))
- return COMMUNITY_LIST_ERR_MALFORMED_VAL;
-
if (style == LARGE_COMMUNITY_LIST_STANDARD)
lcom = lcommunity_str2com(str);
else
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 047b9742ee..fae3f1000f 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -1670,8 +1670,9 @@ static inline bool bgp_evpn_route_add_l3_ecomm_ok(struct bgpevpn *vpn,
{
return p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
&& (is_evpn_prefix_ipaddr_v4(p)
- || !IN6_IS_ADDR_LINKLOCAL(
- &p->prefix.macip_addr.ip.ipaddr_v6))
+ || (is_evpn_prefix_ipaddr_v6(p)
+ && !IN6_IS_ADDR_LINKLOCAL(
+ &p->prefix.macip_addr.ip.ipaddr_v6)))
&& CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)
&& bgpevpn_get_l3vni(vpn) && bgp_evpn_es_add_l3_ecomm_ok(esi);
}
diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c
index 99d0344c9f..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
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..f3857162c3 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);
@@ -443,6 +442,11 @@ static int bgp_accept(struct thread *thread)
if (peer1) {
/* Dynamic neighbor has been created, let it proceed */
peer1->fd = bgp_sock;
+
+ /* Set the user configured MSS to TCP socket */
+ if (CHECK_FLAG(peer1->flags, PEER_FLAG_TCP_MSS))
+ sockopt_tcp_mss_set(bgp_sock, peer1->tcp_mss);
+
bgp_fsm_change_status(peer1, Active);
BGP_TIMER_OFF(
peer1->t_start); /* created in peer_create() */
@@ -714,6 +718,10 @@ int bgp_connect(struct peer *peer)
set_nonblocking(peer->fd);
+ /* Set the user configured MSS to TCP socket */
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_TCP_MSS))
+ sockopt_tcp_mss_set(peer->fd, peer->tcp_mss);
+
bgp_socket_set_buffer_size(peer->fd);
if (bgp_set_socket_ttl(peer, peer->fd) < 0)
@@ -838,7 +846,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_vty.c b/bgpd/bgp_vty.c
index 1e465d2620..0347f49cb8 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -22,6 +22,7 @@
#include "command.h"
#include "lib/json.h"
+#include "lib/sockopt.h"
#include "lib_errors.h"
#include "lib/zclient.h"
#include "lib/printfrr.h"
@@ -840,9 +841,6 @@ int bgp_vty_return(struct vty *vty, int ret)
case BGP_ERR_GR_OPERATION_FAILED:
str = "The Graceful Restart Operation failed due to an err.";
break;
- case BGP_GR_NO_OPERATION:
- str = GR_NO_OPER;
- break;
}
if (str) {
vty_out(vty, "%% %s\n", str);
@@ -12597,6 +12595,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
uint8_t *msg;
json_object *json_neigh = NULL;
time_t epoch_tbuf;
+ uint32_t sync_tcp_mss;
bgp = p->bgp;
@@ -12858,6 +12857,15 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
p->v_delayopen * 1000);
}
+ /* Configured and Synced tcp-mss value for peer */
+ if (CHECK_FLAG(p->flags, PEER_FLAG_TCP_MSS)) {
+ sync_tcp_mss = sockopt_tcp_mss_get(p->fd);
+ json_object_int_add(json_neigh, "bgpTcpMssConfigured",
+ p->tcp_mss);
+ json_object_int_add(json_neigh, "bgpTcpMssSynced",
+ sync_tcp_mss);
+ }
+
if (CHECK_FLAG(p->flags, PEER_FLAG_TIMER)) {
json_object_int_add(json_neigh,
"bgpTimerConfiguredHoldTimeMsecs",
@@ -12941,6 +12949,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
vty_out(vty,
" Configured DelayOpenTime is %d seconds\n",
p->delayopen);
+
+ /* Configured and synced tcp-mss value for peer */
+ if (CHECK_FLAG(p->flags, PEER_FLAG_TCP_MSS)) {
+ sync_tcp_mss = sockopt_tcp_mss_get(p->fd);
+ vty_out(vty, " Configured tcp-mss is %d", p->tcp_mss);
+ vty_out(vty, ", synced tcp-mss is %d\n", sync_tcp_mss);
+ }
}
/* Capability. */
if (p->status == Established) {
@@ -16360,6 +16375,55 @@ void cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list(
vty_out(vty, "\n");
}
+/* Neighbor update tcp-mss. */
+static int peer_tcp_mss_vty(struct vty *vty, const char *peer_str,
+ const char *tcp_mss_str)
+{
+ struct peer *peer;
+ uint32_t tcp_mss_val = 0;
+
+ peer = peer_and_group_lookup_vty(vty, peer_str);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ if (tcp_mss_str) {
+ tcp_mss_val = strtoul(tcp_mss_str, NULL, 10);
+ peer_tcp_mss_set(peer, tcp_mss_val);
+ } else {
+ peer_tcp_mss_unset(peer);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(neighbor_tcp_mss, neighbor_tcp_mss_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> tcp-mss (1-65535)",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "TCP max segment size\n"
+ "TCP MSS value\n")
+{
+ int peer_index = 1;
+ int mss_index = 3;
+
+ vty_out(vty,
+ " Warning: Reset BGP session for tcp-mss value to take effect\n");
+ return peer_tcp_mss_vty(vty, argv[peer_index]->arg,
+ argv[mss_index]->arg);
+}
+
+DEFUN(no_neighbor_tcp_mss, no_neighbor_tcp_mss_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> tcp-mss [(1-65535)]",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "TCP max segment size\n"
+ "TCP MSS value\n")
+{
+ int peer_index = 2;
+
+ vty_out(vty,
+ " Warning: Reset BGP session for tcp-mss value to take effect\n");
+ return peer_tcp_mss_vty(vty, argv[peer_index]->arg, NULL);
+}
+
static void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp,
afi_t afi, safi_t safi)
{
@@ -16809,6 +16873,10 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
vty_out(vty, " neighbor %s interface %s\n", addr, peer->ifname);
}
+ /* TCP max segment size */
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_TCP_MSS))
+ vty_out(vty, " neighbor %s tcp-mss %d\n", addr, peer->tcp_mss);
+
/* passive */
if (peergroup_flag_check(peer, PEER_FLAG_PASSIVE))
vty_out(vty, " neighbor %s passive\n", addr);
@@ -17234,6 +17302,9 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
: "");
}
}
+
+ if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING))
+ bgp_config_write_peer_damp(vty, peer, afi, safi);
}
/* Address family based peer configuration display. */
@@ -17287,23 +17358,11 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
/* BGP flag dampening. */
if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
bgp_config_write_damp(vty, bgp, afi, safi);
- for (ALL_LIST_ELEMENTS_RO(bgp->group, node, group))
- if (peer_af_flag_check(group->conf, afi, safi,
- PEER_FLAG_CONFIG_DAMPENING))
- bgp_config_write_peer_damp(vty, group->conf, afi, safi);
- for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer))
- if (peer_af_flag_check(peer, afi, safi,
- PEER_FLAG_CONFIG_DAMPENING))
- bgp_config_write_peer_damp(vty, peer, afi, safi);
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- /* Skip dynamic neighbors. */
- if (peer_dynamic_neighbor(peer))
- continue;
-
/* Do not display doppelganger peers */
if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
bgp_config_write_peer_af(vty, bgp, peer, afi, safi);
@@ -19229,6 +19288,10 @@ void bgp_vty_init(void)
install_element(BGP_IPV6_NODE, &af_no_route_map_vpn_imexport_cmd);
install_element(BGP_IPV4_NODE, &af_no_import_vrf_route_map_cmd);
install_element(BGP_IPV6_NODE, &af_no_import_vrf_route_map_cmd);
+
+ /* tcp-mss command */
+ install_element(BGP_NODE, &neighbor_tcp_mss_cmd);
+ install_element(BGP_NODE, &no_neighbor_tcp_mss_cmd);
}
#include "memory.h"
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 20bb5e5320..2c9aad5d21 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -43,6 +43,7 @@
#include "jhash.h"
#include "table.h"
#include "lib/json.h"
+#include "lib/sockopt.h"
#include "frr_pthread.h"
#include "bitfield.h"
@@ -1439,6 +1440,8 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
peer_dst->local_as = peer_src->local_as;
peer_dst->port = peer_src->port;
+ /* copy tcp_mss value */
+ peer_dst->tcp_mss = peer_src->tcp_mss;
(void)peer_sort(peer_dst);
peer_dst->rmap_type = peer_src->rmap_type;
@@ -5116,6 +5119,26 @@ void peer_port_unset(struct peer *peer)
peer->port = BGP_PORT_DEFAULT;
}
+/* Set the TCP-MSS value in the peer structure,
+ * This gets applied only after connection reset
+ * So this value will be used in bgp_connect.
+ */
+void peer_tcp_mss_set(struct peer *peer, uint32_t tcp_mss)
+{
+ peer->tcp_mss = tcp_mss;
+ SET_FLAG(peer->flags, PEER_FLAG_TCP_MSS);
+}
+
+/* Reset the TCP-MSS value in the peer structure,
+ * This gets applied only after connection reset
+ * So this value will be used in bgp_connect.
+ */
+void peer_tcp_mss_unset(struct peer *peer)
+{
+ UNSET_FLAG(peer->flags, PEER_FLAG_TCP_MSS);
+ peer->tcp_mss = 0;
+}
+
/*
* Helper function that is called after the name of the policy
* being used by a peer has changed (AF specific). Automatically
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 88588952ba..3343b332f4 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1241,6 +1241,8 @@ struct peer {
#define PEER_FLAG_GRACEFUL_RESTART (1U << 24) /* Graceful Restart */
#define PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT (1U << 25) /* Global-Inherit */
#define PEER_FLAG_RTT_SHUTDOWN (1U << 26) /* shutdown rtt */
+#define PEER_FLAG_TIMER_DELAYOPEN (1U << 27) /* delayopen timer */
+#define PEER_FLAG_TCP_MSS (1U << 28) /* tcp-mss */
/*
*GR-Disabled mode means unset PEER_FLAG_GRACEFUL_RESTART
@@ -1248,8 +1250,6 @@ struct peer {
*and PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT
*/
-#define PEER_FLAG_TIMER_DELAYOPEN (1 << 27) /* delayopen timer */
-
struct bgp_peer_gr PEER_GR_FSM[BGP_PEER_GR_MODE][BGP_PEER_GR_EVENT_CMD];
enum peer_mode peer_gr_present_state;
/* Non stop forwarding afi-safi count for BGP gr feature*/
@@ -1606,6 +1606,9 @@ struct peer {
bool advmap_config_change[AFI_MAX][SAFI_MAX];
bool advmap_table_change;
+ /* set TCP max segment size */
+ uint32_t tcp_mss;
+
QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(peer);
@@ -2409,4 +2412,6 @@ DECLARE_HOOK(bgp_rpki_prefix_status,
void peer_nsf_stop(struct peer *peer);
+void peer_tcp_mss_set(struct peer *peer, uint32_t tcp_mss);
+void peer_tcp_mss_unset(struct peer *peer);
#endif /* _QUAGGA_BGPD_H */
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/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..314873640d 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
^^^^^^^^^^^^^^^^
@@ -3877,6 +3908,147 @@ Example of how to set up a 6-Bone connection.
log file bgpd.log
!
+.. _bgp-tcp-mss:
+
+BGP tcp-mss support
+===================
+TCP provides a mechanism for the user to specify the max segment size.
+setsockopt API is used to set the max segment size for TCP session. We
+can configure this as part of BGP neighbor configuration.
+
+This document explains how to avoid ICMP vulnerability issues by limiting
+TCP max segment size when you are using MTU discovery. Using MTU discovery
+on TCP paths is one method of avoiding BGP packet fragmentation.
+
+TCP negotiates a maximum segment size (MSS) value during session connection
+establishment between two peers. The MSS value negotiated is primarily based
+on the maximum transmission unit (MTU) of the interfaces to which the
+communicating peers are directly connected. However, due to variations in
+link MTU on the path taken by the TCP packets, some packets in the network
+that are well within the MSS value might be fragmented when the packet size
+exceeds the link's MTU.
+
+This feature is supported with TCP over IPv4 and TCP over IPv6.
+
+CLI Configuration:
+------------------
+Below configuration can be done in router bgp mode and allows the user to
+configure the tcp-mss value per neighbor. The configuration gets applied
+only after hard reset is performed on that neighbor. If we configure tcp-mss
+on both the neighbors then both neighbors need to be reset.
+
+The configuration takes effect based on below rules, so there is a configured
+tcp-mss and a synced tcp-mss value per TCP session.
+
+By default if the configuration is not done then the TCP max segment size is
+set to the Maximum Transmission unit (MTU) – (IP/IP6 header size + TCP header
+size + ethernet header). For IPv4 its MTU – (20 bytes IP header + 20 bytes TCP
+header + 12 bytes ethernet header) and for IPv6 its MTU – (40 bytes IPv6 header
++ 20 bytes TCP header + 12 bytes ethernet header).
+
+If the config is done then it reduces 12-14 bytes for the ether header and
+uses it after synchronizing in TCP handshake.
+
+.. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> tcp-mss (1-65535)
+
+When tcp-mss is configured kernel reduces 12-14 bytes for ethernet header.
+E.g. if tcp-mss is configured as 150 the synced value will be 138.
+
+Note: configured and synced value is different since TCP module will reduce
+12 bytes for ethernet header.
+
+Running config:
+---------------
+
+.. code-block:: frr
+
+ frr# show running-config
+ Building configuration...
+
+ Current configuration:
+ !
+ router bgp 100
+ bgp router-id 192.0.2.1
+ neighbor 198.51.100.2 remote-as 100
+ neighbor 198.51.100.2 tcp-mss 150 => new entry
+ neighbor 2001:DB8::2 remote-as 100
+ neighbor 2001:DB8::2 tcp-mss 400 => new entry
+
+Show command:
+-------------
+
+.. code-block:: frr
+
+ frr# show bgp neighbors 198.51.100.2
+ BGP neighbor is 198.51.100.2, remote AS 100, local AS 100, internal link
+ Hostname: frr
+ BGP version 4, remote router ID 192.0.2.2, local router ID 192.0.2.1
+ BGP state = Established, up for 02:15:28
+ Last read 00:00:28, Last write 00:00:28
+ Hold time is 180, keepalive interval is 60 seconds
+ Configured tcp-mss is 150, synced tcp-mss is 138 => new display
+
+.. code-block:: frr
+
+ frr# show bgp neighbors 2001:DB8::2
+ BGP neighbor is 2001:DB8::2, remote AS 100, local AS 100, internal link
+ Hostname: frr
+ BGP version 4, remote router ID 192.0.2.2, local router ID 192.0.2.1
+ BGP state = Established, up for 02:16:34
+ Last read 00:00:34, Last write 00:00:34
+ Hold time is 180, keepalive interval is 60 seconds
+ Configured tcp-mss is 400, synced tcp-mss is 388 => new display
+
+Show command json output:
+-------------------------
+
+.. code-block:: frr
+
+ frr# show bgp neighbors 2001:DB8::2 json
+ {
+ "2001:DB8::2":{
+ "remoteAs":100,
+ "localAs":100,
+ "nbrInternalLink":true,
+ "hostname":"frr",
+ "bgpVersion":4,
+ "remoteRouterId":"192.0.2.2",
+ "localRouterId":"192.0.2.1",
+ "bgpState":"Established",
+ "bgpTimerUpMsec":8349000,
+ "bgpTimerUpString":"02:19:09",
+ "bgpTimerUpEstablishedEpoch":1613054251,
+ "bgpTimerLastRead":9000,
+ "bgpTimerLastWrite":9000,
+ "bgpInUpdateElapsedTimeMsecs":8347000,
+ "bgpTimerHoldTimeMsecs":180000,
+ "bgpTimerKeepAliveIntervalMsecs":60000,
+ "bgpTcpMssConfigured":400, => new entry
+ "bgpTcpMssSynced":388, => new entry
+
+.. code-block:: frr
+
+ frr# show bgp neighbors 198.51.100.2 json
+ {
+ "198.51.100.2":{
+ "remoteAs":100,
+ "localAs":100,
+ "nbrInternalLink":true,
+ "hostname":"frr",
+ "bgpVersion":4,
+ "remoteRouterId":"192.0.2.2",
+ "localRouterId":"192.0.2.1",
+ "bgpState":"Established",
+ "bgpTimerUpMsec":8370000,
+ "bgpTimerUpString":"02:19:30",
+ "bgpTimerUpEstablishedEpoch":1613054251,
+ "bgpTimerLastRead":30000,
+ "bgpTimerLastWrite":30000,
+ "bgpInUpdateElapsedTimeMsecs":8368000,
+ "bgpTimerHoldTimeMsecs":180000,
+ "bgpTimerKeepAliveIntervalMsecs":60000,
+ "bgpTcpMssConfigured":150, => new entry
+ "bgpTcpMssSynced":138, => new entry
.. include:: routeserver.rst
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/doc/user/ripd.rst b/doc/user/ripd.rst
index 83c8c93b1c..0a155bf489 100644
--- a/doc/user/ripd.rst
+++ b/doc/user/ripd.rst
@@ -236,11 +236,13 @@ Filtering RIP Routes
RIP routes can be filtered by a distribute-list.
-.. clicmd:: distribute-list ACCESS_LIST DIRECT IFNAME
+.. clicmd:: distribute-list [prefix] LIST <in|out> IFNAME
You can apply access lists to the interface with a `distribute-list` command.
- ACCESS_LIST is the access list name. DIRECT is ``in`` or ``out``. If DIRECT
- is ``in`` the access list is applied to input packets.
+ If prefix is specified LIST is a prefix-list. If prefix is not specified
+ then LIST is the access list name. `in` specifies packets being received,
+ and `out` specifies outgoing packets. Finally if an interface is specified
+ it will be applied against a specific interface.
The `distribute-list` command can be used to filter the RIP path.
`distribute-list` can apply access-lists to a chosen interface. First, one
@@ -261,13 +263,6 @@ RIP routes can be filtered by a distribute-list.
`distribute-list` can be applied to both incoming and outgoing data.
-.. clicmd:: distribute-list prefix PREFIX_LIST (in|out) IFNAME
-
- You can apply prefix lists to the interface with a `distribute-list`
- command. PREFIX_LIST is the prefix list name. Next is the direction of
- ``in`` or ``out``. If DIRECT is ``in`` the access list is applied to input
- packets.
-
.. _rip-metric-manipulation:
RIP Metric Manipulation
diff --git a/doc/user/ripngd.rst b/doc/user/ripngd.rst
index b273eb3bfa..c7ca22bf95 100644
--- a/doc/user/ripngd.rst
+++ b/doc/user/ripngd.rst
@@ -62,14 +62,34 @@ ripngd Terminal Mode Commands
ripngd Filtering Commands
=========================
-.. clicmd:: distribute-list ACCESS_LIST (in|out) IFNAME
+RIPng routes can be filtered by a distribute-list.
- You can apply an access-list to the interface using the `distribute-list`
- command. ACCESS_LIST is an access-list name. `direct` is ``in`` or
- ``out``. If `direct` is ``in``, the access-list is applied only to incoming
- packets.::
+.. clicmd:: distribute-list [prefix] LIST <in|out> IFNAME
- distribute-list local-only out sit1
+ You can apply access lists to the interface with a `distribute-list` command.
+ If prefix is specified LIST is a prefix-list. If prefix is not specified
+ then LIST is the access list name. `in` specifies packets being received,
+ and `out` specifies outgoing packets. Finally if an interface is specified
+ it will be applied against a specific interface.
+
+ The ``distribute-list`` command can be used to filter the RIPNG path.
+ ``distribute-list`` can apply access-lists to a chosen interface. First, one
+ should specify the access-list. Next, the name of the access-list is used in
+ the distribute-list command. For example, in the following configuration
+ ``eth0`` will permit only the paths that match the route 10.0.0.0/8
+
+ .. code-block:: frr
+
+ !
+ router ripng
+ distribute-list private in eth0
+ !
+ access-list private permit 10 10.0.0.0/8
+ access-list private deny any
+ !
+
+
+ `distribute-list` can be applied to both incoming and outgoing data.
Sample configuration
diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c
index 0ed7e94968..b775c841f0 100644
--- a/eigrpd/eigrp_main.c
+++ b/eigrpd/eigrp_main.c
@@ -227,8 +227,6 @@ int main(int argc, char **argv, char **envp)
route_map_add_hook (eigrp_rmap_update);
route_map_delete_hook (eigrp_rmap_update);*/
/*if_rmap_init (EIGRP_NODE); */
- /* Distribute list install. */
- distribute_list_init(EIGRP_NODE);
frr_config_fork();
frr_run(master);
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/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c
index 5183e645e5..90913a5b28 100644
--- a/eigrpd/eigrp_routemap.c
+++ b/eigrpd/eigrp_routemap.c
@@ -1130,6 +1130,48 @@ ALIAS(no_set_tag, no_set_tag_val_cmd, "no set tag (0-65535)", NO_STR SET_STR
"Tag value for routing protocol\n"
"Tag value\n")
+DEFUN (eigrp_distribute_list,
+ eigrp_distribute_list_cmd,
+ "distribute-list [prefix] WORD <in|out> [WORD]",
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
+ argv[1 + prefix]->arg, ifname);
+}
+
+DEFUN (eigrp_no_distribute_list,
+ eigrp_no_distribute_list_cmd,
+ "no distribute-list [prefix] WORD <in|out> [WORD]",
+ NO_STR
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_no_parser(vty, prefix, true,
+ argv[3 + prefix]->text,
+ argv[2 + prefix]->arg, ifname);
+}
+
/* Route-map init */
void eigrp_route_map_init()
@@ -1139,6 +1181,9 @@ void eigrp_route_map_init()
route_map_add_hook(eigrp_route_map_update);
route_map_delete_hook(eigrp_route_map_update);
+ install_element(EIGRP_NODE, &eigrp_distribute_list_cmd);
+ install_element(EIGRP_NODE, &eigrp_no_distribute_list_cmd);
+
/*route_map_install_match (&route_match_metric_cmd);
route_map_install_match (&route_match_interface_cmd);*/
/*route_map_install_match (&route_match_ip_next_hop_cmd);
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 fd51625bbd..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;
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 cb7ac85d96..616c390e50 100644
--- a/ldpd/ldpd.h
+++ b/ldpd/ldpd.h
@@ -590,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/distribute.c b/lib/distribute.c
index 60bd0a47bb..0f503d2ab9 100644
--- a/lib/distribute.c
+++ b/lib/distribute.c
@@ -240,150 +240,59 @@ static int distribute_list_prefix_unset(struct distribute_ctx *ctx,
return 1;
}
-DEFUN (distribute_list,
- distribute_list_cmd,
- "distribute-list [prefix] WORD <in|out> [WORD]",
- "Filter networks in routing updates\n"
- "Specify a prefix\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
+static enum distribute_type distribute_direction(const char *dir, bool v4)
{
- int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
- /* Check of distribute list type. */
- enum distribute_type type = argv[2 + prefix]->arg[0] == 'i'
- ? DISTRIBUTE_V4_IN
- : DISTRIBUTE_V4_OUT;
-
- /* Set appropriate function call */
- void (*distfn)(struct distribute_ctx *, const char *,
- enum distribute_type, const char *) =
- prefix ? &distribute_list_prefix_set : &distribute_list_set;
- struct distribute_ctx *ctx =
- (struct distribute_ctx *)listnode_head(dist_ctx_list);
-
- /* if interface is present, get name */
- const char *ifname = NULL;
- if (argv[argc - 1]->type == VARIABLE_TKN)
- ifname = argv[argc - 1]->arg;
+ if (dir[0] == 'i') {
+ if (v4)
+ return DISTRIBUTE_V4_IN;
+ else
+ return DISTRIBUTE_V6_IN;
+ } else if (dir[0] == 'o') {
+ if (v4)
+ return DISTRIBUTE_V4_OUT;
+ else
+ return DISTRIBUTE_V6_OUT;
+ }
- /* Get interface name corresponding distribute list. */
- distfn(ctx, ifname, type, argv[1 + prefix]->arg);
+ assert(!"Expecting in or out only, fix your code");
- return CMD_SUCCESS;
+ __builtin_unreachable();
}
-DEFUN (ipv6_distribute_list,
- ipv6_distribute_list_cmd,
- "ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
- "IPv6\n"
- "Filter networks in routing updates\n"
- "Specify a prefix\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
+int distribute_list_parser(bool prefix, bool v4, const char *dir,
+ const char *list, const char *ifname)
{
- int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
- /* Check of distribute list type. */
- enum distribute_type type = argv[3 + prefix]->arg[0] == 'i'
- ? DISTRIBUTE_V6_IN
- : DISTRIBUTE_V6_OUT;
+ enum distribute_type type = distribute_direction(dir, v4);
+ struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
- /* Set appropriate function call */
void (*distfn)(struct distribute_ctx *, const char *,
enum distribute_type, const char *) =
prefix ? &distribute_list_prefix_set : &distribute_list_set;
- struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
- /* if interface is present, get name */
- const char *ifname = NULL;
- if (argv[argc - 1]->type == VARIABLE_TKN)
- ifname = argv[argc - 1]->arg;
-
- /* Get interface name corresponding distribute list. */
- distfn(ctx, ifname, type, argv[2 + prefix]->arg);
+ distfn(ctx, ifname, type, list);
return CMD_SUCCESS;
}
-DEFUN (no_distribute_list,
- no_distribute_list_cmd,
- "no distribute-list [prefix] WORD <in|out> [WORD]",
- NO_STR
- "Filter networks in routing updates\n"
- "Specify a prefix\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
+int distribute_list_no_parser(struct vty *vty, bool prefix, bool v4,
+ const char *dir, const char *list,
+ const char *ifname)
{
- int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
- int idx_alname = 2 + prefix;
- int idx_disttype = idx_alname + 1;
- enum distribute_type type =
- argv[idx_disttype]->arg[0] == 'i' ?
- DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT;
-
- /* Set appropriate function call */
- int (*distfn)(struct distribute_ctx *, const char *,
- enum distribute_type, const char *) =
- prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
+ enum distribute_type type = distribute_direction(dir, v4);
struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
+ int ret;
- /* if interface is present, get name */
- const char *ifname = NULL;
- if (argv[argc - 1]->type == VARIABLE_TKN)
- ifname = argv[argc - 1]->arg;
- /* Get interface name corresponding distribute list. */
- int ret = distfn(ctx, ifname, type, argv[2 + prefix]->arg);
-
- if (!ret) {
- vty_out(vty, "distribute list doesn't exist\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- return CMD_SUCCESS;
-}
-
-DEFUN (no_ipv6_distribute_list,
- no_ipv6_distribute_list_cmd,
- "no ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
- NO_STR
- "IPv6\n"
- "Filter networks in routing updates\n"
- "Specify a prefix\n"
- "Access-list name\n"
- "Filter incoming routing updates\n"
- "Filter outgoing routing updates\n"
- "Interface name\n")
-{
- int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
- int idx_alname = 3 + prefix;
- int idx_disttype = idx_alname + 1;
-
- enum distribute_type type =
- argv[idx_disttype]->arg[0] == 'i' ?
- DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT;
- struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
-
- /* Set appropriate function call */
int (*distfn)(struct distribute_ctx *, const char *,
- enum distribute_type, const char *) =
+ enum distribute_type, const char *) =
prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
- /* if interface is present, get name */
- const char *ifname = NULL;
-
- if (argv[argc - 1]->type == VARIABLE_TKN)
- ifname = argv[argc - 1]->arg;
- /* Get interface name corresponding distribute list. */
- int ret = distfn(ctx, ifname, type, argv[3 + prefix]->arg);
+ ret = distfn(ctx, ifname, type, list);
if (!ret) {
vty_out(vty, "distribute list doesn't exist\n");
return CMD_WARNING_CONFIG_FAILED;
}
+
return CMD_SUCCESS;
}
@@ -577,32 +486,3 @@ struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf)
listnode_add(dist_ctx_list, ctx);
return ctx;
}
-
-/* Initialize distribute list vty commands */
-void distribute_list_init(int node)
-{
- /* vtysh command-extraction doesn't grok install_element(node, ) */
- if (node == RIP_NODE) {
- install_element(RIP_NODE, &distribute_list_cmd);
- install_element(RIP_NODE, &no_distribute_list_cmd);
- } else if (node == RIPNG_NODE) {
- install_element(RIPNG_NODE, &distribute_list_cmd);
- install_element(RIPNG_NODE, &no_distribute_list_cmd);
- /* install v6 */
- install_element(RIPNG_NODE, &ipv6_distribute_list_cmd);
- install_element(RIPNG_NODE, &no_ipv6_distribute_list_cmd);
- }
-
- /* TODO: install v4 syntax command for v6 only protocols. */
- /* if (node == RIPNG_NODE) {
- * install_element (node, &ipv6_as_v4_distribute_list_all_cmd);
- * install_element (node, &no_ipv6_as_v4_distribute_list_all_cmd);
- * install_element (node, &ipv6_as_v4_distribute_list_cmd);
- * install_element (node, &no_ipv6_as_v4_distribute_list_cmd);
- * install_element (node, &ipv6_as_v4_distribute_list_prefix_all_cmd);
- * install_element (node,
- &no_ipv6_as_v4_distribute_list_prefix_all_cmd);
- * install_element (node, &ipv6_as_v4_distribute_list_prefix_cmd);
- * install_element (node, &no_ipv6_as_v4_distribute_list_prefix_cmd);
- }*/
-}
diff --git a/lib/distribute.h b/lib/distribute.h
index 4016d3b133..83682dea6a 100644
--- a/lib/distribute.h
+++ b/lib/distribute.h
@@ -64,7 +64,6 @@ struct distribute_ctx {
};
/* Prototypes for distribute-list. */
-extern void distribute_list_init(int node);
extern struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf);
extern void distribute_list_delete(struct distribute_ctx **ctx);
extern void distribute_list_add_hook(struct distribute_ctx *ctx,
@@ -85,6 +84,11 @@ extern enum filter_type distribute_apply_in(struct interface *,
extern enum filter_type distribute_apply_out(struct interface *,
struct prefix *);
+extern int distribute_list_parser(bool prefix, bool v4, const char *dir,
+ const char *list, const char *ifname);
+extern int distribute_list_no_parser(struct vty *vty, bool prefix, bool v4,
+ const char *dir, const char *list,
+ const char *ifname);
#ifdef __cplusplus
}
#endif
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 0edf5b3e9b..936422104f 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/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/sockopt.c b/lib/sockopt.c
index b624fe2230..98bfda5079 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -667,3 +667,39 @@ int sockopt_tcp_signature(int sock, union sockunion *su, const char *password)
{
return sockopt_tcp_signature_ext(sock, su, 0, password);
}
+
+/* set TCP mss value to socket */
+int sockopt_tcp_mss_set(int sock, int tcp_maxseg)
+{
+ int ret = 0;
+ socklen_t tcp_maxseg_len = sizeof(tcp_maxseg);
+
+ ret = setsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, &tcp_maxseg,
+ tcp_maxseg_len);
+ if (ret != 0) {
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "%s failed: setsockopt(%d): %s", __func__, sock,
+ safe_strerror(errno));
+ }
+
+ return ret;
+}
+
+/* get TCP mss value synced by socket */
+int sockopt_tcp_mss_get(int sock)
+{
+ int ret = 0;
+ int tcp_maxseg = 0;
+ socklen_t tcp_maxseg_len = sizeof(tcp_maxseg);
+
+ ret = getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, &tcp_maxseg,
+ &tcp_maxseg_len);
+ if (ret != 0) {
+ flog_err_sys(EC_LIB_SYSTEM_CALL,
+ "%s failed: getsockopt(%d): %s", __func__, sock,
+ safe_strerror(errno));
+ return 0;
+ }
+
+ return tcp_maxseg;
+}
diff --git a/lib/sockopt.h b/lib/sockopt.h
index 545abe631f..6c80841e3c 100644
--- a/lib/sockopt.h
+++ b/lib/sockopt.h
@@ -133,6 +133,26 @@ extern int sockopt_tcp_signature(int sock, union sockunion *su,
extern int sockopt_tcp_signature_ext(int sock, union sockunion *su,
uint16_t prefixlen, const char *password);
+/*
+ * set TCP max segment size. This option allows user to configure
+ * max segment size for TCP session
+ *
+ * sock
+ * Socket to enable option on.
+ *
+ * tcp_maxseg
+ * value used for TCP segment size negotiation during SYN
+ */
+extern int sockopt_tcp_mss_set(int sock, int tcp_maxseg);
+
+/*
+ * get TCP max segment size. This option allows user to get
+ * the segment size for TCP session
+ *
+ * sock
+ * Socket to get max segement size.
+ */
+extern int sockopt_tcp_mss_get(int sock);
#ifdef __cplusplus
}
#endif
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/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_message.c b/ospf6d/ospf6_message.c
index 7aedd3df45..d2dcfd81d4 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -94,7 +94,7 @@ static void ospf6_header_print(struct ospf6_header *oh)
ntohs(oh->checksum), oh->instance_id);
}
-void ospf6_hello_print(struct ospf6_header *oh)
+void ospf6_hello_print(struct ospf6_header *oh, int action)
{
struct ospf6_hello *hello;
char options[16];
@@ -115,15 +115,21 @@ void ospf6_hello_print(struct ospf6_header *oh)
ntohs(hello->hello_interval), ntohs(hello->dead_interval));
zlog_debug(" DR:%pI4 BDR:%pI4", &hello->drouter, &hello->bdrouter);
- for (p = (char *)((caddr_t)hello + sizeof(struct ospf6_hello));
- p + sizeof(uint32_t) <= OSPF6_MESSAGE_END(oh);
- p += sizeof(uint32_t))
- zlog_debug(" Neighbor: %pI4", (in_addr_t *)p);
+ if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
+ && action == OSPF6_ACTION_RECV)
+ || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
+ && action == OSPF6_ACTION_SEND)) {
- assert(p == OSPF6_MESSAGE_END(oh));
+ for (p = (char *)((caddr_t)hello + sizeof(struct ospf6_hello));
+ p + sizeof(uint32_t) <= OSPF6_MESSAGE_END(oh);
+ p += sizeof(uint32_t))
+ zlog_debug(" Neighbor: %pI4", (in_addr_t *)p);
+
+ assert(p == OSPF6_MESSAGE_END(oh));
+ }
}
-void ospf6_dbdesc_print(struct ospf6_header *oh)
+void ospf6_dbdesc_print(struct ospf6_header *oh, int action)
{
struct ospf6_dbdesc *dbdesc;
char options[16];
@@ -145,34 +151,52 @@ void ospf6_dbdesc_print(struct ospf6_header *oh)
(CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"),
(unsigned long)ntohl(dbdesc->seqnum));
- for (p = (char *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc));
- p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh);
- p += sizeof(struct ospf6_lsa_header))
- ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p);
+ if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
+ && action == OSPF6_ACTION_RECV)
+ || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
+ && action == OSPF6_ACTION_SEND)) {
- assert(p == OSPF6_MESSAGE_END(oh));
+ for (p = (char *)((caddr_t)dbdesc
+ + sizeof(struct ospf6_dbdesc));
+ p + sizeof(struct ospf6_lsa_header)
+ <= OSPF6_MESSAGE_END(oh);
+ p += sizeof(struct ospf6_lsa_header))
+ ospf6_lsa_header_print_raw(
+ (struct ospf6_lsa_header *)p);
+
+ assert(p == OSPF6_MESSAGE_END(oh));
+ }
}
-void ospf6_lsreq_print(struct ospf6_header *oh)
+void ospf6_lsreq_print(struct ospf6_header *oh, int action)
{
char *p;
ospf6_header_print(oh);
assert(oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
- for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header));
- p + sizeof(struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END(oh);
- p += sizeof(struct ospf6_lsreq_entry)) {
- struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *)p;
+ if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
+ && action == OSPF6_ACTION_RECV)
+ || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
+ && action == OSPF6_ACTION_SEND)) {
+
+ for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header));
+ p + sizeof(struct ospf6_lsreq_entry)
+ <= OSPF6_MESSAGE_END(oh);
+ p += sizeof(struct ospf6_lsreq_entry)) {
+ struct ospf6_lsreq_entry *e =
+ (struct ospf6_lsreq_entry *)p;
+
+ zlog_debug(" [%s Id:%pI4 Adv:%pI4]",
+ ospf6_lstype_name(e->type), &e->id,
+ &e->adv_router);
+ }
- zlog_debug(" [%s Id:%pI4 Adv:%pI4]",
- ospf6_lstype_name(e->type), &e->id, &e->adv_router);
+ assert(p == OSPF6_MESSAGE_END(oh));
}
-
- assert(p == OSPF6_MESSAGE_END(oh));
}
-void ospf6_lsupdate_print(struct ospf6_header *oh)
+void ospf6_lsupdate_print(struct ospf6_header *oh, int action)
{
struct ospf6_lsupdate *lsupdate;
unsigned long num;
@@ -187,29 +211,45 @@ void ospf6_lsupdate_print(struct ospf6_header *oh)
num = ntohl(lsupdate->lsa_number);
zlog_debug(" Number of LSA: %ld", num);
- for (p = (char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate));
- p < OSPF6_MESSAGE_END(oh)
- && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh);
- p += OSPF6_LSA_SIZE(p)) {
- ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p);
- }
+ if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
+ && action == OSPF6_ACTION_RECV)
+ || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
+ && action == OSPF6_ACTION_SEND)) {
+
+ for (p = (char *)((caddr_t)lsupdate
+ + sizeof(struct ospf6_lsupdate));
+ p < OSPF6_MESSAGE_END(oh)
+ && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh);
+ p += OSPF6_LSA_SIZE(p)) {
+ ospf6_lsa_header_print_raw(
+ (struct ospf6_lsa_header *)p);
+ }
- assert(p == OSPF6_MESSAGE_END(oh));
+ assert(p == OSPF6_MESSAGE_END(oh));
+ }
}
-void ospf6_lsack_print(struct ospf6_header *oh)
+void ospf6_lsack_print(struct ospf6_header *oh, int action)
{
char *p;
ospf6_header_print(oh);
assert(oh->type == OSPF6_MESSAGE_TYPE_LSACK);
- for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header));
- p + sizeof(struct ospf6_lsa_header) <= OSPF6_MESSAGE_END(oh);
- p += sizeof(struct ospf6_lsa_header))
- ospf6_lsa_header_print_raw((struct ospf6_lsa_header *)p);
+ if ((IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)
+ && action == OSPF6_ACTION_RECV)
+ || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)
+ && action == OSPF6_ACTION_SEND)) {
- assert(p == OSPF6_MESSAGE_END(oh));
+ for (p = (char *)((caddr_t)oh + sizeof(struct ospf6_header));
+ p + sizeof(struct ospf6_lsa_header)
+ <= OSPF6_MESSAGE_END(oh);
+ p += sizeof(struct ospf6_lsa_header))
+ ospf6_lsa_header_print_raw(
+ (struct ospf6_lsa_header *)p);
+
+ assert(p == OSPF6_MESSAGE_END(oh));
+ }
}
static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
@@ -348,21 +388,21 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
+ sizeof(struct ospf6_header));
if (on->state < OSPF6_NEIGHBOR_INIT) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor state less than Init, ignore");
return;
}
switch (on->state) {
case OSPF6_NEIGHBOR_TWOWAY:
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor state is 2-Way, ignore");
return;
case OSPF6_NEIGHBOR_INIT:
thread_execute(master, twoway_received, on, 0);
if (on->state != OSPF6_NEIGHBOR_EXSTART) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Neighbor state is not ExStart, ignore");
return;
@@ -395,14 +435,14 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
sizeof(struct ospf6_dbdesc))) {
/* Duplicated DatabaseDescription is dropped by master
*/
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Duplicated dbdesc discarded by Master, ignore");
return;
}
if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Master/Slave bit mismatch");
thread_add_event(master, seqnumber_mismatch, on, 0,
NULL);
@@ -410,7 +450,7 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
}
if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Initialize bit mismatch");
thread_add_event(master, seqnumber_mismatch, on, 0,
NULL);
@@ -418,7 +458,7 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
}
if (memcmp(on->options, dbdesc->options, sizeof(on->options))) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Option field mismatch");
thread_add_event(master, seqnumber_mismatch, on, 0,
NULL);
@@ -426,7 +466,7 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
}
if (ntohl(dbdesc->seqnum) != on->dbdesc_seqnum) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Sequence number mismatch (%#lx expected)",
(unsigned long)on->dbdesc_seqnum);
@@ -442,13 +482,13 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
sizeof(struct ospf6_dbdesc))) {
/* Duplicated DatabaseDescription is dropped by master
*/
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Duplicated dbdesc discarded by Master, ignore");
return;
}
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Not duplicate dbdesc in state %s",
ospf6_neighbor_state_str[on->state]);
thread_add_event(master, seqnumber_mismatch, on, 0, NULL);
@@ -553,21 +593,21 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
+ sizeof(struct ospf6_header));
if (on->state < OSPF6_NEIGHBOR_INIT) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor state less than Init, ignore");
return;
}
switch (on->state) {
case OSPF6_NEIGHBOR_TWOWAY:
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor state is 2-Way, ignore");
return;
case OSPF6_NEIGHBOR_INIT:
thread_execute(master, twoway_received, on, 0);
if (on->state != OSPF6_NEIGHBOR_EXSTART) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Neighbor state is not ExStart, ignore");
return;
@@ -611,7 +651,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
sizeof(struct ospf6_dbdesc))) {
/* Duplicated DatabaseDescription causes slave to
* retransmit */
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Duplicated dbdesc causes retransmit");
THREAD_OFF(on->thread_send_dbdesc);
@@ -622,7 +662,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
}
if (!CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_MSBIT)) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Master/Slave bit mismatch");
thread_add_event(master, seqnumber_mismatch, on, 0,
NULL);
@@ -630,7 +670,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
}
if (CHECK_FLAG(dbdesc->bits, OSPF6_DBDESC_IBIT)) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Initialize bit mismatch");
thread_add_event(master, seqnumber_mismatch, on, 0,
NULL);
@@ -638,7 +678,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
}
if (memcmp(on->options, dbdesc->options, sizeof(on->options))) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Option field mismatch");
thread_add_event(master, seqnumber_mismatch, on, 0,
NULL);
@@ -646,7 +686,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
}
if (ntohl(dbdesc->seqnum) != on->dbdesc_seqnum + 1) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Sequence number mismatch (%#lx expected)",
(unsigned long)on->dbdesc_seqnum + 1);
@@ -662,7 +702,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
sizeof(struct ospf6_dbdesc))) {
/* Duplicated DatabaseDescription causes slave to
* retransmit */
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Duplicated dbdesc causes retransmit");
THREAD_OFF(on->thread_send_dbdesc);
@@ -671,7 +711,7 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
return;
}
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Not duplicate dbdesc in state %s",
ospf6_neighbor_state_str[on->state]);
thread_add_event(master, seqnumber_mismatch, on, 0, NULL);
@@ -756,7 +796,7 @@ static void ospf6_dbdesc_recv(struct in6_addr *src, struct in6_addr *dst,
on = ospf6_neighbor_lookup(oh->router_id, oi);
if (on == NULL) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor not found, ignore");
return;
}
@@ -773,7 +813,7 @@ static void ospf6_dbdesc_recv(struct in6_addr *src, struct in6_addr *dst,
}
if (dbdesc->reserved1 || dbdesc->reserved2) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug(
"Non-0 reserved field in %s's DbDesc, correct",
on->name);
@@ -788,7 +828,7 @@ static void ospf6_dbdesc_recv(struct in6_addr *src, struct in6_addr *dst,
else if (ntohl(oi->area->ospf6->router_id) < ntohl(oh->router_id))
ospf6_dbdesc_recv_slave(oh, on);
else {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Can't decide which is master, ignore");
}
}
@@ -805,7 +845,7 @@ static void ospf6_lsreq_recv(struct in6_addr *src, struct in6_addr *dst,
on = ospf6_neighbor_lookup(oh->router_id, oi);
if (on == NULL) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor not found, ignore");
return;
}
@@ -813,7 +853,7 @@ static void ospf6_lsreq_recv(struct in6_addr *src, struct in6_addr *dst,
if (on->state != OSPF6_NEIGHBOR_EXCHANGE
&& on->state != OSPF6_NEIGHBOR_LOADING
&& on->state != OSPF6_NEIGHBOR_FULL) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor state less than Exchange, ignore");
return;
}
@@ -882,7 +922,7 @@ static unsigned ospf6_prefixes_examin(
while (length) {
if (length < OSPF6_PREFIX_MIN_SIZE) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug("%s: undersized IPv6 prefix header",
__func__);
return MSG_NG;
@@ -890,7 +930,7 @@ static unsigned ospf6_prefixes_examin(
/* safe to look deeper */
if (current->prefix_length > IPV6_MAX_BITLEN) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug("%s: invalid PrefixLength (%u bits)",
__func__, current->prefix_length);
return MSG_NG;
@@ -901,7 +941,7 @@ static unsigned ospf6_prefixes_examin(
+ OSPF6_PREFIX_SPACE(current->prefix_length);
if (requested_pfx_bytes > length) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug("%s: undersized IPv6 prefix",
__func__);
return MSG_NG;
@@ -913,7 +953,8 @@ static unsigned ospf6_prefixes_examin(
real_num_pfxs++;
}
if (real_num_pfxs != req_num_pfxs) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug(
"%s: IPv6 prefix number mismatch (%u required, %u real)",
__func__, req_num_pfxs, real_num_pfxs);
@@ -945,7 +986,8 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah,
ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK;
if (ltindex < OSPF6_LSTYPE_SIZE && ospf6_lsa_minlen[ltindex]
&& lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("%s: undersized (%u B) LSA", __func__,
lsalen);
return MSG_NG;
@@ -958,7 +1000,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah,
if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE)
% OSPF6_ROUTER_LSDESC_FIX_SIZE) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug(
"%s: interface description alignment error",
__func__);
@@ -972,7 +1014,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah,
- OSPF6_NETWORK_LSA_MIN_SIZE)
% OSPF6_NETWORK_LSDESC_FIX_SIZE) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug(
"%s: router description alignment error",
__func__);
@@ -997,7 +1039,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah,
if (lsalen
> OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug("%s: oversized (%u B) LSA", __func__,
lsalen);
return MSG_NG;
@@ -1026,7 +1068,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah,
prefix before ospf6_prefix_examin() confirms its sizing. */
if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug("%s: undersized (%u B) LSA header",
__func__, lsalen);
return MSG_NG;
@@ -1045,7 +1087,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah,
this check does not include any IPv6 prefix fields. */
if (exp_length > lsalen) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug("%s: undersized (%u B) LSA header",
__func__, lsalen);
return MSG_NG;
@@ -1114,7 +1156,7 @@ ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */
uint16_t lsalen;
if (length < OSPF6_LSA_HEADER_SIZE) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug(
"%s: undersized (%zu B) trailing (#%u) LSA header",
__func__, length, counted_lsas);
@@ -1124,7 +1166,7 @@ ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */
lsalen = OSPF6_LSA_SIZE(lsah);
if (lsalen < OSPF6_LSA_HEADER_SIZE) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
- RECV))
+ RECV_HDR))
zlog_debug(
"%s: malformed LSA header #%u, declared length is %u B",
__func__, counted_lsas, lsalen);
@@ -1134,7 +1176,8 @@ ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */
/* less checks here and in ospf6_lsa_examin() */
if (MSG_OK != ospf6_lsa_examin(lsah, lsalen, 1)) {
if (IS_OSPF6_DEBUG_MESSAGE(
- OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug(
"%s: anomaly in header-only %s LSA #%u",
__func__,
@@ -1151,7 +1194,8 @@ ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */
* further checks */
if (lsalen > length) {
if (IS_OSPF6_DEBUG_MESSAGE(
- OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug(
"%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B",
__func__,
@@ -1161,7 +1205,8 @@ ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */
}
if (MSG_OK != ospf6_lsa_examin(lsah, lsalen, 0)) {
if (IS_OSPF6_DEBUG_MESSAGE(
- OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug(
"%s: anomaly in %s LSA #%u",
__func__,
@@ -1177,7 +1222,8 @@ ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */
}
if (declared_num_lsas && counted_lsas != declared_num_lsas) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug(
"%s: #LSAs declared (%u) does not match actual (%u)",
__func__, declared_num_lsas, counted_lsas);
@@ -1195,14 +1241,16 @@ static unsigned ospf6_packet_examin(struct ospf6_header *oh,
/* length, 1st approximation */
if (bytesonwire < OSPF6_HEADER_SIZE) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("%s: undersized (%u B) packet", __func__,
bytesonwire);
return MSG_NG;
}
/* Now it is safe to access header fields. */
if (bytesonwire != ntohs(oh->length)) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug(
"%s: %s packet length error (%u real, %u declared)",
__func__, lookup_msg(ospf6_message_type_str,
@@ -1212,7 +1260,8 @@ static unsigned ospf6_packet_examin(struct ospf6_header *oh,
}
/* version check */
if (oh->version != OSPFV3_VERSION) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("%s: invalid (%u) protocol version",
__func__, oh->version);
return MSG_NG;
@@ -1221,7 +1270,8 @@ static unsigned ospf6_packet_examin(struct ospf6_header *oh,
if (oh->type < OSPF6_MESSAGE_TYPE_ALL && ospf6_packet_minlen[oh->type]
&& bytesonwire
< OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type]) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("%s: undersized (%u B) %s packet", __func__,
bytesonwire,
lookup_msg(ospf6_message_type_str, oh->type,
@@ -1238,7 +1288,8 @@ static unsigned ospf6_packet_examin(struct ospf6_header *oh,
== (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE)
% 4)
return MSG_OK;
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("%s: alignment error in %s packet", __func__,
lookup_msg(ospf6_message_type_str, oh->type,
NULL));
@@ -1261,7 +1312,8 @@ static unsigned ospf6_packet_examin(struct ospf6_header *oh,
== (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE)
% OSPF6_LSREQ_LSDESC_FIX_SIZE)
return MSG_OK;
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("%s: alignment error in %s packet", __func__,
lookup_msg(ospf6_message_type_str, oh->type,
NULL));
@@ -1289,13 +1341,14 @@ static unsigned ospf6_packet_examin(struct ospf6_header *oh,
1, 0);
break;
default:
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("%s: invalid (%u) message type", __func__,
oh->type);
return MSG_NG;
}
if (test != MSG_OK
- && IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ && IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV_HDR))
zlog_debug("%s: anomaly in %s packet", __func__,
lookup_msg(ospf6_message_type_str, oh->type, NULL));
return test;
@@ -1356,7 +1409,7 @@ static void ospf6_lsupdate_recv(struct in6_addr *src, struct in6_addr *dst,
on = ospf6_neighbor_lookup(oh->router_id, oi);
if (on == NULL) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor not found, ignore");
return;
}
@@ -1364,7 +1417,7 @@ static void ospf6_lsupdate_recv(struct in6_addr *src, struct in6_addr *dst,
if (on->state != OSPF6_NEIGHBOR_EXCHANGE
&& on->state != OSPF6_NEIGHBOR_LOADING
&& on->state != OSPF6_NEIGHBOR_FULL) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor state less than Exchange, ignore");
return;
}
@@ -1398,7 +1451,7 @@ static void ospf6_lsack_recv(struct in6_addr *src, struct in6_addr *dst,
on = ospf6_neighbor_lookup(oh->router_id, oi);
if (on == NULL) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor not found, ignore");
return;
}
@@ -1406,7 +1459,7 @@ static void ospf6_lsack_recv(struct in6_addr *src, struct in6_addr *dst,
if (on->state != OSPF6_NEIGHBOR_EXCHANGE
&& on->state != OSPF6_NEIGHBOR_LOADING
&& on->state != OSPF6_NEIGHBOR_FULL) {
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
zlog_debug("Neighbor state less than Exchange, ignore");
return;
}
@@ -1555,12 +1608,14 @@ int ospf6_receive(struct thread *thread)
oi = ospf6_interface_lookup_by_ifindex(ifindex, ospf6->vrf_id);
if (oi == NULL || oi->area == NULL
|| CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("Message received on disabled interface");
return 0;
}
if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN,
+ RECV_HDR))
zlog_debug("%s: Ignore message on passive interface %s",
__func__, oi->interface->name);
return 0;
@@ -1576,7 +1631,7 @@ int ospf6_receive(struct thread *thread)
which can be dismissed in a cleanup-focused review round later. */
/* Log */
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV)) {
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR)) {
zlog_debug("%s received on %s",
lookup_msg(ospf6_message_type_str, oh->type, NULL),
oi->interface->name);
@@ -1585,19 +1640,19 @@ int ospf6_receive(struct thread *thread)
switch (oh->type) {
case OSPF6_MESSAGE_TYPE_HELLO:
- ospf6_hello_print(oh);
+ ospf6_hello_print(oh, OSPF6_ACTION_RECV);
break;
case OSPF6_MESSAGE_TYPE_DBDESC:
- ospf6_dbdesc_print(oh);
+ ospf6_dbdesc_print(oh, OSPF6_ACTION_RECV);
break;
case OSPF6_MESSAGE_TYPE_LSREQ:
- ospf6_lsreq_print(oh);
+ ospf6_lsreq_print(oh, OSPF6_ACTION_RECV);
break;
case OSPF6_MESSAGE_TYPE_LSUPDATE:
- ospf6_lsupdate_print(oh);
+ ospf6_lsupdate_print(oh, OSPF6_ACTION_RECV);
break;
case OSPF6_MESSAGE_TYPE_LSACK:
- ospf6_lsack_print(oh);
+ ospf6_lsack_print(oh, OSPF6_ACTION_RECV);
break;
default:
assert(0);
@@ -1656,7 +1711,7 @@ static void ospf6_send(struct in6_addr *src, struct in6_addr *dst,
oh->reserved = 0;
/* Log */
- if (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND)) {
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND_HDR)) {
if (src)
inet_ntop(AF_INET6, src, srcname, sizeof(srcname));
else
@@ -1669,19 +1724,19 @@ static void ospf6_send(struct in6_addr *src, struct in6_addr *dst,
switch (oh->type) {
case OSPF6_MESSAGE_TYPE_HELLO:
- ospf6_hello_print(oh);
+ ospf6_hello_print(oh, OSPF6_ACTION_RECV);
break;
case OSPF6_MESSAGE_TYPE_DBDESC:
- ospf6_dbdesc_print(oh);
+ ospf6_dbdesc_print(oh, OSPF6_ACTION_RECV);
break;
case OSPF6_MESSAGE_TYPE_LSREQ:
- ospf6_lsreq_print(oh);
+ ospf6_lsreq_print(oh, OSPF6_ACTION_RECV);
break;
case OSPF6_MESSAGE_TYPE_LSUPDATE:
- ospf6_lsupdate_print(oh);
+ ospf6_lsupdate_print(oh, OSPF6_ACTION_RECV);
break;
case OSPF6_MESSAGE_TYPE_LSACK:
- ospf6_lsack_print(oh);
+ ospf6_lsack_print(oh, OSPF6_ACTION_RECV);
break;
default:
zlog_debug("Unknown message");
@@ -1719,7 +1774,7 @@ int ospf6_hello_send(struct thread *thread)
oi->thread_send_hello = (struct thread *)NULL;
if (oi->state <= OSPF6_INTERFACE_DOWN) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO, SEND_HDR))
zlog_debug("Unable to send Hello on down interface %s",
oi->interface->name);
return 0;
@@ -1758,7 +1813,7 @@ int ospf6_hello_send(struct thread *thread)
if (p - sendbuf + sizeof(uint32_t) > ospf6_packet_max(oi)) {
if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO,
- SEND))
+ SEND_HDR))
zlog_debug(
"sending Hello message: exceeds I/F MTU");
break;
@@ -1790,7 +1845,7 @@ int ospf6_dbdesc_send(struct thread *thread)
on->thread_send_dbdesc = (struct thread *)NULL;
if (on->state < OSPF6_NEIGHBOR_EXSTART) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_DBDESC, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_DBDESC, SEND_HDR))
zlog_debug(
"Quit to send DbDesc to neighbor %s state %s",
on->name, ospf6_neighbor_state_str[on->state]);
@@ -1918,7 +1973,7 @@ int ospf6_lsreq_send(struct thread *thread)
/* LSReq will be sent only in ExStart or Loading */
if (on->state != OSPF6_NEIGHBOR_EXCHANGE
&& on->state != OSPF6_NEIGHBOR_LOADING) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSREQ, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSREQ, SEND_HDR))
zlog_debug("Quit to send LSReq to neighbor %s state %s",
on->name,
ospf6_neighbor_state_str[on->state]);
@@ -2029,11 +2084,12 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread)
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
on->thread_send_lsupdate = (struct thread *)NULL;
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND_HDR))
zlog_debug("LSUpdate to neighbor %s", on->name);
if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE,
+ SEND_HDR))
zlog_debug("Quit to send (neighbor state %s)",
ospf6_neighbor_state_str[on->state]);
return 0;
@@ -2190,7 +2246,7 @@ int ospf6_lsupdate_send_neighbor_now(struct ospf6_neighbor *on,
lsupdate->lsa_number = htonl(lsa_cnt);
if (IS_OSPF6_DEBUG_FLOODING
- || IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
+ || IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND_HDR))
zlog_debug("%s: Send lsupdate with lsa %s (age %u)", __func__,
lsa->name, ntohs(lsa->header->age));
@@ -2212,7 +2268,8 @@ int ospf6_lsupdate_send_interface(struct thread *thread)
oi->thread_send_lsupdate = (struct thread *)NULL;
if (oi->state <= OSPF6_INTERFACE_WAITING) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE,
+ SEND_HDR))
zlog_debug(
"Quit to send LSUpdate to interface %s state %s",
oi->interface->name,
@@ -2299,7 +2356,7 @@ int ospf6_lsack_send_neighbor(struct thread *thread)
on->thread_send_lsack = (struct thread *)NULL;
if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND_HDR))
zlog_debug("Quit to send LSAck to neighbor %s state %s",
on->name,
ospf6_neighbor_state_str[on->state]);
@@ -2377,7 +2434,7 @@ int ospf6_lsack_send_interface(struct thread *thread)
oi->thread_send_lsack = (struct thread *)NULL;
if (oi->state <= OSPF6_INTERFACE_WAITING) {
- if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK, SEND_HDR))
zlog_debug(
"Quit to send LSAck to interface %s state %s",
oi->interface->name,
@@ -2440,21 +2497,21 @@ int ospf6_lsack_send_interface(struct thread *thread)
/* Commands */
-DEFUN (debug_ospf6_message,
- debug_ospf6_message_cmd,
- "debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv>]",
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 message\n"
- "Debug Unknown message\n"
- "Debug Hello message\n"
- "Debug Database Description message\n"
- "Debug Link State Request message\n"
- "Debug Link State Update message\n"
- "Debug Link State Acknowledgement message\n"
- "Debug All message\n"
- "Debug only sending message\n"
- "Debug only receiving message\n")
+DEFUN(debug_ospf6_message, debug_ospf6_message_cmd,
+ "debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv|send-hdr|recv-hdr>]",
+ DEBUG_STR OSPF6_STR
+ "Debug OSPFv3 message\n"
+ "Debug Unknown message\n"
+ "Debug Hello message\n"
+ "Debug Database Description message\n"
+ "Debug Link State Request message\n"
+ "Debug Link State Update message\n"
+ "Debug Link State Acknowledgement message\n"
+ "Debug All message\n"
+ "Debug only sending message, entire packet\n"
+ "Debug only receiving message, entire packet\n"
+ "Debug only sending message, header only\n"
+ "Debug only receiving message, header only\n")
{
int idx_packet = 3;
int idx_send_recv = 4;
@@ -2480,8 +2537,12 @@ DEFUN (debug_ospf6_message,
if (argc == 4)
level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
+ else if (!strncmp(argv[idx_send_recv]->arg, "send-h", 6))
+ level = OSPF6_DEBUG_MESSAGE_SEND_HDR;
else if (!strncmp(argv[idx_send_recv]->arg, "s", 1))
level = OSPF6_DEBUG_MESSAGE_SEND;
+ else if (!strncmp(argv[idx_send_recv]->arg, "recv-h", 6))
+ level = OSPF6_DEBUG_MESSAGE_RECV_HDR;
else if (!strncmp(argv[idx_send_recv]->arg, "r", 1))
level = OSPF6_DEBUG_MESSAGE_RECV;
@@ -2494,22 +2555,21 @@ DEFUN (debug_ospf6_message,
return CMD_SUCCESS;
}
-DEFUN (no_debug_ospf6_message,
- no_debug_ospf6_message_cmd,
- "no debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv>]",
- NO_STR
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 message\n"
- "Debug Unknown message\n"
- "Debug Hello message\n"
- "Debug Database Description message\n"
- "Debug Link State Request message\n"
- "Debug Link State Update message\n"
- "Debug Link State Acknowledgement message\n"
- "Debug All message\n"
- "Debug only sending message\n"
- "Debug only receiving message\n")
+DEFUN(no_debug_ospf6_message, no_debug_ospf6_message_cmd,
+ "no debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv|send-hdr|recv-hdr>]",
+ NO_STR DEBUG_STR OSPF6_STR
+ "Debug OSPFv3 message\n"
+ "Debug Unknown message\n"
+ "Debug Hello message\n"
+ "Debug Database Description message\n"
+ "Debug Link State Request message\n"
+ "Debug Link State Update message\n"
+ "Debug Link State Acknowledgement message\n"
+ "Debug All message\n"
+ "Debug only sending message, entire pkt\n"
+ "Debug only receiving message, entire pkt\n"
+ "Debug only sending message, header only\n"
+ "Debug only receiving message, header only\n")
{
int idx_packet = 4;
int idx_send_recv = 5;
@@ -2534,9 +2594,15 @@ DEFUN (no_debug_ospf6_message,
type = OSPF6_MESSAGE_TYPE_ALL;
if (argc == 5)
- level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
+ level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV
+ | OSPF6_DEBUG_MESSAGE_SEND_HDR
+ | OSPF6_DEBUG_MESSAGE_RECV_HDR;
+ else if (!strncmp(argv[idx_send_recv]->arg, "send-h", 6))
+ level = OSPF6_DEBUG_MESSAGE_SEND_HDR;
else if (!strncmp(argv[idx_send_recv]->arg, "s", 1))
level = OSPF6_DEBUG_MESSAGE_SEND;
+ else if (!strncmp(argv[idx_send_recv]->arg, "recv-h", 6))
+ level = OSPF6_DEBUG_MESSAGE_RECV_HDR;
else if (!strncmp(argv[idx_send_recv]->arg, "r", 1))
level = OSPF6_DEBUG_MESSAGE_RECV;
@@ -2554,16 +2620,23 @@ int config_write_ospf6_debug_message(struct vty *vty)
{
const char *type_str[] = {"unknown", "hello", "dbdesc",
"lsreq", "lsupdate", "lsack"};
- unsigned char s = 0, r = 0;
+ unsigned char s = 0, r = 0, sh = 0, rh = 0;
int i;
for (i = 0; i < 6; i++) {
- if (IS_OSPF6_DEBUG_MESSAGE(i, SEND))
+ if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND))
s |= 1 << i;
- if (IS_OSPF6_DEBUG_MESSAGE(i, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV))
r |= 1 << i;
}
+ for (i = 0; i < 6; i++) {
+ if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND_HDR))
+ sh |= 1 << i;
+ if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV_HDR))
+ rh |= 1 << i;
+ }
+
if (s == 0x3f && r == 0x3f) {
vty_out(vty, "debug ospf6 message all\n");
return 0;
@@ -2577,6 +2650,14 @@ int config_write_ospf6_debug_message(struct vty *vty)
return 0;
}
+ if (sh == 0x3f && rh == 0) {
+ vty_out(vty, "debug ospf6 message all send-hdr\n");
+ return 0;
+ } else if (sh == 0 && rh == 0x3f) {
+ vty_out(vty, "debug ospf6 message all recv-hdr\n");
+ return 0;
+ }
+
/* Unknown message is logged by default */
if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, SEND)
&& !IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
@@ -2587,15 +2668,25 @@ int config_write_ospf6_debug_message(struct vty *vty)
vty_out(vty, "no debug ospf6 message unknown recv\n");
for (i = 1; i < 6; i++) {
- if (IS_OSPF6_DEBUG_MESSAGE(i, SEND)
- && IS_OSPF6_DEBUG_MESSAGE(i, RECV))
+ if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND)
+ && IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV))
vty_out(vty, "debug ospf6 message %s\n", type_str[i]);
- else if (IS_OSPF6_DEBUG_MESSAGE(i, SEND))
+ else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND))
vty_out(vty, "debug ospf6 message %s send\n",
type_str[i]);
- else if (IS_OSPF6_DEBUG_MESSAGE(i, RECV))
+ else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV))
vty_out(vty, "debug ospf6 message %s recv\n",
type_str[i]);
+ else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND_HDR)
+ && IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV_HDR))
+ vty_out(vty, "debug ospf6 message %s; header only\n",
+ type_str[i]);
+ else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, RECV_HDR))
+ vty_out(vty, "debug ospf6 message %s recv-hdr\n",
+ type_str[i]);
+ else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i, SEND_HDR))
+ vty_out(vty, "debug ospf6 message %s send-hdr\n",
+ type_str[i]);
}
return 0;
diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h
index 7ec8cb785f..c4cdbd52f4 100644
--- a/ospf6d/ospf6_message.h
+++ b/ospf6d/ospf6_message.h
@@ -25,14 +25,34 @@
/* Debug option */
extern unsigned char conf_debug_ospf6_message[];
+#define OSPF6_ACTION_SEND 0x01
+#define OSPF6_ACTION_RECV 0x02
#define OSPF6_DEBUG_MESSAGE_SEND 0x01
#define OSPF6_DEBUG_MESSAGE_RECV 0x02
+#define OSPF6_DEBUG_MESSAGE_SEND_HDR 0x04
+#define OSPF6_DEBUG_MESSAGE_RECV_HDR 0x08
+#define OSPF6_DEBUG_MESSAGE_SEND_BOTH \
+ OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_SEND_HDR
+#define OSPF6_DEBUG_MESSAGE_RECV_BOTH \
+ OSPF6_DEBUG_MESSAGE_RECV | OSPF6_DEBUG_MESSAGE_RECV_HDR
+
#define OSPF6_DEBUG_MESSAGE_ON(type, level) \
(conf_debug_ospf6_message[type] |= (level))
#define OSPF6_DEBUG_MESSAGE_OFF(type, level) \
(conf_debug_ospf6_message[type] &= ~(level))
+
#define IS_OSPF6_DEBUG_MESSAGE(t, e) \
- (conf_debug_ospf6_message[t] & OSPF6_DEBUG_MESSAGE_##e)
+ ((OSPF6_DEBUG_MESSAGE_##e) == OSPF6_DEBUG_MESSAGE_RECV_HDR) \
+ ? (conf_debug_ospf6_message[t] \
+ & (OSPF6_DEBUG_MESSAGE_RECV_BOTH)) \
+ : (((OSPF6_DEBUG_MESSAGE_##e) == OSPF6_DEBUG_MESSAGE_SEND_HDR) \
+ ? (conf_debug_ospf6_message[t] \
+ & (OSPF6_DEBUG_MESSAGE_SEND_BOTH)) \
+ : (conf_debug_ospf6_message[t] \
+ & (OSPF6_DEBUG_MESSAGE_##e)))
+
+#define IS_OSPF6_DEBUG_MESSAGE_ENABLED(type, e) \
+ (conf_debug_ospf6_message[type] & (OSPF6_DEBUG_MESSAGE_##e))
/* Type */
#define OSPF6_MESSAGE_TYPE_UNKNOWN 0x0
@@ -110,11 +130,11 @@ struct ospf6_lsupdate {
/* It is just a sequence of LSA Headers */
/* Function definition */
-extern void ospf6_hello_print(struct ospf6_header *);
-extern void ospf6_dbdesc_print(struct ospf6_header *);
-extern void ospf6_lsreq_print(struct ospf6_header *);
-extern void ospf6_lsupdate_print(struct ospf6_header *);
-extern void ospf6_lsack_print(struct ospf6_header *);
+extern void ospf6_hello_print(struct ospf6_header *, int action);
+extern void ospf6_dbdesc_print(struct ospf6_header *, int action);
+extern void ospf6_lsreq_print(struct ospf6_header *, int action);
+extern void ospf6_lsupdate_print(struct ospf6_header *, int action);
+extern void ospf6_lsack_print(struct ospf6_header *, int action);
extern int ospf6_iobuf_size(unsigned int size);
extern void ospf6_message_terminate(void);
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 e01cfe3e03..b022133dcd 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -113,7 +113,6 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance,
struct external_info *new;
struct route_node *rn;
struct ospf_external *ext;
- char inetbuf[INET6_BUFSIZ];
ext = ospf_external_lookup(ospf, type, instance);
if (!ext)
@@ -121,26 +120,23 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance,
rn = route_node_get(EXTERNAL_INFO(ext), (struct prefix *)&p);
/* If old info exists, -- discard new one or overwrite with new one? */
- if (rn)
- if (rn->info) {
- new = rn->info;
- if ((new->ifindex == ifindex)
- && (new->nexthop.s_addr == nexthop.s_addr)
- && (new->tag == tag)) {
- route_unlock_node(rn);
- return NULL; /* NULL => no LSA to refresh */
- }
-
- inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf,
- sizeof(inetbuf));
- if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
- zlog_debug(
- "Redistribute[%s][%d][%u]: %pFX discarding old info with NH %s.",
- ospf_redist_string(type), instance,
- ospf->vrf_id, &p, inetbuf);
- XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info);
+ if (rn && rn->info) {
+ new = rn->info;
+ if ((new->ifindex == ifindex)
+ && (new->nexthop.s_addr == nexthop.s_addr)
+ && (new->tag == tag)) {
+ route_unlock_node(rn);
+ return NULL; /* NULL => no LSA to refresh */
}
+ if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+ zlog_debug(
+ "Redistribute[%s][%d][%u]: %pFX discarding old info with NH %pI4.",
+ ospf_redist_string(type), instance,
+ ospf->vrf_id, &p, &nexthop.s_addr);
+ XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info);
+ }
+
/* Create new External info instance. */
new = ospf_external_info_new(type, instance);
new->p = p;
@@ -155,12 +151,10 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance,
rn->info = new;
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
- inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf,
- sizeof(inetbuf));
zlog_debug(
- "Redistribute[%s][%u]: %pFX external info created, with NH %s",
- ospf_redist_string(type), ospf->vrf_id,
- &p, inetbuf);
+ "Redistribute[%s][%u]: %pFX external info created, with NH %pI4",
+ ospf_redist_string(type), ospf->vrf_id, &p,
+ &nexthop.s_addr);
}
return new;
}
@@ -329,34 +323,36 @@ void ospf_redistribute_withdraw(struct ospf *ospf, uint8_t type,
return;
/* Delete external info for specified type. */
- if (EXTERNAL_INFO(ext))
- for (rn = route_top(EXTERNAL_INFO(ext)); rn;
- rn = route_next(rn))
- if ((ei = rn->info)) {
- struct ospf_external_aggr_rt *aggr;
-
- if (is_prefix_default(&ei->p)
- && ospf->default_originate
- != DEFAULT_ORIGINATE_NONE)
- continue;
+ if (!EXTERNAL_INFO(ext))
+ return;
+
+ for (rn = route_top(EXTERNAL_INFO(ext)); rn; rn = route_next(rn)) {
+ ei = rn->info;
- aggr = ei->aggr_route;
+ if (!ei)
+ continue;
+
+ 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,
+ 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 */
bool is_valid_summary_addr(struct prefix_ipv4 *p)
{
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_sr.c b/ospfd/ospf_sr.c
index a7a2e03632..d003f3bf7c 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -1689,7 +1689,8 @@ void ospf_sr_ext_itf_add(struct ext_itf *exti)
else
srl->nhlfe[1].nexthop = exti->rmt_itf_addr.value;
break;
- default:
+ case PREF_SID:
+ case LOCAL_SID:
/* Wrong SID Type. Abort! */
XFREE(MTYPE_OSPF_SR_PARAMS, srl);
return;
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_zebra.c b/ospfd/ospf_zebra.c
index a2ce4d1ce7..f198995dfa 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -637,7 +637,8 @@ void ospf_zebra_update_prefix_sid(const struct sr_prefix *srp)
}
}
break;
- default:
+ case ADJ_SID:
+ case LAN_ADJ_SID:
return;
}
@@ -765,12 +766,12 @@ int ospf_is_type_redistributed(struct ospf *ospf, int type,
ospf->vrf_id)
: ((instance
&& redist_check_instance(
- &zclient->mi_redist[AFI_IP][type],
- instance))
+ &zclient->mi_redist[AFI_IP][type],
+ instance))
|| (!instance
&& vrf_bitmap_check(
- zclient->redist[AFI_IP][type],
- ospf->vrf_id))));
+ zclient->redist[AFI_IP][type],
+ ospf->vrf_id))));
}
int ospf_redistribute_set(struct ospf *ospf, int type, unsigned short instance,
@@ -1262,104 +1263,92 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
return 0;
}
if (ospf->router_id.s_addr != INADDR_ANY) {
- if (ei) {
- if (is_prefix_default(&p))
- ospf_external_lsa_refresh_default(ospf);
- else {
- struct ospf_external_aggr_rt *aggr;
- struct as_external_lsa *al;
- struct ospf_lsa *lsa = NULL;
- struct in_addr mask;
-
- aggr = ospf_external_aggr_match(ospf,
- &ei->p);
+ if (is_prefix_default(&p))
+ ospf_external_lsa_refresh_default(ospf);
+ else {
+ struct ospf_external_aggr_rt *aggr;
+ struct as_external_lsa *al;
+ struct ospf_lsa *lsa = NULL;
+ struct in_addr mask;
+
+ aggr = ospf_external_aggr_match(ospf, &ei->p);
+
+ if (aggr) {
+ /* Check the AS-external-LSA
+ * should be originated.
+ */
+ if (!ospf_redistribute_check(ospf, ei,
+ NULL))
+ return 0;
+
+ if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+ zlog_debug(
+ "%s: Send Aggreate LSA (%pI4/%d)",
+ __func__,
+ &aggr->p.prefix,
+ aggr->p.prefixlen);
+
+ ospf_originate_summary_lsa(ospf, aggr,
+ ei);
+
+ /* Handling the case where the
+ * external route prefix
+ * and aggegate prefix is same
+ * If same dont flush the
+ * originated
+ * external LSA.
+ */
+ if (prefix_same(
+ (struct prefix *)&aggr->p,
+ (struct prefix *)&ei->p))
+ return 0;
+
+ lsa = ospf_external_info_find_lsa(
+ ospf, &ei->p);
+
+ if (lsa) {
+ al = (struct as_external_lsa *)
+ lsa->data;
+ masklen2ip(ei->p.prefixlen,
+ &mask);
+
+ if (mask.s_addr
+ != al->mask.s_addr)
+ return 0;
- if (aggr) {
- /* Check the AS-external-LSA
- * should be originated.
+ ospf_external_lsa_flush(
+ ospf, ei->type, &ei->p,
+ 0);
+ }
+ } else {
+ struct ospf_lsa *current;
+
+ current = ospf_external_info_find_lsa(
+ ospf, &ei->p);
+ if (!current) {
+ /* Check the
+ * AS-external-LSA
+ * should be
+ * originated.
*/
if (!ospf_redistribute_check(
ospf, ei, NULL))
return 0;
+ ospf_external_lsa_originate(
+ ospf, ei);
+ } else {
if (IS_DEBUG_OSPF(
- lsa,
- EXTNL_LSA_AGGR))
+ zebra,
+ ZEBRA_REDISTRIBUTE))
zlog_debug(
- "%s: Send Aggreate LSA (%pI4/%d)",
+ "%s: %pI4 refreshing LSA",
__func__,
- &aggr->p.prefix,
- aggr->p.prefixlen);
-
- ospf_originate_summary_lsa(
- ospf, aggr, ei);
-
- /* Handling the case where the
- * external route prefix
- * and aggegate prefix is same
- * If same dont flush the
- * originated
- * external LSA.
- */
- if (prefix_same(
- (struct prefix
- *)&aggr->p,
- (struct prefix *)&ei
- ->p))
- return 0;
-
- lsa = ospf_external_info_find_lsa(
- ospf, &ei->p);
-
- if (lsa) {
- al = (struct
- as_external_lsa *)
- lsa->data;
- masklen2ip(
- ei->p.prefixlen,
- &mask);
-
- if (mask.s_addr
- != al->mask.s_addr)
- return 0;
-
- ospf_external_lsa_flush(
- ospf, ei->type,
- &ei->p, 0);
- }
- } else {
- struct ospf_lsa *current;
-
- current =
- ospf_external_info_find_lsa(
- ospf, &ei->p);
- if (!current) {
- /* Check the
- * AS-external-LSA
- * should be
- * originated.
- */
- if (!ospf_redistribute_check(
- ospf, ei,
- NULL))
- return 0;
-
- ospf_external_lsa_originate(
- ospf, ei);
- } else {
- if (IS_DEBUG_OSPF(
- zebra,
- ZEBRA_REDISTRIBUTE))
- zlog_debug(
- "%s: %pI4 refreshing LSA",
- __func__,
- &p.prefix);
- ospf_external_lsa_refresh(
- ospf, current,
- ei,
- LSA_REFRESH_FORCE,
- false);
- }
+ &p.prefix);
+ ospf_external_lsa_refresh(
+ ospf, current, ei,
+ LSA_REFRESH_FORCE,
+ false);
}
}
}
@@ -1371,20 +1360,19 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
*/
ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
- } else /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
- {
+ } else { /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
struct ospf_external_aggr_rt *aggr;
ei = ospf_external_info_lookup(ospf, rt_type, api.instance, &p);
if (ei == NULL)
return 0;
- else
- /*
- * Check if default-information originate i
- * with some routemap prefix/access list match.
- * Apply before ei is deleted.
- */
- ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
+
+ /*
+ * Check if default-information originate i
+ * with some routemap prefix/access list match.
+ * Apply before ei is deleted.
+ */
+ ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
aggr = ospf_external_aggr_match(ospf, &ei->p);
@@ -1405,7 +1393,6 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
}
}
-
return 0;
}
@@ -1490,85 +1477,83 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
rt = ext->external_info;
if (!rt)
continue;
- for (rn = route_top(rt); rn; rn = route_next(rn))
- if ((ei = rn->info) != NULL) {
- if (is_prefix_default(&ei->p))
- default_refresh = 1;
- else {
- struct ospf_external_aggr_rt
- *aggr;
- aggr = ospf_external_aggr_match(
- ospf, &ei->p);
- if (aggr) {
- /* Check the
- * AS-external-LSA
- * should be originated.
- */
- if (!ospf_redistribute_check(
- ospf, ei,
- NULL)) {
-
- ospf_unlink_ei_from_aggr(
- ospf,
- aggr,
- ei);
- continue;
- }
-
- if (IS_DEBUG_OSPF(
- lsa,
- EXTNL_LSA_AGGR))
- zlog_debug(
- "%s: Send Aggregate LSA (%pI4/%d)",
- __func__,
- &aggr->p.prefix,
- aggr->p.prefixlen);
-
- /* Originate Aggregate
- * LSA
- */
- ospf_originate_summary_lsa(
+ for (rn = route_top(rt); rn; rn = route_next(rn)) {
+ ei = rn->info;
+ if (!ei)
+ continue;
+
+ if (is_prefix_default(&ei->p))
+ default_refresh = 1;
+ else {
+ struct ospf_external_aggr_rt *aggr;
+
+ aggr = ospf_external_aggr_match(ospf,
+ &ei->p);
+ if (aggr) {
+ /* Check the
+ * AS-external-LSA
+ * should be originated.
+ */
+ if (!ospf_redistribute_check(
+ ospf, ei, NULL)) {
+
+ ospf_unlink_ei_from_aggr(
ospf, aggr, ei);
- } else if (
- (lsa = ospf_external_info_find_lsa(
- ospf,
- &ei->p))) {
- int force =
- LSA_REFRESH_IF_CHANGED;
- /* If this is a MaxAge
- * LSA, we need to
- * force refresh it
- * because distribute
- * settings might have
- * changed and now,
- * this LSA needs to be
- * originated, not be
- * removed.
- * If we don't force
- * refresh it, it will
- * remain a MaxAge LSA
- * because it will look
- * like it hasn't
- * changed. Neighbors
- * will not receive
- * updates for this LSA.
- */
- if (IS_LSA_MAXAGE(lsa))
- force = LSA_REFRESH_FORCE;
-
- ospf_external_lsa_refresh(
- ospf, lsa, ei,
- force, false);
- } else {
- if (!ospf_redistribute_check(
- ospf, ei,
- NULL))
- continue;
- ospf_external_lsa_originate(
- ospf, ei);
+ continue;
}
+
+ if (IS_DEBUG_OSPF(
+ lsa,
+ EXTNL_LSA_AGGR))
+ zlog_debug(
+ "%s: Send Aggregate LSA (%pI4/%d)",
+ __func__,
+ &aggr->p.prefix,
+ aggr->p.prefixlen);
+
+ /* Originate Aggregate
+ * LSA
+ */
+ ospf_originate_summary_lsa(
+ ospf, aggr, ei);
+ } else if (
+ (lsa = ospf_external_info_find_lsa(
+ ospf, &ei->p))) {
+ int force =
+ LSA_REFRESH_IF_CHANGED;
+ /* If this is a MaxAge
+ * LSA, we need to
+ * force refresh it
+ * because distribute
+ * settings might have
+ * changed and now,
+ * this LSA needs to be
+ * originated, not be
+ * removed.
+ * If we don't force
+ * refresh it, it will
+ * remain a MaxAge LSA
+ * because it will look
+ * like it hasn't
+ * changed. Neighbors
+ * will not receive
+ * updates for this LSA.
+ */
+ if (IS_LSA_MAXAGE(lsa))
+ force = LSA_REFRESH_FORCE;
+
+ ospf_external_lsa_refresh(
+ ospf, lsa, ei, force,
+ false);
+ } else {
+ if (!ospf_redistribute_check(
+ ospf, ei, NULL))
+ continue;
+ ospf_external_lsa_originate(
+ ospf, ei);
}
}
+ }
}
}
if (default_refresh)
@@ -1718,17 +1703,16 @@ void ospf_prefix_list_update(struct prefix_list *plist)
struct ospf_redist *red;
red_list = ospf->redist[type];
- if (red_list) {
- for (ALL_LIST_ELEMENTS_RO(red_list, node,
- red)) {
- if (ROUTEMAP(red)) {
- /* if route-map is not NULL
- * it may be using
- * this prefix list */
- ospf_distribute_list_update(
- ospf, type,
- red->instance);
- }
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP(red)) {
+ /* if route-map is not NULL
+ * it may be using
+ * this prefix list */
+ ospf_distribute_list_update(
+ ospf, type, red->instance);
}
}
}
@@ -1736,28 +1720,24 @@ void ospf_prefix_list_update(struct prefix_list *plist)
/* Update area filter-lists. */
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
/* Update filter-list in. */
- if (PREFIX_NAME_IN(area))
- if (strcmp(PREFIX_NAME_IN(area),
- prefix_list_name(plist))
- == 0) {
- PREFIX_LIST_IN(area) =
- prefix_list_lookup(
- AFI_IP,
- PREFIX_NAME_IN(area));
- abr_inv++;
- }
+ if (PREFIX_NAME_IN(area)
+ && strcmp(PREFIX_NAME_IN(area),
+ prefix_list_name(plist))
+ == 0) {
+ PREFIX_LIST_IN(area) = prefix_list_lookup(
+ AFI_IP, PREFIX_NAME_IN(area));
+ abr_inv++;
+ }
/* Update filter-list out. */
- if (PREFIX_NAME_OUT(area))
- if (strcmp(PREFIX_NAME_OUT(area),
- prefix_list_name(plist))
- == 0) {
- PREFIX_LIST_IN(area) =
- prefix_list_lookup(
- AFI_IP,
- PREFIX_NAME_OUT(area));
- abr_inv++;
- }
+ if (PREFIX_NAME_OUT(area)
+ && strcmp(PREFIX_NAME_OUT(area),
+ prefix_list_name(plist))
+ == 0) {
+ PREFIX_LIST_IN(area) = prefix_list_lookup(
+ AFI_IP, PREFIX_NAME_OUT(area));
+ abr_inv++;
+ }
}
/* Schedule ABR task. */
@@ -1857,14 +1837,17 @@ void ospf_distance_reset(struct ospf *ospf)
struct route_node *rn;
struct ospf_distance *odistance;
- for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn))
- if ((odistance = rn->info) != NULL) {
- if (odistance->access_list)
- free(odistance->access_list);
- ospf_distance_free(odistance);
- rn->info = NULL;
- route_unlock_node(rn);
- }
+ for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn)) {
+ odistance = rn->info;
+ if (!odistance)
+ continue;
+
+ if (odistance->access_list)
+ free(odistance->access_list);
+ ospf_distance_free(odistance);
+ rn->info = NULL;
+ route_unlock_node(rn);
+ }
}
uint8_t ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
@@ -1874,18 +1857,16 @@ uint8_t ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
if (ospf == NULL)
return 0;
- if (ospf->distance_intra)
- if (or->path_type == OSPF_PATH_INTRA_AREA)
- return ospf->distance_intra;
+ if (ospf->distance_intra && or->path_type == OSPF_PATH_INTRA_AREA)
+ return ospf->distance_intra;
- if (ospf->distance_inter)
- if (or->path_type == OSPF_PATH_INTER_AREA)
- return ospf->distance_inter;
+ if (ospf->distance_inter && or->path_type == OSPF_PATH_INTER_AREA)
+ return ospf->distance_inter;
- if (ospf->distance_external)
- if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL ||
- or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
- return ospf->distance_external;
+ if (ospf->distance_external
+ && (or->path_type == OSPF_PATH_TYPE1_EXTERNAL ||
+ or->path_type == OSPF_PATH_TYPE2_EXTERNAL))
+ return ospf->distance_external;
if (ospf->distance_all)
return ospf->distance_all;
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/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/ripd/rip_cli.c b/ripd/rip_cli.c
index 87098ece64..43e5b21fa1 100644
--- a/ripd/rip_cli.c
+++ b/ripd/rip_cli.c
@@ -1019,11 +1019,56 @@ DEFPY_YANG (clear_ip_rip,
return ret;
}
+DEFUN (rip_distribute_list,
+ rip_distribute_list_cmd,
+ "distribute-list [prefix] WORD <in|out> [WORD]",
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
+ argv[1 + prefix]->arg, ifname);
+}
+
+DEFUN (rip_no_distribute_list,
+ rip_no_distribute_list_cmd,
+ "no distribute-list [prefix] WORD <in|out> [WORD]",
+ NO_STR
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_no_parser(vty, prefix, true,
+ argv[3 + prefix]->text,
+ argv[2 + prefix]->arg, ifname);
+}
+
void rip_cli_init(void)
{
install_element(CONFIG_NODE, &router_rip_cmd);
install_element(CONFIG_NODE, &no_router_rip_cmd);
+ install_element(RIP_NODE, &rip_distribute_list_cmd);
+ install_element(RIP_NODE, &rip_no_distribute_list_cmd);
+
install_element(RIP_NODE, &rip_allow_ecmp_cmd);
install_element(RIP_NODE, &rip_default_information_originate_cmd);
install_element(RIP_NODE, &rip_default_metric_cmd);
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 1c23575bf3..9832c7c52a 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -3722,9 +3722,6 @@ void rip_init(void)
prefix_list_add_hook(rip_distribute_update_all);
prefix_list_delete_hook(rip_distribute_update_all);
- /* Distribute list install. */
- distribute_list_init(RIP_NODE);
-
/* Route-map */
rip_route_map_init();
diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c
index 365082f806..7e0d014086 100644
--- a/ripngd/ripng_cli.c
+++ b/ripngd/ripng_cli.c
@@ -503,11 +503,58 @@ DEFPY_YANG (clear_ipv6_rip,
return ret;
}
+DEFUN (ripng_ipv6_distribute_list,
+ ripng_ipv6_distribute_list_cmd,
+ "ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ "IPv6\n"
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_parser(prefix, false, argv[3 + prefix]->text,
+ argv[2 + prefix]->arg, ifname);
+}
+
+DEFUN (ripng_no_ipv6_distribute_list,
+ ripng_no_ipv6_distribute_list_cmd,
+ "no ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ NO_STR
+ "IPv6\n"
+ "Filter networks in routing updates\n"
+ "Specify a prefix\n"
+ "Access-list name\n"
+ "Filter incoming routing updates\n"
+ "Filter outgoing routing updates\n"
+ "Interface name\n")
+{
+ const char *ifname = NULL;
+ int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
+
+ if (argv[argc - 1]->type == VARIABLE_TKN)
+ ifname = argv[argc - 1]->arg;
+
+ return distribute_list_no_parser(vty, prefix, false,
+ argv[4 + prefix]->text,
+ argv[3 + prefix]->arg, ifname);
+}
+
void ripng_cli_init(void)
{
install_element(CONFIG_NODE, &router_ripng_cmd);
install_element(CONFIG_NODE, &no_router_ripng_cmd);
+ install_element(RIPNG_NODE, &ripng_ipv6_distribute_list_cmd);
+ install_element(RIPNG_NODE, &ripng_no_ipv6_distribute_list_cmd);
+
install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd);
install_element(RIPNG_NODE, &ripng_default_information_originate_cmd);
install_element(RIPNG_NODE, &ripng_default_metric_cmd);
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index 0e83140149..5a71928fbd 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -2723,9 +2723,6 @@ void ripng_init(void)
prefix_list_add_hook(ripng_distribute_update_all);
prefix_list_delete_hook(ripng_distribute_update_all);
- /* Distribute list install. */
- distribute_list_init(RIPNG_NODE);
-
/* Route-map for interface. */
ripng_route_map_init();
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/bgp_tcp_mss/__init__.py b/tests/topotests/bgp_tcp_mss/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_tcp_mss/__init__.py
diff --git a/tests/topotests/bgp_tcp_mss/r1/bgpd.conf b/tests/topotests/bgp_tcp_mss/r1/bgpd.conf
new file mode 100644
index 0000000000..07cfe2e2f1
--- /dev/null
+++ b/tests/topotests/bgp_tcp_mss/r1/bgpd.conf
@@ -0,0 +1,6 @@
+router bgp 65000
+ no bgp ebgp-requires-policy
+ neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_tcp_mss/r1/zebra.conf b/tests/topotests/bgp_tcp_mss/r1/zebra.conf
new file mode 100644
index 0000000000..6e9b0b4a7e
--- /dev/null
+++ b/tests/topotests/bgp_tcp_mss/r1/zebra.conf
@@ -0,0 +1,6 @@
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_tcp_mss/r2/bgpd.conf b/tests/topotests/bgp_tcp_mss/r2/bgpd.conf
new file mode 100644
index 0000000000..b2d945583c
--- /dev/null
+++ b/tests/topotests/bgp_tcp_mss/r2/bgpd.conf
@@ -0,0 +1,6 @@
+router bgp 65001
+ no bgp ebgp-requires-policy
+ neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_tcp_mss/r2/zebra.conf b/tests/topotests/bgp_tcp_mss/r2/zebra.conf
new file mode 100644
index 0000000000..6c14de583b
--- /dev/null
+++ b/tests/topotests/bgp_tcp_mss/r2/zebra.conf
@@ -0,0 +1,6 @@
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_tcp_mss/test_bgp_tcp_mss.py b/tests/topotests/bgp_tcp_mss/test_bgp_tcp_mss.py
new file mode 100644
index 0000000000..7500c3b3ad
--- /dev/null
+++ b/tests/topotests/bgp_tcp_mss/test_bgp_tcp_mss.py
@@ -0,0 +1,178 @@
+#!/usr/bin/env python
+
+#
+# bgp_tcp_mss.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2021 by
+# Abhinay Ramesh <rabhinay@vmware.com>
+#
+# Permission to use, copy, modify, and/or 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 NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF 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.
+#
+
+"""
+bgp_tcp_mss.py:
+
+Test if works the following commands:
+router bgp 65000
+ neighbor 192.168.255.2 tcp-mss 500
+
+Need to verify if the tcp-mss value is reflected in the TCP session.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+# add after imports, before defining classes or functions:
+pytestmark = [pytest.mark.bgpd]
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+ def build(self, *_args, **_opts):
+ tgen = get_topogen(self)
+
+ for routern in range(1, 3):
+ tgen.add_router("r{}".format(routern))
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+
+def setup_module(mod):
+ tgen = Topogen(TemplateTopo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ for i, (rname, router) in enumerate(router_list.items(), 1):
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_tcp_mss():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router1 = tgen.gears["r1"]
+ router2 = tgen.gears["r2"]
+
+ def _bgp_converge(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json"))
+ expected = {
+ "192.168.255.2": {
+ "bgpState": "Established",
+ "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 0}},
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ def _bgp_conf_tcp_mss(router, as_num, neigh):
+ router.vtysh_cmd(
+ """configure terminal
+ router bgp {0}
+ neighbor {1} tcp-mss 500""".format(
+ as_num, neigh
+ )
+ )
+
+ def _bgp_clear_session(router):
+ router.vtysh_cmd("clear bgp *")
+
+ def _bgp_check_neighbor_tcp_mss(router, neigh):
+ output = json.loads(router.vtysh_cmd("show bgp neighbor {} json".format(neigh)))
+ expected = {
+ "{}".format(neigh): {"bgpTcpMssConfigured": 500, "bgpTcpMssSynced": 488}
+ }
+ return topotest.json_cmp(output, expected)
+
+ logger.info("Check if neighbor sessions are up in {}".format(router1.name))
+ test_func = functools.partial(_bgp_converge, router1)
+ success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5)
+ assert result is None, 'Failed to see BGP convergence in "{}"'.format(router1.name)
+
+ logger.info("BGP neighbor session is up in {}".format(router1.name))
+
+ logger.info(
+ "Configure tcp-mss 500 on {} and reset the session".format(router1.name)
+ )
+ _bgp_conf_tcp_mss(router1, "65000", "192.168.255.2")
+ _bgp_clear_session(router1)
+
+ logger.info(
+ "Configure tcp-mss 500 on {} and reset the session".format(router2.name)
+ )
+ _bgp_conf_tcp_mss(router2, "65001", "192.168.255.1")
+ _bgp_clear_session(router2)
+
+ logger.info(
+ "Check if neighbor session is up after reset in {}".format(router1.name)
+ )
+ test_func = functools.partial(_bgp_converge, router1)
+ success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5)
+ assert result is None, 'Failed to see BGP convergence after reset in "{}"'.format(
+ router1.name
+ )
+
+ logger.info(
+ "Verify if TCP MSS value is synced with neighbor in {}".format(router1.name)
+ )
+ test_func = functools.partial(_bgp_check_neighbor_tcp_mss, router1, "192.168.255.2")
+ success, result = topotest.run_and_expect(test_func, None, count=3, wait=0.5)
+ assert (
+ result is None
+ ), 'Failed to sync TCP MSS value over BGP session in "{}"'.format(router1.name)
+ logger.info("TCP MSS value is synced with neighbor in {}".format(router1.name))
+
+ logger.info(
+ "Verify if TCP MSS value is synced with neighbor in {}".format(router2.name)
+ )
+ test_func = functools.partial(_bgp_check_neighbor_tcp_mss, router2, "192.168.255.1")
+ success, result = topotest.run_and_expect(test_func, None, count=3, wait=0.5)
+ assert (
+ result is None
+ ), 'Failed to sync TCP MSS value over BGP session in "{}"'.format(router2.name)
+ logger.info("TCP MSS value is synced with neighbor in {}".format(router2.name))
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
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/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/vtysh/extract.pl.in b/vtysh/extract.pl.in
index af974771cc..37ae0ab189 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -119,13 +119,6 @@ sub scan_file {
$protocol = "VTYSH_RIPD|VTYSH_OSPFD|VTYSH_BGPD|VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_ISISD|VTYSH_FABRICD";
}
}
- elsif ($file =~ /lib\/distribute\.c$/) {
- if ($defun_array[1] =~ m/ipv6/) {
- $protocol = "VTYSH_RIPNGD";
- } else {
- $protocol = "VTYSH_RIPD";
- }
- }
elsif ($file =~ /lib\/if_rmap\.c$/) {
if ($defun_array[1] =~ m/ipv6/) {
$protocol = "VTYSH_RIPNGD";
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/if_netlink.c b/zebra/if_netlink.c
index b1e0f21f68..fbf64439e3 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -1119,7 +1119,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;
}
@@ -1695,6 +1695,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 5f3ee9428c..7fd967dd8b 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -1075,6 +1075,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
@@ -1150,18 +1153,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;
@@ -1179,8 +1180,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 753eb6b58f..df4872d48e 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -486,7 +486,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/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/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... */