summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_mplsvpn.c2
-rw-r--r--bgpd/bgp_routemap.c18
-rw-r--r--bgpd/bgp_vty.c54
-rw-r--r--bgpd/bgpd.c3
-rw-r--r--bgpd/bgpd.h80
-rw-r--r--doc/user/ospfd.rst20
-rw-r--r--doc/user/pim.rst2
-rw-r--r--doc/user/routemap.rst12
-rw-r--r--pimd/pim_assert.c99
-rw-r--r--pimd/pim_assert.h4
-rw-r--r--pimd/pim_bfd.c4
-rw-r--r--pimd/pim_bsm.c25
-rw-r--r--pimd/pim_cmd.c10
-rw-r--r--pimd/pim_hello.c168
-rw-r--r--pimd/pim_hello.h4
-rw-r--r--pimd/pim_iface.c111
-rw-r--r--pimd/pim_iface.h15
-rw-r--r--pimd/pim_ifchannel.c75
-rw-r--r--pimd/pim_ifchannel.h6
-rw-r--r--pimd/pim_join.c106
-rw-r--r--pimd/pim_jp_agg.c39
-rw-r--r--pimd/pim_macro.c8
-rw-r--r--pimd/pim_msg.c88
-rw-r--r--pimd/pim_msg.h57
-rw-r--r--pimd/pim_neighbor.c137
-rw-r--r--pimd/pim_neighbor.h6
-rw-r--r--pimd/pim_nht.c40
-rw-r--r--pimd/pim_pim.c2
-rw-r--r--pimd/pim_pim.h4
-rw-r--r--pimd/pim_register.c23
-rw-r--r--pimd/pim_rp.c97
-rw-r--r--pimd/pim_rp.h8
-rw-r--r--pimd/pim_rpf.c26
-rw-r--r--pimd/pim_ssm.c9
-rw-r--r--pimd/pim_ssm.h2
-rw-r--r--pimd/pim_tlv.c228
-rw-r--r--pimd/pim_tlv.h20
-rw-r--r--pimd/pim_upstream.c43
-rw-r--r--pimd/pim_util.c8
-rw-r--r--pimd/pim_util.h2
-rw-r--r--pimd/pim_vty.c10
-rw-r--r--pimd/pim_vxlan.c4
-rw-r--r--pimd/pim_zebra.c46
-rw-r--r--pimd/pim_zlookup.c6
-rw-r--r--pimd/pimd.c14
-rw-r--r--pimd/pimd.h2
-rw-r--r--ripd/ripd.c1
-rw-r--r--staticd/static_main.c2
-rw-r--r--staticd/static_nb_config.c9
-rw-r--r--staticd/static_routes.h1
-rw-r--r--staticd/static_zebra.c5
-rw-r--r--tests/topotests/bgp_route_map/test_route_map_topo1.py21
-rw-r--r--tests/topotests/lib/micronet.py5
-rw-r--r--tests/topotests/lib/micronet_cli.py6
-rw-r--r--tests/topotests/lib/topotest.py4
-rwxr-xr-xtests/topotests/ospf_netns_vrf/__init__.py (renamed from tests/topotests/ospf_topo1_vrf/__init__.py)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/ospfd.conf (renamed from tests/topotests/ospf_topo1_vrf/r1/ospfd.conf)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/ospfroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r1/ospfroute.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/ospfroute_down.txt (renamed from tests/topotests/ospf_topo1_vrf/r1/ospfroute_down.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/zebra.conf (renamed from tests/topotests/ospf_topo1_vrf/r1/zebra.conf)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/zebraroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r1/zebraroute.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt (renamed from tests/topotests/ospf_topo1_vrf/r1/zebraroutedown.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/ospfd.conf (renamed from tests/topotests/ospf_topo1_vrf/r2/ospfd.conf)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/ospfroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r2/ospfroute.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/ospfroute_down.txt (renamed from tests/topotests/ospf_topo1_vrf/r2/ospfroute_down.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/zebra.conf (renamed from tests/topotests/ospf_topo1_vrf/r2/zebra.conf)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/zebraroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r2/zebraroute.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt (renamed from tests/topotests/ospf_topo1_vrf/r2/zebraroutedown.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/ospfd.conf (renamed from tests/topotests/ospf_topo1_vrf/r3/ospfd.conf)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/ospfroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r3/ospfroute.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/ospfroute_down.txt (renamed from tests/topotests/ospf_topo1_vrf/r3/ospfroute_down.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/zebra.conf (renamed from tests/topotests/ospf_topo1_vrf/r3/zebra.conf)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/zebraroute.txt (renamed from tests/topotests/ospf_topo1_vrf/r3/zebraroute.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt (renamed from tests/topotests/ospf_topo1_vrf/r3/zebraroutedown.txt)0
-rw-r--r--tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.dot (renamed from tests/topotests/ospf_topo1_vrf/test_ospf_topo1-vrf.dot)0
-rw-r--r--tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.jpg (renamed from tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.jpg)bin65859 -> 65859 bytes
-rw-r--r--tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py (renamed from tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.py)4
-rw-r--r--tests/topotests/ospf_unnumbered/r1/ospf-route.json (renamed from tests/topotests/ospf_topo2/r1/ospf-route.json)0
-rw-r--r--tests/topotests/ospf_unnumbered/r1/ospfd.conf (renamed from tests/topotests/ospf_topo2/r1/ospfd.conf)0
-rw-r--r--tests/topotests/ospf_unnumbered/r1/v4_route.json (renamed from tests/topotests/ospf_topo2/r1/v4_route.json)0
-rw-r--r--tests/topotests/ospf_unnumbered/r1/zebra.conf (renamed from tests/topotests/ospf_topo2/r1/zebra.conf)0
-rw-r--r--tests/topotests/ospf_unnumbered/r2/ospf-route.json (renamed from tests/topotests/ospf_topo2/r2/ospf-route.json)0
-rw-r--r--tests/topotests/ospf_unnumbered/r2/ospfd.conf (renamed from tests/topotests/ospf_topo2/r2/ospfd.conf)0
-rw-r--r--tests/topotests/ospf_unnumbered/r2/v4_route.json (renamed from tests/topotests/ospf_topo2/r2/v4_route.json)0
-rw-r--r--tests/topotests/ospf_unnumbered/r2/zebra.conf (renamed from tests/topotests/ospf_topo2/r2/zebra.conf)0
-rw-r--r--tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py (renamed from tests/topotests/ospf_topo2/test_ospf_topo2.py)4
-rw-r--r--yang/frr-bgp-route-map.yang10
-rw-r--r--zebra/ioctl.c25
-rw-r--r--zebra/kernel_netlink.c125
-rw-r--r--zebra/kernel_socket.c14
-rw-r--r--zebra/rt.h4
-rw-r--r--zebra/zebra_fpm_netlink.c5
-rw-r--r--zebra/zebra_router.c6
93 files changed, 1038 insertions, 960 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index b5012e4586..eafc37f20c 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -526,7 +526,7 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
struct prefix_ipv6 *chunk;
struct in6_addr sid_buf;
bool alloced = false;
- int label;
+ int label = 0;
if (!bgp || !sid)
return false;
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index fa03276f64..efb7f9eb7b 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1039,10 +1039,14 @@ static void *route_match_evpn_route_type_compile(const char *arg)
route_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t));
- if (strncmp(arg, "ma", 2) == 0)
+ if (strncmp(arg, "ea", 2) == 0)
+ *route_type = BGP_EVPN_AD_ROUTE;
+ else if (strncmp(arg, "ma", 2) == 0)
*route_type = BGP_EVPN_MAC_IP_ROUTE;
else if (strncmp(arg, "mu", 2) == 0)
*route_type = BGP_EVPN_IMET_ROUTE;
+ else if (strncmp(arg, "es", 2) == 0)
+ *route_type = BGP_EVPN_ES_ROUTE;
else
*route_type = BGP_EVPN_IP_PREFIX_ROUTE;
@@ -4167,14 +4171,18 @@ static const char *parse_evpn_rt_type(const char *num_rt_type)
DEFUN_YANG (match_evpn_route_type,
match_evpn_route_type_cmd,
- "match evpn route-type <macip|2|multicast|3|prefix|5>",
+ "match evpn route-type <ead|1|macip|2|multicast|3|es|4|prefix|5>",
MATCH_STR
EVPN_HELP_STR
EVPN_TYPE_HELP_STR
+ EVPN_TYPE_1_HELP_STR
+ EVPN_TYPE_1_HELP_STR
EVPN_TYPE_2_HELP_STR
EVPN_TYPE_2_HELP_STR
EVPN_TYPE_3_HELP_STR
EVPN_TYPE_3_HELP_STR
+ EVPN_TYPE_4_HELP_STR
+ EVPN_TYPE_4_HELP_STR
EVPN_TYPE_5_HELP_STR
EVPN_TYPE_5_HELP_STR)
{
@@ -4194,15 +4202,19 @@ DEFUN_YANG (match_evpn_route_type,
DEFUN_YANG (no_match_evpn_route_type,
no_match_evpn_route_type_cmd,
- "no match evpn route-type <macip|2|multicast|3|prefix|5>",
+ "no match evpn route-type <ead|1|macip|2|multicast|3|es|4|prefix|5>",
NO_STR
MATCH_STR
EVPN_HELP_STR
EVPN_TYPE_HELP_STR
+ EVPN_TYPE_1_HELP_STR
+ EVPN_TYPE_1_HELP_STR
EVPN_TYPE_2_HELP_STR
EVPN_TYPE_2_HELP_STR
EVPN_TYPE_3_HELP_STR
EVPN_TYPE_3_HELP_STR
+ EVPN_TYPE_4_HELP_STR
+ EVPN_TYPE_4_HELP_STR
EVPN_TYPE_5_HELP_STR
EVPN_TYPE_5_HELP_STR)
{
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9a1991cd09..afe4c7ae6f 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -803,11 +803,15 @@ struct peer *peer_and_group_lookup_vty(struct vty *vty, const char *peer_str)
return NULL;
}
-int bgp_vty_return(struct vty *vty, int ret)
+int bgp_vty_return(struct vty *vty, enum bgp_create_error_code ret)
{
const char *str = NULL;
switch (ret) {
+ case BGP_SUCCESS:
+ case BGP_CREATED:
+ case BGP_GR_NO_OPERATION:
+ break;
case BGP_ERR_INVALID_VALUE:
str = "Invalid value";
break;
@@ -877,6 +881,36 @@ 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_ERR_PEER_GROUP_MEMBER:
+ str = "Peer-group member cannot override remote-as of peer-group.";
+ break;
+ case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
+ str = "Peer-group members must be all internal or all external.";
+ break;
+ case BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND:
+ str = "Range specified cannot be deleted because it is not part of current config.";
+ break;
+ case BGP_ERR_INSTANCE_MISMATCH:
+ str = "Instance specified does not match the current instance.";
+ break;
+ case BGP_ERR_NO_INTERFACE_CONFIG:
+ str = "Interface specified is not being used for interface based peer.";
+ break;
+ case BGP_ERR_SOFT_RECONFIG_UNCONFIGURED:
+ str = "No configuration already specified for soft reconfiguration.";
+ break;
+ case BGP_ERR_AS_MISMATCH:
+ str = "BGP is already running.";
+ break;
+ case BGP_ERR_AF_UNCONFIGURED:
+ str = "AFI/SAFI specified is not currently configured.";
+ break;
+ case BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS:
+ str = "AS specified for local as is the same as the remote as and this is not allowed.";
+ break;
+ case BGP_ERR_INVALID_AS:
+ str = "Confederation AS specified is the same AS as our AS.";
+ break;
}
if (str) {
vty_out(vty, "%% %s\n", str);
@@ -4211,17 +4245,6 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
ret = peer_remote_as(bgp, &su, NULL, &as, as_type);
}
- /* This peer belongs to peer group. */
- switch (ret) {
- case BGP_ERR_PEER_GROUP_MEMBER:
- vty_out(vty,
- "%% Peer-group member cannot override remote-as of peer-group\n");
- return CMD_WARNING_CONFIG_FAILED;
- case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
- vty_out(vty,
- "%% Peer-group members must be all internal or all external\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
return bgp_vty_return(vty, ret);
}
@@ -4958,13 +4981,6 @@ DEFUN (neighbor_set_peer_group,
ret = peer_group_bind(bgp, &su, peer, group, &as);
- if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) {
- vty_out(vty,
- "%% Peer with AS %u cannot be in this peer-group, members must be all internal or all external\n",
- as);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
return bgp_vty_return(vty, ret);
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 567b049c1b..43046f7f18 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -651,9 +651,6 @@ int bgp_confederation_peers_add(struct bgp *bgp, as_t as)
struct peer *peer;
struct listnode *node, *nnode;
- if (!bgp)
- return BGP_ERR_INVALID_BGP;
-
if (bgp->as == as)
return BGP_ERR_INVALID_AS;
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index ff295ffa27..8b93c450e8 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -1919,46 +1919,46 @@ enum bgp_clear_type {
(((S) == OpenSent) || ((S) == OpenConfirm) || ((S) == Established))
/* BGP error codes. */
-#define BGP_SUCCESS 0
-#define BGP_CREATED 1
-#define BGP_ERR_INVALID_VALUE -1
-#define BGP_ERR_INVALID_FLAG -2
-#define BGP_ERR_INVALID_AS -3
-#define BGP_ERR_INVALID_BGP -4
-#define BGP_ERR_PEER_GROUP_MEMBER -5
-#define BGP_ERR_PEER_GROUP_NO_REMOTE_AS -7
-#define BGP_ERR_PEER_GROUP_CANT_CHANGE -8
-#define BGP_ERR_PEER_GROUP_MISMATCH -9
-#define BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT -10
-#define BGP_ERR_AS_MISMATCH -12
-#define BGP_ERR_PEER_FLAG_CONFLICT -13
-#define BGP_ERR_PEER_GROUP_SHUTDOWN -14
-#define BGP_ERR_PEER_FILTER_CONFLICT -15
-#define BGP_ERR_NOT_INTERNAL_PEER -16
-#define BGP_ERR_REMOVE_PRIVATE_AS -17
-#define BGP_ERR_AF_UNCONFIGURED -18
-#define BGP_ERR_SOFT_RECONFIG_UNCONFIGURED -19
-#define BGP_ERR_INSTANCE_MISMATCH -20
-#define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP -21
-#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS -22
-#define BGP_ERR_TCPSIG_FAILED -23
-#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK -24
-#define BGP_ERR_NO_IBGP_WITH_TTLHACK -25
-#define BGP_ERR_NO_INTERFACE_CONFIG -26
-#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS -27
-#define BGP_ERR_AS_OVERRIDE -28
-#define BGP_ERR_INVALID_DYNAMIC_NEIGHBORS_LIMIT -29
-#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_EXISTS -30
-#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND -31
-#define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -32
-#define BGP_ERR_MAX -33
-#define BGP_ERR_INVALID_FOR_DIRECT_PEER -34
-#define BGP_ERR_PEER_SAFI_CONFLICT -35
-
-/* BGP GR ERRORS */
-#define BGP_ERR_GR_INVALID_CMD -36
-#define BGP_ERR_GR_OPERATION_FAILED -37
-#define BGP_GR_NO_OPERATION -38
+enum bgp_create_error_code {
+ BGP_SUCCESS = 0,
+ BGP_CREATED = 1,
+ BGP_ERR_INVALID_VALUE = -1,
+ BGP_ERR_INVALID_FLAG = -2,
+ BGP_ERR_INVALID_AS = -3,
+ BGP_ERR_PEER_GROUP_MEMBER = -4,
+ BGP_ERR_PEER_GROUP_NO_REMOTE_AS = -5,
+ BGP_ERR_PEER_GROUP_CANT_CHANGE = -6,
+ BGP_ERR_PEER_GROUP_MISMATCH = -7,
+ BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT = -8,
+ BGP_ERR_AS_MISMATCH = -9,
+ BGP_ERR_PEER_FLAG_CONFLICT = -10,
+ BGP_ERR_PEER_GROUP_SHUTDOWN = -11,
+ BGP_ERR_PEER_FILTER_CONFLICT = -12,
+ BGP_ERR_NOT_INTERNAL_PEER = -13,
+ BGP_ERR_REMOVE_PRIVATE_AS = -14,
+ BGP_ERR_AF_UNCONFIGURED = -15,
+ BGP_ERR_SOFT_RECONFIG_UNCONFIGURED = -16,
+ BGP_ERR_INSTANCE_MISMATCH = -17,
+ BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP = -18,
+ BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS = -19,
+ BGP_ERR_TCPSIG_FAILED = -20,
+ BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK = -21,
+ BGP_ERR_NO_IBGP_WITH_TTLHACK = -22,
+ BGP_ERR_NO_INTERFACE_CONFIG = -23,
+ BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS = -24,
+ BGP_ERR_AS_OVERRIDE = -25,
+ BGP_ERR_INVALID_DYNAMIC_NEIGHBORS_LIMIT = -26,
+ BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_EXISTS = -27,
+ BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND = -28,
+ BGP_ERR_INVALID_FOR_DYNAMIC_PEER = -29,
+ BGP_ERR_INVALID_FOR_DIRECT_PEER = -30,
+ BGP_ERR_PEER_SAFI_CONFLICT = -31,
+
+ /* BGP GR ERRORS */
+ BGP_ERR_GR_INVALID_CMD = -32,
+ BGP_ERR_GR_OPERATION_FAILED = -33,
+ BGP_GR_NO_OPERATION = -34,
+};
/*
* Enumeration of different policy kinds a peer can be configured with.
diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst
index 349b54098e..d1a0bb6f7b 100644
--- a/doc/user/ospfd.rst
+++ b/doc/user/ospfd.rst
@@ -268,8 +268,10 @@ To start OSPF process you have to specify the OSPF router.
the destination prefix. Otherwise, we test whether the network command prefix
contains the local address prefix of the interface.
- In some cases it may be more convenient to enable OSPF on a per
- interface/subnet basis (:clicmd:`ip ospf area AREA [ADDR]`).
+ It is also possible to enable OSPF on a per interface/subnet basis
+ using the interface command (:clicmd:`ip ospf area AREA [ADDR]`).
+ However, mixing both network commands (:clicmd:`network`) and interface
+ commands (:clicmd:`ip ospf`) on the same router is not supported.
.. clicmd:: proactive-arp
@@ -515,12 +517,14 @@ Interfaces
Enable OSPF on the interface, optionally restricted to just the IP address
- given by `ADDR`, putting it in the `AREA` area. Per interface area settings
- take precedence to network commands
- (:clicmd:`network A.B.C.D/M area A.B.C.D`).
-
- If you have a lot of interfaces, and/or a lot of subnets, then enabling OSPF
- via this command may result in a slight performance improvement.
+ given by `ADDR`, putting it in the `AREA` area. If you have a lot of
+ interfaces, and/or a lot of subnets, then enabling OSPF via this command
+ instead of (:clicmd:`network A.B.C.D/M area A.B.C.D`) may result in a
+ slight performance improvement.
+
+ Notice that, mixing both network commands (:clicmd:`network`) and interface
+ commands (:clicmd:`ip ospf`) on the same router is not supported.
+ If (:clicmd:`ip ospf`) is present, (:clicmd:`network`) commands will fail.
.. clicmd:: ip ospf authentication-key AUTH_KEY
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index 5a009eda6b..1c3a0110ac 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -176,7 +176,7 @@ Certain signals have special meanings to *pimd*.
Generate IGMP query (v2/v3) on user requirement. This will not depend on
the existing IGMP general query timer.If no version is provided in the cli,
- it will be considered as default v2 query.This is a hidden command.
+ the default will be the igmp version enabled on that interface.
.. clicmd:: ip igmp watermark-warn (1-65535)
diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst
index a7f22cd40c..ef7aef9c5e 100644
--- a/doc/user/routemap.rst
+++ b/doc/user/routemap.rst
@@ -215,6 +215,18 @@ Route Map Match Command
This is a ZEBRA specific match command. The number is a range from (0-255).
Matches the originating protocols instance specified.
+.. clicmd:: match evpn route-type ROUTE_TYPE_NAME
+
+ This is a BGP EVPN specific match command. It matches to EVPN route-type
+ from type-1 (EAD route-type) to type-5 (Prefix route-type).
+ User can provide in an integral form (1-5) or string form of route-type
+ (i.e ead, macip, multicast, es, prefix).
+
+.. clicmd:: match evpn vni NUMBER
+
+ This is a BGP EVPN specific match command which matches to EVPN VNI id.
+ The number is a range from (1-6777215).
+
.. _route-map-set-command:
Route Map Set Command
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c
index 3c38ebd76b..7d05403c36 100644
--- a/pimd/pim_assert.c
+++ b/pimd/pim_assert.c
@@ -61,18 +61,11 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch,
ch->interface->name);
}
- if (winner_changed) {
- char was_str[INET_ADDRSTRLEN];
- char winner_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<was?>", ch->ifassert_winner, was_str,
- sizeof(was_str));
- pim_inet4_dump("<winner?>", winner, winner_str,
- sizeof(winner_str));
+ if (winner_changed)
zlog_debug(
- "%s: (S,G)=%s assert winner changed from %s to %s on interface %s",
- __func__, ch->sg_str, was_str, winner_str,
- ch->interface->name);
- }
+ "%s: (S,G)=%s assert winner changed from %pPAs to %pPAs on interface %s",
+ __func__, ch->sg_str, &ch->ifassert_winner,
+ &winner, ch->interface->name);
} /* PIM_DEBUG_PIM_EVENTS */
ch->ifassert_state = new_state;
@@ -87,14 +80,10 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch,
}
}
-static void on_trace(const char *label, struct interface *ifp,
- struct in_addr src)
+static void on_trace(const char *label, struct interface *ifp, pim_addr src)
{
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
- zlog_debug("%s: from %s on %s", label, src_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: from %pPAs on %s", label, &src, ifp->name);
}
static int preferred_assert(const struct pim_ifchannel *ch,
@@ -136,8 +125,8 @@ static void if_could_assert_do_a1(const char *caller, struct pim_ifchannel *ch)
}
}
-static int dispatch_assert(struct interface *ifp, struct in_addr source_addr,
- struct in_addr group_addr,
+static int dispatch_assert(struct interface *ifp, pim_addr source_addr,
+ pim_addr group_addr,
struct pim_assert_metric recv_metric)
{
struct pim_ifchannel *ch;
@@ -213,10 +202,11 @@ static int dispatch_assert(struct interface *ifp, struct in_addr source_addr,
}
int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
- struct in_addr src_addr, uint8_t *buf, int buf_size)
+ pim_addr src_addr, uint8_t *buf, int buf_size)
{
pim_sgaddr sg;
- struct prefix msg_source_addr;
+ pim_addr msg_source_addr;
+ bool wrong_af = false;
struct pim_assert_metric msg_metric;
int offset;
uint8_t *curr;
@@ -234,10 +224,9 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
memset(&sg, 0, sizeof(sg));
offset = pim_parse_addr_group(&sg, curr, curr_size);
if (offset < 1) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: pim_parse_addr_group() failure: from %s on %s",
- __func__, src_str, ifp->name);
+ zlog_warn(
+ "%s: pim_parse_addr_group() failure: from %pPAs on %s",
+ __func__, &src_addr, ifp->name);
return -1;
}
curr += offset;
@@ -246,23 +235,21 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
/*
Parse assert source addr
*/
- offset = pim_parse_addr_ucast(&msg_source_addr, curr, curr_size);
- if (offset < 1) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
- __func__, src_str, ifp->name);
+ offset = pim_parse_addr_ucast(&msg_source_addr, curr, curr_size,
+ &wrong_af);
+ if (offset < 1 || wrong_af) {
+ zlog_warn(
+ "%s: pim_parse_addr_ucast() failure: from %pPAs on %s",
+ __func__, &src_addr, ifp->name);
return -2;
}
curr += offset;
curr_size -= offset;
if (curr_size < 8) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn(
- "%s: preference/metric size is less than 8 bytes: size=%d from %s on interface %s",
- __func__, curr_size, src_str, ifp->name);
+ "%s: preference/metric size is less than 8 bytes: size=%d from %pPAs on interface %s",
+ __func__, curr_size, &src_addr, ifp->name);
return -3;
}
@@ -284,19 +271,13 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
msg_metric.route_metric = pim_read_uint32_host(curr);
- if (PIM_DEBUG_PIM_TRACE) {
- char neigh_str[INET_ADDRSTRLEN];
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<neigh?>", src_addr, neigh_str,
- sizeof(neigh_str));
- pim_inet4_dump("<src?>", msg_source_addr.u.prefix4, source_str,
- sizeof(source_str));
+ if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
- "%s: from %s on %s: (S,G)=(%s,%pPAs) pref=%u metric=%u rpt_bit=%u",
- __func__, neigh_str, ifp->name, source_str, &sg.grp,
- msg_metric.metric_preference, msg_metric.route_metric,
+ "%s: from %pPAs on %s: (S,G)=(%pPAs,%pPAs) pref=%u metric=%u rpt_bit=%u",
+ __func__, &src_addr, ifp->name, &msg_source_addr,
+ &sg.grp, msg_metric.metric_preference,
+ msg_metric.route_metric,
PIM_FORCE_BOOLEAN(msg_metric.rpt_bit_flag));
- }
msg_metric.ip_address = src_addr;
@@ -304,8 +285,7 @@ int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
assert(pim_ifp);
++pim_ifp->pim_ifstat_assert_recv;
- return dispatch_assert(ifp, msg_source_addr.u.prefix4, sg.grp,
- msg_metric);
+ return dispatch_assert(ifp, msg_source_addr, sg.grp, msg_metric);
}
/*
@@ -354,7 +334,7 @@ int pim_assert_metric_match(const struct pim_assert_metric *m1,
}
int pim_assert_build_msg(uint8_t *pim_msg, int buf_size, struct interface *ifp,
- struct in_addr group_addr, struct in_addr source_addr,
+ pim_addr group_addr, pim_addr source_addr,
uint32_t metric_preference, uint32_t route_metric,
uint32_t rpt_bit_flag)
{
@@ -368,28 +348,21 @@ int pim_assert_build_msg(uint8_t *pim_msg, int buf_size, struct interface *ifp,
/* Encode group */
remain = buf_pastend - pim_msg_curr;
- pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr, group_addr);
+ pim_msg_curr = pim_msg_addr_encode_group(pim_msg_curr, group_addr);
if (!pim_msg_curr) {
- char group_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<grp?>", group_addr, group_str,
- sizeof(group_str));
zlog_warn(
- "%s: failure encoding group address %s: space left=%d",
- __func__, group_str, remain);
+ "%s: failure encoding group address %pPA: space left=%d",
+ __func__, &group_addr, remain);
return -1;
}
/* Encode source */
remain = buf_pastend - pim_msg_curr;
- pim_msg_curr =
- pim_msg_addr_encode_ipv4_ucast(pim_msg_curr, source_addr);
+ pim_msg_curr = pim_msg_addr_encode_ucast(pim_msg_curr, source_addr);
if (!pim_msg_curr) {
- char source_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", source_addr, source_str,
- sizeof(source_str));
zlog_warn(
- "%s: failure encoding source address %s: space left=%d",
- __func__, source_str, remain);
+ "%s: failure encoding source address %pPA: space left=%d",
+ __func__, &source_addr, remain);
return -2;
}
diff --git a/pimd/pim_assert.h b/pimd/pim_assert.h
index a149fb176e..22bab67c59 100644
--- a/pimd/pim_assert.h
+++ b/pimd/pim_assert.h
@@ -59,7 +59,7 @@ void pim_ifassert_winner_set(struct pim_ifchannel *ch,
struct pim_assert_metric winner_metric);
int pim_assert_recv(struct interface *ifp, struct pim_neighbor *neigh,
- struct in_addr src_addr, uint8_t *buf, int buf_size);
+ pim_addr src_addr, uint8_t *buf, int buf_size);
int pim_assert_metric_better(const struct pim_assert_metric *m1,
const struct pim_assert_metric *m2);
@@ -67,7 +67,7 @@ int pim_assert_metric_match(const struct pim_assert_metric *m1,
const struct pim_assert_metric *m2);
int pim_assert_build_msg(uint8_t *pim_msg, int buf_size, struct interface *ifp,
- struct in_addr group_addr, struct in_addr source_addr,
+ pim_addr group_addr, pim_addr source_addr,
uint32_t metric_preference, uint32_t route_metric,
uint32_t rpt_bit_flag);
diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c
index 31f672bb80..3e3021dc4d 100644
--- a/pimd/pim_bfd.c
+++ b/pimd/pim_bfd.c
@@ -94,7 +94,11 @@ void pim_bfd_info_nbr_create(struct pim_interface *pim_ifp,
bfd_sess_set_timers(
neigh->bfd_session, pim_ifp->bfd_config.detection_multiplier,
pim_ifp->bfd_config.min_rx, pim_ifp->bfd_config.min_tx);
+#if PIM_IPV == 4 || !defined(PIM_V6_TEMP_BREAK)
bfd_sess_set_ipv4_addrs(neigh->bfd_session, NULL, &neigh->source_addr);
+#else
+ bfd_sess_set_ipv6_addrs(neigh->bfd_session, NULL, &neigh->source_addr);
+#endif
bfd_sess_set_interface(neigh->bfd_session, neigh->interface->name);
bfd_sess_set_vrf(neigh->bfd_session, neigh->interface->vrf->vrf_id);
bfd_sess_set_profile(neigh->bfd_session, pim_ifp->bfd_config.profile);
diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c
index 4214790476..0b993ec05e 100644
--- a/pimd/pim_bsm.c
+++ b/pimd/pim_bsm.c
@@ -667,10 +667,7 @@ void pim_bsm_clear(struct pim_instance *pim)
struct prefix grp;
struct rp_info *trp_info;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
-
+ pim_addr_to_prefix(&grp, up->sg.grp);
trp_info = pim_rp_find_match_group(pim, &grp);
/* RP not found for the group grp */
@@ -690,7 +687,7 @@ void pim_bsm_clear(struct pim_instance *pim)
}
static bool pim_bsm_send_intf(uint8_t *buf, int len, struct interface *ifp,
- struct in_addr dst_addr)
+ pim_addr dst_addr)
{
struct pim_interface *pim_ifp;
@@ -723,8 +720,7 @@ static bool pim_bsm_send_intf(uint8_t *buf, int len, struct interface *ifp,
}
static bool pim_bsm_frag_send(uint8_t *buf, uint32_t len, struct interface *ifp,
- uint32_t pim_mtu, struct in_addr dst_addr,
- bool no_fwd)
+ uint32_t pim_mtu, pim_addr dst_addr, bool no_fwd)
{
struct bsmmsg_grpinfo *grpinfo, *curgrp;
uint8_t *firstgrp_ptr;
@@ -895,7 +891,7 @@ static void pim_bsm_fwd_whole_sz(struct pim_instance *pim, uint8_t *buf,
{
struct interface *ifp;
struct pim_interface *pim_ifp;
- struct in_addr dst_addr;
+ pim_addr dst_addr;
uint32_t pim_mtu;
bool no_fwd = false;
bool ret = false;
@@ -942,7 +938,7 @@ static void pim_bsm_fwd_whole_sz(struct pim_instance *pim, uint8_t *buf,
bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
{
- struct in_addr dst_addr;
+ pim_addr dst_addr;
struct pim_interface *pim_ifp;
struct bsm_scope *scope;
struct bsm_frag *bsfrag;
@@ -951,17 +947,14 @@ bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp)
bool no_fwd = true;
bool ret = false;
- if (PIM_DEBUG_BSM) {
- pim_inet4_dump("<src?>", neigh->source_addr, neigh_src_str,
- sizeof(neigh_src_str));
- zlog_debug("%s: New neighbor %s seen on %s", __func__,
- neigh_src_str, ifp->name);
- }
+ if (PIM_DEBUG_BSM)
+ zlog_debug("%s: New neighbor %pPA seen on %s", __func__,
+ &neigh->source_addr, ifp->name);
pim_ifp = ifp->info;
/* DR only forwards BSM packet */
- if (pim_ifp->pim_dr_addr.s_addr == pim_ifp->primary_address.s_addr) {
+ if (!pim_addr_cmp(pim_ifp->pim_dr_addr, pim_ifp->primary_address)) {
if (PIM_DEBUG_BSM)
zlog_debug(
"%s: It is not DR, so don't forward BSM packet",
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 61d4f22e9f..83ba74f69f 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -2427,9 +2427,9 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
struct pim_neighbor *nbr;
- nbr = pim_neighbor_find(
+ nbr = pim_neighbor_find_prefix(
up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr.u.prefix4);
+ &up->rpf.rpf_addr);
if (nbr)
pim_time_timer_to_hhmmss(join_timer,
sizeof(join_timer),
@@ -8237,7 +8237,8 @@ DEFPY_HIDDEN (interface_ip_igmp_query_generate,
"IGMP version number\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
- int igmp_version = 2;
+ int igmp_version;
+ struct pim_interface *pim_ifp = ifp->info;
if (!ifp->info) {
vty_out(vty, "IGMP/PIM is not enabled on the interface %s\n",
@@ -8245,6 +8246,9 @@ DEFPY_HIDDEN (interface_ip_igmp_query_generate,
return CMD_WARNING_CONFIG_FAILED;
}
+ /* It takes the igmp version configured on the interface as default */
+ igmp_version = pim_ifp->igmp_version;
+
if (argc > 3)
igmp_version = atoi(argv[4]->arg);
diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c
index 45ea6a9562..fe4f10aa6a 100644
--- a/pimd/pim_hello.c
+++ b/pimd/pim_hello.c
@@ -33,81 +33,62 @@
#include "pim_upstream.h"
#include "pim_bsm.h"
-static void on_trace(const char *label, struct interface *ifp,
- struct in_addr src)
+static void on_trace(const char *label, struct interface *ifp, pim_addr src)
{
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
- zlog_debug("%s: from %s on %s", label, src_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s: from %pPAs on %s", label, &src, ifp->name);
}
static void tlv_trace_bool(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
- int isset, int value)
+ const char *ifname, pim_addr src_addr, int isset,
+ int value)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ if (isset)
zlog_debug(
- "%s: PIM hello option from %s on interface %s: %s=%d",
- label, src_str, ifname, tlv_name, value);
- }
+ "%s: PIM hello option from %pPAs on interface %s: %s=%d",
+ label, &src_addr, ifname, tlv_name, value);
}
static void tlv_trace_uint16(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
- int isset, uint16_t value)
+ const char *ifname, pim_addr src_addr, int isset,
+ uint16_t value)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ if (isset)
zlog_debug(
- "%s: PIM hello option from %s on interface %s: %s=%u",
- label, src_str, ifname, tlv_name, value);
- }
+ "%s: PIM hello option from %pPAs on interface %s: %s=%u",
+ label, &src_addr, ifname, tlv_name, value);
}
static void tlv_trace_uint32(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
- int isset, uint32_t value)
+ const char *ifname, pim_addr src_addr, int isset,
+ uint32_t value)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ if (isset)
zlog_debug(
- "%s: PIM hello option from %s on interface %s: %s=%u",
- label, src_str, ifname, tlv_name, value);
- }
+ "%s: PIM hello option from %pPAs on interface %s: %s=%u",
+ label, &src_addr, ifname, tlv_name, value);
}
static void tlv_trace_uint32_hex(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
+ const char *ifname, pim_addr src_addr,
int isset, uint32_t value)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ if (isset)
zlog_debug(
- "%s: PIM hello option from %s on interface %s: %s=%08x",
- label, src_str, ifname, tlv_name, value);
- }
+ "%s: PIM hello option from %pPAs on interface %s: %s=%08x",
+ label, &src_addr, ifname, tlv_name, value);
}
static void tlv_trace_list(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
- int isset, struct list *addr_list)
+ const char *ifname, pim_addr src_addr, int isset,
+ struct list *addr_list)
{
- if (isset) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ if (isset)
zlog_debug(
- "%s: PIM hello option from %s on interface %s: %s size=%d list=%p",
- label, src_str, ifname, tlv_name,
+ "%s: PIM hello option from %pPAs on interface %s: %s size=%d list=%p",
+ label, &src_addr, ifname, tlv_name,
addr_list ? ((int)listcount(addr_list)) : -1,
(void *)addr_list);
- }
}
#define FREE_ADDR_LIST \
@@ -121,8 +102,8 @@ static void tlv_trace_list(const char *label, const char *tlv_name,
return (code); \
}
-int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
- uint8_t *tlv_buf, int tlv_buf_size)
+int pim_hello_recv(struct interface *ifp, pim_addr src_addr, uint8_t *tlv_buf,
+ int tlv_buf_size)
{
struct pim_interface *pim_ifp;
struct pim_neighbor *neigh;
@@ -158,15 +139,11 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
int remain = tlv_pastend - tlv_curr;
if (remain < PIM_TLV_MIN_SIZE) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_debug(
- "%s: short PIM hello TLV size=%d < min=%d from %s on interface %s",
+ "%s: short PIM hello TLV size=%d < min=%d from %pPAs on interface %s",
__func__, remain, PIM_TLV_MIN_SIZE,
- src_str, ifp->name);
- }
+ &src_addr, ifp->name);
FREE_ADDR_LIST_THEN_RETURN(-1);
}
@@ -176,28 +153,20 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
tlv_curr += PIM_TLV_LENGTH_SIZE;
if ((tlv_curr + option_len) > tlv_pastend) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_debug(
- "%s: long PIM hello TLV type=%d length=%d > left=%td from %s on interface %s",
+ "%s: long PIM hello TLV type=%d length=%d > left=%td from %pPAs on interface %s",
__func__, option_type, option_len,
- tlv_pastend - tlv_curr, src_str,
+ tlv_pastend - tlv_curr, &src_addr,
ifp->name);
- }
FREE_ADDR_LIST_THEN_RETURN(-2);
}
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_debug(
- "%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %s on %s",
+ "%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %pPAs on %s",
__func__, remain, option_type, option_len,
- src_str, ifp->name);
- }
+ &src_addr, ifp->name);
switch (option_type) {
case PIM_MSG_OPTION_TYPE_HOLDTIME:
@@ -242,26 +211,18 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
}
break;
case PIM_MSG_OPTION_TYPE_DM_STATE_REFRESH:
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_debug(
- "%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %s on interface %s",
+ "%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %pPAs on interface %s",
__func__, option_type, option_len,
- src_str, ifp->name);
- }
+ &src_addr, ifp->name);
break;
default:
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_debug(
- "%s: ignoring unknown PIM hello TLV type=%d length=%d from %s on interface %s",
+ "%s: ignoring unknown PIM hello TLV type=%d length=%d from %pPAs on interface %s",
__func__, option_type, option_len,
- src_str, ifp->name);
- }
+ &src_addr, ifp->name);
}
tlv_curr += option_len;
@@ -310,14 +271,10 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
}
if (!PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_debug(
- "%s: PIM hello missing holdtime from %s on interface %s",
- __func__, src_str, ifp->name);
- }
+ "%s: PIM hello missing holdtime from %pPAs on interface %s",
+ __func__, &src_addr, ifp->name);
}
/*
@@ -335,14 +292,10 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
hello_option_dr_priority, hello_option_generation_id,
hello_option_addr_list, PIM_NEIGHBOR_SEND_DELAY);
if (!neigh) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_warn(
- "%s: failure creating PIM neighbor %s on interface %s",
- __func__, src_str, ifp->name);
- }
+ "%s: failure creating PIM neighbor %pPAs on interface %s",
+ __func__, &src_addr, ifp->name);
FREE_ADDR_LIST_THEN_RETURN(-8);
}
/* Forward BSM if required */
@@ -368,16 +321,12 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
|| (hello_option_generation_id != neigh->generation_id)) {
/* GenID mismatch, then replace neighbor */
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_debug(
- "%s: GenId mismatch new=%08x old=%08x: replacing neighbor %s on %s",
+ "%s: GenId mismatch new=%08x old=%08x: replacing neighbor %pPAs on %s",
__func__, hello_option_generation_id,
- neigh->generation_id, src_str,
+ neigh->generation_id, &src_addr,
ifp->name);
- }
pim_upstream_rpf_genid_changed(pim_ifp->pim,
neigh->source_addr);
@@ -392,15 +341,10 @@ int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
hello_option_addr_list,
PIM_NEIGHBOR_SEND_NOW);
if (!neigh) {
- if (PIM_DEBUG_PIM_HELLO) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr,
- src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_HELLO)
zlog_debug(
- "%s: failure re-creating PIM neighbor %s on interface %s",
- __func__, src_str, ifp->name);
- }
+ "%s: failure re-creating PIM neighbor %pPAs on interface %s",
+ __func__, &src_addr, ifp->name);
FREE_ADDR_LIST_THEN_RETURN(-9);
}
/* Forward BSM if required */
diff --git a/pimd/pim_hello.h b/pimd/pim_hello.h
index df41f97d9e..56084e06d2 100644
--- a/pimd/pim_hello.h
+++ b/pimd/pim_hello.h
@@ -24,8 +24,8 @@
#include "if.h"
-int pim_hello_recv(struct interface *ifp, struct in_addr src_addr,
- uint8_t *tlv_buf, int tlv_buf_size);
+int pim_hello_recv(struct interface *ifp, pim_addr src_addr, uint8_t *tlv_buf,
+ int tlv_buf_size);
int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf,
int tlv_buf_size, uint16_t holdtime,
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 3f138e22e5..57fe97816e 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -193,7 +193,6 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
void pim_if_delete(struct interface *ifp)
{
struct pim_interface *pim_ifp;
- struct pim_ifchannel *ch;
assert(ifp);
pim_ifp = ifp->info;
@@ -218,13 +217,6 @@ void pim_if_delete(struct interface *ifp)
list_delete(&pim_ifp->sec_addr_list);
XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
-
- while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
- ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
-
- pim_ifchannel_delete(ch);
- }
-
XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
ifp->info = NULL;
@@ -299,27 +291,20 @@ static int detect_primary_address_change(struct interface *ifp,
const char *caller)
{
struct pim_interface *pim_ifp = ifp->info;
- struct in_addr new_prim_addr;
+ pim_addr new_prim_addr;
int changed;
if (force_prim_as_any)
- new_prim_addr.s_addr = INADDR_ANY;
+ new_prim_addr = PIMADDR_ANY;
else
new_prim_addr = pim_find_primary_addr(ifp);
- changed = new_prim_addr.s_addr != pim_ifp->primary_address.s_addr;
+ changed = pim_addr_cmp(new_prim_addr, pim_ifp->primary_address);
- if (PIM_DEBUG_ZEBRA) {
- char new_prim_str[INET_ADDRSTRLEN];
- char old_prim_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<new?>", new_prim_addr, new_prim_str,
- sizeof(new_prim_str));
- pim_inet4_dump("<old?>", pim_ifp->primary_address, old_prim_str,
- sizeof(old_prim_str));
- zlog_debug("%s: old=%s new=%s on interface %s: %s", __func__,
- old_prim_str, new_prim_str, ifp->name,
- changed ? "changed" : "unchanged");
- }
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug("%s: old=%pPA new=%pPA on interface %s: %s",
+ __func__, &pim_ifp->primary_address, &new_prim_addr,
+ ifp->name, changed ? "changed" : "unchanged");
if (changed) {
/* Before updating pim_ifp send Hello time with 0 hold time */
@@ -401,19 +386,18 @@ static int pim_sec_addr_update(struct interface *ifp)
}
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
- struct prefix *p = ifc->address;
+ pim_addr addr = pim_addr_from_prefix(ifc->address);
- if (p->u.prefix4.s_addr == INADDR_ANY) {
+ if (pim_addr_is_any(addr))
continue;
- }
- if (pim_ifp->primary_address.s_addr == p->u.prefix4.s_addr) {
+ if (!pim_addr_cmp(addr, pim_ifp->primary_address)) {
/* don't add the primary address into the secondary
* address list */
continue;
}
- if (pim_sec_addr_add(pim_ifp, p)) {
+ if (pim_sec_addr_add(pim_ifp, ifc->address)) {
changed = 1;
}
}
@@ -480,7 +464,7 @@ static void detect_address_change(struct interface *ifp, int force_prim_as_any,
* address change on all of them when the lo address changes */
}
-int pim_update_source_set(struct interface *ifp, struct in_addr source)
+int pim_update_source_set(struct interface *ifp, pim_addr source)
{
struct pim_interface *pim_ifp = ifp->info;
@@ -488,7 +472,7 @@ int pim_update_source_set(struct interface *ifp, struct in_addr source)
return PIM_IFACE_NOT_FOUND;
}
- if (pim_ifp->update_source.s_addr == source.s_addr) {
+ if (!pim_addr_cmp(pim_ifp->update_source, source)) {
return PIM_UPDATE_SOURCE_DUP;
}
@@ -827,11 +811,10 @@ void pim_if_addr_del_all_igmp(struct interface *ifp)
}
}
-struct in_addr pim_find_primary_addr(struct interface *ifp)
+pim_addr pim_find_primary_addr(struct interface *ifp)
{
struct connected *ifc;
struct listnode *node;
- struct in_addr addr = {0};
int v4_addrs = 0;
int v6_addrs = 0;
struct pim_interface *pim_ifp = ifp->info;
@@ -841,28 +824,35 @@ struct in_addr pim_find_primary_addr(struct interface *ifp)
}
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
- struct prefix *p = ifc->address;
+ pim_addr addr;
- if (p->family != AF_INET) {
+ switch (ifc->address->family) {
+ case AF_INET:
+ v4_addrs++;
+ break;
+ case AF_INET6:
v6_addrs++;
+ break;
+ default:
continue;
}
- if (p->u.prefix4.s_addr == INADDR_ANY) {
- zlog_warn(
- "%s: null IPv4 address connected to interface %s",
- __func__, ifp->name);
+ if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
continue;
- }
- v4_addrs++;
-
- if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
+ if (ifc->address->family != PIM_AF)
continue;
- return p->u.prefix4;
+ addr = pim_addr_from_prefix(ifc->address);
+
+#if PIM_IPV == 6
+ if (!IN6_IS_ADDR_LINKLOCAL(&addr))
+ continue;
+#endif
+ return addr;
}
+#if PIM_IPV == 4
/*
* If we have no v4_addrs and v6 is configured
* We probably are using unnumbered
@@ -882,10 +872,8 @@ struct in_addr pim_find_primary_addr(struct interface *ifp)
if (lo_ifp && (lo_ifp != ifp))
return pim_find_primary_addr(lo_ifp);
}
-
- addr.s_addr = PIM_NET_INADDR_ANY;
-
- return addr;
+#endif
+ return PIMADDR_ANY;
}
static int pim_iface_next_vif_index(struct interface *ifp)
@@ -1094,8 +1082,7 @@ uint16_t pim_if_jp_override_interval_msec(struct interface *ifp)
router (Section 4.3.4). The primary IP address of a neighbor is the
address that it uses as the source of its PIM Hello messages.
*/
-struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
- struct in_addr addr)
+struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, pim_addr addr)
{
struct listnode *neighnode;
struct pim_neighbor *neigh;
@@ -1111,15 +1098,13 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
return 0;
}
- p.family = AF_INET;
- p.u.prefix4 = addr;
- p.prefixlen = IPV4_MAX_BITLEN;
+ pim_addr_to_prefix(&p, addr);
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
neigh)) {
/* primary address ? */
- if (neigh->source_addr.s_addr == addr.s_addr)
+ if (!pim_addr_cmp(neigh->source_addr, addr))
return neigh;
/* secondary address ? */
@@ -1127,13 +1112,10 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
return neigh;
}
- if (PIM_DEBUG_PIM_TRACE) {
- char addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
+ if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
- "%s: neighbor not found for address %s on interface %s",
- __func__, addr_str, ifp->name);
- }
+ "%s: neighbor not found for address %pPA on interface %s",
+ __func__, &addr, ifp->name);
return NULL;
}
@@ -1383,8 +1365,7 @@ static void pim_if_igmp_join_del_all(struct interface *ifp)
gone down (and may have come back up), and so we must assume it no
longer knows it was the winner.
*/
-void pim_if_assert_on_neighbor_down(struct interface *ifp,
- struct in_addr neigh_addr)
+void pim_if_assert_on_neighbor_down(struct interface *ifp, pim_addr neigh_addr)
{
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
@@ -1397,7 +1378,7 @@ void pim_if_assert_on_neighbor_down(struct interface *ifp,
if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
continue;
/* Dead neighbor was winner ? */
- if (ch->ifassert_winner.s_addr != neigh_addr.s_addr)
+ if (pim_addr_cmp(ch->ifassert_winner, neigh_addr))
continue;
assert_action_a5(ch);
@@ -1473,7 +1454,7 @@ void pim_if_create_pimreg(struct pim_instance *pim)
}
}
-struct prefix *pim_if_connected_to_source(struct interface *ifp, struct in_addr src)
+struct prefix *pim_if_connected_to_source(struct interface *ifp, pim_addr src)
{
struct listnode *cnode;
struct connected *c;
@@ -1482,12 +1463,10 @@ struct prefix *pim_if_connected_to_source(struct interface *ifp, struct in_addr
if (!ifp)
return NULL;
- p.family = AF_INET;
- p.u.prefix4 = src;
- p.prefixlen = IPV4_MAX_BITLEN;
+ pim_addr_to_prefix(&p, src);
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
- if (c->address->family != AF_INET)
+ if (c->address->family != PIM_AF)
continue;
if (prefix_match(c->address, &p))
return c->address;
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index 1ddf743619..00ec8e7427 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -59,7 +59,8 @@
#define PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPPRESSION(options) \
((options) &= ~PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION)
-#define PIM_I_am_DR(pim_ifp) (pim_ifp)->pim_dr_addr.s_addr == (pim_ifp)->primary_address.s_addr
+#define PIM_I_am_DR(pim_ifp) \
+ !pim_addr_cmp((pim_ifp)->pim_dr_addr, (pim_ifp)->primary_address)
#define PIM_I_am_DualActive(pim_ifp) (pim_ifp)->activeactive == true
/* Macros for interface flags */
@@ -225,13 +226,12 @@ int pim_if_lan_delay_enabled(struct interface *ifp);
uint16_t pim_if_effective_propagation_delay_msec(struct interface *ifp);
uint16_t pim_if_effective_override_interval_msec(struct interface *ifp);
uint16_t pim_if_jp_override_interval_msec(struct interface *ifp);
-struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
- struct in_addr addr);
+struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp, pim_addr addr);
long pim_if_t_suppressed_msec(struct interface *ifp);
int pim_if_t_override_msec(struct interface *ifp);
-struct in_addr pim_find_primary_addr(struct interface *ifp);
+pim_addr pim_find_primary_addr(struct interface *ifp);
ferr_r pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr,
struct in_addr source_addr);
@@ -240,8 +240,7 @@ int pim_if_igmp_join_del(struct interface *ifp, struct in_addr group_addr,
void pim_if_update_could_assert(struct interface *ifp);
-void pim_if_assert_on_neighbor_down(struct interface *ifp,
- struct in_addr neigh_addr);
+void pim_if_assert_on_neighbor_down(struct interface *ifp, pim_addr neigh_addr);
void pim_if_rpf_interface_changed(struct interface *old_rpf_ifp,
struct pim_upstream *up);
@@ -252,8 +251,8 @@ void pim_if_update_assert_tracking_desired(struct interface *ifp);
void pim_if_create_pimreg(struct pim_instance *pim);
-struct prefix *pim_if_connected_to_source(struct interface *ifp, struct in_addr src);
-int pim_update_source_set(struct interface *ifp, struct in_addr source);
+struct prefix *pim_if_connected_to_source(struct interface *ifp, pim_addr src);
+int pim_update_source_set(struct interface *ifp, pim_addr source);
bool pim_if_is_vrf_device(struct interface *ifp);
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 9248177724..a613c89b7e 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -423,11 +423,9 @@ const char *pim_ifchannel_ifassert_name(enum pim_ifassert_state ifassert_state)
*/
void reset_ifassert_state(struct pim_ifchannel *ch)
{
- struct in_addr any = {.s_addr = INADDR_ANY};
-
THREAD_OFF(ch->t_ifassert_timer);
- pim_ifassert_winner_set(ch, PIM_IFASSERT_NOINFO, any,
+ pim_ifassert_winner_set(ch, PIM_IFASSERT_NOINFO, PIMADDR_ANY,
router->infinite_assert_metric);
}
@@ -587,7 +585,7 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, pim_sgaddr *sg,
ch->ifassert_my_metric = pim_macro_ch_my_assert_metric_eval(ch);
ch->ifassert_winner_metric = pim_macro_ch_my_assert_metric_eval(ch);
- ch->ifassert_winner.s_addr = INADDR_ANY;
+ ch->ifassert_winner = PIMADDR_ANY;
/* Assert state */
ch->t_ifassert_timer = NULL;
@@ -688,8 +686,8 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
struct pim_rpf rpf;
rpf.source_nexthop.interface = ifp;
- rpf.rpf_addr.u.prefix4 =
- pim_ifp->primary_address;
+ pim_addr_to_prefix(&rpf.rpf_addr,
+ pim_ifp->primary_address);
pim_jp_agg_single_upstream_send(
&rpf, ch->upstream, 0);
}
@@ -733,11 +731,12 @@ static int on_ifjoin_prune_pending_timer(struct thread *t)
}
static void check_recv_upstream(int is_join, struct interface *recv_ifp,
- struct in_addr upstream, pim_sgaddr *sg,
+ pim_addr upstream, pim_sgaddr *sg,
uint8_t source_flags, int holdtime)
{
struct pim_upstream *up;
struct pim_interface *pim_ifp = recv_ifp->info;
+ pim_addr rpf_addr;
/* Upstream (S,G) in Joined state ? */
up = pim_upstream_find(pim_ifp->pim, sg);
@@ -755,16 +754,13 @@ static void check_recv_upstream(int is_join, struct interface *recv_ifp,
return;
}
+ rpf_addr = pim_addr_from_prefix(&up->rpf.rpf_addr);
+
/* upstream directed to RPF'(S,G) ? */
- if (upstream.s_addr != up->rpf.rpf_addr.u.prefix4.s_addr) {
- char up_str[INET_ADDRSTRLEN];
- char rpf_str[PREFIX_STRLEN];
- pim_inet4_dump("<up?>", upstream, up_str, sizeof(up_str));
- pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_str,
- sizeof(rpf_str));
+ if (pim_addr_cmp(upstream, rpf_addr)) {
zlog_warn(
- "%s %s: (S,G)=%s upstream=%s not directed to RPF'(S,G)=%s on interface %s",
- __FILE__, __func__, up->sg_str, up_str, rpf_str,
+ "%s %s: (S,G)=%s upstream=%pPAs not directed to RPF'(S,G)=%pPAs on interface %s",
+ __FILE__, __func__, up->sg_str, &upstream, &rpf_addr,
recv_ifp->name);
return;
}
@@ -798,7 +794,7 @@ static void check_recv_upstream(int is_join, struct interface *recv_ifp,
}
static int nonlocal_upstream(int is_join, struct interface *recv_ifp,
- struct in_addr upstream, pim_sgaddr *sg,
+ pim_addr upstream, pim_sgaddr *sg,
uint8_t source_flags, uint16_t holdtime)
{
struct pim_interface *recv_pim_ifp;
@@ -807,18 +803,16 @@ static int nonlocal_upstream(int is_join, struct interface *recv_ifp,
recv_pim_ifp = recv_ifp->info;
assert(recv_pim_ifp);
- is_local = (upstream.s_addr == recv_pim_ifp->primary_address.s_addr);
+ is_local = !pim_addr_cmp(upstream, recv_pim_ifp->primary_address);
if (is_local)
return 0;
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- char up_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- zlog_warn("%s: recv %s (S,G)=%pSG to non-local upstream=%s on %s",
- __func__, is_join ? "join" : "prune",
- sg, up_str, recv_ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_warn(
+ "%s: recv %s (S,G)=%pSG to non-local upstream=%pPAs on %s",
+ __func__, is_join ? "join" : "prune", sg, &upstream,
+ recv_ifp->name);
/*
* Since recv upstream addr was not directed to our primary
@@ -851,8 +845,8 @@ static void pim_ifchannel_ifjoin_handler(struct pim_ifchannel *ch,
}
-void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
- struct in_addr upstream, pim_sgaddr *sg,
+void pim_ifchannel_join_add(struct interface *ifp, pim_addr neigh_addr,
+ pim_addr upstream, pim_sgaddr *sg,
uint8_t source_flags, uint16_t holdtime)
{
struct pim_interface *pim_ifp;
@@ -883,11 +877,8 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
address of the join message is our primary address.
*/
if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
- char neigh_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<neigh?>", neigh_addr, neigh_str,
- sizeof(neigh_str));
- zlog_warn("%s: Assert Loser recv Join%s from %s on %s",
- __func__, ch->sg_str, neigh_str, ifp->name);
+ zlog_warn("%s: Assert Loser recv Join%s from %pI4 on %s",
+ __func__, ch->sg_str, &neigh_addr, ifp->name);
assert_action_a5(ch);
}
@@ -1016,7 +1007,7 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
}
}
-void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
+void pim_ifchannel_prune(struct interface *ifp, pim_addr upstream,
pim_sgaddr *sg, uint8_t source_flags,
uint16_t holdtime)
{
@@ -1235,10 +1226,8 @@ int pim_ifchannel_local_membership_add(struct interface *ifp, pim_sgaddr *sg,
struct prefix_list *plist = prefix_list_lookup(
AFI_IP, pim->spt.plist);
struct prefix g;
- g.family = AF_INET;
- g.prefixlen = IPV4_MAX_BITLEN;
- g.u.prefix4 = up->sg.grp;
+ pim_addr_to_prefix(&g, up->sg.grp);
if (prefix_list_apply(plist, &g)
== PREFIX_DENY) {
pim_channel_add_oif(
@@ -1368,23 +1357,17 @@ void pim_ifchannel_update_my_assert_metric(struct pim_ifchannel *ch)
if (pim_assert_metric_match(&my_metric_new, &ch->ifassert_my_metric))
return;
- if (PIM_DEBUG_PIM_EVENTS) {
- char old_addr_str[INET_ADDRSTRLEN];
- char new_addr_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<old_addr?>", ch->ifassert_my_metric.ip_address,
- old_addr_str, sizeof(old_addr_str));
- pim_inet4_dump("<new_addr?>", my_metric_new.ip_address,
- new_addr_str, sizeof(new_addr_str));
+ if (PIM_DEBUG_PIM_EVENTS)
zlog_debug(
- "%s: my_assert_metric(%pPAs,%pPAs,%s) changed from %u,%u,%u,%s to %u,%u,%u,%s",
+ "%s: my_assert_metric(%pPAs,%pPAs,%s) changed from %u,%u,%u,%pPAs to %u,%u,%u,%pPAs",
__func__, &ch->sg.src, &ch->sg.grp, ch->interface->name,
ch->ifassert_my_metric.rpt_bit_flag,
ch->ifassert_my_metric.metric_preference,
- ch->ifassert_my_metric.route_metric, old_addr_str,
+ ch->ifassert_my_metric.route_metric,
+ &ch->ifassert_my_metric.ip_address,
my_metric_new.rpt_bit_flag,
my_metric_new.metric_preference,
- my_metric_new.route_metric, new_addr_str);
- }
+ my_metric_new.route_metric, &my_metric_new.ip_address);
ch->ifassert_my_metric = my_metric_new;
diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h
index ab405202e3..0c5b6780d1 100644
--- a/pimd/pim_ifchannel.h
+++ b/pimd/pim_ifchannel.h
@@ -126,10 +126,10 @@ void pim_ifchannel_delete_on_noinfo(struct interface *ifp);
struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp, pim_sgaddr *sg);
struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, pim_sgaddr *sg,
uint8_t ch_flags, int up_flags);
-void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
- struct in_addr upstream, pim_sgaddr *sg,
+void pim_ifchannel_join_add(struct interface *ifp, pim_addr neigh_addr,
+ pim_addr upstream, pim_sgaddr *sg,
uint8_t source_flags, uint16_t holdtime);
-void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
+void pim_ifchannel_prune(struct interface *ifp, pim_addr upstream,
pim_sgaddr *sg, uint8_t source_flags,
uint16_t holdtime);
int pim_ifchannel_local_membership_add(struct interface *ifp, pim_sgaddr *sg,
diff --git a/pimd/pim_join.c b/pimd/pim_join.c
index fa2d8d462b..51a3ceee15 100644
--- a/pimd/pim_join.c
+++ b/pimd/pim_join.c
@@ -54,23 +54,17 @@ static void on_trace(const char *label, struct interface *ifp,
}
static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
- uint16_t holdtime, struct in_addr upstream,
- pim_sgaddr *sg, uint8_t source_flags)
+ uint16_t holdtime, pim_addr upstream, pim_sgaddr *sg,
+ uint8_t source_flags)
{
struct pim_interface *pim_ifp = NULL;
- if (PIM_DEBUG_PIM_TRACE) {
- char up_str[INET_ADDRSTRLEN];
- char neigh_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str,
- sizeof(neigh_str));
- zlog_debug("%s: join (S,G)=%pSG rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
- __func__, sg,
- !!(source_flags & PIM_RPT_BIT_MASK),
- !!(source_flags & PIM_WILDCARD_BIT_MASK), up_str,
- holdtime, neigh_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "%s: join (S,G)=%pSG rpt=%d wc=%d upstream=%pPAs holdtime=%d from %pPA on %s",
+ __func__, sg, !!(source_flags & PIM_RPT_BIT_MASK),
+ !!(source_flags & PIM_WILDCARD_BIT_MASK), &upstream,
+ holdtime, &neigh->source_addr, ifp->name);
pim_ifp = ifp->info;
assert(pim_ifp);
@@ -84,6 +78,7 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
if ((source_flags & PIM_RPT_BIT_MASK)
&& (source_flags & PIM_WILDCARD_BIT_MASK)) {
struct pim_rpf *rp = RP(pim_ifp->pim, sg->grp);
+ pim_addr rpf_addr;
if (!rp) {
zlog_warn("%s: Lookup of RP failed for %pSG", __func__,
@@ -94,13 +89,11 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
* If the RP sent in the message is not
* our RP for the group, drop the message
*/
- if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr) {
- char local_rp[INET_ADDRSTRLEN];
- pim_inet4_dump("<local?>", rp->rpf_addr.u.prefix4,
- local_rp, sizeof(local_rp));
+ rpf_addr = pim_addr_from_prefix(&rp->rpf_addr);
+ if (pim_addr_cmp(sg->src, rpf_addr)) {
zlog_warn(
- "%s: Specified RP(%pPAs) in join is different than our configured RP(%s)",
- __func__, &sg->src, local_rp);
+ "%s: Specified RP(%pPAs) in join is different than our configured RP(%pPAs)",
+ __func__, &sg->src, &rpf_addr);
return;
}
@@ -120,24 +113,17 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
}
static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh,
- uint16_t holdtime, struct in_addr upstream,
- pim_sgaddr *sg, uint8_t source_flags)
+ uint16_t holdtime, pim_addr upstream, pim_sgaddr *sg,
+ uint8_t source_flags)
{
struct pim_interface *pim_ifp = NULL;
- if (PIM_DEBUG_PIM_TRACE) {
- char up_str[INET_ADDRSTRLEN];
- char neigh_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str));
- pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str,
- sizeof(neigh_str));
- zlog_debug("%s: prune (S,G)=%pSG rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s",
- __func__, sg,
- source_flags & PIM_RPT_BIT_MASK,
- source_flags & PIM_WILDCARD_BIT_MASK, up_str,
- holdtime,
- neigh_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug(
+ "%s: prune (S,G)=%pSG rpt=%d wc=%d upstream=%pPAs holdtime=%d from %pPA on %s",
+ __func__, sg, source_flags & PIM_RPT_BIT_MASK,
+ source_flags & PIM_WILDCARD_BIT_MASK, &upstream,
+ holdtime, &neigh->source_addr, ifp->name);
pim_ifp = ifp->info;
assert(pim_ifp);
@@ -165,7 +151,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
struct in_addr src_addr, uint8_t *tlv_buf,
int tlv_buf_size)
{
- struct prefix msg_upstream_addr;
+ pim_addr msg_upstream_addr;
+ bool wrong_af = false;
struct pim_interface *pim_ifp;
uint8_t msg_num_groups;
uint16_t msg_holdtime;
@@ -184,8 +171,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
/*
Parse ucast addr
*/
- addr_offset =
- pim_parse_addr_ucast(&msg_upstream_addr, buf, pastend - buf);
+ addr_offset = pim_parse_addr_ucast(&msg_upstream_addr, buf,
+ pastend - buf, &wrong_af);
if (addr_offset < 1) {
char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
@@ -198,12 +185,12 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
/*
Check upstream address family
*/
- if (msg_upstream_addr.family != AF_INET) {
+ if (wrong_af) {
char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn(
- "%s: ignoring join/prune directed to unexpected addr family=%d from %s on %s",
- __func__, msg_upstream_addr.family, src_str, ifp->name);
+ "%s: ignoring join/prune directed to unexpected addr family from %s on %s",
+ __func__, src_str, ifp->name);
return -2;
}
@@ -226,14 +213,11 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
if (PIM_DEBUG_PIM_J_P) {
char src_str[INET_ADDRSTRLEN];
- char upstream_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
- pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
- upstream_str, sizeof(upstream_str));
zlog_debug(
- "%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s",
- __func__, upstream_str, msg_num_groups, msg_holdtime,
- src_str, ifp->name);
+ "%s: join/prune upstream=%pPAs groups=%d holdtime=%d from %s on %s",
+ __func__, &msg_upstream_addr, msg_num_groups,
+ msg_holdtime, src_str, ifp->name);
}
/* Scan groups */
@@ -271,14 +255,11 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
if (PIM_DEBUG_PIM_J_P) {
char src_str[INET_ADDRSTRLEN];
- char upstream_str[INET_ADDRSTRLEN];
pim_inet4_dump("<src?>", src_addr, src_str,
sizeof(src_str));
- pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4,
- upstream_str, sizeof(upstream_str));
zlog_debug(
- "%s: join/prune upstream=%s group=%pPA/32 join_src=%d prune_src=%d from %s on %s",
- __func__, upstream_str, &sg.grp,
+ "%s: join/prune upstream=%pPAs group=%pPA/32 join_src=%d prune_src=%d from %s on %s",
+ __func__, &msg_upstream_addr, &sg.grp,
msg_num_joined_sources, msg_num_pruned_sources,
src_str, ifp->name);
}
@@ -300,9 +281,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
if (filtered)
continue;
- recv_join(ifp, neigh, msg_holdtime,
- msg_upstream_addr.u.prefix4, &sg,
- msg_source_flags);
+ recv_join(ifp, neigh, msg_holdtime, msg_upstream_addr,
+ &sg, msg_source_flags);
if (pim_addr_is_any(sg.src)) {
starg_ch = pim_ifchannel_find(ifp, &sg);
@@ -326,9 +306,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
if (filtered)
continue;
- recv_prune(ifp, neigh, msg_holdtime,
- msg_upstream_addr.u.prefix4, &sg,
- msg_source_flags);
+ recv_prune(ifp, neigh, msg_holdtime, msg_upstream_addr,
+ &sg, msg_source_flags);
/*
* So if we are receiving a S,G,RPT prune
* before we have any data for that S,G
@@ -516,7 +495,7 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
grp = &msg->groups[0];
curr_ptr = (uint8_t *)grp;
packet_size = sizeof(struct pim_msg_header);
- packet_size += sizeof(struct pim_encoded_ipv4_unicast);
+ packet_size += sizeof(pim_encoded_unicast);
packet_size +=
4; // reserved (1) + groups (1) + holdtime (2)
@@ -525,14 +504,11 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
}
if (PIM_DEBUG_PIM_J_P) {
char dst_str[INET_ADDRSTRLEN];
- char grp_str[INET_ADDRSTRLEN];
pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4,
dst_str, sizeof(dst_str));
- pim_inet4_dump("<grp?>", group->group, grp_str,
- sizeof(grp_str));
zlog_debug(
- "%s: sending (G)=%s to upstream=%s on interface %s",
- __func__, grp_str, dst_str,
+ "%s: sending (G)=%pPAs to upstream=%s on interface %s",
+ __func__, &group->group, dst_str,
rpf->source_nexthop.interface->name);
}
@@ -564,7 +540,7 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)
grp = &msg->groups[0];
curr_ptr = (uint8_t *)grp;
packet_size = sizeof(struct pim_msg_header);
- packet_size += sizeof(struct pim_encoded_ipv4_unicast);
+ packet_size += sizeof(pim_encoded_unicast);
packet_size +=
4; // reserved (1) + groups (1) + holdtime (2)
diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c
index feeef15f81..42ad5dcd1e 100644
--- a/pimd/pim_jp_agg.c
+++ b/pimd/pim_jp_agg.c
@@ -60,13 +60,7 @@ int pim_jp_agg_group_list_cmp(void *arg1, void *arg2)
const struct pim_jp_agg_group *jag2 =
(const struct pim_jp_agg_group *)arg2;
- if (jag1->group.s_addr < jag2->group.s_addr)
- return -1;
-
- if (jag1->group.s_addr > jag2->group.s_addr)
- return 1;
-
- return 0;
+ return pim_addr_cmp(jag1->group, jag2->group);
}
static int pim_jp_agg_src_cmp(void *arg1, void *arg2)
@@ -163,17 +157,10 @@ void pim_jp_agg_remove_group(struct list *group, struct pim_upstream *up,
}
if (nbr) {
- if (PIM_DEBUG_TRACE) {
- char src_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<src?>", nbr->source_addr, src_str,
- sizeof(src_str));
- zlog_debug(
- "up %s remove from nbr %s/%s jp-agg-list",
- up->sg_str,
- nbr->interface->name,
- src_str);
- }
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("up %s remove from nbr %s/%pPAs jp-agg-list",
+ up->sg_str, nbr->interface->name,
+ &nbr->source_addr);
}
if (js) {
@@ -290,17 +277,11 @@ void pim_jp_agg_add_group(struct list *group, struct pim_upstream *up,
}
if (nbr) {
- if (PIM_DEBUG_TRACE) {
- char src_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<src?>", nbr->source_addr, src_str,
- sizeof(src_str));
- zlog_debug(
- "up %s add to nbr %s/%s jp-agg-list",
- up->sg_str,
- up->rpf.source_nexthop.interface->name,
- src_str);
- }
+ if (PIM_DEBUG_TRACE)
+ zlog_debug("up %s add to nbr %s/%pPAs jp-agg-list",
+ up->sg_str,
+ up->rpf.source_nexthop.interface->name,
+ &nbr->source_addr);
}
if (!js) {
diff --git a/pimd/pim_macro.c b/pimd/pim_macro.c
index aa41033cea..0896c52a75 100644
--- a/pimd/pim_macro.c
+++ b/pimd/pim_macro.c
@@ -132,7 +132,7 @@ int pim_macro_ch_lost_assert(const struct pim_ifchannel *ch)
return 0; /* false */
/* AssertWinner(S,G,I) == me ? */
- if (ch->ifassert_winner.s_addr == pim_ifp->primary_address.s_addr)
+ if (!pim_addr_cmp(ch->ifassert_winner, pim_ifp->primary_address))
return 0; /* false */
spt_assert_metric = pim_macro_spt_assert_metric(
@@ -170,7 +170,7 @@ int pim_macro_chisin_pim_include(const struct pim_ifchannel *ch)
return 0; /* false */
/* OR AssertWinner(S,G,I) == me ? */
- if (ch->ifassert_winner.s_addr == pim_ifp->primary_address.s_addr)
+ if (!pim_addr_cmp(ch->ifassert_winner, pim_ifp->primary_address))
return 1; /* true */
/*
@@ -412,8 +412,8 @@ int pim_macro_assert_tracking_desired_eval(const struct pim_ifchannel *ch)
return 1; /* true */
/* AssertWinner(S,G,I) == me ? */
- if (ch->ifassert_winner.s_addr
- == pim_ifp->primary_address.s_addr)
+ if (!pim_addr_cmp(ch->ifassert_winner,
+ pim_ifp->primary_address))
return 1; /* true */
}
diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c
index c493ded0c6..e25cf11549 100644
--- a/pimd/pim_msg.c
+++ b/pimd/pim_msg.c
@@ -97,6 +97,68 @@ uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
return buf + PIM_ENCODED_IPV4_SOURCE_SIZE;
}
+uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr,
+ uint8_t bits)
+{
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV6; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ buf[2] = bits;
+ buf[3] = 128; /* mask len */
+ buf += 4;
+
+ memcpy(buf, &addr, sizeof(addr));
+ buf += sizeof(addr);
+
+ return buf;
+}
+
+uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr)
+{
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV6; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ buf += 2;
+
+ memcpy(buf, &addr, sizeof(addr));
+ buf += sizeof(addr);
+
+ return buf;
+}
+
+uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr)
+{
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV6; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ buf[2] = '\0'; /* reserved */
+ buf[3] = 128; /* mask len */
+ buf += 4;
+
+ memcpy(buf, &addr, sizeof(addr));
+ buf += sizeof(addr);
+
+ return buf;
+}
+
+#if PIM_IPV == 4 || !defined(PIM_V6_TEMP_BREAK)
+#define pim_msg_addr_encode(what) pim_msg_addr_encode_ipv4_##what
+#else
+#define pim_msg_addr_encode(what) pim_msg_addr_encode_ipv6_##what
+#endif
+
+uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr)
+{
+ return pim_msg_addr_encode(ucast)(buf, addr);
+}
+
+uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr)
+{
+ return pim_msg_addr_encode(group)(buf, addr);
+}
+
+uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits)
+{
+ return pim_msg_addr_encode(source)(buf, addr, bits);
+}
+
/*
* For the given 'struct pim_jp_sources' list
* determine the size_t it would take up.
@@ -109,10 +171,10 @@ size_t pim_msg_get_jp_group_size(struct list *sources)
if (!sources)
return 0;
- size += sizeof(struct pim_encoded_group_ipv4);
+ size += sizeof(pim_encoded_group);
size += 4; // Joined sources (2) + Pruned Sources (2)
- size += sizeof(struct pim_encoded_source_ipv4) * sources->count;
+ size += sizeof(pim_encoded_source) * sources->count;
js = listgetdata(listhead(sources));
if (js && pim_addr_is_any(js->up->sg.src) && js->is_join) {
@@ -137,8 +199,7 @@ size_t pim_msg_get_jp_group_size(struct list *sources)
if (child->rpf.source_nexthop.interface &&
!pim_rpf_is_same(&up->rpf,
&child->rpf)) {
- size += sizeof(
- struct pim_encoded_source_ipv4);
+ size += sizeof(pim_encoded_source);
PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
child->flags);
if (PIM_DEBUG_PIM_PACKETS)
@@ -156,8 +217,7 @@ size_t pim_msg_get_jp_group_size(struct list *sources)
* but it's inherited OIL is empty. So just
* prune it off.
*/
- size += sizeof(
- struct pim_encoded_source_ipv4);
+ size += sizeof(pim_encoded_source);
PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
child->flags);
if (PIM_DEBUG_PIM_PACKETS)
@@ -179,12 +239,12 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
struct listnode *node, *nnode;
struct pim_jp_sources *source;
struct pim_upstream *up = NULL;
- struct in_addr stosend;
+ pim_addr stosend;
uint8_t bits;
uint8_t tgroups = 0;
memset(grp, 0, size);
- pim_msg_addr_encode_ipv4_group((uint8_t *)&grp->g, sgs->group);
+ pim_msg_addr_encode_group((uint8_t *)&grp->g, sgs->group);
for (ALL_LIST_ELEMENTS(sgs->sources, node, nnode, source)) {
/* number of joined/pruned sources */
@@ -198,7 +258,7 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
struct pim_rpf *rpf = pim_rp_g(pim, source->up->sg.grp);
bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT
| PIM_ENCODE_RPT_BIT;
- stosend = rpf->rpf_addr.u.prefix4;
+ stosend = pim_addr_from_prefix(&rpf->rpf_addr);
/* Only Send SGRpt in case of *,G Join */
if (source->is_join)
up = source->up;
@@ -207,8 +267,8 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
stosend = source->up->sg.src;
}
- pim_msg_addr_encode_ipv4_source((uint8_t *)&grp->s[tgroups],
- stosend, bits);
+ pim_msg_addr_encode_source((uint8_t *)&grp->s[tgroups], stosend,
+ bits);
tgroups++;
}
@@ -218,11 +278,11 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
for (ALL_LIST_ELEMENTS(up->sources, node, nnode, child)) {
if (PIM_UPSTREAM_FLAG_TEST_SEND_SG_RPT_PRUNE(
child->flags)) {
- pim_msg_addr_encode_ipv4_source(
+ pim_msg_addr_encode_source(
(uint8_t *)&grp->s[tgroups],
child->sg.src,
- PIM_ENCODE_SPARSE_BIT
- | PIM_ENCODE_RPT_BIT);
+ PIM_ENCODE_SPARSE_BIT |
+ PIM_ENCODE_RPT_BIT);
tgroups++;
PIM_UPSTREAM_FLAG_UNSET_SEND_SG_RPT_PRUNE(
child->flags);
diff --git a/pimd/pim_msg.h b/pimd/pim_msg.h
index 2d69a4b03a..522e94504a 100644
--- a/pimd/pim_msg.h
+++ b/pimd/pim_msg.h
@@ -75,6 +75,12 @@ struct pim_encoded_ipv4_unicast {
struct in_addr addr;
} __attribute__((packed));
+struct pim_encoded_ipv6_unicast {
+ uint8_t family;
+ uint8_t reserved;
+ struct in6_addr addr;
+} __attribute__((packed));
+
/*
* Encoded Group format. RFC 4601 Sec 4.9.1
* 0 1 2 3
@@ -103,6 +109,23 @@ struct pim_encoded_group_ipv4 {
struct in_addr addr;
} __attribute__((packed));
+struct pim_encoded_group_ipv6 {
+ uint8_t family;
+ uint8_t ne;
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+ uint8_t sz : 1; /* scope zone bit */
+ uint8_t reserved : 6; /* Reserved */
+ uint8_t bidir : 1; /* Bidir bit */
+#elif (BYTE_ORDER == BIG_ENDIAN)
+ uint8_t bidir : 1; /* Bidir bit */
+ uint8_t reserved : 6; /* Reserved */
+ uint8_t sz : 1; /* scope zone bit */
+#else
+#error "Please set byte order"
+#endif
+ uint8_t mask;
+ struct in6_addr addr;
+} __attribute__((packed));
/*
* Encoded Source format. RFC 4601 Sec 4.9.1
@@ -122,16 +145,36 @@ struct pim_encoded_source_ipv4 {
struct in_addr addr;
} __attribute__((packed));
+struct pim_encoded_source_ipv6 {
+ uint8_t family;
+ uint8_t ne;
+ uint8_t bits;
+ uint8_t mask;
+ struct in6_addr addr;
+} __attribute__((packed));
+
+/* clang-format off */
+#if PIM_IPV == 4
+typedef struct pim_encoded_ipv4_unicast pim_encoded_unicast;
+typedef struct pim_encoded_group_ipv4 pim_encoded_group;
+typedef struct pim_encoded_source_ipv4 pim_encoded_source;
+#else
+typedef struct pim_encoded_ipv6_unicast pim_encoded_unicast;
+typedef struct pim_encoded_group_ipv6 pim_encoded_group;
+typedef struct pim_encoded_source_ipv6 pim_encoded_source;
+#endif
+/* clang-format on */
+
struct pim_jp_groups {
- struct pim_encoded_group_ipv4 g;
+ pim_encoded_group g;
uint16_t joins;
uint16_t prunes;
- struct pim_encoded_source_ipv4 s[1];
+ pim_encoded_source s[1];
} __attribute__((packed));
struct pim_jp {
struct pim_msg_header header;
- struct pim_encoded_ipv4_unicast addr;
+ pim_encoded_unicast addr;
uint8_t reserved;
uint8_t num_groups;
uint16_t holdtime;
@@ -149,6 +192,14 @@ uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr);
uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
uint8_t bits);
+uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr);
+uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr);
+uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr,
+ uint8_t bits);
+
+uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr);
+uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr);
+uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits);
size_t pim_msg_get_jp_group_size(struct list *sources);
size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c
index 530c2e429b..6e3d2739e7 100644
--- a/pimd/pim_neighbor.c
+++ b/pimd/pim_neighbor.c
@@ -58,10 +58,8 @@ static void dr_election_by_addr(struct interface *ifp)
}
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) {
- if (ntohl(neigh->source_addr.s_addr)
- > ntohl(pim_ifp->pim_dr_addr.s_addr)) {
+ if (pim_addr_cmp(neigh->source_addr, pim_ifp->pim_dr_addr) > 0)
pim_ifp->pim_dr_addr = neigh->source_addr;
- }
}
}
@@ -85,15 +83,14 @@ static void dr_election_by_pri(struct interface *ifp)
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) {
if (PIM_DEBUG_PIM_TRACE) {
- zlog_info("%s: neigh pri %u addr %x if dr addr %x",
+ zlog_info("%s: neigh pri %u addr %pPA if dr addr %pPA",
__func__, neigh->dr_priority,
- ntohl(neigh->source_addr.s_addr),
- ntohl(pim_ifp->pim_dr_addr.s_addr));
+ &neigh->source_addr, &pim_ifp->pim_dr_addr);
}
- if ((neigh->dr_priority > dr_pri)
- || ((neigh->dr_priority == dr_pri)
- && (ntohl(neigh->source_addr.s_addr)
- > ntohl(pim_ifp->pim_dr_addr.s_addr)))) {
+ if ((neigh->dr_priority > dr_pri) ||
+ ((neigh->dr_priority == dr_pri) &&
+ (pim_addr_cmp(neigh->source_addr, pim_ifp->pim_dr_addr) >
+ 0))) {
pim_ifp->pim_dr_addr = neigh->source_addr;
dr_pri = neigh->dr_priority;
}
@@ -110,7 +107,7 @@ static void dr_election_by_pri(struct interface *ifp)
int pim_if_dr_election(struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
- struct in_addr old_dr_addr;
+ pim_addr old_dr_addr;
++pim_ifp->pim_dr_election_count;
@@ -123,18 +120,13 @@ int pim_if_dr_election(struct interface *ifp)
}
/* DR changed ? */
- if (old_dr_addr.s_addr != pim_ifp->pim_dr_addr.s_addr) {
-
- if (PIM_DEBUG_PIM_EVENTS) {
- char dr_old_str[INET_ADDRSTRLEN];
- char dr_new_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<old_dr?>", old_dr_addr, dr_old_str,
- sizeof(dr_old_str));
- pim_inet4_dump("<new_dr?>", pim_ifp->pim_dr_addr,
- dr_new_str, sizeof(dr_new_str));
- zlog_debug("%s: DR was %s now is %s on interface %s",
- __func__, dr_old_str, dr_new_str, ifp->name);
- }
+ if (pim_addr_cmp(old_dr_addr, pim_ifp->pim_dr_addr)) {
+
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug(
+ "%s: DR was %pPA now is %pPA on interface %s",
+ __func__, &old_dr_addr, &pim_ifp->pim_dr_addr,
+ ifp->name);
pim_ifp->pim_dr_election_last =
pim_time_monotonic_sec(); /* timestamp */
@@ -218,14 +210,10 @@ static int on_neighbor_timer(struct thread *t)
ifp = neigh->interface;
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", neigh->source_addr, src_str,
- sizeof(src_str));
+ if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
- "Expired %d sec holdtime for neighbor %s on interface %s",
- neigh->holdtime, src_str, ifp->name);
- }
+ "Expired %d sec holdtime for neighbor %pPA on interface %s",
+ neigh->holdtime, &neigh->source_addr, ifp->name);
snprintf(msg, sizeof(msg), "%d-sec holdtime expired", neigh->holdtime);
pim_neighbor_delete(ifp, neigh, msg);
@@ -255,14 +243,10 @@ void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime)
return;
}
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", neigh->source_addr, src_str,
- sizeof(src_str));
- zlog_debug("%s: starting %u sec timer for neighbor %s on %s",
- __func__, neigh->holdtime, src_str,
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug("%s: starting %u sec timer for neighbor %pPA on %s",
+ __func__, neigh->holdtime, &neigh->source_addr,
neigh->interface->name);
- }
thread_add_timer(router->master, on_neighbor_timer, neigh,
neigh->holdtime, &neigh->t_expire_timer);
@@ -273,17 +257,14 @@ static int on_neighbor_jp_timer(struct thread *t)
struct pim_neighbor *neigh = THREAD_ARG(t);
struct pim_rpf rpf;
- if (PIM_DEBUG_PIM_TRACE) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", neigh->source_addr, src_str,
- sizeof(src_str));
- zlog_debug("%s:Sending JP Agg to %s on %s with %d groups",
- __func__, src_str, neigh->interface->name,
+ if (PIM_DEBUG_PIM_TRACE)
+ zlog_debug("%s:Sending JP Agg to %pPA on %s with %d groups",
+ __func__, &neigh->source_addr,
+ neigh->interface->name,
neigh->upstream_jp_agg->count);
- }
rpf.source_nexthop.interface = neigh->interface;
- rpf.rpf_addr.u.prefix4 = neigh->source_addr;
+ pim_addr_to_prefix(&rpf.rpf_addr, neigh->source_addr);
pim_joinprune_send(&rpf, neigh->upstream_jp_agg);
thread_add_timer(router->master, on_neighbor_jp_timer, neigh,
@@ -300,7 +281,7 @@ static void pim_neighbor_start_jp_timer(struct pim_neighbor *neigh)
}
static struct pim_neighbor *
-pim_neighbor_new(struct interface *ifp, struct in_addr source_addr,
+pim_neighbor_new(struct interface *ifp, pim_addr source_addr,
pim_hello_options hello_options, uint16_t holdtime,
uint16_t propagation_delay, uint16_t override_interval,
uint32_t dr_priority, uint32_t generation_id,
@@ -308,7 +289,6 @@ pim_neighbor_new(struct interface *ifp, struct in_addr source_addr,
{
struct pim_interface *pim_ifp;
struct pim_neighbor *neigh;
- char src_str[INET_ADDRSTRLEN];
assert(ifp);
pim_ifp = ifp->info;
@@ -343,15 +323,12 @@ pim_neighbor_new(struct interface *ifp, struct in_addr source_addr,
*/
PIM_IF_FLAG_UNSET_HELLO_SENT(pim_ifp->flags);
- pim_inet4_dump("<src?>", source_addr, src_str, sizeof(src_str));
-
- if (PIM_DEBUG_PIM_EVENTS) {
- zlog_debug("%s: creating PIM neighbor %s on interface %s",
- __func__, src_str, ifp->name);
- }
+ if (PIM_DEBUG_PIM_EVENTS)
+ zlog_debug("%s: creating PIM neighbor %pPA on interface %s",
+ __func__, &source_addr, ifp->name);
- zlog_notice("PIM NEIGHBOR UP: neighbor %s on interface %s", src_str,
- ifp->name);
+ zlog_notice("PIM NEIGHBOR UP: neighbor %pPA on interface %s",
+ &source_addr, ifp->name);
if (neigh->propagation_delay_msec
> pim_ifp->pim_neighbors_highest_propagation_delay_msec) {
@@ -448,7 +425,7 @@ struct pim_neighbor *pim_neighbor_find_by_secondary(struct interface *ifp,
}
struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
- struct in_addr source_addr)
+ pim_addr source_addr)
{
struct pim_interface *pim_ifp;
struct listnode *node;
@@ -462,7 +439,7 @@ struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
return NULL;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, node, neigh)) {
- if (source_addr.s_addr == neigh->source_addr.s_addr) {
+ if (!pim_addr_cmp(source_addr, neigh->source_addr)) {
return neigh;
}
}
@@ -470,6 +447,15 @@ struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
return NULL;
}
+struct pim_neighbor *pim_neighbor_find_prefix(struct interface *ifp,
+ const struct prefix *src_prefix)
+{
+ pim_addr addr;
+
+ addr = pim_addr_from_prefix(src_prefix);
+ return pim_neighbor_find(ifp, addr);
+}
+
/*
* Find the *one* interface out
* this interface. If more than
@@ -486,7 +472,7 @@ struct pim_neighbor *pim_neighbor_find_if(struct interface *ifp)
}
struct pim_neighbor *
-pim_neighbor_add(struct interface *ifp, struct in_addr source_addr,
+pim_neighbor_add(struct interface *ifp, pim_addr source_addr,
pim_hello_options hello_options, uint16_t holdtime,
uint16_t propagation_delay, uint16_t override_interval,
uint32_t dr_priority, uint32_t generation_id,
@@ -507,11 +493,8 @@ pim_neighbor_add(struct interface *ifp, struct in_addr source_addr,
listnode_add(pim_ifp->pim_neighbor_list, neigh);
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
- char str[INET_ADDRSTRLEN];
- pim_inet4_dump("<nht_nbr?>", source_addr, str, sizeof(str));
- zlog_debug("%s: neighbor %s added ", __func__, str);
- }
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
+ zlog_debug("%s: neighbor %pPA added ", __func__, &source_addr);
/*
RFC 4601: 4.3.2. DR Election
@@ -610,14 +593,12 @@ void pim_neighbor_delete(struct interface *ifp, struct pim_neighbor *neigh,
const char *delete_message)
{
struct pim_interface *pim_ifp;
- char src_str[INET_ADDRSTRLEN];
pim_ifp = ifp->info;
assert(pim_ifp);
- pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
- zlog_notice("PIM NEIGHBOR DOWN: neighbor %s on interface %s: %s",
- src_str, ifp->name, delete_message);
+ zlog_notice("PIM NEIGHBOR DOWN: neighbor %pPA on interface %s: %s",
+ &neigh->source_addr, ifp->name, delete_message);
THREAD_OFF(neigh->t_expire_timer);
@@ -664,8 +645,8 @@ void pim_neighbor_delete(struct interface *ifp, struct pim_neighbor *neigh,
}
if (PIM_DEBUG_PIM_TRACE) {
- zlog_debug("%s: deleting PIM neighbor %s on interface %s",
- __func__, src_str, ifp->name);
+ zlog_debug("%s: deleting PIM neighbor %pPA on interface %s",
+ __func__, &neigh->source_addr, ifp->name);
}
listnode_delete(pim_ifp->pim_neighbor_list, neigh);
@@ -720,8 +701,7 @@ struct prefix *pim_neighbor_find_secondary(struct pim_neighbor *neigh,
administrator in a rate-limited manner.
*/
static void delete_from_neigh_addr(struct interface *ifp,
- struct list *addr_list,
- struct in_addr neigh_addr)
+ struct list *addr_list, pim_addr neigh_addr)
{
struct listnode *addr_node;
struct prefix *addr;
@@ -752,24 +732,15 @@ static void delete_from_neigh_addr(struct interface *ifp,
neigh, addr);
if (p) {
char addr_str[INET_ADDRSTRLEN];
- char this_neigh_str[INET_ADDRSTRLEN];
- char other_neigh_str[INET_ADDRSTRLEN];
pim_inet4_dump(
"<addr?>", addr->u.prefix4,
addr_str, sizeof(addr_str));
- pim_inet4_dump("<neigh1?>", neigh_addr,
- this_neigh_str,
- sizeof(this_neigh_str));
- pim_inet4_dump("<neigh2?>",
- neigh->source_addr,
- other_neigh_str,
- sizeof(other_neigh_str));
zlog_info(
- "secondary addr %s recvd from neigh %s deleted from neigh %s on %s",
- addr_str, this_neigh_str,
- other_neigh_str, ifp->name);
+ "secondary addr %s recvd from neigh %pPA deleted from neigh %pPA on %s",
+ addr_str, &neigh_addr,
+ &neigh->source_addr, ifp->name);
listnode_delete(neigh->prefix_list, p);
prefix_free(&p);
diff --git a/pimd/pim_neighbor.h b/pimd/pim_neighbor.h
index 12c469ae2a..2673d22480 100644
--- a/pimd/pim_neighbor.h
+++ b/pimd/pim_neighbor.h
@@ -51,7 +51,9 @@ struct pim_neighbor {
void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime);
void pim_neighbor_free(struct pim_neighbor *neigh);
struct pim_neighbor *pim_neighbor_find(struct interface *ifp,
- struct in_addr source_addr);
+ pim_addr source_addr);
+struct pim_neighbor *pim_neighbor_find_prefix(struct interface *ifp,
+ const struct prefix *src_prefix);
struct pim_neighbor *pim_neighbor_find_by_secondary(struct interface *ifp,
struct prefix *src);
struct pim_neighbor *pim_neighbor_find_if(struct interface *ifp);
@@ -60,7 +62,7 @@ struct pim_neighbor *pim_neighbor_find_if(struct interface *ifp);
#define PIM_NEIGHBOR_SEND_DELAY 0
#define PIM_NEIGHBOR_SEND_NOW 1
struct pim_neighbor *
-pim_neighbor_add(struct interface *ifp, struct in_addr source_addr,
+pim_neighbor_add(struct interface *ifp, pim_addr source_addr,
pim_hello_options hello_options, uint16_t holdtime,
uint16_t propagation_delay, uint16_t override_interval,
uint32_t dr_priority, uint32_t generation_id,
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 26ca48543f..beaa5c802b 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -237,10 +237,7 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
if (!pim_addr_is_any(upstream->sg.src))
continue;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = upstream->sg.grp;
-
+ pim_addr_to_prefix(&grp, upstream->sg.grp);
trp_info = pim_rp_find_match_group(pim, &grp);
if (trp_info == rp)
hash_release(pnc->upstream_hash, upstream);
@@ -338,8 +335,7 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
if (if_is_loopback(ifp) && if_is_loopback(src_ifp))
return true;
- nbr = pim_neighbor_find(ifp,
- znh->nexthop_addr.u.prefix4);
+ nbr = pim_neighbor_find_prefix(ifp, &znh->nexthop_addr);
if (!nbr)
continue;
@@ -362,9 +358,10 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
*/
for (nh = pnc->nexthop; nh; nh = nh->next) {
- struct in_addr nhaddr;
+ pim_addr nhaddr;
switch (nh->type) {
+#if PIM_IPV == 4 || !defined(PIM_V6_TEMP_BREAK)
case NEXTHOP_TYPE_IPV4:
if (nh->ifindex == IFINDEX_INTERNAL)
continue;
@@ -373,7 +370,16 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
case NEXTHOP_TYPE_IPV4_IFINDEX:
nhaddr = nh->gate.ipv4;
break;
+#else
+ case NEXTHOP_TYPE_IPV6:
+ if (nh->ifindex == IFINDEX_INTERNAL)
+ continue;
+ /* fallthru */
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ nhaddr = nh->gate.ipv6;
+ break;
+#endif
case NEXTHOP_TYPE_IFINDEX:
nhaddr = bsr_addr;
break;
@@ -550,9 +556,9 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
if (curr_route_valid
&& !pim_if_connected_to_source(nexthop->interface,
src->u.prefix4)) {
- nbr = pim_neighbor_find(
+ nbr = pim_neighbor_find_prefix(
nexthop->interface,
- nexthop->mrib_nexthop_addr.u.prefix4);
+ &nexthop->mrib_nexthop_addr);
if (!nbr
&& !if_is_loopback(nexthop->interface)) {
if (PIM_DEBUG_PIM_NHT)
@@ -599,8 +605,12 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
ifps[i] =
if_lookup_by_index(nh_node->ifindex, pim->vrf->vrf_id);
if (ifps[i]) {
- nbrs[i] = pim_neighbor_find(ifps[i],
- nh_node->gate.ipv4);
+#if PIM_IPV == 4 || !defined(PIM_V6_TEMP_BREAK)
+ pim_addr nhaddr = nh_node->gate.ipv4;
+#else
+ pim_addr nhaddr = nh_node->gate.ipv6;
+#endif
+ nbrs[i] = pim_neighbor_find(ifps[i], nhaddr);
if (nbrs[i] || pim_if_connected_to_source(ifps[i],
src->u.prefix4))
@@ -789,7 +799,11 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
nbr = pim_neighbor_find_if(ifp1);
/* Overwrite with Nbr address as NH addr */
if (nbr)
+#if PIM_IPV == 4 || !defined(PIM_V6_TEMP_BREAK)
nexthop->gate.ipv4 = nbr->source_addr;
+#else
+ nexthop->gate.ipv6 = nbr->source_addr;
+#endif
else {
// Mark nexthop address to 0 until PIM
// Nbr is resolved.
@@ -950,8 +964,8 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
ifps[i] = if_lookup_by_index(nexthop_tab[i].ifindex,
pim->vrf->vrf_id);
if (ifps[i]) {
- nbrs[i] = pim_neighbor_find(
- ifps[i], nexthop_tab[i].nexthop_addr.u.prefix4);
+ nbrs[i] = pim_neighbor_find_prefix(
+ ifps[i], &nexthop_tab[i].nexthop_addr);
if (nbrs[i]
|| pim_if_connected_to_source(ifps[i],
src->u.prefix4))
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index 2142d9010b..93ccfd78df 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -570,7 +570,7 @@ static int pim_msg_send_frame(int fd, char *buf, size_t len,
return 0;
}
-int pim_msg_send(int fd, pim_addr src, struct in_addr dst, uint8_t *pim_msg,
+int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
int pim_msg_size, const char *ifname)
{
struct sockaddr_in to;
diff --git a/pimd/pim_pim.h b/pimd/pim_pim.h
index b9fdb14dc0..1931e8cee8 100644
--- a/pimd/pim_pim.h
+++ b/pimd/pim_pim.h
@@ -56,8 +56,8 @@ void pim_hello_restart_triggered(struct interface *ifp);
int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len);
-int pim_msg_send(int fd, struct in_addr src, struct in_addr dst,
- uint8_t *pim_msg, int pim_msg_size, const char *ifname);
+int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
+ int pim_msg_size, const char *ifname);
int pim_hello_send(struct interface *ifp, uint16_t holdtime);
#endif /* PIM_PIM_H */
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index 855d912566..2cc80f957c 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -72,7 +72,6 @@ void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,
unsigned int b1length = 0;
unsigned int length;
uint8_t *b1;
- struct prefix p;
if (PIM_DEBUG_PIM_REG) {
zlog_debug("Sending Register stop for %pSG to %pI4 on %s", sg,
@@ -86,10 +85,7 @@ void pim_register_stop_send(struct interface *ifp, pim_sgaddr *sg,
b1length += length;
b1 += length;
- p.family = AF_INET;
- p.u.prefix4 = sg->src;
- p.prefixlen = IPV4_MAX_BITLEN;
- length = pim_encode_addr_ucast(b1, &p);
+ length = pim_encode_addr_ucast(b1, sg->src);
b1length += length;
pim_msg_build_header(buffer, b1length + PIM_MSG_REGISTER_STOP_LEN,
@@ -117,8 +113,8 @@ int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
struct pim_interface *pim_ifp = ifp->info;
struct pim_instance *pim = pim_ifp->pim;
struct pim_upstream *upstream = NULL;
- struct prefix source;
pim_sgaddr sg;
+ bool wrong_af = false;
int l;
++pim_ifp->pim_ifstat_reg_stop_recv;
@@ -127,8 +123,12 @@ int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
l = pim_parse_addr_group(&sg, buf, buf_size);
buf += l;
buf_size -= l;
- pim_parse_addr_ucast(&source, buf, buf_size);
- sg.src = source.u.prefix4;
+ pim_parse_addr_ucast(&sg.src, buf, buf_size, &wrong_af);
+
+ if (wrong_af) {
+ zlog_err("invalid AF in Register-Stop on %s", ifp->name);
+ return 0;
+ }
upstream = pim_upstream_find(pim, &sg);
if (!upstream) {
@@ -399,11 +399,10 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
struct prefix_list *plist;
struct prefix src;
- plist = prefix_list_lookup(AFI_IP, pim->register_plist);
+ plist = prefix_list_lookup(PIM_AFI,
+ pim->register_plist);
- src.family = AF_INET;
- src.prefixlen = IPV4_MAX_BITLEN;
- src.u.prefix4 = sg.src;
+ pim_addr_to_prefix(&src, sg.src);
if (prefix_list_apply(plist, &src) == PREFIX_DENY) {
pim_register_stop_send(ifp, &sg, dest_addr,
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index f35adb0cea..a5183c9e9b 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -322,9 +322,11 @@ static int pim_rp_check_interface_addrs(struct rp_info *rp_info,
{
struct listnode *node;
struct pim_secondary_addr *sec_addr;
+ pim_addr rpf_addr;
- if (pim_ifp->primary_address.s_addr
- == rp_info->rp.rpf_addr.u.prefix4.s_addr)
+ rpf_addr = pim_addr_from_prefix(&rp_info->rp.rpf_addr);
+
+ if (!pim_addr_cmp(pim_ifp->primary_address, rpf_addr))
return 1;
if (!pim_ifp->sec_addr_list) {
@@ -362,8 +364,8 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
{
struct pim_rpf old_rpf;
enum pim_rpf_result rpf_result;
- struct in_addr old_upstream_addr;
- struct in_addr new_upstream_addr;
+ pim_addr old_upstream_addr;
+ pim_addr new_upstream_addr;
struct prefix nht_p;
old_upstream_addr = up->upstream_addr;
@@ -374,7 +376,7 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
zlog_debug("%s: pim upstream update for old upstream %pI4",
__func__, &old_upstream_addr);
- if (old_upstream_addr.s_addr == new_upstream_addr.s_addr)
+ if (!pim_addr_cmp(old_upstream_addr, new_upstream_addr))
return;
/* Lets consider a case, where a PIM upstream has a better RP as a
@@ -382,11 +384,9 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
* This upstream has to be added to the upstream hash of new RP's
* NHT(pnc) and has to be removed from old RP's NHT upstream hash
*/
- if (old_upstream_addr.s_addr != INADDR_ANY) {
+ if (!pim_addr_is_any(old_upstream_addr)) {
/* Deregister addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = old_upstream_addr;
+ pim_addr_to_prefix(&nht_p, old_upstream_addr);
if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
"%s: Deregister upstream %s addr %pFX with Zebra NHT",
@@ -536,14 +536,12 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
/* Find (*, G) upstream whose RP is not
* configured yet
*/
- if ((up->upstream_addr.s_addr == INADDR_ANY) &&
+ if (pim_addr_is_any(up->upstream_addr) &&
pim_addr_is_any(up->sg.src)) {
struct prefix grp;
struct rp_info *trp_info;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
+ pim_addr_to_prefix(&grp, up->sg.grp);
trp_info = pim_rp_find_match_group(
pim, &grp);
if (trp_info == rp_all) {
@@ -632,9 +630,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
struct prefix grp;
struct rp_info *trp_info;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
+ pim_addr_to_prefix(&grp, up->sg.grp);
trp_info = pim_rp_find_match_group(pim, &grp);
if (trp_info == rp_info) {
@@ -778,17 +774,18 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
/* Find the upstream (*, G) whose upstream address is
* same as the deleted RP
*/
- if ((up->upstream_addr.s_addr ==
- rp_info->rp.rpf_addr.u.prefix4.s_addr) &&
+ pim_addr rpf_addr;
+
+ rpf_addr = pim_addr_from_prefix(&rp_info->rp.rpf_addr);
+ if (!pim_addr_cmp(up->upstream_addr, rpf_addr) &&
pim_addr_is_any(up->sg.src)) {
struct prefix grp;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
+
+ pim_addr_to_prefix(&grp, up->sg.grp);
trp_info = pim_rp_find_match_group(pim, &grp);
if (trp_info == rp_all) {
pim_upstream_rpf_clear(pim, up);
- up->upstream_addr.s_addr = INADDR_ANY;
+ up->upstream_addr = PIMADDR_ANY;
}
}
}
@@ -826,15 +823,14 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
/* Find the upstream (*, G) whose upstream address is same as
* the deleted RP
*/
- if ((up->upstream_addr.s_addr ==
- rp_info->rp.rpf_addr.u.prefix4.s_addr) &&
+ pim_addr rpf_addr;
+
+ rpf_addr = pim_addr_from_prefix(&rp_info->rp.rpf_addr);
+ if (!pim_addr_cmp(up->upstream_addr, rpf_addr) &&
pim_addr_is_any(up->sg.src)) {
struct prefix grp;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
-
+ pim_addr_to_prefix(&grp, up->sg.grp);
trp_info = pim_rp_find_match_group(pim, &grp);
/* RP not found for the group grp */
@@ -918,9 +914,7 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
struct prefix grp;
struct rp_info *trp_info;
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
+ pim_addr_to_prefix(&grp, up->sg.grp);
trp_info = pim_rp_find_match_group(pim, &grp);
if (trp_info == rp_info) {
@@ -1064,13 +1058,14 @@ void pim_i_am_rp_re_evaluate(struct pim_instance *pim)
}
}
+#if PIM_IPV == 4
/*
* I_am_RP(G) is true if the group-to-RP mapping indicates that
* this router is the RP for the group.
*
* Since we only have static RP, all groups are part of this RP
*/
-int pim_rp_i_am_rp(struct pim_instance *pim, struct in_addr group)
+int pim_rp_i_am_rp(struct pim_instance *pim, pim_addr group)
{
struct prefix g;
struct rp_info *rp_info;
@@ -1084,7 +1079,6 @@ int pim_rp_i_am_rp(struct pim_instance *pim, struct in_addr group)
if (rp_info)
return rp_info->i_am_rp;
-
return 0;
}
@@ -1093,7 +1087,7 @@ int pim_rp_i_am_rp(struct pim_instance *pim, struct in_addr group)
*
* Return the RP that the Group belongs too.
*/
-struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group)
+struct pim_rpf *pim_rp_g(struct pim_instance *pim, pim_addr group)
{
struct prefix g;
struct rp_info *rp_info;
@@ -1135,8 +1129,8 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group)
* then set the upstream addr as INADDR_ANY and return failure.
*
*/
-int pim_rp_set_upstream_addr(struct pim_instance *pim, struct in_addr *up,
- struct in_addr source, struct in_addr group)
+int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up,
+ pim_addr source, pim_addr group)
{
struct rp_info *rp_info;
struct prefix g;
@@ -1162,6 +1156,25 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, struct in_addr *up,
return 1;
}
+#else
+CPP_NOTICE("functions stubbed out for IPv6");
+
+int pim_rp_i_am_rp(struct pim_instance *pim, pim_addr group)
+{
+ return 0;
+}
+
+struct pim_rpf *pim_rp_g(struct pim_instance *pim, pim_addr group)
+{
+ return NULL;
+}
+
+int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up,
+ pim_addr source, pim_addr group)
+{
+ return 0;
+}
+#endif
int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
const char *spaces)
@@ -1353,17 +1366,19 @@ void pim_resolve_rp_nh(struct pim_instance *pim, struct pim_neighbor *nbr)
if (nbr->interface != ifp1)
continue;
+#if PIM_IPV == 4 || !defined(PIM_V6_TEMP_BREAK)
nh_node->gate.ipv4 = nbr->source_addr;
+#else
+ nh_node->gate.ipv6 = nbr->source_addr;
+#endif
if (PIM_DEBUG_PIM_NHT_RP) {
char str[PREFIX_STRLEN];
- char str1[INET_ADDRSTRLEN];
- pim_inet4_dump("<nht_nbr?>", nbr->source_addr,
- str1, sizeof(str1));
pim_addr_dump("<nht_addr?>", &nht_p, str,
sizeof(str));
zlog_debug(
- "%s: addr %s new nexthop addr %s interface %s",
- __func__, str, str1, ifp1->name);
+ "%s: addr %s new nexthop addr %pPAs interface %s",
+ __func__, str, &nbr->source_addr,
+ ifp1->name);
}
}
}
diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h
index 595025e5c9..c223402ddd 100644
--- a/pimd/pim_rp.h
+++ b/pimd/pim_rp.h
@@ -65,17 +65,17 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
void pim_rp_setup(struct pim_instance *pim);
-int pim_rp_i_am_rp(struct pim_instance *pim, struct in_addr group);
+int pim_rp_i_am_rp(struct pim_instance *pim, pim_addr group);
void pim_rp_check_on_if_add(struct pim_interface *pim_ifp);
void pim_i_am_rp_re_evaluate(struct pim_instance *pim);
bool pim_rp_check_is_my_ip_address(struct pim_instance *pim,
struct in_addr dest_addr);
-int pim_rp_set_upstream_addr(struct pim_instance *pim, struct in_addr *up,
- struct in_addr source, struct in_addr group);
+int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up,
+ pim_addr source, pim_addr group);
-struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group);
+struct pim_rpf *pim_rp_g(struct pim_instance *pim, pim_addr group);
#define I_am_RP(P, G) pim_rp_i_am_rp ((P), (G))
#define RP(P, G) pim_rp_g ((P), (G))
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index 1e865a3956..2e8fc8e661 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -141,8 +141,8 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
i++;
} else if (neighbor_needed
&& !pim_if_connected_to_source(ifp, addr)) {
- nbr = pim_neighbor_find(
- ifp, nexthop_tab[i].nexthop_addr.u.prefix4);
+ nbr = pim_neighbor_find_prefix(
+ ifp, &nexthop_tab[i].nexthop_addr);
if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug("ifp name: %s, pim nbr: %p",
ifp->name, nbr);
@@ -234,7 +234,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags))
return PIM_RPF_OK;
- if (up->upstream_addr.s_addr == INADDR_ANY) {
+ if (pim_addr_is_any(up->upstream_addr)) {
zlog_debug("%s(%s): RP is not configured yet for %s",
__func__, caller, up->sg_str);
return PIM_RPF_OK;
@@ -248,16 +248,10 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
old->rpf_addr = saved.rpf_addr;
}
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr;
+ pim_addr_to_prefix(&nht_p, up->upstream_addr);
- src.family = AF_INET;
- src.prefixlen = IPV4_MAX_BITLEN;
- src.u.prefix4 = up->upstream_addr; // RP or Src address
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = up->sg.grp;
+ pim_addr_to_prefix(&src, up->upstream_addr); // RP or Src address
+ pim_addr_to_prefix(&grp, up->sg.grp);
if ((pim_addr_is_any(up->sg.src) && I_am_RP(pim, up->sg.grp)) ||
PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
@@ -398,9 +392,11 @@ static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up)
/* return NBR( RPF_interface(S), MRIB.next_hop( S ) ) */
- neigh = pim_if_find_neighbor(
- up->rpf.source_nexthop.interface,
- up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4);
+ pim_addr nhaddr;
+
+ nhaddr =
+ pim_addr_from_prefix(&up->rpf.source_nexthop.mrib_nexthop_addr);
+ neigh = pim_if_find_neighbor(up->rpf.source_nexthop.interface, nhaddr);
if (neigh)
rpf_addr = neigh->source_addr;
else
diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c
index 6c5883aebf..45aac7756a 100644
--- a/pimd/pim_ssm.c
+++ b/pimd/pim_ssm.c
@@ -83,23 +83,20 @@ static int pim_is_grp_standard_ssm(struct prefix *group)
return prefix_match(&group_ssm, group);
}
-int pim_is_grp_ssm(struct pim_instance *pim, struct in_addr group_addr)
+int pim_is_grp_ssm(struct pim_instance *pim, pim_addr group_addr)
{
struct pim_ssm *ssm;
struct prefix group;
struct prefix_list *plist;
- memset(&group, 0, sizeof(group));
- group.family = AF_INET;
- group.u.prefix4 = group_addr;
- group.prefixlen = 32;
+ pim_addr_to_prefix(&group, group_addr);
ssm = pim->ssm_info;
if (!ssm->plist_name) {
return pim_is_grp_standard_ssm(&group);
}
- plist = prefix_list_lookup(AFI_IP, ssm->plist_name);
+ plist = prefix_list_lookup(PIM_AFI, ssm->plist_name);
if (!plist)
return 0;
diff --git a/pimd/pim_ssm.h b/pimd/pim_ssm.h
index 7235ade8dc..117713b866 100644
--- a/pimd/pim_ssm.h
+++ b/pimd/pim_ssm.h
@@ -34,7 +34,7 @@ struct pim_ssm {
void pim_ssm_prefix_list_update(struct pim_instance *pim,
struct prefix_list *plist);
-int pim_is_grp_ssm(struct pim_instance *pim, struct in_addr group_addr);
+int pim_is_grp_ssm(struct pim_instance *pim, pim_addr group_addr);
int pim_ssm_range_set(struct pim_instance *pim, vrf_id_t vrf_id,
const char *plist_name);
void *pim_ssm_init(void);
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index a4f60e5198..86403dd54a 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -29,6 +29,12 @@
#include "pim_str.h"
#include "pim_msg.h"
+#if PIM_IPV == 4
+#define PIM_MSG_ADDRESS_FAMILY PIM_MSG_ADDRESS_FAMILY_IPV4
+#else
+#define PIM_MSG_ADDRESS_FAMILY PIM_MSG_ADDRESS_FAMILY_IPV6
+#endif
+
uint8_t *pim_tlv_append_uint16(uint8_t *buf, const uint8_t *buf_pastend,
uint16_t option_type, uint16_t option_value)
{
@@ -117,7 +123,23 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf, const uint8_t *buf_pastend,
* The unicast address as represented by the given Address Family
* and Encoding Type.
*/
-int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p)
+int pim_encode_addr_ucast(uint8_t *buf, pim_addr addr)
+{
+ uint8_t *start = buf;
+
+#if PIM_IPV == 4
+ *buf++ = PIM_MSG_ADDRESS_FAMILY_IPV4;
+#else
+ *buf++ = PIM_MSG_ADDRESS_FAMILY_IPV6;
+#endif
+ *buf++ = 0;
+ memcpy(buf, &addr, sizeof(addr));
+ buf += sizeof(addr);
+
+ return buf - start;
+}
+
+int pim_encode_addr_ucast_prefix(uint8_t *buf, struct prefix *p)
{
switch (p->family) {
case AF_INET:
@@ -188,28 +210,22 @@ int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p)
* Contains the group address.
*/
int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope,
- struct in_addr group)
+ pim_addr group)
{
+ uint8_t *start = buf;
uint8_t flags = 0;
flags |= bidir << 8;
flags |= scope;
- switch (afi) {
- case AFI_IP:
- *buf = PIM_MSG_ADDRESS_FAMILY_IPV4;
- ++buf;
- *buf = 0;
- ++buf;
- *buf = flags;
- ++buf;
- *buf = 32;
- ++buf;
- memcpy(buf, &group, sizeof(struct in_addr));
- return group_ipv4_encoding_len;
- default:
- return 0;
- }
+ *buf++ = PIM_MSG_ADDRESS_FAMILY;
+ *buf++ = 0;
+ *buf++ = flags;
+ *buf++ = sizeof(group) / 8;
+ memcpy(buf, &group, sizeof(group));
+ buf += sizeof(group);
+
+ return buf - start;
}
uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
@@ -248,7 +264,7 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
if (p->family != family)
continue;
- l_encode = pim_encode_addr_ucast(curr, p);
+ l_encode = pim_encode_addr_ucast_prefix(curr, p);
curr += l_encode;
option_len += l_encode;
}
@@ -274,15 +290,13 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
}
static int check_tlv_length(const char *label, const char *tlv_name,
- const char *ifname, struct in_addr src_addr,
+ const char *ifname, pim_addr src_addr,
int correct_len, int option_len)
{
if (option_len != correct_len) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
zlog_warn(
- "%s: PIM hello %s TLV with incorrect value size=%d correct=%d from %s on interface %s",
- label, tlv_name, option_len, correct_len, src_str,
+ "%s: PIM hello %s TLV with incorrect value size=%d correct=%d from %pPAs on interface %s",
+ label, tlv_name, option_len, correct_len, &src_addr,
ifname);
return -1;
}
@@ -290,49 +304,44 @@ static int check_tlv_length(const char *label, const char *tlv_name,
return 0;
}
-static void check_tlv_redefinition_uint16(
- const char *label, const char *tlv_name, const char *ifname,
- struct in_addr src_addr, pim_hello_options options,
- pim_hello_options opt_mask, uint16_t new, uint16_t old)
+static void check_tlv_redefinition_uint16(const char *label,
+ const char *tlv_name,
+ const char *ifname, pim_addr src_addr,
+ pim_hello_options options,
+ pim_hello_options opt_mask,
+ uint16_t new, uint16_t old)
{
- if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ if (PIM_OPTION_IS_SET(options, opt_mask))
zlog_warn(
- "%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
- label, tlv_name, new, old, src_str, ifname);
- }
+ "%s: PIM hello TLV redefined %s=%u old=%u from %pPAs on interface %s",
+ label, tlv_name, new, old, &src_addr, ifname);
}
-static void check_tlv_redefinition_uint32(
- const char *label, const char *tlv_name, const char *ifname,
- struct in_addr src_addr, pim_hello_options options,
- pim_hello_options opt_mask, uint32_t new, uint32_t old)
+static void check_tlv_redefinition_uint32(const char *label,
+ const char *tlv_name,
+ const char *ifname, pim_addr src_addr,
+ pim_hello_options options,
+ pim_hello_options opt_mask,
+ uint32_t new, uint32_t old)
{
- if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ if (PIM_OPTION_IS_SET(options, opt_mask))
zlog_warn(
- "%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
- label, tlv_name, new, old, src_str, ifname);
- }
+ "%s: PIM hello TLV redefined %s=%u old=%u from %pPAs on interface %s",
+ label, tlv_name, new, old, &src_addr, ifname);
}
static void check_tlv_redefinition_uint32_hex(
const char *label, const char *tlv_name, const char *ifname,
- struct in_addr src_addr, pim_hello_options options,
+ pim_addr src_addr, pim_hello_options options,
pim_hello_options opt_mask, uint32_t new, uint32_t old)
{
- if (PIM_OPTION_IS_SET(options, opt_mask)) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
+ if (PIM_OPTION_IS_SET(options, opt_mask))
zlog_warn(
- "%s: PIM hello TLV redefined %s=%08x old=%08x from %s on interface %s",
- label, tlv_name, new, old, src_str, ifname);
- }
+ "%s: PIM hello TLV redefined %s=%08x old=%08x from %pPAs on interface %s",
+ label, tlv_name, new, old, &src_addr, ifname);
}
-int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_holdtime(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
uint16_t *hello_option_holdtime, uint16_t option_len,
const uint8_t *tlv_curr)
@@ -356,7 +365,7 @@ int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr,
return 0;
}
-int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_lan_prune_delay(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
uint16_t *hello_option_propagation_delay,
uint16_t *hello_option_override_interval,
@@ -392,7 +401,7 @@ int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr,
return 0;
}
-int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_dr_priority(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
uint32_t *hello_option_dr_priority,
uint16_t option_len, const uint8_t *tlv_curr)
@@ -416,7 +425,7 @@ int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr,
return 0;
}
-int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_generation_id(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
uint32_t *hello_option_generation_id,
uint16_t option_len, const uint8_t *tlv_curr)
@@ -441,7 +450,8 @@ int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr,
return 0;
}
-int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size)
+int pim_parse_addr_ucast_prefix(struct prefix *p, const uint8_t *buf,
+ int buf_size)
{
const int ucast_encoding_min_len = 3; /* 1 family + 1 type + 1 addr */
const uint8_t *addr;
@@ -510,6 +520,25 @@ int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size)
return addr - buf;
}
+int pim_parse_addr_ucast(pim_addr *out, const uint8_t *buf, int buf_size,
+ bool *wrong_af)
+{
+ struct prefix p;
+ int ret;
+
+ ret = pim_parse_addr_ucast_prefix(&p, buf, buf_size);
+ if (ret < 0)
+ return ret;
+
+ if (p.family != PIM_AF) {
+ *wrong_af = true;
+ return -5;
+ }
+
+ memcpy(out, &p.u.val, sizeof(*out));
+ return ret;
+}
+
int pim_parse_addr_group(pim_sgaddr *sg, const uint8_t *buf, int buf_size)
{
const int grp_encoding_min_len =
@@ -532,40 +561,32 @@ int pim_parse_addr_group(pim_sgaddr *sg, const uint8_t *buf, int buf_size)
family = *addr++;
type = *addr++;
- //++addr;
++addr; /* skip b_reserved_z fields */
mask_len = *addr++;
- switch (family) {
- case PIM_MSG_ADDRESS_FAMILY_IPV4:
- if (type) {
- zlog_warn(
- "%s: unknown group address encoding type=%d from",
- __func__, type);
- return -2;
- }
-
- if ((addr + sizeof(struct in_addr)) > pastend) {
- zlog_warn(
- "%s: IPv4 group address overflow: left=%td needed=%zu from",
- __func__, pastend - addr,
- sizeof(struct in_addr));
- return -3;
- }
-
- memcpy(&sg->grp.s_addr, addr, sizeof(struct in_addr));
-
- addr += sizeof(struct in_addr);
+ if (type) {
+ zlog_warn("%s: unknown group address encoding type=%d from",
+ __func__, type);
+ return -2;
+ }
- break;
- default: {
+ if (family != PIM_MSG_ADDRESS_FAMILY) {
zlog_warn(
"%s: unknown group address encoding family=%d mask_len=%d from",
__func__, family, mask_len);
return -4;
}
+
+ if ((addr + sizeof(sg->grp)) > pastend) {
+ zlog_warn(
+ "%s: group address overflow: left=%td needed=%zu from",
+ __func__, pastend - addr, sizeof(sg->grp));
+ return -3;
}
+ memcpy(&sg->grp, addr, sizeof(sg->grp));
+ addr += sizeof(sg->grp);
+
return addr - buf;
}
@@ -654,7 +675,7 @@ int pim_parse_addr_source(pim_sgaddr *sg, uint8_t *flags, const uint8_t *buf,
} \
}
-int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_addr_list(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
struct list **hello_option_addr_list,
uint16_t option_len, const uint8_t *tlv_curr)
@@ -670,20 +691,18 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
addr = tlv_curr;
pastend = tlv_curr + option_len;
while (addr < pastend) {
- struct prefix tmp;
+ struct prefix tmp, src_pfx;
int addr_offset;
/*
Parse ucast addr
*/
- addr_offset = pim_parse_addr_ucast(&tmp, addr, pastend - addr);
+ addr_offset =
+ pim_parse_addr_ucast_prefix(&tmp, addr, pastend - addr);
if (addr_offset < 1) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
zlog_warn(
- "%s: pim_parse_addr_ucast() failure: from %s on %s",
- __func__, src_str, ifname);
+ "%s: pim_parse_addr_ucast() failure: from %pPAs on %s",
+ __func__, &src_addr, ifname);
FREE_ADDR_LIST(*hello_option_addr_list);
return -1;
}
@@ -696,35 +715,28 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
switch (tmp.family) {
case AF_INET: {
char addr_str[INET_ADDRSTRLEN];
- char src_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", tmp.u.prefix4,
addr_str, sizeof(addr_str));
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
zlog_debug(
- "%s: PIM hello TLV option: list_old_size=%d IPv4 address %s from %s on %s",
+ "%s: PIM hello TLV option: list_old_size=%d IPv4 address %s from %pPAs on %s",
__func__,
*hello_option_addr_list
? ((int)listcount(
- *hello_option_addr_list))
+ *hello_option_addr_list))
: -1,
- addr_str, src_str, ifname);
+ addr_str, &src_addr, ifname);
} break;
case AF_INET6:
break;
- default: {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
+ default:
zlog_debug(
- "%s: PIM hello TLV option: list_old_size=%d UNKNOWN address family from %s on %s",
+ "%s: PIM hello TLV option: list_old_size=%d UNKNOWN address family from %pPAs on %s",
__func__,
*hello_option_addr_list
? ((int)listcount(
- *hello_option_addr_list))
+ *hello_option_addr_list))
: -1,
- src_str, ifname);
- }
+ &src_addr, ifname);
}
}
@@ -732,16 +744,12 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
Exclude neighbor's primary address if incorrectly included in
the secondary address list
*/
- if (tmp.family == AF_INET) {
- if (tmp.u.prefix4.s_addr == src_addr.s_addr) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>", src_addr, src_str,
- sizeof(src_str));
- zlog_warn(
- "%s: ignoring primary address in secondary list from %s on %s",
- __func__, src_str, ifname);
- continue;
- }
+ pim_addr_to_prefix(&src_pfx, src_addr);
+ if (!prefix_cmp(&tmp, &src_pfx)) {
+ zlog_warn(
+ "%s: ignoring primary address in secondary list from %pPAs on %s",
+ __func__, &src_addr, ifname);
+ continue;
}
/*
diff --git a/pimd/pim_tlv.h b/pimd/pim_tlv.h
index 1aa60d5dbb..64b3a0b6ba 100644
--- a/pimd/pim_tlv.h
+++ b/pimd/pim_tlv.h
@@ -84,33 +84,37 @@ uint8_t *pim_tlv_append_uint32(uint8_t *buf, const uint8_t *buf_pastend,
uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
struct list *ifconnected, int family);
-int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_holdtime(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
uint16_t *hello_option_holdtime, uint16_t option_len,
const uint8_t *tlv_curr);
-int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_lan_prune_delay(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
uint16_t *hello_option_propagation_delay,
uint16_t *hello_option_override_interval,
uint16_t option_len, const uint8_t *tlv_curr);
-int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_dr_priority(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
uint32_t *hello_option_dr_priority,
uint16_t option_len, const uint8_t *tlv_curr);
-int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_generation_id(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
uint32_t *hello_option_generation_id,
uint16_t option_len, const uint8_t *tlv_curr);
-int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
+int pim_tlv_parse_addr_list(const char *ifname, pim_addr src_addr,
pim_hello_options *hello_options,
struct list **hello_option_addr_list,
uint16_t option_len, const uint8_t *tlv_curr);
-int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p);
+int pim_encode_addr_ucast(uint8_t *buf, pim_addr addr);
+int pim_encode_addr_ucast_prefix(uint8_t *buf, struct prefix *p);
int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope,
- struct in_addr group);
+ pim_addr group);
-int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size);
+int pim_parse_addr_ucast(pim_addr *out, const uint8_t *buf, int buf_size,
+ bool *wrong_af);
+int pim_parse_addr_ucast_prefix(struct prefix *out, const uint8_t *buf,
+ int buf_size);
int pim_parse_addr_group(pim_sgaddr *sg, const uint8_t *buf, int buf_size);
int pim_parse_addr_source(pim_sgaddr *sg, uint8_t *flags, const uint8_t *buf,
int buf_size);
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 800ec9c45c..a410a1c2ce 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -259,11 +259,9 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
* to INADDR_ANY. This is done in order to avoid de-registering for
* 255.255.255.255 which is maintained for some reason..
*/
- if (up->upstream_addr.s_addr != INADDR_ANY) {
+ if (!pim_addr_is_any(up->upstream_addr)) {
/* Deregister addr with Zebra NHT */
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = up->upstream_addr;
+ pim_addr_to_prefix(&nht_p, up->upstream_addr);
if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
"%s: Deregister upstream %s addr %pFX with Zebra NHT",
@@ -343,8 +341,8 @@ static void join_timer_stop(struct pim_upstream *up)
THREAD_OFF(up->t_join_timer);
if (up->rpf.source_nexthop.interface)
- nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr.u.prefix4);
+ nbr = pim_neighbor_find_prefix(up->rpf.source_nexthop.interface,
+ &up->rpf.rpf_addr);
if (nbr)
pim_jp_agg_remove_group(nbr->upstream_jp_agg, up, nbr);
@@ -357,8 +355,8 @@ void join_timer_start(struct pim_upstream *up)
struct pim_neighbor *nbr = NULL;
if (up->rpf.source_nexthop.interface) {
- nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr.u.prefix4);
+ nbr = pim_neighbor_find_prefix(up->rpf.source_nexthop.interface,
+ &up->rpf.rpf_addr);
if (PIM_DEBUG_PIM_EVENTS) {
zlog_debug(
@@ -449,8 +447,8 @@ void pim_upstream_join_suppress(struct pim_upstream *up,
pim_time_timer_remain_msec(up->t_join_timer);
else {
/* Remove it from jp agg from the nbr for suppression */
- nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr.u.prefix4);
+ nbr = pim_neighbor_find_prefix(up->rpf.source_nexthop.interface,
+ &up->rpf.rpf_addr);
if (nbr) {
join_timer_remain_msec =
pim_time_timer_remain_msec(nbr->jp_timer);
@@ -504,8 +502,8 @@ void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
/* upstream join tracked with neighbor jp timer */
struct pim_neighbor *nbr;
- nbr = pim_neighbor_find(up->rpf.source_nexthop.interface,
- up->rpf.rpf_addr.u.prefix4);
+ nbr = pim_neighbor_find_prefix(up->rpf.source_nexthop.interface,
+ &up->rpf.rpf_addr);
if (nbr)
join_timer_remain_msec =
pim_time_timer_remain_msec(nbr->jp_timer);
@@ -713,7 +711,7 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
{
enum pim_upstream_state old_state = up->join_state;
- if (up->upstream_addr.s_addr == INADDR_ANY) {
+ if (pim_addr_is_any(up->upstream_addr)) {
if (PIM_DEBUG_PIM_EVENTS)
zlog_debug("%s: RPF not configured for %s", __func__,
up->sg_str);
@@ -937,7 +935,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
if (PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags))
pim_upstream_keep_alive_timer_start(
up, pim->keep_alive_time);
- } else if (up->upstream_addr.s_addr != INADDR_ANY) {
+ } else if (!pim_addr_is_any(up->upstream_addr)) {
pim_upstream_update_use_rpt(up,
false /*update_mroute*/);
rpf_result = pim_rpf_update(pim, up, NULL, __func__);
@@ -1274,15 +1272,13 @@ void pim_upstream_rpf_genid_changed(struct pim_instance *pim,
*/
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (PIM_DEBUG_PIM_TRACE) {
- char neigh_str[INET_ADDRSTRLEN];
char rpf_addr_str[PREFIX_STRLEN];
- pim_inet4_dump("<neigh?>", neigh_addr, neigh_str,
- sizeof(neigh_str));
pim_addr_dump("<rpf?>", &up->rpf.rpf_addr, rpf_addr_str,
sizeof(rpf_addr_str));
zlog_debug(
- "%s: matching neigh=%s against upstream (S,G)=%s[%s] joined=%d rpf_addr=%s",
- __func__, neigh_str, up->sg_str, pim->vrf->name,
+ "%s: matching neigh=%pI4 against upstream (S,G)=%s[%s] joined=%d rpf_addr=%s",
+ __func__, &neigh_addr, up->sg_str,
+ pim->vrf->name,
up->join_state == PIM_UPSTREAM_JOINED,
rpf_addr_str);
}
@@ -1914,7 +1910,7 @@ void pim_upstream_find_new_rpf(struct pim_instance *pim)
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
*/
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
- if (up->upstream_addr.s_addr == INADDR_ANY) {
+ if (pim_addr_is_any(up->upstream_addr)) {
if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
"%s: RP not configured for Upstream %s",
@@ -2153,10 +2149,7 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
struct prefix g;
enum prefix_list_type apply_new;
- np = prefix_list_lookup(AFI_IP, nlist);
-
- g.family = AF_INET;
- g.prefixlen = IPV4_MAX_BITLEN;
+ np = prefix_list_lookup(PIM_AFI, nlist);
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (!pim_addr_is_any(up->sg.src))
@@ -2170,7 +2163,7 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
PIM_OIF_FLAG_PROTO_IGMP, __func__);
continue;
}
- g.u.prefix4 = up->sg.grp;
+ pim_addr_to_prefix(&g, up->sg.grp);
apply_new = prefix_list_apply(np, &g);
if (apply_new == PREFIX_DENY)
pim_channel_add_oif(up->channel_oil, pim->regiface,
diff --git a/pimd/pim_util.c b/pimd/pim_util.c
index decc491ede..8232d7205b 100644
--- a/pimd/pim_util.c
+++ b/pimd/pim_util.c
@@ -139,7 +139,7 @@ int pim_is_group_224_4(struct in_addr group_addr)
return prefix_match(&group_all, &group);
}
-bool pim_is_group_filtered(struct pim_interface *pim_ifp, struct in_addr *grp)
+bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp)
{
struct prefix grp_pfx;
struct prefix_list *pl;
@@ -147,10 +147,8 @@ bool pim_is_group_filtered(struct pim_interface *pim_ifp, struct in_addr *grp)
if (!pim_ifp->boundary_oil_plist)
return false;
- grp_pfx.family = AF_INET;
- grp_pfx.prefixlen = IPV4_MAX_BITLEN;
- grp_pfx.u.prefix4 = *grp;
+ pim_addr_to_prefix(&grp_pfx, *grp);
- pl = prefix_list_lookup(AFI_IP, pim_ifp->boundary_oil_plist);
+ pl = prefix_list_lookup(PIM_AFI, pim_ifp->boundary_oil_plist);
return pl ? prefix_list_apply(pl, &grp_pfx) == PREFIX_DENY : false;
}
diff --git a/pimd/pim_util.h b/pimd/pim_util.h
index c66dd7b660..b9c227996e 100644
--- a/pimd/pim_util.h
+++ b/pimd/pim_util.h
@@ -35,5 +35,5 @@ void pim_pkt_dump(const char *label, const uint8_t *buf, int size);
int pim_is_group_224_0_0_0_24(struct in_addr group_addr);
int pim_is_group_224_4(struct in_addr group_addr);
-bool pim_is_group_filtered(struct pim_interface *pim_ifp, struct in_addr *grp);
+bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp);
#endif /* PIM_UTIL_H */
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index c543c63eeb..8130aac872 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -341,13 +341,9 @@ int pim_interface_config_write(struct vty *vty)
/* update source */
if (!pim_addr_is_any(pim_ifp->update_source)) {
- char src_str[INET_ADDRSTRLEN];
- pim_inet4_dump("<src?>",
- pim_ifp->update_source,
- src_str,
- sizeof(src_str));
- vty_out(vty, " ip pim use-source %s\n",
- src_str);
+ vty_out(vty,
+ " ip pim use-source %pPA\n",
+ &pim_ifp->update_source);
++writes;
}
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index c1e7be5870..39a1a32a5b 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -354,9 +354,7 @@ static void pim_vxlan_orig_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
* iif
*/
if (!PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags)) {
- nht_p.family = AF_INET;
- nht_p.prefixlen = IPV4_MAX_BITLEN;
- nht_p.u.prefix4 = up->upstream_addr;
+ pim_addr_to_prefix(&nht_p, up->upstream_addr);
pim_delete_tracked_nexthop(vxlan_sg->pim, &nht_p, up,
NULL);
}
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 2efafd4b9b..11b13db318 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -141,12 +141,14 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
#endif
}
- if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
- /* trying to add primary address */
-
- struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
- if (p->family != AF_INET
- || primary_addr.s_addr != p->u.prefix4.s_addr) {
+ if (p->family != PIM_AF)
+ SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY);
+ else if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
+ /* trying to add primary address? */
+ pim_addr primary_addr = pim_find_primary_addr(c->ifp);
+ pim_addr addr = pim_addr_from_prefix(p);
+
+ if (pim_addr_cmp(primary_addr, addr)) {
if (PIM_DEBUG_ZEBRA)
zlog_warn(
"%s: %s : forcing secondary flag on %pFX",
@@ -254,8 +256,8 @@ void pim_zebra_upstream_rpf_changed(struct pim_instance *pim,
if (old->source_nexthop.interface) {
struct pim_neighbor *nbr;
- nbr = pim_neighbor_find(old->source_nexthop.interface,
- old->rpf_addr.u.prefix4);
+ nbr = pim_neighbor_find_prefix(old->source_nexthop.interface,
+ &old->rpf_addr);
if (nbr)
pim_jp_agg_remove_group(nbr->upstream_jp_agg, up, nbr);
@@ -337,8 +339,8 @@ static int pim_zebra_vxlan_sg_proc(ZAPI_CALLBACK_ARGS)
s = zclient->ibuf;
prefixlen = stream_getl(s);
- stream_get(&sg.src.s_addr, s, prefixlen);
- stream_get(&sg.grp.s_addr, s, prefixlen);
+ stream_get(&sg.src, s, prefixlen);
+ stream_get(&sg.grp, s, prefixlen);
if (PIM_DEBUG_ZEBRA)
zlog_debug("%u:recv SG %s %pSG", vrf_id,
@@ -606,7 +608,7 @@ void igmp_source_forward_start(struct pim_instance *pim,
}
if (!source->source_channel_oil) {
- struct in_addr vif_source;
+ pim_addr vif_source;
struct prefix src, grp;
struct pim_nexthop nexthop;
struct pim_upstream *up = NULL;
@@ -619,12 +621,8 @@ void igmp_source_forward_start(struct pim_instance *pim,
}
else {
- src.family = AF_INET;
- src.prefixlen = IPV4_MAX_BITLEN;
- src.u.prefix4 = vif_source; // RP or Src address
- grp.family = AF_INET;
- grp.prefixlen = IPV4_MAX_BITLEN;
- grp.u.prefix4 = sg.grp;
+ pim_addr_to_prefix(&src, vif_source); // RP or Src addr
+ pim_addr_to_prefix(&grp, sg.grp);
up = pim_upstream_find(pim, &sg);
if (up) {
@@ -642,15 +640,11 @@ void igmp_source_forward_start(struct pim_instance *pim,
pim_ecmp_fib_lookup_if_vif_index(
pim, &src, &grp);
- if (PIM_DEBUG_ZEBRA) {
- char buf2[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<source?>", vif_source, buf2,
- sizeof(buf2));
- zlog_debug("%s: NHT %pSG vif_source %s vif_index:%d ",
- __func__, &sg, buf2,
- input_iface_vif_index);
- }
+ if (PIM_DEBUG_ZEBRA)
+ zlog_debug(
+ "%s: NHT %pSG vif_source %pPAs vif_index:%d ",
+ __func__, &sg, &vif_source,
+ input_iface_vif_index);
if (input_iface_vif_index < 1) {
if (PIM_DEBUG_IGMP_TRACE) {
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index 5997cc25a4..b169335a3a 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -300,9 +300,9 @@ static int zclient_read_nexthop(struct pim_instance *pim,
if (nbr) {
nexthop_tab[num_ifindex].nexthop_addr.family =
AF_INET;
- nexthop_tab[num_ifindex]
- .nexthop_addr.u.prefix4 =
- nbr->source_addr;
+ pim_addr_to_prefix(
+ &nexthop_tab[num_ifindex].nexthop_addr,
+ nbr->source_addr);
}
++num_ifindex;
break;
diff --git a/pimd/pimd.c b/pimd/pimd.c
index 992bb931bd..9621f9794d 100644
--- a/pimd/pimd.c
+++ b/pimd/pimd.c
@@ -49,15 +49,22 @@
CPP_NOTICE("Work needs to be done to make this work properly via the pim mroute socket\n");
#endif /* MAXVIFS > 256 */
+#if PIM_IPV == 4
const char *const PIM_ALL_SYSTEMS = MCAST_ALL_SYSTEMS;
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;
+#else
+const char *const PIM_ALL_SYSTEMS = "ff02::1";
+const char *const PIM_ALL_ROUTERS = "ff02::2";
+const char *const PIM_ALL_PIM_ROUTERS = "ff02::d";
+const char *const PIM_ALL_IGMP_ROUTERS = "ff02::16";
+#endif
DEFINE_MTYPE_STATIC(PIMD, ROUTER, "PIM Router information");
struct pim_router *router = NULL;
-struct in_addr qpim_all_pim_routers_addr;
+pim_addr qpim_all_pim_routers_addr;
void pim_prefix_list_update(struct prefix_list *plist)
{
@@ -103,7 +110,7 @@ void pim_router_init(void)
PIM_ASSERT_METRIC_PREFERENCE_MAX;
router->infinite_assert_metric.route_metric =
PIM_ASSERT_ROUTE_METRIC_MAX;
- router->infinite_assert_metric.ip_address.s_addr = INADDR_ANY;
+ router->infinite_assert_metric.ip_address = PIMADDR_ANY;
router->rpf_cache_refresh_delay_msec = 50;
router->register_suppress_time = PIM_REGISTER_SUPPRESSION_TIME_DEFAULT;
router->packet_process = PIM_DEFAULT_PACKET_PROCESS;
@@ -120,7 +127,8 @@ void pim_router_terminate(void)
void pim_init(void)
{
- if (!inet_aton(PIM_ALL_PIM_ROUTERS, &qpim_all_pim_routers_addr)) {
+ if (!inet_pton(PIM_AF, 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",
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 7732dc5b74..d4eac58a29 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -134,7 +134,7 @@ extern const char *const PIM_ALL_PIM_ROUTERS;
extern const char *const PIM_ALL_IGMP_ROUTERS;
extern struct zebra_privs_t pimd_privs;
-extern struct in_addr qpim_all_pim_routers_addr;
+extern pim_addr qpim_all_pim_routers_addr;
extern uint8_t qpim_ecmp_enable;
extern uint8_t qpim_ecmp_rebalance_enable;
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 5e5be159f1..8bfb200305 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -1515,6 +1515,7 @@ static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to,
cmsgptr->cmsg_type = IP_PKTINFO;
pkt = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
pkt->ipi_ifindex = ifc->ifp->ifindex;
+ pkt->ipi_spec_dst.s_addr = ifc->address->u.prefix4.s_addr;
#endif /* GNU_LINUX */
ret = sendmsg(rip->sock, &msg, 0);
diff --git a/staticd/static_main.c b/staticd/static_main.c
index 6051b2df1c..3bd784b594 100644
--- a/staticd/static_main.c
+++ b/staticd/static_main.c
@@ -43,7 +43,7 @@
char backup_config_file[256];
bool mpls_enabled;
-
+uint32_t zebra_ecmp_count = MULTIPATH_NUM;
zebra_capabilities_t _caps_p[] = {
};
diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c
index 470c7bdad5..9ccffe53d9 100644
--- a/staticd/static_nb_config.c
+++ b/staticd/static_nb_config.c
@@ -115,7 +115,7 @@ static int static_path_list_tag_modify(struct nb_cb_modify_args *args)
}
struct nexthop_iter {
- int count;
+ uint32_t count;
bool blackhole;
};
@@ -169,7 +169,12 @@ static bool static_nexthop_create(struct nb_cb_create_args *args)
if (iter.blackhole && iter.count > 1) {
snprintf(
args->errmsg, args->errmsg_len,
- "Route can not have blackhole and non-blackhole nexthops simultaneously");
+ "Route cannot have blackhole and non-blackhole nexthops simultaneously");
+ return NB_ERR_VALIDATION;
+ } else if (iter.count > zebra_ecmp_count) {
+ snprintf(args->errmsg, args->errmsg_len,
+ "Route cannot have more than %d ECMP nexthops",
+ zebra_ecmp_count);
return NB_ERR_VALIDATION;
}
break;
diff --git a/staticd/static_routes.h b/staticd/static_routes.h
index c901a8926a..71c3689be5 100644
--- a/staticd/static_routes.h
+++ b/staticd/static_routes.h
@@ -163,6 +163,7 @@ static_route_info_from_rnode(struct route_node *rn)
}
extern bool mpls_enabled;
+extern uint32_t zebra_ecmp_count;
extern struct zebra_privs_t static_privs;
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 311aeda338..b75e1a1cdf 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -205,6 +205,7 @@ static int static_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
static void static_zebra_capabilities(struct zclient_capabilities *cap)
{
mpls_enabled = cap->mpls_enabled;
+ zebra_ecmp_count = cap->ecmp;
}
static unsigned int static_nht_hash_key(const void *data)
@@ -413,6 +414,10 @@ extern void static_zebra_route_add(struct static_path *pn, bool install)
api.tableid = pn->table_id;
}
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
+ /* Don't overrun the nexthop array */
+ if (nh_num == zebra_ecmp_count)
+ break;
+
api_nh = &api.nexthops[nh_num];
if (nh->nh_vrf_id == VRF_UNKNOWN)
continue;
diff --git a/tests/topotests/bgp_route_map/test_route_map_topo1.py b/tests/topotests/bgp_route_map/test_route_map_topo1.py
index 3c2d7f28a2..6556c050bb 100644
--- a/tests/topotests/bgp_route_map/test_route_map_topo1.py
+++ b/tests/topotests/bgp_route_map/test_route_map_topo1.py
@@ -444,9 +444,10 @@ def test_route_map_inbound_outbound_same_neighbor_p0(request):
result = verify_rib(
tgen, adt, dut, input_dict_2, protocol=protocol, expected=False
)
- assert result is not True, (
- "Testcase {} : Failed \n"
- "routes are not present in rib \n Error: {}".format(tc_name, result)
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \nroutes are not present in rib \n Error: {}".format(
+ tc_name, result
)
logger.info("Expected behaviour: {}".format(result))
@@ -466,9 +467,10 @@ def test_route_map_inbound_outbound_same_neighbor_p0(request):
result = verify_rib(
tgen, adt, dut, input_dict, protocol=protocol, expected=False
)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "routes are not present in rib \n Error: {}".format(tc_name, result)
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \nroutes are not present in rib \n Error: {}".format(
+ tc_name, result
)
logger.info("Expected behaviour: {}".format(result))
@@ -664,9 +666,10 @@ def test_route_map_with_action_values_combination_of_prefix_action_p0(
result = verify_rib(
tgen, adt, dut, input_dict_2, protocol=protocol, expected=False
)
- assert result is not True, (
- "Testcase {} : Failed \n "
- "Routes are still present \n Error: {}".format(tc_name, result)
+ assert (
+ result is not True
+ ), "Testcase {} : Failed \nRoutes are still present \n Error: {}".format(
+ tc_name, result
)
logger.info("Expected behaviour: {}".format(result))
else:
diff --git a/tests/topotests/lib/micronet.py b/tests/topotests/lib/micronet.py
index 8567bd3b4b..59dd80ff7b 100644
--- a/tests/topotests/lib/micronet.py
+++ b/tests/topotests/lib/micronet.py
@@ -358,11 +358,14 @@ class Commander(object): # pylint: disable=R0205
# wait for not supported in screen for now
channel = None
cmd = [self.get_exec_path("screen")]
+ if title:
+ cmd.append("-t")
+ cmd.append(title)
if not os.path.exists(
"/run/screen/S-{}/{}".format(os.environ["USER"], os.environ["STY"])
):
cmd = ["sudo", "-u", os.environ["SUDO_USER"]] + cmd
- cmd.append(nscmd)
+ cmd.extend(nscmd.split(" "))
elif "DISPLAY" in os.environ:
# We need it broken up for xterm
user_cmd = cmd
diff --git a/tests/topotests/lib/micronet_cli.py b/tests/topotests/lib/micronet_cli.py
index 6459d5d151..4292f47ce0 100644
--- a/tests/topotests/lib/micronet_cli.py
+++ b/tests/topotests/lib/micronet_cli.py
@@ -113,11 +113,11 @@ def doline(unet, line, writef):
hosts = [unet.hosts[x] for x in args]
for host in hosts:
if cmd == "t" or cmd == "term":
- host.run_in_window("bash")
+ host.run_in_window("bash", title="sh-%s" % host)
elif cmd == "v" or cmd == "vtysh":
- host.run_in_window("vtysh")
+ host.run_in_window("vtysh", title="vt-%s" % host)
elif cmd == "x" or cmd == "xterm":
- host.run_in_window("bash", forcex=True)
+ host.run_in_window("bash", title="sh-%s" % host, forcex=True)
elif cmd == "sh":
hosts, cmd = host_cmd_split(unet, oargs)
for host in hosts:
diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py
index 6be644ac00..d3438f67e5 100644
--- a/tests/topotests/lib/topotest.py
+++ b/tests/topotests/lib/topotest.py
@@ -1613,7 +1613,7 @@ class Router(Node):
shell_routers = g_extra_config["shell"]
if "all" in shell_routers or self.name in shell_routers:
- self.run_in_window(os.getenv("SHELL", "bash"))
+ self.run_in_window(os.getenv("SHELL", "bash"), title="sh-%s" % self.name)
if self.daemons["eigrpd"] == 1:
eigrpd_path = os.path.join(self.daemondir, "eigrpd")
@@ -1631,7 +1631,7 @@ class Router(Node):
vtysh_routers = g_extra_config["vtysh"]
if "all" in vtysh_routers or self.name in vtysh_routers:
- self.run_in_window("vtysh")
+ self.run_in_window("vtysh", title="vt-%s" % self.name)
return status
diff --git a/tests/topotests/ospf_topo1_vrf/__init__.py b/tests/topotests/ospf_netns_vrf/__init__.py
index e69de29bb2..e69de29bb2 100755
--- a/tests/topotests/ospf_topo1_vrf/__init__.py
+++ b/tests/topotests/ospf_netns_vrf/__init__.py
diff --git a/tests/topotests/ospf_topo1_vrf/r1/ospfd.conf b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf
index e1e2bfb99a..e1e2bfb99a 100644
--- a/tests/topotests/ospf_topo1_vrf/r1/ospfd.conf
+++ b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf
diff --git a/tests/topotests/ospf_topo1_vrf/r1/ospfroute.txt b/tests/topotests/ospf_netns_vrf/r1/ospfroute.txt
index d617ab36d9..d617ab36d9 100644
--- a/tests/topotests/ospf_topo1_vrf/r1/ospfroute.txt
+++ b/tests/topotests/ospf_netns_vrf/r1/ospfroute.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r1/ospfroute_down.txt b/tests/topotests/ospf_netns_vrf/r1/ospfroute_down.txt
index 4f7fd699cf..4f7fd699cf 100644
--- a/tests/topotests/ospf_topo1_vrf/r1/ospfroute_down.txt
+++ b/tests/topotests/ospf_netns_vrf/r1/ospfroute_down.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r1/zebra.conf b/tests/topotests/ospf_netns_vrf/r1/zebra.conf
index 56d7a9764e..56d7a9764e 100644
--- a/tests/topotests/ospf_topo1_vrf/r1/zebra.conf
+++ b/tests/topotests/ospf_netns_vrf/r1/zebra.conf
diff --git a/tests/topotests/ospf_topo1_vrf/r1/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r1/zebraroute.txt
index 979af20c59..979af20c59 100644
--- a/tests/topotests/ospf_topo1_vrf/r1/zebraroute.txt
+++ b/tests/topotests/ospf_netns_vrf/r1/zebraroute.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r1/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt
index ec99fad762..ec99fad762 100644
--- a/tests/topotests/ospf_topo1_vrf/r1/zebraroutedown.txt
+++ b/tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r2/ospfd.conf b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf
index c1984276f4..c1984276f4 100644
--- a/tests/topotests/ospf_topo1_vrf/r2/ospfd.conf
+++ b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf
diff --git a/tests/topotests/ospf_topo1_vrf/r2/ospfroute.txt b/tests/topotests/ospf_netns_vrf/r2/ospfroute.txt
index 89763ff733..89763ff733 100644
--- a/tests/topotests/ospf_topo1_vrf/r2/ospfroute.txt
+++ b/tests/topotests/ospf_netns_vrf/r2/ospfroute.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r2/ospfroute_down.txt b/tests/topotests/ospf_netns_vrf/r2/ospfroute_down.txt
index d946f02dfd..d946f02dfd 100644
--- a/tests/topotests/ospf_topo1_vrf/r2/ospfroute_down.txt
+++ b/tests/topotests/ospf_netns_vrf/r2/ospfroute_down.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r2/zebra.conf b/tests/topotests/ospf_netns_vrf/r2/zebra.conf
index 6ff72d1267..6ff72d1267 100644
--- a/tests/topotests/ospf_topo1_vrf/r2/zebra.conf
+++ b/tests/topotests/ospf_netns_vrf/r2/zebra.conf
diff --git a/tests/topotests/ospf_topo1_vrf/r2/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r2/zebraroute.txt
index df66e92abc..df66e92abc 100644
--- a/tests/topotests/ospf_topo1_vrf/r2/zebraroute.txt
+++ b/tests/topotests/ospf_netns_vrf/r2/zebraroute.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r2/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt
index 4afc354ca7..4afc354ca7 100644
--- a/tests/topotests/ospf_topo1_vrf/r2/zebraroutedown.txt
+++ b/tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r3/ospfd.conf b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf
index b73d547e3e..b73d547e3e 100644
--- a/tests/topotests/ospf_topo1_vrf/r3/ospfd.conf
+++ b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf
diff --git a/tests/topotests/ospf_topo1_vrf/r3/ospfroute.txt b/tests/topotests/ospf_netns_vrf/r3/ospfroute.txt
index 917702b14c..917702b14c 100644
--- a/tests/topotests/ospf_topo1_vrf/r3/ospfroute.txt
+++ b/tests/topotests/ospf_netns_vrf/r3/ospfroute.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r3/ospfroute_down.txt b/tests/topotests/ospf_netns_vrf/r3/ospfroute_down.txt
index 966185e495..966185e495 100644
--- a/tests/topotests/ospf_topo1_vrf/r3/ospfroute_down.txt
+++ b/tests/topotests/ospf_netns_vrf/r3/ospfroute_down.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r3/zebra.conf b/tests/topotests/ospf_netns_vrf/r3/zebra.conf
index 1534150048..1534150048 100644
--- a/tests/topotests/ospf_topo1_vrf/r3/zebra.conf
+++ b/tests/topotests/ospf_netns_vrf/r3/zebra.conf
diff --git a/tests/topotests/ospf_topo1_vrf/r3/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r3/zebraroute.txt
index b435c2ebe5..b435c2ebe5 100644
--- a/tests/topotests/ospf_topo1_vrf/r3/zebraroute.txt
+++ b/tests/topotests/ospf_netns_vrf/r3/zebraroute.txt
diff --git a/tests/topotests/ospf_topo1_vrf/r3/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt
index f30a4be6c6..f30a4be6c6 100644
--- a/tests/topotests/ospf_topo1_vrf/r3/zebraroutedown.txt
+++ b/tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt
diff --git a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1-vrf.dot b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.dot
index 789fdd7c09..789fdd7c09 100644
--- a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1-vrf.dot
+++ b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.dot
diff --git a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.jpg b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.jpg
index 85f2e52f8e..85f2e52f8e 100644
--- a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.jpg
+++ b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.jpg
Binary files differ
diff --git a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.py b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py
index 44de61d82a..621d8079dc 100644
--- a/tests/topotests/ospf_topo1_vrf/test_ospf_topo1_vrf.py
+++ b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
-# test_ospf_topo1.py
+# test_ospf_netns_vrf.py
# Part of NetDEF Topology Tests
#
# Copyright (c) 2017 by
@@ -23,7 +23,7 @@
#
"""
-test_ospf_topo1.py: Test the FRR OSPF routing daemon.
+test_ospf_netns_vrf.py: Test OSPF with Network Namespace VRFs.
"""
import os
diff --git a/tests/topotests/ospf_topo2/r1/ospf-route.json b/tests/topotests/ospf_unnumbered/r1/ospf-route.json
index 6beb7e9bed..6beb7e9bed 100644
--- a/tests/topotests/ospf_topo2/r1/ospf-route.json
+++ b/tests/topotests/ospf_unnumbered/r1/ospf-route.json
diff --git a/tests/topotests/ospf_topo2/r1/ospfd.conf b/tests/topotests/ospf_unnumbered/r1/ospfd.conf
index 65843cbb83..65843cbb83 100644
--- a/tests/topotests/ospf_topo2/r1/ospfd.conf
+++ b/tests/topotests/ospf_unnumbered/r1/ospfd.conf
diff --git a/tests/topotests/ospf_topo2/r1/v4_route.json b/tests/topotests/ospf_unnumbered/r1/v4_route.json
index 76c6396169..76c6396169 100644
--- a/tests/topotests/ospf_topo2/r1/v4_route.json
+++ b/tests/topotests/ospf_unnumbered/r1/v4_route.json
diff --git a/tests/topotests/ospf_topo2/r1/zebra.conf b/tests/topotests/ospf_unnumbered/r1/zebra.conf
index d96d9707c1..d96d9707c1 100644
--- a/tests/topotests/ospf_topo2/r1/zebra.conf
+++ b/tests/topotests/ospf_unnumbered/r1/zebra.conf
diff --git a/tests/topotests/ospf_topo2/r2/ospf-route.json b/tests/topotests/ospf_unnumbered/r2/ospf-route.json
index 3cfd255bfd..3cfd255bfd 100644
--- a/tests/topotests/ospf_topo2/r2/ospf-route.json
+++ b/tests/topotests/ospf_unnumbered/r2/ospf-route.json
diff --git a/tests/topotests/ospf_topo2/r2/ospfd.conf b/tests/topotests/ospf_unnumbered/r2/ospfd.conf
index b032f1a8ac..b032f1a8ac 100644
--- a/tests/topotests/ospf_topo2/r2/ospfd.conf
+++ b/tests/topotests/ospf_unnumbered/r2/ospfd.conf
diff --git a/tests/topotests/ospf_topo2/r2/v4_route.json b/tests/topotests/ospf_unnumbered/r2/v4_route.json
index 1638536388..1638536388 100644
--- a/tests/topotests/ospf_topo2/r2/v4_route.json
+++ b/tests/topotests/ospf_unnumbered/r2/v4_route.json
diff --git a/tests/topotests/ospf_topo2/r2/zebra.conf b/tests/topotests/ospf_unnumbered/r2/zebra.conf
index f9dd2c4471..f9dd2c4471 100644
--- a/tests/topotests/ospf_topo2/r2/zebra.conf
+++ b/tests/topotests/ospf_unnumbered/r2/zebra.conf
diff --git a/tests/topotests/ospf_topo2/test_ospf_topo2.py b/tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py
index 1ad62ff18e..a9640adca3 100644
--- a/tests/topotests/ospf_topo2/test_ospf_topo2.py
+++ b/tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
-# test_ospf_topo2.py
+# test_ospf_unnumbered.py
#
# Copyright (c) 2019 by
# Cumulus Networks, Inc
@@ -23,7 +23,7 @@
#
"""
-test_ospf_topo2.py: Test the OSPF unnumbered.
+test_ospf_unnumbered.py: Test the OSPF unnumbered.
"""
import os
diff --git a/yang/frr-bgp-route-map.yang b/yang/frr-bgp-route-map.yang
index 9bd26043a7..74008bc078 100644
--- a/yang/frr-bgp-route-map.yang
+++ b/yang/frr-bgp-route-map.yang
@@ -532,6 +532,16 @@ module frr-bgp-route-map {
description
"Prefix route";
}
+ enum "ead" {
+ value 3;
+ description
+ "Ethernet Auto-Discovery route";
+ }
+ enum "es" {
+ value 4;
+ description
+ "Ethernet Segment route";
+ }
}
}
}
diff --git a/zebra/ioctl.c b/zebra/ioctl.c
index 8b30eea9f1..9b6aaf1d85 100644
--- a/zebra/ioctl.c
+++ b/zebra/ioctl.c
@@ -410,11 +410,14 @@ int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx)
void if_get_flags(struct interface *ifp)
{
int ret;
- struct ifreq ifreq;
+ struct ifreq ifreqflags;
+ struct ifreq ifreqdata;
- ifreq_set_name(&ifreq, ifp);
+ ifreq_set_name(&ifreqflags, ifp);
+ ifreq_set_name(&ifreqdata, ifp);
- ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf->vrf_id);
+ ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreqflags,
+ ifp->vrf->vrf_id);
if (ret < 0) {
flog_err_sys(EC_LIB_SYSTEM_CALL,
"vrf_if_ioctl(SIOCGIFFLAGS %s) failed: %s",
@@ -448,8 +451,8 @@ void if_get_flags(struct interface *ifp)
struct if_data ifd = {.ifi_link_state = 0};
struct if_data *ifdata = &ifd;
- ifreq.ifr_data = (caddr_t)ifdata;
- ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifreq, ifp->vrf->vrf_id);
+ ifreqdata.ifr_data = (caddr_t)ifdata;
+ ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifreqdata, ifp->vrf->vrf_id);
#endif
if (ret == -1)
@@ -459,12 +462,12 @@ void if_get_flags(struct interface *ifp)
safe_strerror(errno));
else {
if (ifdata->ifi_link_state >= LINK_STATE_UP)
- SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+ SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
else if (ifdata->ifi_link_state == LINK_STATE_UNKNOWN)
/* BSD traditionally treats UNKNOWN as UP */
- SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+ SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
else
- UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+ UNSET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
}
#elif defined(HAVE_BSD_LINK_DETECT)
@@ -489,14 +492,14 @@ void if_get_flags(struct interface *ifp)
ifp->name, safe_strerror(errno));
} else if (ifmr.ifm_status & IFM_AVALID) { /* media state is valid */
if (ifmr.ifm_status & IFM_ACTIVE) /* media is active */
- SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+ SET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
else
- UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+ UNSET_FLAG(ifreqflags.ifr_flags, IFF_RUNNING);
}
#endif /* HAVE_BSD_LINK_DETECT */
out:
- if_flags_update(ifp, (ifreq.ifr_flags & 0x0000ffff));
+ if_flags_update(ifp, (ifreqflags.ifr_flags & 0x0000ffff));
}
/* Set interface flags */
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index ca83a42685..84c15a2a92 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -159,7 +159,17 @@ extern struct zebra_privs_t zserv_privs;
DEFINE_MTYPE_STATIC(ZEBRA, NL_BUF, "Zebra Netlink buffers");
-struct hash *nlsock_hash;
+/* Hashtable and mutex to allow lookup of nlsock structs by socket/fd value.
+ * We have both the main and dplane pthreads using these structs, so we have
+ * to protect the hash with a lock.
+ */
+static struct hash *nlsock_hash;
+pthread_mutex_t nlsock_mutex;
+
+/* Lock and unlock wrappers for nlsock hash */
+#define NLSOCK_LOCK() pthread_mutex_lock(&nlsock_mutex)
+#define NLSOCK_UNLOCK() pthread_mutex_unlock(&nlsock_mutex)
+
size_t nl_batch_tx_bufsize;
char *nl_batch_tx_buf;
@@ -1513,11 +1523,31 @@ void kernel_update_multi(struct dplane_ctx_q *ctx_list)
struct nlsock *kernel_netlink_nlsock_lookup(int sock)
{
- struct nlsock lookup;
+ struct nlsock lookup, *retval;
lookup.sock = sock;
- return hash_lookup(nlsock_hash, &lookup);
+ NLSOCK_LOCK();
+ retval = hash_lookup(nlsock_hash, &lookup);
+ NLSOCK_UNLOCK();
+
+ return retval;
+}
+
+/* Insert nlsock entry into hash */
+static void kernel_netlink_nlsock_insert(struct nlsock *nls)
+{
+ NLSOCK_LOCK();
+ (void)hash_get(nlsock_hash, nls, hash_alloc_intern);
+ NLSOCK_UNLOCK();
+}
+
+/* Remove nlsock entry from hash */
+static void kernel_netlink_nlsock_remove(struct nlsock *nls)
+{
+ NLSOCK_LOCK();
+ (void)hash_release(nlsock_hash, nls);
+ NLSOCK_UNLOCK();
}
static uint32_t kernel_netlink_nlsock_key(const void *arg)
@@ -1547,11 +1577,6 @@ void kernel_init(struct zebra_ns *zns)
int one, ret;
#endif
- if (!nlsock_hash)
- nlsock_hash = hash_create_size(8, kernel_netlink_nlsock_key,
- kernel_netlink_nlsock_hash_equal,
- "Netlink Socket Hash");
-
/*
* Initialize netlink sockets
*
@@ -1584,7 +1609,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink.name);
exit(-1);
}
- (void)hash_get(nlsock_hash, &zns->netlink, hash_alloc_intern);
+
+ kernel_netlink_nlsock_insert(&zns->netlink);
snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name),
"netlink-cmd (NS %u)", zns->ns_id);
@@ -1594,7 +1620,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_cmd.name);
exit(-1);
}
- (void)hash_get(nlsock_hash, &zns->netlink_cmd, hash_alloc_intern);
+
+ kernel_netlink_nlsock_insert(&zns->netlink_cmd);
/* Outbound socket for dplane programming of the host OS. */
snprintf(zns->netlink_dplane_out.name,
@@ -1606,8 +1633,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_dplane_out.name);
exit(-1);
}
- (void)hash_get(nlsock_hash, &zns->netlink_dplane_out,
- hash_alloc_intern);
+
+ kernel_netlink_nlsock_insert(&zns->netlink_dplane_out);
/* Inbound socket for OS events coming to the dplane. */
snprintf(zns->netlink_dplane_in.name,
@@ -1620,7 +1647,8 @@ void kernel_init(struct zebra_ns *zns)
zns->netlink_dplane_in.name);
exit(-1);
}
- (void)hash_get(nlsock_hash, &zns->netlink_dplane_in, hash_alloc_intern);
+
+ kernel_netlink_nlsock_insert(&zns->netlink_dplane_in);
/*
* SOL_NETLINK is not available on all platforms yet
@@ -1706,47 +1734,56 @@ void kernel_init(struct zebra_ns *zns)
rt_netlink_init();
}
+/* Helper to clean up an nlsock */
+static void kernel_nlsock_fini(struct nlsock *nls)
+{
+ if (nls && nls->sock >= 0) {
+ kernel_netlink_nlsock_remove(nls);
+ close(nls->sock);
+ nls->sock = -1;
+ XFREE(MTYPE_NL_BUF, nls->buf);
+ nls->buflen = 0;
+ }
+}
+
void kernel_terminate(struct zebra_ns *zns, bool complete)
{
thread_cancel(&zns->t_netlink);
- if (zns->netlink.sock >= 0) {
- hash_release(nlsock_hash, &zns->netlink);
- close(zns->netlink.sock);
- zns->netlink.sock = -1;
- XFREE(MTYPE_NL_BUF, zns->netlink.buf);
- zns->netlink.buflen = 0;
- }
+ kernel_nlsock_fini(&zns->netlink);
- if (zns->netlink_cmd.sock >= 0) {
- hash_release(nlsock_hash, &zns->netlink_cmd);
- close(zns->netlink_cmd.sock);
- zns->netlink_cmd.sock = -1;
- XFREE(MTYPE_NL_BUF, zns->netlink_cmd.buf);
- zns->netlink_cmd.buflen = 0;
- }
+ kernel_nlsock_fini(&zns->netlink_cmd);
- if (zns->netlink_dplane_in.sock >= 0) {
- hash_release(nlsock_hash, &zns->netlink_dplane_in);
- close(zns->netlink_dplane_in.sock);
- zns->netlink_dplane_in.sock = -1;
- XFREE(MTYPE_NL_BUF, zns->netlink_dplane_in.buf);
- zns->netlink_dplane_in.buflen = 0;
- }
+ kernel_nlsock_fini(&zns->netlink_dplane_in);
/* During zebra shutdown, we need to leave the dataplane socket
* around until all work is done.
*/
- if (complete) {
- if (zns->netlink_dplane_out.sock >= 0) {
- hash_release(nlsock_hash, &zns->netlink_dplane_out);
- close(zns->netlink_dplane_out.sock);
- zns->netlink_dplane_out.sock = -1;
- XFREE(MTYPE_NL_BUF, zns->netlink_dplane_out.buf);
- zns->netlink_dplane_out.buflen = 0;
- }
+ if (complete)
+ kernel_nlsock_fini(&zns->netlink_dplane_out);
+}
- hash_free(nlsock_hash);
- }
+/*
+ * Global init for platform-/OS-specific things
+ */
+void kernel_router_init(void)
+{
+ /* Init nlsock hash and lock */
+ pthread_mutex_init(&nlsock_mutex, NULL);
+ nlsock_hash = hash_create_size(8, kernel_netlink_nlsock_key,
+ kernel_netlink_nlsock_hash_equal,
+ "Netlink Socket Hash");
+}
+
+/*
+ * Global deinit for platform-/OS-specific things
+ */
+void kernel_router_terminate(void)
+{
+ pthread_mutex_destroy(&nlsock_mutex);
+
+ hash_free(nlsock_hash);
+ nlsock_hash = NULL;
}
+
#endif /* HAVE_NETLINK */
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 3c9d203a0b..b9228072e5 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1460,6 +1460,20 @@ void kernel_terminate(struct zebra_ns *zns, bool complete)
}
/*
+ * Global init for platform-/OS-specific things
+ */
+void kernel_router_init(void)
+{
+}
+
+/*
+ * Global deinit for platform-/OS-specific things
+ */
+void kernel_router_terminate(void)
+{
+}
+
+/*
* Called by the dplane pthread to read incoming OS messages and dispatch them.
*/
int kernel_dplane_read(struct zebra_dplane_info *info)
diff --git a/zebra/rt.h b/zebra/rt.h
index 90148d2c0d..5e626928d9 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -78,6 +78,10 @@ extern int kernel_interface_set_master(struct interface *master,
extern int mpls_kernel_init(void);
+/* Global init and deinit for platform-/OS-specific things */
+void kernel_router_init(void);
+void kernel_router_terminate(void);
+
extern uint32_t kernel_get_speed(struct interface *ifp, int *error);
extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index 168e36ac9b..ec22c5dd48 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -116,6 +116,8 @@ struct fpm_nh_encap_info_t {
* data structures for convenience.
*/
struct netlink_nh_info {
+ /* Weight of the nexthop ( for unequal cost ECMP ) */
+ uint8_t weight;
uint32_t if_index;
union g_addr *gateway;
@@ -179,6 +181,7 @@ static int netlink_route_info_add_nh(struct netlink_route_info *ri,
nhi.recursive = nexthop->rparent ? 1 : 0;
nhi.type = nexthop->type;
nhi.if_index = nexthop->ifindex;
+ nhi.weight = nexthop->weight;
if (nexthop->type == NEXTHOP_TYPE_IPV4
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
@@ -480,6 +483,8 @@ static int netlink_route_info_encode(struct netlink_route_info *ri,
rtnh->rtnh_ifindex = nhi->if_index;
}
+ rtnh->rtnh_hops = nhi->weight;
+
encap = nhi->encap_info.encap_type;
switch (encap) {
case FPM_NH_ENCAP_NONE:
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 92a3b9424b..6b4a7543cd 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -262,6 +262,9 @@ void zebra_router_terminate(void)
#ifdef HAVE_SCRIPTING
zebra_script_destroy();
#endif
+
+ /* OS-specific deinit */
+ kernel_router_terminate();
}
bool zebra_router_notify_on_ack(void)
@@ -307,4 +310,7 @@ void zebra_router_init(bool asic_offload, bool notify_on_ack)
#ifdef HAVE_SCRIPTING
zebra_script_init();
#endif
+
+ /* OS-specific init */
+ kernel_router_init();
}