summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_attr.c8
-rw-r--r--bgpd/bgp_evpn_vty.c30
-rw-r--r--bgpd/bgp_packet.c10
-rw-r--r--bgpd/bgp_route.c9
-rw-r--r--bgpd/bgpd.h2
-rw-r--r--doc/user/installation.rst12
-rw-r--r--doc/user/sharp.rst10
-rw-r--r--isisd/isis_northbound.c5
-rw-r--r--lib/mlag.c41
-rw-r--r--lib/mlag.h32
-rw-r--r--lib/northbound_cli.c13
-rw-r--r--lib/northbound_cli.h2
-rw-r--r--lib/subdir.am2
-rw-r--r--lib/zclient.c13
-rw-r--r--lib/zclient.h3
-rw-r--r--pimd/pim_assert.c2
-rw-r--r--pimd/pim_cmd.c21
-rw-r--r--pimd/pim_iface.c2
-rw-r--r--pimd/pim_ifchannel.c33
-rw-r--r--pimd/pim_igmp.c14
-rw-r--r--pimd/pim_igmpv3.c7
-rw-r--r--pimd/pim_instance.c8
-rw-r--r--pimd/pim_instance.h24
-rw-r--r--pimd/pim_macro.c2
-rw-r--r--pimd/pim_main.c4
-rw-r--r--pimd/pim_mroute.c4
-rw-r--r--pimd/pim_msdp.c9
-rw-r--r--pimd/pim_msdp.h5
-rw-r--r--pimd/pim_msdp_socket.c2
-rw-r--r--pimd/pim_neighbor.c12
-rw-r--r--pimd/pim_pim.c12
-rw-r--r--pimd/pim_ssmpingd.c2
-rw-r--r--pimd/pim_upstream.c24
-rw-r--r--pimd/pim_upstream.h5
-rw-r--r--pimd/pim_vty.c14
-rw-r--r--pimd/pim_zebra.c16
-rw-r--r--pimd/pim_zlookup.c6
-rw-r--r--pimd/pimd.c63
-rw-r--r--pimd/pimd.h193
-rw-r--r--sharpd/sharp_main.c2
-rw-r--r--sharpd/sharp_vty.c97
-rw-r--r--sharpd/sharp_zebra.c101
-rw-r--r--sharpd/sharp_zebra.h9
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf2
-rwxr-xr-xvtysh/extract.pl.in2
-rw-r--r--vtysh/vtysh.c5
-rw-r--r--zebra/if_netlink.c2
-rw-r--r--zebra/kernel_netlink.c11
-rw-r--r--zebra/kernel_socket.c35
-rw-r--r--zebra/subdir.am7
-rw-r--r--zebra/zapi_msg.c6
-rw-r--r--zebra/zebra_mlag.c83
-rw-r--r--zebra/zebra_mlag.h31
-rw-r--r--zebra/zebra_ns.c1
-rw-r--r--zebra/zebra_router.c5
-rw-r--r--zebra/zebra_vxlan.c35
61 files changed, 780 insertions, 340 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 87ebb9c285..b990e99bda 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -78,7 +78,7 @@ static const struct message attr_str[] = {
{BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT"},
{BGP_ATTR_PMSI_TUNNEL, "PMSI_TUNNEL_ATTRIBUTE"},
{BGP_ATTR_ENCAP, "ENCAP"},
-#if ENABLE_BGP_VNC
+#if ENABLE_BGP_VNC_ATTR
{BGP_ATTR_VNC, "VNC"},
#endif
{BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY"},
@@ -2593,7 +2593,7 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
case BGP_ATTR_EXT_COMMUNITIES:
ret = bgp_attr_ext_communities(&attr_args);
break;
-#if ENABLE_BGP_VNC
+#if ENABLE_BGP_VNC_ATTR
case BGP_ATTR_VNC:
#endif
case BGP_ATTR_ENCAP:
@@ -2946,7 +2946,7 @@ static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
attrhdrlen = 1 + 1; /* subTLV T + L */
break;
-#if ENABLE_BGP_VNC
+#if ENABLE_BGP_VNC_ATTR
case BGP_ATTR_VNC:
attrname = "VNC";
subtlvs = attr->vnc_subtlvs;
@@ -3433,7 +3433,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
/* Tunnel Encap attribute */
bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
-#if ENABLE_BGP_VNC
+#if ENABLE_BGP_VNC_ATTR
/* VNC attribute */
bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC);
#endif
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 13f899e880..776f8f8ef7 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -2883,6 +2883,12 @@ DEFUN (bgp_evpn_advertise_default_gw,
if (!bgp)
return CMD_WARNING;
+ if (bgp->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
evpn_set_advertise_default_gw(bgp, NULL);
return CMD_SUCCESS;
@@ -2899,6 +2905,12 @@ DEFUN (no_bgp_evpn_advertise_default_gw,
if (!bgp)
return CMD_WARNING;
+ if (bgp->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
evpn_unset_advertise_default_gw(bgp, NULL);
return CMD_SUCCESS;
@@ -3011,6 +3023,12 @@ DEFPY (dup_addr_detection,
if (!bgp_vrf)
return CMD_WARNING;
+ if (bgp_vrf->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
bgp_vrf->evpn_info->dup_addr_detect = true;
if (time_val)
@@ -3037,6 +3055,12 @@ DEFPY (dup_addr_detection_auto_recovery,
if (!bgp_vrf)
return CMD_WARNING;
+ if (bgp_vrf->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
bgp_vrf->evpn_info->dup_addr_detect = true;
bgp_vrf->evpn_info->dad_freeze = true;
bgp_vrf->evpn_info->dad_freeze_time = freeze_time;
@@ -3066,6 +3090,12 @@ DEFPY (no_dup_addr_detection,
if (!bgp_vrf)
return CMD_WARNING;
+ if (bgp_vrf->vrf_id != VRF_DEFAULT) {
+ vty_out(vty,
+ "This command is only supported under Default VRF\n");
+ return CMD_WARNING;
+ }
+
if (argc == 2) {
if (!bgp_vrf->evpn_info->dup_addr_detect)
return CMD_SUCCESS;
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 73a07c8232..7b76d7e83e 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1612,6 +1612,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
}
if (afi && peer->afc[afi][safi]) {
+ struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
+
/* End-of-RIB received */
if (!CHECK_FLAG(peer->af_sflags[afi][safi],
PEER_STATUS_EOR_RECEIVED)) {
@@ -1624,11 +1626,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
if (peer->nsf[afi][safi])
bgp_clear_stale_route(peer, afi, safi);
- if (bgp_debug_neighbor_events(peer)) {
- zlog_debug("rcvd End-of-RIB for %s from %s",
- afi_safi_print(afi, safi),
- peer->host);
- }
+ zlog_info("%%NOTIFICATION: rcvd End-of-RIB for %s from %s in vrf %s",
+ afi_safi_print(afi, safi), peer->host,
+ vrf ? vrf->name : VRF_DEFAULT_NAME);
}
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 2c361bef4d..31cd3d1f05 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -9529,9 +9529,16 @@ DEFUN (show_ip_bgp_json,
}
if (argv_find(argv, argc, "community", &idx)) {
- char *maybecomm = idx + 1 < argc ? argv[idx + 1]->text : NULL;
+ char *maybecomm = NULL;
char *community = NULL;
+ if (idx + 1 < argc) {
+ if (argv[idx + 1]->type == VARIABLE_TKN)
+ maybecomm = argv[idx + 1]->arg;
+ else
+ maybecomm = argv[idx + 1]->text;
+ }
+
if (maybecomm && !strmatch(maybecomm, "json")
&& !strmatch(maybecomm, "exact-match"))
community = maybecomm;
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 62096d651a..f28ca9fa0b 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1280,7 +1280,7 @@ struct bgp_nlri {
#define BGP_ATTR_ENCAP 23
#define BGP_ATTR_LARGE_COMMUNITIES 32
#define BGP_ATTR_PREFIX_SID 40
-#if ENABLE_BGP_VNC
+#if ENABLE_BGP_VNC_ATTR
#define BGP_ATTR_VNC 255
#endif
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index 9654cc2eb8..2decfcc4b2 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -324,7 +324,7 @@ GNU/Linux, make sure that the current kernel configuration is what you want.
FRR will run with any kernel configuration but some recommendations do exist.
:makevar:`CONFIG_NETLINK`
- Kernel/User Netlink socket. This is a enables an advanced interface between
+ Kernel/User Netlink socket. This enables an advanced interface between
the Linux kernel and *zebra* (:ref:`kernel-interface`).
:makevar:`CONFIG_RTNETLINK`
@@ -356,9 +356,9 @@ Additional kernel modules are also needed to support MPLS forwarding.
net.ipv6.conf.all.forwarding=1
:makevar:`MPLS forwarding`
- Basic MPLS kernel support was introduced 4.1, additional capability
- was introduced in 4.3 and 4.5. For some general information on Linux
- MPLS support see
+ Basic MPLS support was introduced in the kernel in version 4.1 and
+ additional capability was introduced in 4.3 and 4.5.
+ For some general information on Linux MPLS support, see
https://www.netdevconf.org/1.1/proceedings/slides/prabhu-mpls-tutorial.pdf.
The following modules should be loaded to support MPLS forwarding,
and are generally added to a configuration file such as
@@ -418,7 +418,7 @@ Additional kernel modules are also needed to support MPLS forwarding.
running these kernel versions, if unable to establish any VRF BGP
adjacencies, either downgrade to 4.13 or set
'net.ipv4.tcp_l3mdev_accept=1'. The fix for this issue is planned to be
- included in future kernel versions so upgrading your kernel may also
+ included in future kernel versions. So upgrading your kernel may also
address this issue.
@@ -440,7 +440,7 @@ the options you chose:
--enable-watchfrr \
...
-After configuring the software, you are ready to build and install it for your
+After configuring the software, you are ready to build and install it in your
system.
.. code-block:: shell
diff --git a/doc/user/sharp.rst b/doc/user/sharp.rst
index 8831c0159b..c2d32a718e 100644
--- a/doc/user/sharp.rst
+++ b/doc/user/sharp.rst
@@ -33,16 +33,20 @@ All sharp commands are under the enable node and preceeded by the ``sharp``
keyword. At present, no sharp commands will be preserved in the config.
.. index:: sharp install
-.. clicmd:: sharp install routes A.B.C.D nexthop <E.F.G.H|X:X::X:X> (1-1000000)
+.. clicmd:: sharp install routes A.B.C.D <nexthop <E.F.G.H|X:X::X:X>|nexthop-group NAME> (1-1000000) [instance (0-255)] [repeat (2-1000)]
Install up to 1,000,000 (one million) /32 routes starting at ``A.B.C.D``
with specified nexthop ``E.F.G.H`` or ``X:X::X:X``. The nexthop is
a ``NEXTHOP_TYPE_IPV4`` or ``NEXTHOP_TYPE_IPV6`` and must be reachable
- to be installed into the kernel. The routes are installed into zebra as
- ``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route
+ to be installed into the kernel. Alternatively a nexthop-group NAME
+ can be specified and used as the nexthops. The routes are installed into
+ zebra as ``ZEBRA_ROUTE_SHARP`` and can be used as part of a normal route
redistribution. Route installation time is noted in the debug
log. When zebra successfully installs a route into the kernel and SHARP
receives success notifications for all routes this is logged as well.
+ Instance (0-255) if specified causes the routes to be installed in a different
+ instance. If repeat is used then we will install/uninstall the routes the
+ number of times specified.
.. index:: sharp remove
.. clicmd:: sharp remove routes A.B.C.D (1-1000000)
diff --git a/isisd/isis_northbound.c b/isisd/isis_northbound.c
index a467282826..9c2bb1728e 100644
--- a/isisd/isis_northbound.c
+++ b/isisd/isis_northbound.c
@@ -1982,11 +1982,10 @@ static int lib_interface_isis_network_type_modify(enum nb_event event,
circuit = yang_dnode_get_entry(dnode, false);
if (!circuit)
break;
- if (circuit->circ_type == CIRCUIT_T_LOOPBACK
- || circuit->circ_type == CIRCUIT_T_UNKNOWN) {
+ if (circuit->circ_type == CIRCUIT_T_LOOPBACK) {
flog_warn(
EC_LIB_NB_CB_CONFIG_VALIDATE,
- "Cannot change network type on unknown or loopback interface");
+ "Cannot change network type on loopback interface");
return NB_ERR_VALIDATION;
}
if (net_type == CIRCUIT_T_BROADCAST
diff --git a/lib/mlag.c b/lib/mlag.c
new file mode 100644
index 0000000000..acdc662924
--- /dev/null
+++ b/lib/mlag.c
@@ -0,0 +1,41 @@
+/* mlag generic code.
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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.
+ *
+ * FRR 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 FRR; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include <zebra.h>
+
+#include <mlag.h>
+
+char *mlag_role2str(enum mlag_role role, char *buf, size_t size)
+{
+ switch (role) {
+ case MLAG_ROLE_NONE:
+ snprintf(buf, size, "NONE");
+ break;
+ case MLAG_ROLE_PRIMARY:
+ snprintf(buf, size, "PRIMARY");
+ break;
+ case MLAG_ROLE_SECONDARY:
+ snprintf(buf, size, "SECONDARY");
+ break;
+ }
+
+ return buf;
+}
diff --git a/lib/mlag.h b/lib/mlag.h
new file mode 100644
index 0000000000..73725ca3fd
--- /dev/null
+++ b/lib/mlag.h
@@ -0,0 +1,32 @@
+/* mlag header.
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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.
+ *
+ * FRR 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 FRR; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef __MLAG_H__
+#define __MLAG_H__
+
+enum mlag_role {
+ MLAG_ROLE_NONE,
+ MLAG_ROLE_PRIMARY,
+ MLAG_ROLE_SECONDARY
+};
+
+extern char *mlag_role2str(enum mlag_role role, char *buf, size_t size);
+#endif
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index acde0ead02..2b024ace93 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -79,8 +79,7 @@ void nb_cli_enqueue_change(struct vty *vty, const char *xpath,
int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...)
{
struct nb_config *candidate_transitory;
- char xpath_base[XPATH_MAXLEN];
- va_list ap;
+ char xpath_base[XPATH_MAXLEN] = {};
bool error = false;
int ret;
@@ -94,9 +93,13 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...)
candidate_transitory = nb_config_dup(vty->candidate_config);
/* Parse the base XPath format string. */
- va_start(ap, xpath_base_fmt);
- vsnprintf(xpath_base, sizeof(xpath_base), xpath_base_fmt, ap);
- va_end(ap);
+ if (xpath_base_fmt) {
+ va_list ap;
+
+ va_start(ap, xpath_base_fmt);
+ vsnprintf(xpath_base, sizeof(xpath_base), xpath_base_fmt, ap);
+ va_end(ap);
+ }
/* Edit candidate configuration. */
for (size_t i = 0; i < vty->num_cfg_changes; i++) {
diff --git a/lib/northbound_cli.h b/lib/northbound_cli.h
index 362a4bc325..884f250941 100644
--- a/lib/northbound_cli.h
+++ b/lib/northbound_cli.h
@@ -60,7 +60,7 @@ extern void nb_cli_enqueue_change(struct vty *vty, const char *xpath,
*
* xpath_base_fmt
* Prepend the given XPath (absolute or relative) to all enqueued
- * configuration changes.
+ * configuration changes. This is an optional parameter.
*
* Returns:
* CMD_SUCCESS on success, CMD_WARNING_CONFIG_FAILED otherwise.
diff --git a/lib/subdir.am b/lib/subdir.am
index 43b39100cb..ccbe13bca6 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -44,6 +44,7 @@ lib_libfrr_la_SOURCES = \
lib/md5.c \
lib/memory.c \
lib/memory_vty.c \
+ lib/mlag.c \
lib/module.c \
lib/mpls.c \
lib/network.c \
@@ -134,6 +135,7 @@ pkginclude_HEADERS += \
lib/bitfield.h \
lib/buffer.h \
lib/checksum.h \
+ lib/mlag.h \
lib/command.h \
lib/command_graph.h \
lib/command_match.h \
diff --git a/lib/zclient.c b/lib/zclient.c
index beb3ca4f34..1c40750db0 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1770,19 +1770,19 @@ struct interface *zebra_interface_vrf_update_read(struct stream *s,
vrf_id_t vrf_id,
vrf_id_t *new_vrf_id)
{
- unsigned int ifindex;
+ char ifname[INTERFACE_NAMSIZ];
struct interface *ifp;
vrf_id_t new_id;
- /* Get interface index. */
- ifindex = stream_getl(s);
+ /* Read interface name. */
+ stream_get(ifname, s, INTERFACE_NAMSIZ);
/* Lookup interface. */
- ifp = if_lookup_by_index(ifindex, vrf_id);
+ ifp = if_lookup_by_name(ifname, vrf_id);
if (ifp == NULL) {
flog_err(EC_LIB_ZAPI_ENCODE,
- "INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
- ifindex, vrf_id);
+ "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
+ ifname, vrf_id);
return NULL;
}
@@ -2355,6 +2355,7 @@ static void zclient_capability_decode(int command, struct zclient *zclient,
STREAM_GETC(s, mpls_enabled);
cap.mpls_enabled = !!mpls_enabled;
STREAM_GETL(s, cap.ecmp);
+ STREAM_GETC(s, cap.role);
if (zclient->zebra_capabilities)
(*zclient->zebra_capabilities)(&cap);
diff --git a/lib/zclient.h b/lib/zclient.h
index 8fe711f310..831cccfb7e 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -36,6 +36,8 @@
/* For union pw_protocol_fields */
#include "pw.h"
+#include "mlag.h"
+
/* For input/output buffer to zebra. */
#define ZEBRA_MAX_PACKET_SIZ 16384
@@ -171,6 +173,7 @@ struct redist_proto {
struct zclient_capabilities {
uint32_t ecmp;
bool mpls_enabled;
+ enum mlag_role role;
};
/* Structure for the zebra client. */
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c
index 3f863ebeca..0a450834e3 100644
--- a/pimd/pim_assert.c
+++ b/pimd/pim_assert.c
@@ -569,7 +569,7 @@ static void pim_assert_timer_set(struct pim_ifchannel *ch, int interval)
ch->interface->name);
}
- thread_add_timer(master, on_assert_timer, ch, interval,
+ thread_add_timer(router->master, on_assert_timer, ch, interval,
&ch->t_ifassert_timer);
}
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 26932eea20..7089e21513 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -2646,7 +2646,7 @@ static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
if (json) {
json_object_int_add(json, "rpfCacheRefreshDelayMsecs",
- qpim_rpf_cache_refresh_delay_msec);
+ router->rpf_cache_refresh_delay_msec);
json_object_int_add(
json, "rpfCacheRefreshTimer",
pim_time_timer_remain_msec(pim->rpf_cache_refresher));
@@ -2669,7 +2669,7 @@ static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
"RPF Cache Refresh Last: %s\n"
"Nexthop Lookups: %lld\n"
"Nexthop Lookups Avoided: %lld\n",
- qpim_rpf_cache_refresh_delay_msec,
+ router->rpf_cache_refresh_delay_msec,
pim_time_timer_remain_msec(pim->rpf_cache_refresher),
(long long)pim->rpf_cache_refresh_requests,
(long long)pim->rpf_cache_refresh_events,
@@ -4408,9 +4408,12 @@ static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
struct vrf *vrf = pim->vrf;
time_t now = pim_time_monotonic_sec();
char uptime[10];
+ char mlag_role[80];
pim = vrf->info;
+ vty_out(vty, "Router MLAG Role: %s\n",
+ mlag_role2str(router->role, mlag_role, sizeof(mlag_role)));
vty_out(vty, "Mroute socket descriptor:");
vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
@@ -4428,7 +4431,7 @@ static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim,
vty_out(vty, "Maximum highest VifIndex: %d\n", PIM_MAX_USABLE_VIFS);
vty_out(vty, "\n");
- vty_out(vty, "Upstream Join Timer: %d secs\n", qpim_t_periodic);
+ vty_out(vty, "Upstream Join Timer: %d secs\n", router->t_periodic);
vty_out(vty, "Join/Prune Holdtime: %d secs\n", PIM_JP_HOLDTIME);
vty_out(vty, "PIM ECMP: %s\n", pim->ecmp_enable ? "Enable" : "Disable");
vty_out(vty, "PIM ECMP Rebalance: %s\n",
@@ -5229,7 +5232,7 @@ DEFUN (ip_pim_joinprune_time,
"Seconds\n")
{
PIM_DECLVAR_CONTEXT(vrf, pim);
- qpim_t_periodic = atoi(argv[3]->arg);
+ router->t_periodic = atoi(argv[3]->arg);
return CMD_SUCCESS;
}
@@ -5243,7 +5246,7 @@ DEFUN (no_ip_pim_joinprune_time,
"Seconds\n")
{
PIM_DECLVAR_CONTEXT(vrf, pim);
- qpim_t_periodic = PIM_DEFAULT_T_PERIODIC;
+ router->t_periodic = PIM_DEFAULT_T_PERIODIC;
return CMD_SUCCESS;
}
@@ -5256,7 +5259,7 @@ DEFUN (ip_pim_register_suppress,
"Seconds\n")
{
PIM_DECLVAR_CONTEXT(vrf, pim);
- qpim_register_suppress_time = atoi(argv[3]->arg);
+ router->register_suppress_time = atoi(argv[3]->arg);
return CMD_SUCCESS;
}
@@ -5270,7 +5273,7 @@ DEFUN (no_ip_pim_register_suppress,
"Seconds\n")
{
PIM_DECLVAR_CONTEXT(vrf, pim);
- qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
+ router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
return CMD_SUCCESS;
}
@@ -5339,7 +5342,7 @@ DEFUN (ip_pim_packets,
"Number of packets\n")
{
PIM_DECLVAR_CONTEXT(vrf, pim);
- qpim_packet_process = atoi(argv[3]->arg);
+ router->packet_process = atoi(argv[3]->arg);
return CMD_SUCCESS;
}
@@ -5353,7 +5356,7 @@ DEFUN (no_ip_pim_packets,
"Number of packets\n")
{
PIM_DECLVAR_CONTEXT(vrf, pim);
- qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
+ router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
return CMD_SUCCESS;
}
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 1ad71823b8..0451ab1e71 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1157,7 +1157,7 @@ long pim_if_t_suppressed_msec(struct interface *ifp)
/* t_suppressed = t_periodic * rand(1.1, 1.4) */
ramount = 1100 + (random() % (1400 - 1100 + 1));
- t_suppressed_msec = qpim_t_periodic * ramount;
+ t_suppressed_msec = router->t_periodic * ramount;
return t_suppressed_msec;
}
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 8f6a9ece53..14ce8d7d9f 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -415,7 +415,7 @@ void reset_ifassert_state(struct pim_ifchannel *ch)
THREAD_OFF(ch->t_ifassert_timer);
pim_ifassert_winner_set(ch, PIM_IFASSERT_NOINFO, any,
- qpim_infinite_assert_metric);
+ router->infinite_assert_metric);
}
struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
@@ -889,8 +889,8 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
}
if (holdtime != 0xFFFF) {
- thread_add_timer(master, on_ifjoin_expiry_timer, ch, holdtime,
- &ch->t_ifjoin_expiry_timer);
+ thread_add_timer(router->master, on_ifjoin_expiry_timer, ch,
+ holdtime, &ch->t_ifjoin_expiry_timer);
}
}
@@ -945,11 +945,12 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
THREAD_OFF(ch->t_ifjoin_expiry_timer);
thread_add_timer_msec(
- master, on_ifjoin_prune_pending_timer, ch,
- jp_override_interval_msec,
+ router->master, on_ifjoin_prune_pending_timer,
+ ch, jp_override_interval_msec,
&ch->t_ifjoin_prune_pending_timer);
- thread_add_timer(master, on_ifjoin_expiry_timer, ch,
- holdtime, &ch->t_ifjoin_expiry_timer);
+ thread_add_timer(router->master, on_ifjoin_expiry_timer,
+ ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
pim_upstream_update_join_desired(pim_ifp->pim,
ch->upstream);
}
@@ -973,31 +974,35 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
be taken not to use "ch" afterwards since it would be
deleted. */
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- thread_add_timer_msec(master, on_ifjoin_prune_pending_timer, ch,
+ thread_add_timer_msec(router->master,
+ on_ifjoin_prune_pending_timer, ch,
jp_override_interval_msec,
&ch->t_ifjoin_prune_pending_timer);
break;
case PIM_IFJOIN_PRUNE:
if (source_flags & PIM_ENCODE_RPT_BIT) {
THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
- thread_add_timer(master, on_ifjoin_expiry_timer, ch,
- holdtime, &ch->t_ifjoin_expiry_timer);
+ thread_add_timer(router->master, on_ifjoin_expiry_timer,
+ ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
case PIM_IFJOIN_PRUNE_TMP:
if (source_flags & PIM_ENCODE_RPT_BIT) {
ch->ifjoin_state = PIM_IFJOIN_PRUNE;
THREAD_OFF(ch->t_ifjoin_expiry_timer);
- thread_add_timer(master, on_ifjoin_expiry_timer, ch,
- holdtime, &ch->t_ifjoin_expiry_timer);
+ thread_add_timer(router->master, on_ifjoin_expiry_timer,
+ ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
case PIM_IFJOIN_PRUNE_PENDING_TMP:
if (source_flags & PIM_ENCODE_RPT_BIT) {
ch->ifjoin_state = PIM_IFJOIN_PRUNE_PENDING;
THREAD_OFF(ch->t_ifjoin_expiry_timer);
- thread_add_timer(master, on_ifjoin_expiry_timer, ch,
- holdtime, &ch->t_ifjoin_expiry_timer);
+ thread_add_timer(router->master, on_ifjoin_expiry_timer,
+ ch, holdtime,
+ &ch->t_ifjoin_expiry_timer);
}
break;
}
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 7a19d25a7b..cdd156b96f 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -250,8 +250,8 @@ void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp)
other_querier_present_interval_msec % 1000);
}
- thread_add_timer_msec(master, pim_igmp_other_querier_expire, igmp,
- other_querier_present_interval_msec,
+ thread_add_timer_msec(router->master, pim_igmp_other_querier_expire,
+ igmp, other_querier_present_interval_msec,
&igmp->t_other_querier_timer);
}
@@ -603,8 +603,8 @@ void pim_igmp_general_query_on(struct igmp_sock *igmp)
startup_mode ? "startup" : "non-startup", igmp->fd);
}
igmp->t_igmp_query_timer = NULL;
- thread_add_timer(master, pim_igmp_general_query, igmp, query_interval,
- &igmp->t_igmp_query_timer);
+ thread_add_timer(router->master, pim_igmp_general_query, igmp,
+ query_interval, &igmp->t_igmp_query_timer);
}
void pim_igmp_general_query_off(struct igmp_sock *igmp)
@@ -940,7 +940,7 @@ static void igmp_read_on(struct igmp_sock *igmp)
igmp->fd);
}
igmp->t_igmp_read = NULL;
- thread_add_read(master, pim_igmp_read, igmp, igmp->fd,
+ thread_add_read(router->master, pim_igmp_read, igmp, igmp->fd,
&igmp->t_igmp_read);
}
@@ -1067,8 +1067,8 @@ void igmp_group_timer_on(struct igmp_group *group, long interval_msec,
*/
zassert(group->group_filtermode_isexcl);
- thread_add_timer_msec(master, igmp_group_timer, group, interval_msec,
- &group->t_group_timer);
+ thread_add_timer_msec(router->master, igmp_group_timer, group,
+ interval_msec, &group->t_group_timer);
}
struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 430cba76b0..b845f54f06 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -214,8 +214,8 @@ static void igmp_source_timer_on(struct igmp_group *group,
source_str, group->group_igmp_sock->interface->name);
}
- thread_add_timer_msec(master, igmp_source_timer, source, interval_msec,
- &source->t_source_timer);
+ thread_add_timer_msec(router->master, igmp_source_timer, source,
+ interval_msec, &source->t_source_timer);
/*
RFC 3376: 6.3. IGMPv3 Source-Specific Forwarding Rules
@@ -1294,7 +1294,8 @@ static void group_retransmit_timer_on(struct igmp_group *group)
igmp->interface->name);
}
- thread_add_timer_msec(master, igmp_group_retransmit, group, lmqi_msec,
+ thread_add_timer_msec(router->master, igmp_group_retransmit, group,
+ lmqi_msec,
&group->t_group_query_retransmit_timer);
}
diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c
index b0d7a7b2db..092a2d76fa 100644
--- a/pimd/pim_instance.c
+++ b/pimd/pim_instance.c
@@ -85,7 +85,7 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
pim->spt.switchover = PIM_SPT_IMMEDIATE;
pim->spt.plist = NULL;
- pim_msdp_init(pim, master);
+ pim_msdp_init(pim, router->master);
snprintf(hash_name, 64, "PIM %s RPF Hash", vrf->name);
pim->rpf_hash = hash_create_size(256, pim_rpf_hash_key, pim_rpf_equal,
@@ -101,9 +101,6 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
pim->send_v6_secondary = 1;
- if (vrf->vrf_id == VRF_DEFAULT)
- pimg = pim;
-
pim_rp_init(pim);
pim_oil_init(pim);
@@ -132,9 +129,6 @@ static int pim_vrf_new(struct vrf *vrf)
vrf->info = (void *)pim;
- if (vrf->vrf_id == VRF_DEFAULT)
- pimg = pim;
-
pim_ssmpingd_init(pim);
return 0;
}
diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h
index b447075e9a..e651356bfe 100644
--- a/pimd/pim_instance.h
+++ b/pimd/pim_instance.h
@@ -21,8 +21,11 @@
#ifndef __PIM_INSTANCE_H__
#define __PIM_INSTANCE_H__
+#include <mlag.h>
+
#include "pim_str.h"
#include "pim_msdp.h"
+#include "pim_assert.h"
#if defined(HAVE_LINUX_MROUTE_H)
#include <linux/mroute.h>
@@ -35,13 +38,32 @@
#define MAXVIFS (256)
#endif
#endif
-extern struct pim_instance *pimg; // Pim Global Instance
enum pim_spt_switchover {
PIM_SPT_IMMEDIATE,
PIM_SPT_INFINITY,
};
+struct pim_router {
+ struct thread_master *master;
+
+ uint32_t debugs;
+
+ int t_periodic;
+ struct pim_assert_metric infinite_assert_metric;
+ long rpf_cache_refresh_delay_msec;
+ int32_t register_suppress_time;
+ int packet_process;
+ int32_t register_probe_time;
+
+ /*
+ * What is the default vrf that we work in
+ */
+ vrf_id_t vrf_id;
+
+ enum mlag_role role;
+};
+
/* Per VRF PIM DB */
struct pim_instance {
vrf_id_t vrf_id;
diff --git a/pimd/pim_macro.c b/pimd/pim_macro.c
index 13f4240dba..908026ab14 100644
--- a/pimd/pim_macro.c
+++ b/pimd/pim_macro.c
@@ -295,7 +295,7 @@ pim_macro_ch_my_assert_metric_eval(const struct pim_ifchannel *ch)
}
}
- return qpim_infinite_assert_metric;
+ return router->infinite_assert_metric;
}
/*
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index 50ebc4003e..dc42899c7b 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -109,7 +109,7 @@ int main(int argc, char **argv, char **envp)
}
}
- master = frr_init();
+ pim_router_init();
/*
* Initializations
@@ -157,7 +157,7 @@ int main(int argc, char **argv, char **envp)
"PIM_UNEXPECTED_KERNEL_UPCALL: report unexpected kernel upcall");
#endif
- frr_run(master);
+ frr_run(router->master);
/* never reached */
return 0;
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index dc4c4402a1..dd9e21cae8 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -708,7 +708,7 @@ static int mroute_read(struct thread *t)
result = pim_mroute_msg(pim, buf, rd, ifindex);
count++;
- if (count % qpim_packet_process == 0)
+ if (count % router->packet_process == 0)
cont = 0;
}
/* Keep reading */
@@ -720,7 +720,7 @@ done:
static void mroute_read_on(struct pim_instance *pim)
{
- thread_add_read(master, mroute_read, pim, pim->mroute_socket,
+ thread_add_read(router->master, mroute_read, pim, pim->mroute_socket,
&pim->thread);
}
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 7e072e6ade..a4f87fa1a6 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -1523,8 +1523,8 @@ enum pim_msdp_err pim_msdp_mg_src_add(struct pim_instance *pim,
}
/*********************** MSDP feature APIs *********************************/
-int pim_msdp_config_write_helper(struct pim_instance *pim, struct vty *vty,
- const char *spaces)
+int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
+ const char *spaces)
{
struct listnode *mbrnode;
struct pim_msdp_mg_mbr *mbr;
@@ -1553,11 +1553,6 @@ int pim_msdp_config_write_helper(struct pim_instance *pim, struct vty *vty,
return count;
}
-int pim_msdp_config_write(struct vty *vty)
-{
- return pim_msdp_config_write_helper(pimg, vty, "");
-}
-
/* 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 8363d50991..6caa3181e7 100644
--- a/pimd/pim_msdp.h
+++ b/pimd/pim_msdp.h
@@ -232,9 +232,8 @@ void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str);
int pim_msdp_write(struct thread *thread);
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 vty *vty);
-int pim_msdp_config_write_helper(struct pim_instance *pim, struct vty *vty,
- const char *spaces);
+int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
+ 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_msdp_socket.c b/pimd/pim_msdp_socket.c
index 7997d3138a..b1f7cfd2c6 100644
--- a/pimd/pim_msdp_socket.c
+++ b/pimd/pim_msdp_socket.c
@@ -79,7 +79,7 @@ static int pim_msdp_sock_accept(struct thread *thread)
return -1;
}
pim->msdp.listener.thread = NULL;
- thread_add_read(master, pim_msdp_sock_accept, pim, accept_sock,
+ thread_add_read(router->master, pim_msdp_sock_accept, pim, accept_sock,
&pim->msdp.listener.thread);
/* accept client connection. */
diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c
index f402629653..436f2dec27 100644
--- a/pimd/pim_neighbor.c
+++ b/pimd/pim_neighbor.c
@@ -255,8 +255,8 @@ void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime)
neigh->interface->name);
}
- thread_add_timer(master, on_neighbor_timer, neigh, neigh->holdtime,
- &neigh->t_expire_timer);
+ thread_add_timer(router->master, on_neighbor_timer, neigh,
+ neigh->holdtime, &neigh->t_expire_timer);
}
static int on_neighbor_jp_timer(struct thread *t)
@@ -277,8 +277,8 @@ static int on_neighbor_jp_timer(struct thread *t)
rpf.rpf_addr.u.prefix4 = neigh->source_addr;
pim_joinprune_send(&rpf, neigh->upstream_jp_agg);
- thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic,
- &neigh->jp_timer);
+ thread_add_timer(router->master, on_neighbor_jp_timer, neigh,
+ router->t_periodic, &neigh->jp_timer);
return 0;
}
@@ -286,8 +286,8 @@ static int on_neighbor_jp_timer(struct thread *t)
static void pim_neighbor_start_jp_timer(struct pim_neighbor *neigh)
{
THREAD_TIMER_OFF(neigh->jp_timer);
- thread_add_timer(master, on_neighbor_jp_timer, neigh, qpim_t_periodic,
- &neigh->jp_timer);
+ thread_add_timer(router->master, on_neighbor_jp_timer, neigh,
+ router->t_periodic, &neigh->jp_timer);
}
static struct pim_neighbor *
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index 0696a680e7..71b0d47928 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -346,7 +346,7 @@ static int pim_sock_read(struct thread *t)
}
count++;
- if (count % qpim_packet_process == 0)
+ if (count % router->packet_process == 0)
cont = 0;
}
@@ -376,8 +376,8 @@ static void pim_sock_read_on(struct interface *ifp)
pim_ifp->pim_sock_fd);
}
pim_ifp->t_pim_sock_read = NULL;
- thread_add_read(master, pim_sock_read, ifp, pim_ifp->pim_sock_fd,
- &pim_ifp->t_pim_sock_read);
+ thread_add_read(router->master, pim_sock_read, ifp,
+ pim_ifp->pim_sock_fd, &pim_ifp->t_pim_sock_read);
}
static int pim_sock_open(struct interface *ifp)
@@ -683,7 +683,7 @@ static void hello_resched(struct interface *ifp)
pim_ifp->pim_hello_period, ifp->name);
}
THREAD_OFF(pim_ifp->t_pim_hello_timer);
- thread_add_timer(master, on_pim_hello_send, ifp,
+ thread_add_timer(router->master, on_pim_hello_send, ifp,
pim_ifp->pim_hello_period,
&pim_ifp->t_pim_hello_timer);
}
@@ -796,8 +796,8 @@ void pim_hello_restart_triggered(struct interface *ifp)
random_msec, ifp->name);
}
- thread_add_timer_msec(master, on_pim_hello_send, ifp, random_msec,
- &pim_ifp->t_pim_hello_timer);
+ thread_add_timer_msec(router->master, on_pim_hello_send, ifp,
+ random_msec, &pim_ifp->t_pim_hello_timer);
}
int pim_sock_add(struct interface *ifp)
diff --git a/pimd/pim_ssmpingd.c b/pimd/pim_ssmpingd.c
index c3d958428c..17bc375c12 100644
--- a/pimd/pim_ssmpingd.c
+++ b/pimd/pim_ssmpingd.c
@@ -339,7 +339,7 @@ static int ssmpingd_sock_read(struct thread *t)
static void ssmpingd_read_on(struct ssmpingd_sock *ss)
{
- thread_add_read(master, ssmpingd_sock_read, ss, ss->sock_fd,
+ thread_add_read(router->master, ssmpingd_sock_read, ss, ss->sock_fd,
&ss->t_sock_read);
}
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index cd5b632ded..c6ab8f5a2a 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -308,7 +308,7 @@ void join_timer_start(struct pim_upstream *up)
if (PIM_DEBUG_PIM_EVENTS) {
zlog_debug(
"%s: starting %d sec timer for upstream (S,G)=%s",
- __PRETTY_FUNCTION__, qpim_t_periodic,
+ __PRETTY_FUNCTION__, router->t_periodic,
up->sg_str);
}
}
@@ -317,8 +317,8 @@ void join_timer_start(struct pim_upstream *up)
pim_jp_agg_add_group(nbr->upstream_jp_agg, up, 1);
else {
THREAD_OFF(up->t_join_timer);
- thread_add_timer(master, on_join_timer, up, qpim_t_periodic,
- &up->t_join_timer);
+ thread_add_timer(router->master, on_join_timer, up,
+ router->t_periodic, &up->t_join_timer);
}
pim_jp_agg_upstream_verification(up, true);
}
@@ -346,7 +346,7 @@ static void pim_upstream_join_timer_restart_msec(struct pim_upstream *up,
}
THREAD_OFF(up->t_join_timer);
- thread_add_timer_msec(master, on_join_timer, up, interval_msec,
+ thread_add_timer_msec(router->master, on_join_timer, up, interval_msec,
&up->t_join_timer);
}
@@ -647,9 +647,9 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4.s_addr =
PIM_NET_INADDR_ANY;
up->rpf.source_nexthop.mrib_metric_preference =
- qpim_infinite_assert_metric.metric_preference;
+ router->infinite_assert_metric.metric_preference;
up->rpf.source_nexthop.mrib_route_metric =
- qpim_infinite_assert_metric.route_metric;
+ router->infinite_assert_metric.route_metric;
up->rpf.rpf_addr.family = AF_INET;
up->rpf.rpf_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
@@ -1124,8 +1124,8 @@ void pim_upstream_keep_alive_timer_start(struct pim_upstream *up, uint32_t time)
up->sg_str);
}
THREAD_OFF(up->t_ka_timer);
- thread_add_timer(master, pim_upstream_keep_alive_timer, up, time,
- &up->t_ka_timer);
+ thread_add_timer(router->master, pim_upstream_keep_alive_timer, up,
+ time, &up->t_ka_timer);
/* any time keepalive is started against a SG we will have to
* re-evaluate our active source database */
@@ -1145,7 +1145,7 @@ static int pim_upstream_msdp_reg_timer(struct thread *t)
void pim_upstream_msdp_reg_timer_start(struct pim_upstream *up)
{
THREAD_OFF(up->t_msdp_reg_timer);
- thread_add_timer(master, pim_upstream_msdp_reg_timer, up,
+ thread_add_timer(router->master, pim_upstream_msdp_reg_timer, up,
PIM_MSDP_REG_RXED_PERIOD, &up->t_msdp_reg_timer);
pim_msdp_sa_local_update(up);
@@ -1406,8 +1406,8 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up,
"%s: (S,G)=%s Starting upstream register stop timer %d",
__PRETTY_FUNCTION__, up->sg_str, time);
}
- thread_add_timer(master, pim_upstream_register_stop_timer, up, time,
- &up->t_rs_timer);
+ thread_add_timer(router->master, pim_upstream_register_stop_timer, up,
+ time, &up->t_rs_timer);
}
int pim_upstream_inherited_olist_decide(struct pim_instance *pim,
@@ -1768,7 +1768,7 @@ void pim_upstream_init(struct pim_instance *pim)
snprintf(name, 64, "PIM %s Timer Wheel",
pim->vrf->name);
pim->upstream_sg_wheel =
- wheel_init(master, 31000, 100, pim_upstream_hash_key,
+ wheel_init(router->master, 31000, 100, pim_upstream_hash_key,
pim_upstream_sg_running, name);
snprintf(name, 64, "PIM %s Upstream Hash",
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index a347ab991c..f44b95c811 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -126,13 +126,14 @@ struct pim_upstream {
*/
struct thread *t_ka_timer;
#define PIM_KEEPALIVE_PERIOD (210)
-#define PIM_RP_KEEPALIVE_PERIOD ( 3 * qpim_register_suppress_time + qpim_register_probe_time )
+#define PIM_RP_KEEPALIVE_PERIOD \
+ (3 * router->register_suppress_time + router->register_probe_time)
/* on the RP we restart a timer to indicate if registers are being rxed
* for
* SG. This is needed by MSDP to determine its local SA cache */
struct thread *t_msdp_reg_timer;
-#define PIM_MSDP_REG_RXED_PERIOD (3 * (1.5 * qpim_register_suppress_time))
+#define PIM_MSDP_REG_RXED_PERIOD (3 * (1.5 * router->register_suppress_time))
int64_t state_transition; /* Record current state uptime */
};
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index a4aec710e9..f6385a0ac9 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -163,7 +163,7 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
else
sprintf(spaces, "%s", " ");
- writes += pim_msdp_config_write_helper(pim, vty, spaces);
+ writes += pim_msdp_config_write(pim, vty, spaces);
if (!pim->send_v6_secondary) {
vty_out(vty, "%sno ip pim send-v6-secondary\n", spaces);
@@ -172,15 +172,15 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
writes += pim_rp_config_write(pim, vty, spaces);
- if (qpim_register_suppress_time
+ if (router->register_suppress_time
!= PIM_REGISTER_SUPPRESSION_TIME_DEFAULT) {
vty_out(vty, "%sip pim register-suppress-time %d\n", spaces,
- qpim_register_suppress_time);
+ router->register_suppress_time);
++writes;
}
- if (qpim_t_periodic != PIM_DEFAULT_T_PERIODIC) {
+ if (router->t_periodic != PIM_DEFAULT_T_PERIODIC) {
vty_out(vty, "%sip pim join-prune-interval %d\n", spaces,
- qpim_t_periodic);
+ router->t_periodic);
++writes;
}
if (pim->keep_alive_time != PIM_KEEPALIVE_PERIOD) {
@@ -193,9 +193,9 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
pim->rp_keep_alive_time);
++writes;
}
- if (qpim_packet_process != PIM_DEFAULT_PACKET_PROCESS) {
+ if (router->packet_process != PIM_DEFAULT_PACKET_PROCESS) {
vty_out(vty, "%sip pim packets %d\n", spaces,
- qpim_packet_process);
+ router->packet_process);
++writes;
}
if (ssm->plist_name) {
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 10ea17cf1f..b7111cf7bf 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -727,11 +727,11 @@ void sched_rpf_cache_refresh(struct pim_instance *pim)
if (PIM_DEBUG_ZEBRA) {
zlog_debug("%s: triggering %ld msec timer", __PRETTY_FUNCTION__,
- qpim_rpf_cache_refresh_delay_msec);
+ router->rpf_cache_refresh_delay_msec);
}
- thread_add_timer_msec(master, on_rpf_cache_refresh, pim,
- qpim_rpf_cache_refresh_delay_msec,
+ thread_add_timer_msec(router->master, on_rpf_cache_refresh, pim,
+ router->rpf_cache_refresh_delay_msec,
&pim->rpf_cache_refresher);
}
@@ -740,14 +740,20 @@ static void pim_zebra_connected(struct zclient *zclient)
/* Send the client registration */
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
- zclient_send_reg_requests(zclient, pimg->vrf_id);
+ zclient_send_reg_requests(zclient, router->vrf_id);
+}
+
+static void pim_zebra_capabilities(struct zclient_capabilities *cap)
+{
+ router->role = cap->role;
}
void pim_zebra_init(void)
{
/* Socket for receiving updates from Zebra daemon */
- zclient = zclient_new(master, &zclient_options_default);
+ zclient = zclient_new(router->master, &zclient_options_default);
+ zclient->zebra_capabilities = pim_zebra_capabilities;
zclient->zebra_connected = pim_zebra_connected;
zclient->router_id_update = pim_router_id_update_zebra;
zclient->interface_add = pim_zebra_if_add;
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index 6b45313081..0ffe313c17 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -71,7 +71,7 @@ static int zclient_lookup_connect(struct thread *t)
/* Schedule connection with delay. */
static void zclient_lookup_sched(struct zclient *zlookup, int delay)
{
- thread_add_timer(master, zclient_lookup_connect, zlookup, delay,
+ thread_add_timer(router->master, zclient_lookup_connect, zlookup, delay,
&zlookup->t_connect);
zlog_notice("%s: zclient lookup connection scheduled for %d seconds",
@@ -81,7 +81,7 @@ static void zclient_lookup_sched(struct zclient *zlookup, int delay)
/* Schedule connection for now. */
static void zclient_lookup_sched_now(struct zclient *zlookup)
{
- thread_add_event(master, zclient_lookup_connect, zlookup, 0,
+ thread_add_event(router->master, zclient_lookup_connect, zlookup, 0,
&zlookup->t_connect);
zlog_notice("%s: zclient lookup immediate connection scheduled",
@@ -120,7 +120,7 @@ void zclient_lookup_free(void)
void zclient_lookup_new(void)
{
- zlookup = zclient_new(master, &zclient_options_default);
+ zlookup = zclient_new(router->master, &zclient_options_default);
if (!zlookup) {
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure",
__PRETTY_FUNCTION__);
diff --git a/pimd/pimd.c b/pimd/pimd.c
index 5d3018b2fd..b993bcdc03 100644
--- a/pimd/pimd.c
+++ b/pimd/pimd.c
@@ -47,17 +47,9 @@ const char *const PIM_ALL_ROUTERS = MCAST_ALL_ROUTERS;
const char *const PIM_ALL_PIM_ROUTERS = MCAST_ALL_PIM_ROUTERS;
const char *const PIM_ALL_IGMP_ROUTERS = MCAST_ALL_IGMP_ROUTERS;
-struct thread_master *master = NULL;
-uint32_t qpim_debugs = 0;
-int qpim_t_periodic =
- PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */
-struct pim_assert_metric qpim_infinite_assert_metric;
-long qpim_rpf_cache_refresh_delay_msec = 50;
-int qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS;
-struct pim_instance *pimg = NULL;
-
-int32_t qpim_register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
-int32_t qpim_register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT;
+DEFINE_MTYPE_STATIC(PIMD, ROUTER, "PIM Router information");
+
+struct pim_router *router = NULL;
void pim_prefix_list_update(struct prefix_list *plist)
{
@@ -82,17 +74,13 @@ static void pim_free()
zclient_lookup_free();
}
-void pim_init()
+void pim_router_init(void)
{
- if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) {
- flog_err(
- EC_LIB_SOCKET,
- "%s %s: could not solve %s to group address: errno=%d: %s",
- __FILE__, __PRETTY_FUNCTION__, PIM_ALL_PIM_ROUTERS,
- errno, safe_strerror(errno));
- zassert(0);
- return;
- }
+ router = XCALLOC(MTYPE_ROUTER, sizeof(*router));
+
+ router->debugs = 0;
+ router->master = frr_init();
+ router->t_periodic = PIM_DEFAULT_T_PERIODIC;
/*
RFC 4601: 4.6.3. Assert Metrics
@@ -102,11 +90,35 @@ void pim_init()
return {1,infinity,infinity,0}
}
*/
- qpim_infinite_assert_metric.rpt_bit_flag = 1;
- qpim_infinite_assert_metric.metric_preference =
+ router->infinite_assert_metric.rpt_bit_flag = 1;
+ router->infinite_assert_metric.metric_preference =
PIM_ASSERT_METRIC_PREFERENCE_MAX;
- qpim_infinite_assert_metric.route_metric = PIM_ASSERT_ROUTE_METRIC_MAX;
- qpim_infinite_assert_metric.ip_address.s_addr = INADDR_ANY;
+ router->infinite_assert_metric.route_metric =
+ PIM_ASSERT_ROUTE_METRIC_MAX;
+ router->infinite_assert_metric.ip_address.s_addr = INADDR_ANY;
+ router->rpf_cache_refresh_delay_msec = 50;
+ router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
+ router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
+ router->register_probe_time = PIM_REGISTER_PROBE_TIME_DEFAULT;
+ router->vrf_id = VRF_DEFAULT;
+}
+
+void pim_router_terminate(void)
+{
+ XFREE(MTYPE_ROUTER, router);
+}
+
+void pim_init(void)
+{
+ if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) {
+ flog_err(
+ EC_LIB_SOCKET,
+ "%s %s: could not solve %s to group address: errno=%d: %s",
+ __FILE__, __PRETTY_FUNCTION__, PIM_ALL_PIM_ROUTERS,
+ errno, safe_strerror(errno));
+ zassert(0);
+ return;
+ }
pim_cmd_init();
}
@@ -130,5 +142,6 @@ void pim_terminate()
zclient_free(zclient);
}
+ pim_router_terminate();
frr_fini();
}
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 1b11dc3f73..73ea9f82c4 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -132,110 +132,125 @@ const char *const PIM_ALL_ROUTERS;
const char *const PIM_ALL_PIM_ROUTERS;
const char *const PIM_ALL_IGMP_ROUTERS;
-extern struct thread_master *master;
+extern struct pim_router *router;
extern struct zebra_privs_t pimd_privs;
-uint32_t qpim_debugs;
struct in_addr qpim_all_pim_routers_addr;
-int qpim_t_periodic; /* Period between Join/Prune Messages */
-struct pim_assert_metric qpim_infinite_assert_metric;
-long qpim_rpf_cache_refresh_delay_msec;
-extern int qpim_packet_process;
extern uint8_t qpim_ecmp_enable;
extern uint8_t qpim_ecmp_rebalance_enable;
#define PIM_DEFAULT_PACKET_PROCESS 3
-#define PIM_JP_HOLDTIME (qpim_t_periodic * 7 / 2)
+#define PIM_JP_HOLDTIME (router->t_periodic * 7 / 2)
/*
* Register-Stop Timer (RST(S,G))
* Default values
*/
-extern int32_t qpim_register_suppress_time;
-extern int32_t qpim_register_probe_time;
#define PIM_REGISTER_SUPPRESSION_TIME_DEFAULT (60)
#define PIM_REGISTER_PROBE_TIME_DEFAULT (5)
-#define PIM_DEBUG_PIM_EVENTS (qpim_debugs & PIM_MASK_PIM_EVENTS)
-#define PIM_DEBUG_PIM_EVENTS_DETAIL (qpim_debugs & PIM_MASK_PIM_EVENTS_DETAIL)
-#define PIM_DEBUG_PIM_PACKETS (qpim_debugs & PIM_MASK_PIM_PACKETS)
-#define PIM_DEBUG_PIM_PACKETDUMP_SEND (qpim_debugs & PIM_MASK_PIM_PACKETDUMP_SEND)
-#define PIM_DEBUG_PIM_PACKETDUMP_RECV (qpim_debugs & PIM_MASK_PIM_PACKETDUMP_RECV)
-#define PIM_DEBUG_PIM_TRACE (qpim_debugs & PIM_MASK_PIM_TRACE)
-#define PIM_DEBUG_PIM_TRACE_DETAIL (qpim_debugs & PIM_MASK_PIM_TRACE_DETAIL)
-#define PIM_DEBUG_IGMP_EVENTS (qpim_debugs & PIM_MASK_IGMP_EVENTS)
-#define PIM_DEBUG_IGMP_PACKETS (qpim_debugs & PIM_MASK_IGMP_PACKETS)
-#define PIM_DEBUG_IGMP_TRACE (qpim_debugs & PIM_MASK_IGMP_TRACE)
-#define PIM_DEBUG_IGMP_TRACE_DETAIL (qpim_debugs & PIM_MASK_IGMP_TRACE_DETAIL)
-#define PIM_DEBUG_ZEBRA (qpim_debugs & PIM_MASK_ZEBRA)
-#define PIM_DEBUG_SSMPINGD (qpim_debugs & PIM_MASK_SSMPINGD)
-#define PIM_DEBUG_MROUTE (qpim_debugs & PIM_MASK_MROUTE)
-#define PIM_DEBUG_MROUTE_DETAIL (qpim_debugs & PIM_MASK_MROUTE_DETAIL)
-#define PIM_DEBUG_PIM_HELLO (qpim_debugs & PIM_MASK_PIM_HELLO)
-#define PIM_DEBUG_PIM_J_P (qpim_debugs & PIM_MASK_PIM_J_P)
-#define PIM_DEBUG_PIM_REG (qpim_debugs & PIM_MASK_PIM_REG)
-#define PIM_DEBUG_STATIC (qpim_debugs & PIM_MASK_STATIC)
-#define PIM_DEBUG_MSDP_EVENTS (qpim_debugs & PIM_MASK_MSDP_EVENTS)
-#define PIM_DEBUG_MSDP_PACKETS (qpim_debugs & PIM_MASK_MSDP_PACKETS)
-#define PIM_DEBUG_MSDP_INTERNAL (qpim_debugs & PIM_MASK_MSDP_INTERNAL)
-#define PIM_DEBUG_PIM_NHT (qpim_debugs & PIM_MASK_PIM_NHT)
-#define PIM_DEBUG_PIM_NHT_DETAIL (qpim_debugs & PIM_MASK_PIM_NHT_DETAIL)
-#define PIM_DEBUG_PIM_NHT_RP (qpim_debugs & PIM_MASK_PIM_NHT_RP)
-#define PIM_DEBUG_MTRACE (qpim_debugs & PIM_MASK_MTRACE)
-
-#define PIM_DEBUG_EVENTS (qpim_debugs & (PIM_MASK_PIM_EVENTS | PIM_MASK_IGMP_EVENTS | PIM_MASK_MSDP_EVENTS))
-#define PIM_DEBUG_PACKETS (qpim_debugs & (PIM_MASK_PIM_PACKETS | PIM_MASK_IGMP_PACKETS | PIM_MASK_MSDP_PACKETS))
-#define PIM_DEBUG_TRACE (qpim_debugs & (PIM_MASK_PIM_TRACE | PIM_MASK_IGMP_TRACE))
-
-#define PIM_DO_DEBUG_PIM_EVENTS (qpim_debugs |= PIM_MASK_PIM_EVENTS)
-#define PIM_DO_DEBUG_PIM_PACKETS (qpim_debugs |= PIM_MASK_PIM_PACKETS)
-#define PIM_DO_DEBUG_PIM_PACKETDUMP_SEND (qpim_debugs |= PIM_MASK_PIM_PACKETDUMP_SEND)
-#define PIM_DO_DEBUG_PIM_PACKETDUMP_RECV (qpim_debugs |= PIM_MASK_PIM_PACKETDUMP_RECV)
-#define PIM_DO_DEBUG_PIM_TRACE (qpim_debugs |= PIM_MASK_PIM_TRACE)
-#define PIM_DO_DEBUG_PIM_TRACE_DETAIL (qpim_debugs |= PIM_MASK_PIM_TRACE_DETAIL)
-#define PIM_DO_DEBUG_IGMP_EVENTS (qpim_debugs |= PIM_MASK_IGMP_EVENTS)
-#define PIM_DO_DEBUG_IGMP_PACKETS (qpim_debugs |= PIM_MASK_IGMP_PACKETS)
-#define PIM_DO_DEBUG_IGMP_TRACE (qpim_debugs |= PIM_MASK_IGMP_TRACE)
-#define PIM_DO_DEBUG_IGMP_TRACE_DETAIL (qpim_debugs |= PIM_MASK_IGMP_TRACE_DETAIL)
-#define PIM_DO_DEBUG_ZEBRA (qpim_debugs |= PIM_MASK_ZEBRA)
-#define PIM_DO_DEBUG_SSMPINGD (qpim_debugs |= PIM_MASK_SSMPINGD)
-#define PIM_DO_DEBUG_MROUTE (qpim_debugs |= PIM_MASK_MROUTE)
-#define PIM_DO_DEBUG_MROUTE_DETAIL (qpim_debugs |= PIM_MASK_MROUTE_DETAIL)
-#define PIM_DO_DEBUG_PIM_HELLO (qpim_debugs |= PIM_MASK_PIM_HELLO)
-#define PIM_DO_DEBUG_PIM_J_P (qpim_debugs |= PIM_MASK_PIM_J_P)
-#define PIM_DO_DEBUG_PIM_REG (qpim_debugs |= PIM_MASK_PIM_REG)
-#define PIM_DO_DEBUG_STATIC (qpim_debugs |= PIM_MASK_STATIC)
-#define PIM_DO_DEBUG_MSDP_EVENTS (qpim_debugs |= PIM_MASK_MSDP_EVENTS)
-#define PIM_DO_DEBUG_MSDP_PACKETS (qpim_debugs |= PIM_MASK_MSDP_PACKETS)
-#define PIM_DO_DEBUG_MSDP_INTERNAL (qpim_debugs |= PIM_MASK_MSDP_INTERNAL)
-#define PIM_DO_DEBUG_PIM_NHT (qpim_debugs |= PIM_MASK_PIM_NHT)
-#define PIM_DO_DEBUG_PIM_NHT_RP (qpim_debugs |= PIM_MASK_PIM_NHT_RP)
-#define PIM_DO_DEBUG_MTRACE (qpim_debugs |= PIM_MASK_MTRACE)
-
-#define PIM_DONT_DEBUG_PIM_EVENTS (qpim_debugs &= ~PIM_MASK_PIM_EVENTS)
-#define PIM_DONT_DEBUG_PIM_PACKETS (qpim_debugs &= ~PIM_MASK_PIM_PACKETS)
-#define PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND (qpim_debugs &= ~PIM_MASK_PIM_PACKETDUMP_SEND)
-#define PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV (qpim_debugs &= ~PIM_MASK_PIM_PACKETDUMP_RECV)
-#define PIM_DONT_DEBUG_PIM_TRACE (qpim_debugs &= ~PIM_MASK_PIM_TRACE)
-#define PIM_DONT_DEBUG_PIM_TRACE_DETAIL (qpim_debugs &= ~PIM_MASK_PIM_TRACE_DETAIL)
-#define PIM_DONT_DEBUG_IGMP_EVENTS (qpim_debugs &= ~PIM_MASK_IGMP_EVENTS)
-#define PIM_DONT_DEBUG_IGMP_PACKETS (qpim_debugs &= ~PIM_MASK_IGMP_PACKETS)
-#define PIM_DONT_DEBUG_IGMP_TRACE (qpim_debugs &= ~PIM_MASK_IGMP_TRACE)
-#define PIM_DONT_DEBUG_IGMP_TRACE_DETAIL (qpim_debugs &= ~PIM_MASK_IGMP_TRACE_DETAIL)
-#define PIM_DONT_DEBUG_ZEBRA (qpim_debugs &= ~PIM_MASK_ZEBRA)
-#define PIM_DONT_DEBUG_SSMPINGD (qpim_debugs &= ~PIM_MASK_SSMPINGD)
-#define PIM_DONT_DEBUG_MROUTE (qpim_debugs &= ~PIM_MASK_MROUTE)
-#define PIM_DONT_DEBUG_MROUTE_DETAIL (qpim_debugs &= ~PIM_MASK_MROUTE_DETAIL)
-#define PIM_DONT_DEBUG_PIM_HELLO (qpim_debugs &= ~PIM_MASK_PIM_HELLO)
-#define PIM_DONT_DEBUG_PIM_J_P (qpim_debugs &= ~PIM_MASK_PIM_J_P)
-#define PIM_DONT_DEBUG_PIM_REG (qpim_debugs &= ~PIM_MASK_PIM_REG)
-#define PIM_DONT_DEBUG_STATIC (qpim_debugs &= ~PIM_MASK_STATIC)
-#define PIM_DONT_DEBUG_MSDP_EVENTS (qpim_debugs &= ~PIM_MASK_MSDP_EVENTS)
-#define PIM_DONT_DEBUG_MSDP_PACKETS (qpim_debugs &= ~PIM_MASK_MSDP_PACKETS)
-#define PIM_DONT_DEBUG_MSDP_INTERNAL (qpim_debugs &= ~PIM_MASK_MSDP_INTERNAL)
-#define PIM_DONT_DEBUG_PIM_NHT (qpim_debugs &= ~PIM_MASK_PIM_NHT)
-#define PIM_DONT_DEBUG_PIM_NHT_RP (qpim_debugs &= ~PIM_MASK_PIM_NHT_RP)
-#define PIM_DONT_DEBUG_MTRACE (qpim_debugs &= ~PIM_MASK_MTRACE)
+#define PIM_DEBUG_PIM_EVENTS (router->debugs & PIM_MASK_PIM_EVENTS)
+#define PIM_DEBUG_PIM_EVENTS_DETAIL \
+ (router->debugs & PIM_MASK_PIM_EVENTS_DETAIL)
+#define PIM_DEBUG_PIM_PACKETS (router->debugs & PIM_MASK_PIM_PACKETS)
+#define PIM_DEBUG_PIM_PACKETDUMP_SEND \
+ (router->debugs & PIM_MASK_PIM_PACKETDUMP_SEND)
+#define PIM_DEBUG_PIM_PACKETDUMP_RECV \
+ (router->debugs & PIM_MASK_PIM_PACKETDUMP_RECV)
+#define PIM_DEBUG_PIM_TRACE (router->debugs & PIM_MASK_PIM_TRACE)
+#define PIM_DEBUG_PIM_TRACE_DETAIL (router->debugs & PIM_MASK_PIM_TRACE_DETAIL)
+#define PIM_DEBUG_IGMP_EVENTS (router->debugs & PIM_MASK_IGMP_EVENTS)
+#define PIM_DEBUG_IGMP_PACKETS (router->debugs & PIM_MASK_IGMP_PACKETS)
+#define PIM_DEBUG_IGMP_TRACE (router->debugs & PIM_MASK_IGMP_TRACE)
+#define PIM_DEBUG_IGMP_TRACE_DETAIL \
+ (router->debugs & PIM_MASK_IGMP_TRACE_DETAIL)
+#define PIM_DEBUG_ZEBRA (router->debugs & PIM_MASK_ZEBRA)
+#define PIM_DEBUG_SSMPINGD (router->debugs & PIM_MASK_SSMPINGD)
+#define PIM_DEBUG_MROUTE (router->debugs & PIM_MASK_MROUTE)
+#define PIM_DEBUG_MROUTE_DETAIL (router->debugs & PIM_MASK_MROUTE_DETAIL)
+#define PIM_DEBUG_PIM_HELLO (router->debugs & PIM_MASK_PIM_HELLO)
+#define PIM_DEBUG_PIM_J_P (router->debugs & PIM_MASK_PIM_J_P)
+#define PIM_DEBUG_PIM_REG (router->debugs & PIM_MASK_PIM_REG)
+#define PIM_DEBUG_STATIC (router->debugs & PIM_MASK_STATIC)
+#define PIM_DEBUG_MSDP_EVENTS (router->debugs & PIM_MASK_MSDP_EVENTS)
+#define PIM_DEBUG_MSDP_PACKETS (router->debugs & PIM_MASK_MSDP_PACKETS)
+#define PIM_DEBUG_MSDP_INTERNAL (router->debugs & PIM_MASK_MSDP_INTERNAL)
+#define PIM_DEBUG_PIM_NHT (router->debugs & PIM_MASK_PIM_NHT)
+#define PIM_DEBUG_PIM_NHT_DETAIL (router->debugs & PIM_MASK_PIM_NHT_DETAIL)
+#define PIM_DEBUG_PIM_NHT_RP (router->debugs & PIM_MASK_PIM_NHT_RP)
+#define PIM_DEBUG_MTRACE (router->debugs & PIM_MASK_MTRACE)
+
+#define PIM_DEBUG_EVENTS \
+ (router->debugs \
+ & (PIM_MASK_PIM_EVENTS | PIM_MASK_IGMP_EVENTS \
+ | PIM_MASK_MSDP_EVENTS))
+#define PIM_DEBUG_PACKETS \
+ (router->debugs \
+ & (PIM_MASK_PIM_PACKETS | PIM_MASK_IGMP_PACKETS \
+ | PIM_MASK_MSDP_PACKETS))
+#define PIM_DEBUG_TRACE \
+ (router->debugs & (PIM_MASK_PIM_TRACE | PIM_MASK_IGMP_TRACE))
+
+#define PIM_DO_DEBUG_PIM_EVENTS (router->debugs |= PIM_MASK_PIM_EVENTS)
+#define PIM_DO_DEBUG_PIM_PACKETS (router->debugs |= PIM_MASK_PIM_PACKETS)
+#define PIM_DO_DEBUG_PIM_PACKETDUMP_SEND \
+ (router->debugs |= PIM_MASK_PIM_PACKETDUMP_SEND)
+#define PIM_DO_DEBUG_PIM_PACKETDUMP_RECV \
+ (router->debugs |= PIM_MASK_PIM_PACKETDUMP_RECV)
+#define PIM_DO_DEBUG_PIM_TRACE (router->debugs |= PIM_MASK_PIM_TRACE)
+#define PIM_DO_DEBUG_PIM_TRACE_DETAIL \
+ (router->debugs |= PIM_MASK_PIM_TRACE_DETAIL)
+#define PIM_DO_DEBUG_IGMP_EVENTS (router->debugs |= PIM_MASK_IGMP_EVENTS)
+#define PIM_DO_DEBUG_IGMP_PACKETS (router->debugs |= PIM_MASK_IGMP_PACKETS)
+#define PIM_DO_DEBUG_IGMP_TRACE (router->debugs |= PIM_MASK_IGMP_TRACE)
+#define PIM_DO_DEBUG_IGMP_TRACE_DETAIL \
+ (router->debugs |= PIM_MASK_IGMP_TRACE_DETAIL)
+#define PIM_DO_DEBUG_ZEBRA (router->debugs |= PIM_MASK_ZEBRA)
+#define PIM_DO_DEBUG_SSMPINGD (router->debugs |= PIM_MASK_SSMPINGD)
+#define PIM_DO_DEBUG_MROUTE (router->debugs |= PIM_MASK_MROUTE)
+#define PIM_DO_DEBUG_MROUTE_DETAIL (router->debugs |= PIM_MASK_MROUTE_DETAIL)
+#define PIM_DO_DEBUG_PIM_HELLO (router->debugs |= PIM_MASK_PIM_HELLO)
+#define PIM_DO_DEBUG_PIM_J_P (router->debugs |= PIM_MASK_PIM_J_P)
+#define PIM_DO_DEBUG_PIM_REG (router->debugs |= PIM_MASK_PIM_REG)
+#define PIM_DO_DEBUG_STATIC (router->debugs |= PIM_MASK_STATIC)
+#define PIM_DO_DEBUG_MSDP_EVENTS (router->debugs |= PIM_MASK_MSDP_EVENTS)
+#define PIM_DO_DEBUG_MSDP_PACKETS (router->debugs |= PIM_MASK_MSDP_PACKETS)
+#define PIM_DO_DEBUG_MSDP_INTERNAL (router->debugs |= PIM_MASK_MSDP_INTERNAL)
+#define PIM_DO_DEBUG_PIM_NHT (router->debugs |= PIM_MASK_PIM_NHT)
+#define PIM_DO_DEBUG_PIM_NHT_RP (router->debugs |= PIM_MASK_PIM_NHT_RP)
+#define PIM_DO_DEBUG_MTRACE (router->debugs |= PIM_MASK_MTRACE)
+
+#define PIM_DONT_DEBUG_PIM_EVENTS (router->debugs &= ~PIM_MASK_PIM_EVENTS)
+#define PIM_DONT_DEBUG_PIM_PACKETS (router->debugs &= ~PIM_MASK_PIM_PACKETS)
+#define PIM_DONT_DEBUG_PIM_PACKETDUMP_SEND \
+ (router->debugs &= ~PIM_MASK_PIM_PACKETDUMP_SEND)
+#define PIM_DONT_DEBUG_PIM_PACKETDUMP_RECV \
+ (router->debugs &= ~PIM_MASK_PIM_PACKETDUMP_RECV)
+#define PIM_DONT_DEBUG_PIM_TRACE (router->debugs &= ~PIM_MASK_PIM_TRACE)
+#define PIM_DONT_DEBUG_PIM_TRACE_DETAIL \
+ (router->debugs &= ~PIM_MASK_PIM_TRACE_DETAIL)
+#define PIM_DONT_DEBUG_IGMP_EVENTS (router->debugs &= ~PIM_MASK_IGMP_EVENTS)
+#define PIM_DONT_DEBUG_IGMP_PACKETS (router->debugs &= ~PIM_MASK_IGMP_PACKETS)
+#define PIM_DONT_DEBUG_IGMP_TRACE (router->debugs &= ~PIM_MASK_IGMP_TRACE)
+#define PIM_DONT_DEBUG_IGMP_TRACE_DETAIL \
+ (router->debugs &= ~PIM_MASK_IGMP_TRACE_DETAIL)
+#define PIM_DONT_DEBUG_ZEBRA (router->debugs &= ~PIM_MASK_ZEBRA)
+#define PIM_DONT_DEBUG_SSMPINGD (router->debugs &= ~PIM_MASK_SSMPINGD)
+#define PIM_DONT_DEBUG_MROUTE (router->debugs &= ~PIM_MASK_MROUTE)
+#define PIM_DONT_DEBUG_MROUTE_DETAIL (router->debugs &= ~PIM_MASK_MROUTE_DETAIL)
+#define PIM_DONT_DEBUG_PIM_HELLO (router->debugs &= ~PIM_MASK_PIM_HELLO)
+#define PIM_DONT_DEBUG_PIM_J_P (router->debugs &= ~PIM_MASK_PIM_J_P)
+#define PIM_DONT_DEBUG_PIM_REG (router->debugs &= ~PIM_MASK_PIM_REG)
+#define PIM_DONT_DEBUG_STATIC (router->debugs &= ~PIM_MASK_STATIC)
+#define PIM_DONT_DEBUG_MSDP_EVENTS (router->debugs &= ~PIM_MASK_MSDP_EVENTS)
+#define PIM_DONT_DEBUG_MSDP_PACKETS (router->debugs &= ~PIM_MASK_MSDP_PACKETS)
+#define PIM_DONT_DEBUG_MSDP_INTERNAL (router->debugs &= ~PIM_MASK_MSDP_INTERNAL)
+#define PIM_DONT_DEBUG_PIM_NHT (router->debugs &= ~PIM_MASK_PIM_NHT)
+#define PIM_DONT_DEBUG_PIM_NHT_RP (router->debugs &= ~PIM_MASK_PIM_NHT_RP)
+#define PIM_DONT_DEBUG_MTRACE (router->debugs &= ~PIM_MASK_MTRACE)
+
+void pim_router_init(void);
+void pim_router_terminate(void);
void pim_init(void);
void pim_terminate(void);
diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c
index 20cdd21e7d..175a276089 100644
--- a/sharpd/sharp_main.c
+++ b/sharpd/sharp_main.c
@@ -42,6 +42,7 @@
#include "distribute.h"
#include "libfrr.h"
#include "routemap.h"
+#include "nexthop_group.h"
#include "sharp_zebra.h"
#include "sharp_vty.h"
@@ -150,6 +151,7 @@ int main(int argc, char **argv, char **envp)
master = frr_init();
+ nexthop_group_init(NULL, NULL, NULL, NULL);
vrf_init(NULL, NULL, NULL, NULL, NULL);
access_list_init();
diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c
index 797e336c2d..d0a34c0f93 100644
--- a/sharpd/sharp_vty.c
+++ b/sharpd/sharp_vty.c
@@ -28,6 +28,7 @@
#include "log.h"
#include "vrf.h"
#include "zclient.h"
+#include "nexthop_group.h"
#include "sharpd/sharp_zebra.h"
#include "sharpd/sharp_vty.h"
@@ -39,6 +40,14 @@ extern uint32_t total_routes;
extern uint32_t installed_routes;
extern uint32_t removed_routes;
+uint8_t inst;
+struct prefix prefix;
+struct prefix orig_prefix;
+struct nexthop nhop;
+struct nexthop_group nhop_group;
+uint32_t rts;
+int32_t repeat;
+
DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
"sharp watch nexthop X:X::X:X$nhop",
"Sharp routing Protocol\n"
@@ -81,7 +90,7 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
DEFPY (install_routes,
install_routes_cmd,
- "sharp install routes A.B.C.D$start nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6> (1-1000000)$routes [instance (0-255)$instance]",
+ "sharp install routes A.B.C.D$start <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
"Sharp routing Protocol\n"
"install some routes\n"
"Routes to install\n"
@@ -89,40 +98,57 @@ DEFPY (install_routes,
"Nexthop to use(Can be an IPv4 or IPv6 address)\n"
"V4 Nexthop address to use\n"
"V6 Nexthop address to use\n"
+ "Nexthop-Group to use\n"
+ "The Name of the nexthop-group\n"
"How many to create\n"
"Instance to use\n"
- "Instance\n")
+ "Instance\n"
+ "Should we repeat this command\n"
+ "How many times to repeat this command\n")
{
- int i;
- struct prefix p;
- struct nexthop nhop;
- uint32_t temp;
-
total_routes = routes;
installed_routes = 0;
- memset(&p, 0, sizeof(p));
- memset(&nhop, 0, sizeof(nhop));
-
- p.family = AF_INET;
- p.prefixlen = 32;
- p.u.prefix4 = start;
+ if (rpt >= 2)
+ repeat = rpt * 2;
+ else
+ repeat = 0;
- if (nexthop4.s_addr != INADDR_ANY) {
- nhop.gate.ipv4 = nexthop4;
- nhop.type = NEXTHOP_TYPE_IPV4;
+ memset(&prefix, 0, sizeof(prefix));
+ memset(&orig_prefix, 0, sizeof(orig_prefix));
+ memset(&nhop, 0, sizeof(nhop));
+ memset(&nhop_group, 0, sizeof(nhop_group));
+
+ prefix.family = AF_INET;
+ prefix.prefixlen = 32;
+ prefix.u.prefix4 = start;
+ orig_prefix = prefix;
+
+ if (nexthop_group) {
+ struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
+ if (!nhgc) {
+ vty_out(vty,
+ "Specified Nexthop Group: %s does not exist\n",
+ nexthop_group);
+ return CMD_WARNING;
+ }
+
+ nhop_group.nexthop = nhgc->nhg.nexthop;
} else {
- memcpy(&nhop.gate.ipv6, &nexthop6, IPV6_MAX_BYTELEN);
- nhop.type = NEXTHOP_TYPE_IPV6;
+ if (nexthop4.s_addr != INADDR_ANY) {
+ nhop.gate.ipv4 = nexthop4;
+ nhop.type = NEXTHOP_TYPE_IPV4;
+ } else {
+ nhop.gate.ipv6 = nexthop6;
+ nhop.type = NEXTHOP_TYPE_IPV6;
+ }
+
+ nhop_group.nexthop = &nhop;
}
- zlog_debug("Inserting %ld routes", routes);
-
- temp = ntohl(p.u.prefix4.s_addr);
- for (i = 0; i < routes; i++) {
- route_add(&p, (uint8_t)instance, &nhop);
- p.u.prefix4.s_addr = htonl(++temp);
- }
+ inst = instance;
+ rts = routes;
+ sharp_install_routes_helper(&prefix, inst, &nhop_group, rts);
return CMD_SUCCESS;
}
@@ -168,25 +194,18 @@ DEFPY (remove_routes,
"instance to use\n"
"Value of instance\n")
{
- int i;
- struct prefix p;
- uint32_t temp;
total_routes = routes;
removed_routes = 0;
- memset(&p, 0, sizeof(p));
+ memset(&prefix, 0, sizeof(prefix));
- p.family = AF_INET;
- p.prefixlen = 32;
- p.u.prefix4 = start;
+ prefix.family = AF_INET;
+ prefix.prefixlen = 32;
+ prefix.u.prefix4 = start;
- zlog_debug("Removing %ld routes", routes);
-
- temp = ntohl(p.u.prefix4.s_addr);
- for (i = 0; i < routes; i++) {
- route_delete(&p, (uint8_t)instance);
- p.u.prefix4.s_addr = htonl(++temp);
- }
+ inst = instance;
+ rts = routes;
+ sharp_remove_routes_helper(&prefix, inst, rts);
return CMD_SUCCESS;
}
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index f752009eb8..37591fa41f 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -34,6 +34,7 @@
#include "plist.h"
#include "log.h"
#include "nexthop.h"
+#include "nexthop_group.h"
#include "sharp_zebra.h"
@@ -131,6 +132,59 @@ static int interface_state_down(int command, struct zclient *zclient,
extern uint32_t total_routes;
extern uint32_t installed_routes;
extern uint32_t removed_routes;
+extern int32_t repeat;
+extern struct prefix orig_prefix;
+extern struct nexthop_group nhop_group;
+extern uint8_t inst;
+
+void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
+ struct nexthop_group *nhg,
+ uint32_t routes)
+{
+ uint32_t temp, i;
+
+ zlog_debug("Inserting %u routes", routes);
+
+ temp = ntohl(p->u.prefix4.s_addr);
+ for (i = 0; i < routes; i++) {
+ route_add(p, (uint8_t)instance, nhg);
+ p->u.prefix4.s_addr = htonl(++temp);
+ }
+}
+
+void sharp_remove_routes_helper(struct prefix *p, uint8_t instance,
+ uint32_t routes)
+{
+ uint32_t temp, i;
+
+ zlog_debug("Removing %u routes", routes);
+
+ temp = ntohl(p->u.prefix4.s_addr);
+ for (i = 0; i < routes; i++) {
+ route_delete(p, (uint8_t)instance);
+ p->u.prefix4.s_addr = htonl(++temp);
+ }
+}
+
+static void handle_repeated(bool installed)
+{
+ struct prefix p = orig_prefix;
+ repeat--;
+
+ if (repeat <= 0)
+ return;
+
+ if (installed) {
+ removed_routes = 0;
+ sharp_remove_routes_helper(&p, inst, total_routes);
+ }
+
+ if (!installed) {
+ installed_routes = 0;
+ sharp_install_routes_helper(&p, inst, &nhop_group,
+ total_routes);
+ }
+}
static int route_notify_owner(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
@@ -145,8 +199,10 @@ static int route_notify_owner(int command, struct zclient *zclient,
switch (note) {
case ZAPI_ROUTE_INSTALLED:
installed_routes++;
- if (total_routes == installed_routes)
+ if (total_routes == installed_routes) {
zlog_debug("Installed All Items");
+ handle_repeated(true);
+ }
break;
case ZAPI_ROUTE_FAIL_INSTALL:
zlog_debug("Failed install of route");
@@ -156,8 +212,10 @@ static int route_notify_owner(int command, struct zclient *zclient,
break;
case ZAPI_ROUTE_REMOVED:
removed_routes++;
- if (total_routes == removed_routes)
+ if (total_routes == removed_routes) {
zlog_debug("Removed all Items");
+ handle_repeated(false);
+ }
break;
case ZAPI_ROUTE_REMOVE_FAIL:
zlog_debug("Route removal Failure");
@@ -176,10 +234,12 @@ void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label)
zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
}
-void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh)
+void route_add(struct prefix *p, uint8_t instance, struct nexthop_group *nhg)
{
struct zapi_route api;
struct zapi_nexthop *api_nh;
+ struct nexthop *nh;
+ int i = 0;
memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT;
@@ -191,12 +251,35 @@ void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh)
SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
- api_nh = &api.nexthops[0];
- api_nh->vrf_id = VRF_DEFAULT;
- api_nh->gate = nh->gate;
- api_nh->type = nh->type;
- api_nh->ifindex = nh->ifindex;
- api.nexthop_num = 1;
+ for (ALL_NEXTHOPS_PTR(nhg, nh)) {
+ api_nh = &api.nexthops[i];
+ api_nh->vrf_id = VRF_DEFAULT;
+ api_nh->type = nh->type;
+ switch (nh->type) {
+ case NEXTHOP_TYPE_IPV4:
+ api_nh->gate = nh->gate;
+ break;
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ api_nh->gate = nh->gate;
+ api_nh->ifindex = nh->ifindex;
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ api_nh->ifindex = nh->ifindex;
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16);
+ break;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ api_nh->ifindex = nh->ifindex;
+ memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16);
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ api_nh->bh_type = nh->bh_type;
+ break;
+ }
+ i++;
+ }
+ api.nexthop_num = i;
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
}
diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h
index 58438ed01d..7326056cae 100644
--- a/sharpd/sharp_zebra.h
+++ b/sharpd/sharp_zebra.h
@@ -25,7 +25,14 @@
extern void sharp_zebra_init(void);
extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
-extern void route_add(struct prefix *p, uint8_t instance, struct nexthop *nh);
+extern void route_add(struct prefix *p, uint8_t instance,
+ struct nexthop_group *nhg);
extern void route_delete(struct prefix *p, uint8_t instance);
extern void sharp_zebra_nexthop_watch(struct prefix *p, bool watch);
+
+extern void sharp_install_routes_helper(struct prefix *p, uint8_t instance,
+ struct nexthop_group *nhg,
+ uint32_t routes);
+extern void sharp_remove_routes_helper(struct prefix *p, uint8_t instance,
+ uint32_t routes);
#endif
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf
index fc301e13d7..05eac758f1 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf
@@ -20,7 +20,7 @@ router bgp 5226
neighbor 2.2.2.2 activate
exit-address-family
!
- rfp holddown-factor 100
+ rfp holddown-factor 0
!
vnc defaults
rd auto:vn:123
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
index 0066f65a40..67b26e3a50 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
@@ -18,7 +18,7 @@ router bgp 5226
neighbor 2.2.2.2 activate
exit-address-family
!
- rfp holddown-factor 100
+ rfp holddown-factor 0
!
vnc defaults
rd auto:vn:123
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf
index 67c06506b5..2ba5c74e5b 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf
@@ -19,7 +19,7 @@ router bgp 5226
neighbor 2.2.2.2 activate
exit-address-family
!
- rfp holddown-factor 100
+ rfp holddown-factor 0
!
vnc defaults
rd auto:vn:123
diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf
index eb8d703a35..f7f5e2ee96 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf
@@ -20,7 +20,7 @@ router bgp 5226
neighbor 2.2.2.2 activate
exit-address-family
!
- rfp holddown-factor 100
+ rfp holddown-factor 0
rfp full-table-download off
!
vnc defaults
diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
index 61164c6948..17e351988d 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
@@ -18,7 +18,7 @@ router bgp 5226
neighbor 2.2.2.2 activate
exit-address-family
!
- rfp holddown-factor 100
+ rfp holddown-factor 0
rfp full-table-download off
!
vnc defaults
diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf
index 4294274d3d..0b8808cb80 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf
@@ -19,7 +19,7 @@ router bgp 5226
neighbor 2.2.2.2 activate
exit-address-family
!
- rfp holddown-factor 100
+ rfp holddown-factor 0
rfp full-table-download off
!
vnc defaults
diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
index 596f01738a..2b48f1f360 100755
--- a/vtysh/extract.pl.in
+++ b/vtysh/extract.pl.in
@@ -109,7 +109,7 @@ sub scan_file {
$protocol = "VTYSH_ZEBRA";
}
elsif ($file =~ /lib\/nexthop_group\.c$/) {
- $protocol = "VTYSH_PBRD";
+ $protocol = "VTYSH_PBRD | VTYSH_SHARPD";
}
elsif ($file =~ /lib\/plist\.c$/) {
if ($defun_array[1] =~ m/ipv6/) {
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 2327f2b46d..6cf45789dd 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -2110,7 +2110,7 @@ DEFSH(VTYSH_ZEBRA, vtysh_no_logicalrouter_cmd,
"The Name Space\n"
"The file name in " NS_RUN_DIR ", or a full pathname\n")
-DEFUNSH(VTYSH_PBRD, vtysh_nexthop_group, vtysh_nexthop_group_cmd,
+DEFUNSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_nexthop_group, vtysh_nexthop_group_cmd,
"nexthop-group NAME",
"Nexthop Group configuration\n"
"Name of the Nexthop Group\n")
@@ -2119,7 +2119,8 @@ DEFUNSH(VTYSH_PBRD, vtysh_nexthop_group, vtysh_nexthop_group_cmd,
return CMD_SUCCESS;
}
-DEFSH(VTYSH_PBRD, vtysh_no_nexthop_group_cmd, "no nexthop-group NAME",
+DEFSH(VTYSH_PBRD | VTYSH_SHARPD, vtysh_no_nexthop_group_cmd,
+ "no nexthop-group NAME",
NO_STR
"Nexthop Group Configuration\n"
"Name of the Nexthop Group\n")
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index f4bd193569..4e49c1fc58 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -399,7 +399,7 @@ static int get_iflink_speed(struct interface *interface)
(char *)&ifdata);
}
if (rc < 0) {
- if (IS_ZEBRA_DEBUG_KERNEL)
+ if (errno != EOPNOTSUPP && IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
"IOCTL failure to read interface %s speed: %d %s",
ifname, errno, safe_strerror(errno));
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index afc3985854..360f596b8f 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -784,7 +784,8 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
if (h->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
- zlog_err("%s error: message truncated",
+ flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
+ "%s error: message truncated",
nl->name);
return -1;
}
@@ -820,14 +821,6 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
continue;
}
- if (h->nlmsg_len
- < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
- flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
- "%s error: message truncated",
- nl->name);
- return -1;
- }
-
/* Deal with errors that occur because of races
* in link handling */
if (zns->is_cmd
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 3e46a79e96..84b06e579f 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -232,7 +232,9 @@ int dplane_routing_sock = -1;
/* Yes I'm checking ugly routing socket behavior. */
/* #define DEBUG */
+size_t _rta_get(caddr_t sap, void *destp, size_t destlen, bool checkaf);
size_t rta_get(caddr_t sap, void *dest, size_t destlen);
+size_t rta_getattr(caddr_t sap, void *destp, size_t destlen);
size_t rta_getsdlname(caddr_t sap, void *dest, short *destlen);
/* Supported address family check. */
@@ -245,9 +247,10 @@ static inline int af_check(int family)
return 0;
}
-size_t rta_get(caddr_t sap, void *destp, size_t destlen)
+size_t _rta_get(caddr_t sap, void *destp, size_t destlen, bool checkaf)
{
struct sockaddr *sa = (struct sockaddr *)sap;
+ struct sockaddr_dl *sdl;
uint8_t *dest = destp;
size_t tlen, copylen;
@@ -258,7 +261,21 @@ size_t rta_get(caddr_t sap, void *destp, size_t destlen)
copylen = tlen = SAROUNDUP(sap);
#endif /* !HAVE_STRUCT_SOCKADDR_SA_LEN */
- if (copylen > 0 && dest != NULL && af_check(sa->sa_family)) {
+ if (copylen > 0 && dest != NULL) {
+ if (checkaf && af_check(sa->sa_family) == 0)
+ return tlen;
+ /*
+ * Handle sockaddr_dl corner case:
+ * RTA_NETMASK might be AF_LINK, but it doesn't anything
+ * relevant (e.g. zeroed out fields). Check for this
+ * case and avoid warning log message.
+ */
+ if (sa->sa_family == AF_LINK) {
+ sdl = (struct sockaddr_dl *)sa;
+ if (sdl->sdl_index == 0 || sdl->sdl_nlen == 0)
+ copylen = sizeof(*sdl) - sizeof(sdl->sdl_data);
+ }
+
if (copylen > destlen) {
zlog_warn("%s: destination buffer too small (%lu vs %lu)",
__func__, copylen, destlen);
@@ -270,6 +287,16 @@ size_t rta_get(caddr_t sap, void *destp, size_t destlen)
return tlen;
}
+size_t rta_get(caddr_t sap, void *destp, size_t destlen)
+{
+ return _rta_get(sap, destp, destlen, true);
+}
+
+size_t rta_getattr(caddr_t sap, void *destp, size_t destlen)
+{
+ return _rta_get(sap, destp, destlen, false);
+}
+
size_t rta_getsdlname(caddr_t sap, void *destp, short *destlen)
{
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sap;
@@ -684,7 +711,7 @@ static void ifam_read_mesg(struct ifa_msghdr *ifm, union sockunion *addr,
pnt += rta_get(pnt, &gateway, sizeof(gateway));
break;
case RTA_NETMASK:
- pnt += rta_get(pnt, mask, sizeof(*mask));
+ pnt += rta_getattr(pnt, mask, sizeof(*mask));
break;
case RTA_IFP:
pnt += rta_getsdlname(pnt, ifname, ifnlen);
@@ -742,7 +769,7 @@ static void ifam_read_mesg(struct ifa_msghdr *ifm, union sockunion *addr,
/* Assert read up end point matches to end point */
pnt = (caddr_t)ROUNDUP((size_t)pnt);
- if (pnt != end)
+ if (pnt != (caddr_t)ROUNDUP((size_t)end))
zlog_debug("ifam_read() doesn't read all socket data");
}
diff --git a/zebra/subdir.am b/zebra/subdir.am
index b8f5e0d409..23c3cd4239 100644
--- a/zebra/subdir.am
+++ b/zebra/subdir.am
@@ -10,6 +10,7 @@ vtysh_scan += \
$(top_srcdir)/zebra/interface.c \
$(top_srcdir)/zebra/router-id.c \
$(top_srcdir)/zebra/rtadv.c \
+ $(top_srcdir)/zebra/zebra_mlag.c \
$(top_srcdir)/zebra/zebra_mpls_vty.c \
$(top_srcdir)/zebra/zebra_ptm.c \
$(top_srcdir)/zebra/zebra_pw.c \
@@ -64,6 +65,7 @@ zebra_zebra_SOURCES = \
zebra/rtread_sysctl.c \
zebra/rule_netlink.c \
zebra/rule_socket.c \
+ zebra/zebra_mlag.c \
zebra/zebra_l2.c \
zebra/zebra_memory.c \
zebra/zebra_dplane.c \
@@ -93,10 +95,12 @@ zebra_zebra_SOURCES = \
zebra/zebra_errors.c \
# end
+zebra/zebra_mlag_clippy.c: $(CLIPPY_DEPS)
+zebra/zebra_mlag.$(OBJEXT): zebra/zebra_mlag_clippy.c
+
zebra/zebra_vty_clippy.c: $(CLIPPY_DEPS)
zebra/zebra_vty.$(OBJEXT): zebra/zebra_vty_clippy.c
-
zebra/zebra_routemap_clippy.c: $(CLIPPY_DEPS)
zebra/zebra_routemap.$(OBJEXT): zebra/zebra_routemap_clippy.c
@@ -119,6 +123,7 @@ noinst_HEADERS += \
zebra/rt_netlink.h \
zebra/rtadv.h \
zebra/rule_netlink.h \
+ zebra/zebra_mlag.h \
zebra/zebra_fpm_private.h \
zebra/zebra_l2.h \
zebra/zebra_dplane.h \
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 26a3cd5b42..faa0eb90e4 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -63,6 +63,7 @@
#include "zebra/table_manager.h"
#include "zebra/zapi_msg.h"
#include "zebra/zebra_errors.h"
+#include "zebra/zebra_mlag.h"
/* Encoding helpers -------------------------------------------------------- */
@@ -432,8 +433,8 @@ int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp,
zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
- /* Fill in the ifIndex of the interface and its new VRF (id) */
- stream_putl(s, ifp->ifindex);
+ /* Fill in the name of the interface and its new VRF (id) */
+ stream_put(s, ifp->name, INTERFACE_NAMSIZ);
stream_putl(s, vrf_id);
/* Write packet size. */
@@ -1657,6 +1658,7 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
zclient_create_header(s, ZEBRA_CAPABILITIES, zvrf->vrf->vrf_id);
stream_putc(s, mpls_enabled);
stream_putl(s, multipath_num);
+ stream_putc(s, zebra_mlag_get_role());
stream_putw_at(s, 0, stream_get_endp(s));
zserv_send_message(client, s);
diff --git a/zebra/zebra_mlag.c b/zebra/zebra_mlag.c
new file mode 100644
index 0000000000..35be07c024
--- /dev/null
+++ b/zebra/zebra_mlag.c
@@ -0,0 +1,83 @@
+/* Zebra Mlag Code.
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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.
+ *
+ * FRR 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 FRR; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#include "zebra.h"
+
+#include "command.h"
+#include "hook.h"
+
+#include "zebra/zebra_mlag.h"
+
+#ifndef VTYSH_EXTRACT_PL
+#include "zebra/zebra_mlag_clippy.c"
+#endif
+
+enum mlag_role role = MLAG_ROLE_NONE;
+
+enum mlag_role zebra_mlag_get_role(void)
+{
+ return role;
+}
+
+DEFUN_HIDDEN (show_mlag,
+ show_mlag_cmd,
+ "show zebra mlag",
+ SHOW_STR
+ ZEBRA_STR
+ "The mlag role on this machine\n")
+{
+ char buf[80];
+
+ vty_out(vty, "MLag is configured to: %s\n",
+ mlag_role2str(role, buf, sizeof(buf)));
+
+ return CMD_SUCCESS;
+}
+
+DEFPY_HIDDEN (test_mlag,
+ test_mlag_cmd,
+ "test zebra mlag <none$none|primary$primary|secondary$secondary>",
+ "Test code\n"
+ ZEBRA_STR
+ "Modify the Mlag state\n"
+ "Mlag is not setup on the machine\n"
+ "Mlag is setup to be primary\n"
+ "Mlag is setup to be the secondary\n")
+{
+ if (none)
+ role = MLAG_ROLE_NONE;
+ if (primary)
+ role = MLAG_ROLE_PRIMARY;
+ if (secondary)
+ role = MLAG_ROLE_SECONDARY;
+
+ return CMD_SUCCESS;
+}
+
+void zebra_mlag_init(void)
+{
+ install_element(VIEW_NODE, &show_mlag_cmd);
+ install_element(ENABLE_NODE, &test_mlag_cmd);
+}
+
+void zebra_mlag_terminate(void)
+{
+}
diff --git a/zebra/zebra_mlag.h b/zebra/zebra_mlag.h
new file mode 100644
index 0000000000..c5c147c833
--- /dev/null
+++ b/zebra/zebra_mlag.h
@@ -0,0 +1,31 @@
+/* Zebra mlag header.
+ * Copyright (C) 2018 Cumulus Networks, Inc.
+ * Donald Sharp
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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.
+ *
+ * FRR 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 FRR; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef __ZEBRA_MLAG_H__
+#define __ZEBRA_MLAG_H__
+
+#include "mlag.h"
+
+void zebra_mlag_init(void);
+void zebra_mlag_terminate(void);
+
+enum mlag_role zebra_mlag_get_role(void);
+#endif
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 9b86657f1b..03987fcb5b 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -73,6 +73,7 @@ static int zebra_ns_new(struct ns *ns)
zns = zebra_ns_alloc();
ns->info = zns;
zns->ns = ns;
+ zns->ns_id = ns->ns_id;
/* Do any needed per-NS data structure allocation. */
zns->if_table = route_table_init();
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 2e1c69fb92..ae18a0d290 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -25,6 +25,7 @@
#include "zebra_memory.h"
#include "zebra_pbr.h"
#include "zebra_vxlan.h"
+#include "zebra_mlag.h"
struct zebra_router zrouter;
@@ -159,6 +160,8 @@ void zebra_router_terminate(void)
}
zebra_vxlan_disable();
+ zebra_mlag_terminate();
+
hash_clean(zrouter.rules_hash, zebra_pbr_rules_free);
hash_free(zrouter.rules_hash);
@@ -173,6 +176,8 @@ void zebra_router_terminate(void)
void zebra_router_init(void)
{
zebra_vxlan_init();
+ zebra_mlag_init();
+
zrouter.rules_hash = hash_create_size(8, zebra_pbr_rules_hash_key,
zebra_pbr_rules_hash_equal,
"Rules Hash");
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 20dc64b0bc..b55ca60c00 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -412,7 +412,7 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
* this MAC update.
*/
if (zvrf->dad_freeze)
- *is_dup_detect = false;
+ *is_dup_detect = true;
return;
}
@@ -464,11 +464,6 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
if (is_local)
mac->dad_count++;
- zlog_debug("%s: MAC DAD %s dad_count %u ",
- __PRETTY_FUNCTION__,
- prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
- mac->dad_count);
-
if (mac->dad_count >= zvrf->dad_max_moves) {
flog_warn(EC_ZEBRA_DUP_MAC_DETECTED,
"VNI %u: MAC %s detected as duplicate during %s VTEP %s",
@@ -521,11 +516,11 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
&mac->dad_mac_auto_recovery_timer);
}
- /* Do not inform to client (BGPd),
+ /* In case of local update, do not inform to client (BGPd),
* upd_neigh for neigh sequence change.
*/
if (zvrf->dad_freeze)
- *is_dup_detect = false;
+ *is_dup_detect = true;
}
}
@@ -5176,11 +5171,11 @@ static void process_remote_macip_add(vni_t vni,
do_dad, &is_dup_detect,
false);
- zvni_process_neigh_on_remote_mac_add(zvni, mac);
-
- /* Install the entry. */
- if (!is_dup_detect)
+ if (!is_dup_detect) {
+ zvni_process_neigh_on_remote_mac_add(zvni, mac);
+ /* Install the entry. */
zvni_mac_install(zvni, mac);
+ }
}
/* Update seq number. */
@@ -6386,7 +6381,8 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
* to BGP. Similarly remote macip update, neigh needs to be
* installed locally.
*/
- if (nbr->dad_count) {
+ if (zvrf->dad_freeze &&
+ CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
ZEBRA_NEIGH_SET_INACTIVE(nbr);
else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))
@@ -6406,6 +6402,10 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
mac->dad_dup_detect_time = 0;
THREAD_OFF(mac->dad_mac_auto_recovery_timer);
+ /* warn-only action return */
+ if (!zvrf->dad_freeze)
+ return CMD_SUCCESS;
+
/* Local: Notify Peer VTEPs, Remote: Install the entry */
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
/* Inform to BGP */
@@ -7412,6 +7412,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
bool mac_sticky = false;
bool inform_client = false;
bool upd_neigh = false;
+ bool is_dup_detect = false;
struct in_addr vtep_ip = {.s_addr = 0};
/* We are interested in MACs only on ports or (port, VLAN) that
@@ -7559,8 +7560,12 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
zebra_vxlan_dup_addr_detect_for_mac(zvrf, mac, vtep_ip,
do_dad,
- &inform_client,
+ &is_dup_detect,
true);
+ if (is_dup_detect) {
+ inform_client = false;
+ upd_neigh = false;
+ }
}
}
@@ -8971,7 +8976,7 @@ static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t)
/* Remove all IPs as duplicate associcated with this MAC */
for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) {
- if (nbr->dad_count) {
+ if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL))
ZEBRA_NEIGH_SET_INACTIVE(nbr);
else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE))