summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am2
-rw-r--r--babeld/babel_interface.c83
-rw-r--r--babeld/kernel.c10
-rw-r--r--babeld/util.c37
-rw-r--r--babeld/util.h3
-rw-r--r--bgpd/bgp_encap_tlv.c14
-rw-r--r--bgpd/bgp_evpn.c9
-rw-r--r--bgpd/bgp_evpn_vty.c6
-rw-r--r--bgpd/bgp_flowspec_util.c8
-rw-r--r--bgpd/bgp_fsm.c1
-rw-r--r--bgpd/bgp_label.c4
-rw-r--r--bgpd/bgp_mplsvpn.c4
-rw-r--r--bgpd/bgp_network.c13
-rw-r--r--bgpd/bgp_nht.c13
-rw-r--r--bgpd/bgp_route.c1
-rw-r--r--bgpd/bgp_routemap.c47
-rw-r--r--bgpd/bgp_script.c15
-rw-r--r--bgpd/bgp_script.h11
-rw-r--r--bgpd/bgp_updgrp.c5
-rw-r--r--bgpd/bgp_vty.c222
-rw-r--r--bgpd/bgp_zebra.c24
-rw-r--r--bgpd/bgpd.c37
-rw-r--r--bgpd/bgpd.h59
-rw-r--r--bgpd/rfapi/rfapi.c8
-rw-r--r--bgpd/rfapi/rfapi_import.c18
-rw-r--r--bgpd/rfapi/rfapi_private.h4
-rw-r--r--bgpd/rfapi/rfapi_vty.c12
-rw-r--r--bgpd/rfapi/vnc_export_bgp.c6
-rw-r--r--bgpd/rfapi/vnc_import_bgp.c12
-rw-r--r--bgpd/rfapi/vnc_zebra.c10
-rw-r--r--changelog-auto.in1487
-rw-r--r--configure.ac5
-rw-r--r--[l---------]debian/changelog1524
-rw-r--r--debian/gbp.conf2
-rwxr-xr-xdebian/tests/py-frr-reload10
-rw-r--r--doc/developer/frr-release-procedure.rst21
-rw-r--r--doc/developer/packaging-debian.rst32
-rw-r--r--doc/developer/scripting.rst206
-rw-r--r--doc/user/bgp.rst59
-rw-r--r--doc/user/ipv6.rst5
-rw-r--r--doc/user/pim.rst21
-rw-r--r--docker/ubuntu20-ci/Dockerfile2
-rw-r--r--eigrpd/eigrp_network.c2
-rw-r--r--isisd/isis_route.c4
-rw-r--r--isisd/isis_tlvs.c6
-rw-r--r--isisd/isis_zebra.c5
-rw-r--r--ldpd/labelmapping.c4
-rw-r--r--ldpd/lde.c8
-rw-r--r--ldpd/util.c4
-rw-r--r--lib/command.c6
-rw-r--r--lib/command_match.c4
-rw-r--r--lib/compiler.h23
-rw-r--r--lib/filter.c10
-rw-r--r--lib/frrlua.c100
-rw-r--r--lib/frrlua.h21
-rw-r--r--lib/frrscript.c18
-rw-r--r--lib/frrscript.h76
-rw-r--r--lib/prefix.c17
-rw-r--r--lib/prefix.h10
-rw-r--r--lib/sockunion.c3
-rw-r--r--lib/sockunion.h1
-rw-r--r--lib/table.c4
-rw-r--r--lib/zclient.c24
-rw-r--r--lib/zclient.h3
-rw-r--r--ospf6d/ospf6_asbr.c71
-rw-r--r--ospf6d/ospf6_asbr.h3
-rw-r--r--ospf6d/ospf6_top.c6
-rw-r--r--ospf6d/ospf6_top.h6
-rw-r--r--ospf6d/ospf6_zebra.c11
-rw-r--r--ospfd/ospf_asbr.c2
-rw-r--r--ospfd/ospf_interface.c19
-rw-r--r--ospfd/ospf_te.c12
-rw-r--r--ospfd/ospf_ti_lfa.c2
-rw-r--r--ospfd/ospf_vty.c8
-rw-r--r--ospfd/ospf_zebra.c7
-rw-r--r--pbrd/pbr_zebra.c12
-rw-r--r--pimd/pim_bsm.c2
-rw-r--r--pimd/pim_cmd.c86
-rw-r--r--pimd/pim_iface.c2
-rw-r--r--pimd/pim_ifchannel.c2
-rw-r--r--pimd/pim_igmpv3.c2
-rw-r--r--pimd/pim_instance.c6
-rw-r--r--pimd/pim_msdp.c145
-rw-r--r--pimd/pim_msdp.h48
-rw-r--r--pimd/pim_msdp_packet.c16
-rw-r--r--pimd/pim_nb.c19
-rw-r--r--pimd/pim_nb.h7
-rw-r--r--pimd/pim_nb_config.c231
-rw-r--r--pimd/pim_register.c4
-rw-r--r--pimd/pim_rp.c10
-rw-r--r--pimd/pim_tlv.c6
-rw-r--r--pimd/pim_upstream.c2
-rw-r--r--pimd/pim_util.c6
-rw-r--r--pimd/pim_vty.c11
-rw-r--r--pimd/pim_zlookup.c2
-rw-r--r--ripd/rip_interface.c2
-rw-r--r--ripd/ripd.c5
-rw-r--r--ripngd/ripngd.c2
-rw-r--r--sharpd/sharp_vty.c20
-rw-r--r--staticd/static_nht.c3
-rw-r--r--tests/.gitignore2
-rw-r--r--tests/bgpd/test_peer_attr.c1
-rw-r--r--tests/lib/script1.lua1
-rw-r--r--tests/lib/test_frrlua.c111
-rw-r--r--tests/lib/test_frrlua.py14
-rw-r--r--tests/lib/test_frrscript.c37
-rw-r--r--tests/lib/test_frrscript.py14
-rw-r--r--tests/subdir.am28
-rw-r--r--tests/topotests/bgp_default_afi_safi/__init__.py (renamed from tests/topotests/bgp_default_ipv4_ipv6_unicast/__init__.py)0
-rw-r--r--tests/topotests/bgp_default_afi_safi/r1/bgpd.conf (renamed from tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/bgpd.conf)0
-rw-r--r--tests/topotests/bgp_default_afi_safi/r1/zebra.conf (renamed from tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/zebra.conf)0
-rw-r--r--tests/topotests/bgp_default_afi_safi/r2/bgpd.conf (renamed from tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/bgpd.conf)0
-rw-r--r--tests/topotests/bgp_default_afi_safi/r2/zebra.conf (renamed from tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/zebra.conf)0
-rw-r--r--tests/topotests/bgp_default_afi_safi/r3/bgpd.conf5
-rw-r--r--tests/topotests/bgp_default_afi_safi/r3/zebra.conf (renamed from tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/zebra.conf)0
-rw-r--r--tests/topotests/bgp_default_afi_safi/r4/bgpd.conf (renamed from tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/bgpd.conf)1
-rw-r--r--tests/topotests/bgp_default_afi_safi/r4/zebra.conf6
-rw-r--r--tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py (renamed from tests/topotests/bgp_default_ipv4_ipv6_unicast/test_bgp-default-ipv4-ipv6-unicast.py)43
-rw-r--r--tests/topotests/lib/bgp.py34
-rw-r--r--tests/topotests/lib/common_config.py195
-rw-r--r--tests/topotests/lib/ospf.py24
-rw-r--r--tests/topotests/lib/pim.py36
-rw-r--r--tests/topotests/msdp_mesh_topo1/r1/pimd.conf1
-rw-r--r--tests/topotests/msdp_mesh_topo1/r2/pimd.conf1
-rw-r--r--tests/topotests/msdp_mesh_topo1/r3/pimd.conf1
-rw-r--r--tests/topotests/msdp_mesh_topo1/test_msdp_mesh_topo1.py2
-rw-r--r--tests/topotests/msdp_topo1/__init__.py0
-rw-r--r--tests/topotests/msdp_topo1/r1/bgpd.conf8
-rw-r--r--tests/topotests/msdp_topo1/r1/pimd.conf21
-rw-r--r--tests/topotests/msdp_topo1/r1/zebra.conf14
-rw-r--r--tests/topotests/msdp_topo1/r2/bgpd.conf8
-rw-r--r--tests/topotests/msdp_topo1/r2/pimd.conf17
-rw-r--r--tests/topotests/msdp_topo1/r2/zebra.conf11
-rw-r--r--tests/topotests/msdp_topo1/r3/bgpd.conf8
-rw-r--r--tests/topotests/msdp_topo1/r3/pimd.conf17
-rw-r--r--tests/topotests/msdp_topo1/r3/zebra.conf11
-rw-r--r--tests/topotests/msdp_topo1/r4/bgpd.conf9
-rw-r--r--tests/topotests/msdp_topo1/r4/pimd.conf21
-rw-r--r--tests/topotests/msdp_topo1/r4/zebra.conf14
-rwxr-xr-xtests/topotests/msdp_topo1/test_msdp_topo1.py499
-rw-r--r--tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py3
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py7
-rwxr-xr-xtests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py116
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_authentication.py8
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py8
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py4
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py4
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py2
-rw-r--r--tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py9
-rw-r--r--tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py11
-rwxr-xr-xtools/build-debian-package.sh72
-rwxr-xr-xtools/generate_support_bundle.py186
-rwxr-xr-xtools/tarsource.sh336
-rw-r--r--vtysh/vtysh.c10
-rw-r--r--vtysh/vtysh.h2
-rw-r--r--vtysh/vtysh_config.c6
-rw-r--r--vtysh/vtysh_main.c11
-rw-r--r--yang/frr-pim.yang50
-rw-r--r--zebra/connected.c25
-rw-r--r--zebra/interface.c4
-rw-r--r--zebra/kernel_socket.c4
-rw-r--r--zebra/main.c1
-rw-r--r--zebra/rib.h18
-rw-r--r--zebra/router-id.c16
-rw-r--r--zebra/rtadv.c411
-rw-r--r--zebra/rtadv.h3
-rw-r--r--zebra/zapi_msg.c4
-rw-r--r--zebra/zebra_dplane.c3
-rw-r--r--zebra/zebra_mpls.c4
-rw-r--r--zebra/zebra_nhg.c22
-rw-r--r--zebra/zebra_pbr.c4
-rw-r--r--zebra/zebra_rib.c4
-rw-r--r--zebra/zebra_router.c2
-rw-r--r--zebra/zebra_router.h3
-rw-r--r--zebra/zebra_vrf.c2
-rw-r--r--zebra/zebra_vty.c14
177 files changed, 4626 insertions, 3202 deletions
diff --git a/.gitignore b/.gitignore
index 33d03296db..40f6475a26 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,7 +28,6 @@
/aclocal.m4
/libtool
/libtool.orig
-/changelog-auto
/test-driver
/test-suite.log
diff --git a/Makefile.am b/Makefile.am
index 8c9d7df77c..9bc5dd7d22 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -195,8 +195,6 @@ EXTRA_DIST += \
m4/README.txt \
m4/libtool-whole-archive.patch \
config.version \
- changelog-auto \
- changelog-auto.in \
\
python/clidef.py \
python/clippy/__init__.py \
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c
index 41391c51ac..43ed97cf17 100644
--- a/babeld/babel_interface.c
+++ b/babeld/babel_interface.c
@@ -177,10 +177,11 @@ babel_interface_address_delete (ZAPI_CALLBACK_ARGS)
if (prefix->family == AF_INET) {
flush_interface_routes(ifc->ifp, 0);
babel_ifp = babel_get_if_nfo(ifc->ifp);
- if (babel_ifp->ipv4 != NULL
- && memcmp(babel_ifp->ipv4, &prefix->u.prefix4, 4) == 0) {
- free(babel_ifp->ipv4);
- babel_ifp->ipv4 = NULL;
+ if (babel_ifp->ipv4 != NULL
+ && memcmp(babel_ifp->ipv4, &prefix->u.prefix4, IPV4_MAX_BYTELEN)
+ == 0) {
+ free(babel_ifp->ipv4);
+ babel_ifp->ipv4 = NULL;
}
}
@@ -825,9 +826,11 @@ is_interface_ll_address(struct interface *ifp, const unsigned char *address)
return 0;
FOR_ALL_INTERFACES_ADDRESSES(ifp, connected, node) {
- if(connected->address->family == AF_INET6 &&
- memcmp(&connected->address->u.prefix6, address, 16) == 0)
- return 1;
+ if (connected->address->family == AF_INET6
+ && memcmp(&connected->address->u.prefix6, address,
+ IPV6_MAX_BYTELEN)
+ == 0)
+ return 1;
}
return 0;
@@ -941,13 +944,13 @@ static int
babel_prefix_eq(struct prefix *prefix, unsigned char *p, int plen)
{
if(prefix->family == AF_INET6) {
- if(prefix->prefixlen != plen ||
- memcmp(&prefix->u.prefix6, p, 16) != 0)
- return 0;
+ if (prefix->prefixlen != plen
+ || memcmp(&prefix->u.prefix6, p, IPV6_MAX_BYTELEN) != 0)
+ return 0;
} else if(prefix->family == AF_INET) {
- if(plen < 96 || !v4mapped(p) || prefix->prefixlen != plen - 96 ||
- memcmp(&prefix->u.prefix4, p + 12, 4) != 0)
- return 0;
+ if (plen < 96 || !v4mapped(p) || prefix->prefixlen != plen - 96
+ || memcmp(&prefix->u.prefix4, p + 12, IPV4_MAX_BYTELEN) != 0)
+ return 0;
} else {
return 0;
}
@@ -959,31 +962,35 @@ static void
show_babel_routes_sub(struct babel_route *route, struct vty *vty,
struct prefix *prefix)
{
- const unsigned char *nexthop =
- memcmp(route->nexthop, route->neigh->address, 16) == 0 ?
- NULL : route->nexthop;
- char channels[100];
-
- if(prefix && !babel_prefix_eq(prefix, route->src->prefix, route->src->plen))
- return;
-
- if(route->channels[0] == 0)
- channels[0] = '\0';
- else {
- int k, j = 0;
- snprintf(channels, sizeof(channels), " chan (");
- j = strlen(channels);
- for(k = 0; k < DIVERSITY_HOPS; k++) {
- if(route->channels[k] == 0)
- break;
- if(k > 0)
- channels[j++] = ',';
- snprintf(channels + j, 100 - j, "%u", route->channels[k]);
- j = strlen(channels);
- }
- snprintf(channels + j, 100 - j, ")");
- if(k == 0)
- channels[0] = '\0';
+ const unsigned char *nexthop =
+ memcmp(route->nexthop, route->neigh->address, IPV6_MAX_BYTELEN)
+ == 0
+ ? NULL
+ : route->nexthop;
+ char channels[100];
+
+ if (prefix
+ && !babel_prefix_eq(prefix, route->src->prefix, route->src->plen))
+ return;
+
+ if (route->channels[0] == 0)
+ channels[0] = '\0';
+ else {
+ int k, j = 0;
+ snprintf(channels, sizeof(channels), " chan (");
+ j = strlen(channels);
+ for (k = 0; k < DIVERSITY_HOPS; k++) {
+ if (route->channels[k] == 0)
+ break;
+ if (k > 0)
+ channels[j++] = ',';
+ snprintf(channels + j, 100 - j, "%u",
+ route->channels[k]);
+ j = strlen(channels);
+ }
+ snprintf(channels + j, 100 - j, ")");
+ if (k == 0)
+ channels[0] = '\0';
}
vty_out (vty,
diff --git a/babeld/kernel.c b/babeld/kernel.c
index e3c76bdd92..3941db8d5f 100644
--- a/babeld/kernel.c
+++ b/babeld/kernel.c
@@ -176,11 +176,11 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen,
switch (family) {
case AF_INET:
uchar_to_inaddr(&api_nh->gate.ipv4, gate);
- if (IPV4_ADDR_SAME (&api_nh->gate.ipv4, &quagga_prefix.u.prefix4) &&
- quagga_prefix.prefixlen == 32) {
- api_nh->type = NEXTHOP_TYPE_IFINDEX;
- } else {
- api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ if (IPV4_ADDR_SAME(&api_nh->gate.ipv4, &quagga_prefix.u.prefix4)
+ && quagga_prefix.prefixlen == IPV4_MAX_BITLEN) {
+ api_nh->type = NEXTHOP_TYPE_IFINDEX;
+ } else {
+ api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
}
break;
case AF_INET6:
diff --git a/babeld/util.c b/babeld/util.c
index e99bd861dc..e2db75996e 100644
--- a/babeld/util.c
+++ b/babeld/util.c
@@ -216,33 +216,13 @@ parse_nat(const char *string)
return (int)l;
}
-int
-in_prefix(const unsigned char *restrict address,
- const unsigned char *restrict prefix, unsigned char plen)
-{
- unsigned char m;
-
- if(plen > 128)
- plen = 128;
-
- if(memcmp(address, prefix, plen / 8) != 0)
- return 0;
-
- if(plen % 8 == 0)
- return 1;
-
- m = 0xFF << (8 - (plen % 8));
-
- return ((address[plen / 8] & m) == (prefix[plen / 8] & m));
-}
-
unsigned char *
mask_prefix(unsigned char *restrict ret,
const unsigned char *restrict prefix, unsigned char plen)
{
- if(plen >= 128) {
- memcpy(ret, prefix, 16);
- return ret;
+ if (plen >= IPV6_MAX_BITLEN) {
+ memcpy(ret, prefix, IPV6_MAX_BYTELEN);
+ return ret;
}
memset(ret, 0, 16);
@@ -329,9 +309,10 @@ parse_address(const char *address, unsigned char *addr_r, int *af_r)
rc = inet_pton(AF_INET6, address, &ina6);
if(rc > 0) {
- memcpy(addr_r, &ina6, 16);
- if(af_r) *af_r = AF_INET6;
- return 0;
+ memcpy(addr_r, &ina6, IPV6_MAX_BYTELEN);
+ if (af_r)
+ *af_r = AF_INET6;
+ return 0;
}
return -1;
@@ -433,13 +414,13 @@ uchar_to_inaddr(struct in_addr *dest, const unsigned char *src)
void
in6addr_to_uchar(unsigned char *dest, const struct in6_addr *src)
{
- memcpy(dest, src, 16);
+ memcpy(dest, src, IPV6_MAX_BYTELEN);
}
void
uchar_to_in6addr(struct in6_addr *dest, const unsigned char *src)
{
- memcpy(dest, src, 16);
+ memcpy(dest, src, IPV6_MAX_BYTELEN);
}
int
diff --git a/babeld/util.h b/babeld/util.h
index 037ebe3666..ef1387364c 100644
--- a/babeld/util.h
+++ b/babeld/util.h
@@ -100,9 +100,6 @@ void timeval_min(struct timeval *d, const struct timeval *s);
void timeval_min_sec(struct timeval *d, time_t secs);
int parse_nat(const char *string) ATTRIBUTE ((pure));
int parse_msec(const char *string) ATTRIBUTE ((pure));
-int in_prefix(const unsigned char *restrict address,
- const unsigned char *restrict prefix, unsigned char plen)
- ATTRIBUTE ((pure));
unsigned char *mask_prefix(unsigned char *restrict ret,
const unsigned char *restrict prefix,
unsigned char plen);
diff --git a/bgpd/bgp_encap_tlv.c b/bgpd/bgp_encap_tlv.c
index 964adec9b6..fd429120e6 100644
--- a/bgpd/bgp_encap_tlv.c
+++ b/bgpd/bgp_encap_tlv.c
@@ -212,12 +212,12 @@ subtlv_encode_remote_endpoint(struct bgp_tea_subtlv_remote_endpoint *st)
new->length = total;
p = new->value;
if (st->family == AF_INET) {
- memcpy(p, &(st->ip_address.v4.s_addr), 4);
- p += 4;
+ memcpy(p, &(st->ip_address.v4.s_addr), IPV4_MAX_BYTELEN);
+ p += IPV4_MAX_BYTELEN;
} else {
assert(st->family == AF_INET6);
- memcpy(p, &(st->ip_address.v6.s6_addr), 16);
- p += 16;
+ memcpy(p, &(st->ip_address.v6.s6_addr), IPV6_MAX_BYTELEN);
+ p += IPV6_MAX_BYTELEN;
}
memcpy(p, &(st->as4), 4);
return new;
@@ -577,10 +577,12 @@ subtlv_decode_remote_endpoint(struct bgp_attr_encap_subtlv *subtlv,
}
if (subtlv->length == 8) {
st->family = AF_INET;
- memcpy(&st->ip_address.v4.s_addr, subtlv->value, 4);
+ memcpy(&st->ip_address.v4.s_addr, subtlv->value,
+ IPV4_MAX_BYTELEN);
} else {
st->family = AF_INET6;
- memcpy(&(st->ip_address.v6.s6_addr), subtlv->value, 16);
+ memcpy(&(st->ip_address.v6.s6_addr), subtlv->value,
+ IPV6_MAX_BYTELEN);
}
i = subtlv->length - 4;
ptr_get_be32(subtlv->value + i, &st->as4);
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 5ef593b9c0..c99f539c7b 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -4114,10 +4114,11 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
gw_afi = AF_INET;
} else {
SET_IPADDR_V6(&p.prefix.prefix_addr.ip);
- memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx, 16);
- pfx += 16;
- memcpy(&evpn.gw_ip.ipv6, pfx, 16);
- pfx += 16;
+ memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx,
+ IPV6_MAX_BYTELEN);
+ pfx += IPV6_MAX_BYTELEN;
+ memcpy(&evpn.gw_ip.ipv6, pfx, IPV6_MAX_BYTELEN);
+ pfx += IPV6_MAX_BYTELEN;
gw_afi = AF_INET6;
}
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 190323859f..2bda5dbf9a 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -63,10 +63,8 @@ int argv_find_and_parse_oly_idx(struct cmd_token **argv, int argc, int *oly_idx,
enum overlay_index_type *oly)
{
*oly = OVERLAY_INDEX_TYPE_NONE;
- if (argv_find(argv, argc, "gateway-ip", oly_idx)) {
- if (oly)
- *oly = OVERLAY_INDEX_GATEWAY_IP;
- }
+ if (argv_find(argv, argc, "gateway-ip", oly_idx))
+ *oly = OVERLAY_INDEX_GATEWAY_IP;
return 1;
}
diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c
index 23baa0184e..348dc7c9d1 100644
--- a/bgpd/bgp_flowspec_util.c
+++ b/bgpd/bgp_flowspec_util.c
@@ -227,12 +227,8 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
BGP_FLOWSPEC_STRING_DISPLAY_MAX);
break;
case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE:
- if (prefix) {
- if (prefix_local.family == AF_INET)
- PREFIX_COPY_IPV4(prefix, &prefix_local);
- else
- PREFIX_COPY_IPV6(prefix, &prefix_local);
- }
+ if (prefix)
+ prefix_copy(prefix, &prefix_local);
break;
case BGP_FLOWSPEC_VALIDATE_ONLY:
default:
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 4cc096d8e7..79dc0aec9d 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -256,6 +256,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
from_peer->last_major_event = last_maj_evt;
peer->remote_id = from_peer->remote_id;
peer->last_reset = from_peer->last_reset;
+ peer->max_packet_size = from_peer->max_packet_size;
peer->peer_gr_present_state = from_peer->peer_gr_present_state;
peer->peer_gr_new_status_flag = from_peer->peer_gr_new_status_flag;
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index 73ca9f07e0..3c8f2f3668 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -390,8 +390,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
return BGP_NLRI_PARSE_ERROR_LABEL_LENGTH;
}
- if ((afi == AFI_IP && p.prefixlen > 32)
- || (afi == AFI_IP6 && p.prefixlen > 128))
+ if ((afi == AFI_IP && p.prefixlen > IPV4_MAX_BITLEN)
+ || (afi == AFI_IP6 && p.prefixlen > IPV6_MAX_BITLEN))
return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
/* Fetch prefix from NLRI packet */
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 564424a082..0de48dcf78 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1440,7 +1440,7 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
case AF_INET:
/* save */
nexthop_orig.u.prefix4 = path_vpn->attr->mp_nexthop_global_in;
- nexthop_orig.prefixlen = 32;
+ nexthop_orig.prefixlen = IPV4_MAX_BITLEN;
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
@@ -1457,7 +1457,7 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
case AF_INET6:
/* save */
nexthop_orig.u.prefix6 = path_vpn->attr->mp_nexthop_global;
- nexthop_orig.prefixlen = 128;
+ nexthop_orig.prefixlen = IPV6_MAX_BITLEN;
if (CHECK_FLAG(bgp_vrf->af_flags[afi][safi],
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index a51816116e..3c061ef1e0 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -101,9 +101,8 @@ static int bgp_md5_set_socket(int socket, union sockunion *su,
su2.sin6.sin6_port = 0;
/* For addresses, use the non-extended signature functionality */
- if ((su2.sa.sa_family == AF_INET && prefixlen == IPV4_MAX_PREFIXLEN)
- || (su2.sa.sa_family == AF_INET6
- && prefixlen == IPV6_MAX_PREFIXLEN))
+ if ((su2.sa.sa_family == AF_INET && prefixlen == IPV4_MAX_BITLEN)
+ || (su2.sa.sa_family == AF_INET6 && prefixlen == IPV6_MAX_BITLEN))
ret = sockopt_tcp_signature(socket, &su2, password);
else
ret = sockopt_tcp_signature_ext(socket, &su2, prefixlen,
@@ -164,8 +163,8 @@ static int bgp_md5_set_password(struct peer *peer, const char *password)
peer->su.sa.sa_family) {
uint16_t prefixlen =
peer->su.sa.sa_family == AF_INET
- ? IPV4_MAX_PREFIXLEN
- : IPV6_MAX_PREFIXLEN;
+ ? IPV4_MAX_BITLEN
+ : IPV6_MAX_BITLEN;
/*
* if we have stored a BGP vrf instance in the
@@ -745,8 +744,8 @@ int bgp_connect(struct peer *peer)
if (peer->password) {
uint16_t prefixlen = peer->su.sa.sa_family == AF_INET
- ? IPV4_MAX_PREFIXLEN
- : IPV6_MAX_PREFIXLEN;
+ ? IPV4_MAX_BITLEN
+ : IPV6_MAX_BITLEN;
bgp_md5_set_connect(peer->fd, &peer->su, prefixlen,
peer->password);
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 4c72bd9f45..eb00a4641c 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -793,7 +793,18 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
|| IN6_IS_ADDR_LINKLOCAL(
&pi->attr->mp_nexthop_global)))
p->u.prefix6 = pi->attr->mp_nexthop_local;
- else
+ /* If we receive MR_REACH with (GA)::(LL)
+ * then check for route-map to choose GA or LL
+ */
+ else if (pi->attr->mp_nexthop_len
+ == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ if (pi->attr->mp_nexthop_prefer_global)
+ p->u.prefix6 =
+ pi->attr->mp_nexthop_global;
+ else
+ p->u.prefix6 =
+ pi->attr->mp_nexthop_local;
+ } else
p->u.prefix6 = pi->attr->mp_nexthop_global;
p->prefixlen = IPV6_MAX_BITLEN;
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 6d6e3a95a6..107aa1eb12 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -14379,6 +14379,7 @@ int bgp_distance_unset(uint8_t distance, const char *ip_str,
if (bdistance->distance != distance) {
snprintf(errmsg, errmsg_len,
"Distance does not match configured\n");
+ bgp_dest_unlock_node(dest);
return CMD_WARNING_CONFIG_FAILED;
}
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 9a7b7b3cf2..529abcbea0 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -29,6 +29,7 @@
#include "memory.h"
#include "log.h"
#include "frrlua.h"
+#include "frrscript.h"
#ifdef HAVE_LIBPCREPOSIX
#include <pcreposix.h>
#else
@@ -373,42 +374,29 @@ route_match_script(void *rule, const struct prefix *prefix, void *object)
return RMAP_NOMATCH;
}
- enum frrlua_rm_status status_failure = LUA_RM_FAILURE,
+ enum frrlua_rm_status lrm_status = LUA_RM_FAILURE,
status_nomatch = LUA_RM_NOMATCH,
status_match = LUA_RM_MATCH,
status_match_and_change = LUA_RM_MATCH_AND_CHANGE;
- /* Make result values available */
- struct frrscript_env env[] = {
- {"integer", "RM_FAILURE", &status_failure},
- {"integer", "RM_NOMATCH", &status_nomatch},
- {"integer", "RM_MATCH", &status_match},
- {"integer", "RM_MATCH_AND_CHANGE", &status_match_and_change},
- {"integer", "action", &status_failure},
- {"prefix", "prefix", prefix},
- {"attr", "attributes", path->attr},
- {"peer", "peer", path->peer},
- {}};
-
- struct frrscript_env results[] = {
- {"integer", "action"},
- {"attr", "attributes"},
- {},
- };
-
- int result = frrscript_call(fs, env);
+ struct attr newattr = *path->attr;
+
+ int result = frrscript_call(
+ fs, ("RM_FAILURE", (long long *)&lrm_status),
+ ("RM_NOMATCH", (long long *)&status_nomatch),
+ ("RM_MATCH", (long long *)&status_match),
+ ("RM_MATCH_AND_CHANGE", (long long *)&status_match_and_change),
+ ("action", (long long *)&lrm_status), ("prefix", prefix),
+ ("attributes", &newattr), ("peer", path->peer));
if (result) {
zlog_err("Issue running script rule; defaulting to no match");
return RMAP_NOMATCH;
}
- enum frrlua_rm_status *lrm_status =
- frrscript_get_result(fs, &results[0]);
-
int status = RMAP_NOMATCH;
- switch (*lrm_status) {
+ switch (lrm_status) {
case LUA_RM_FAILURE:
zlog_err(
"Executing route-map match script '%s' failed; defaulting to no match",
@@ -423,27 +411,22 @@ route_match_script(void *rule, const struct prefix *prefix, void *object)
zlog_debug("Updating attribute based on script's values");
uint32_t locpref = 0;
- struct attr *newattr = frrscript_get_result(fs, &results[1]);
- path->attr->med = newattr->med;
+ path->attr->med = newattr.med;
if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
locpref = path->attr->local_pref;
- if (locpref != newattr->local_pref) {
+ if (locpref != newattr.local_pref) {
SET_FLAG(path->attr->flag,
ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF));
- path->attr->local_pref = newattr->local_pref;
+ path->attr->local_pref = newattr.local_pref;
}
-
- aspath_free(newattr->aspath);
- XFREE(MTYPE_TMP, newattr);
break;
case LUA_RM_MATCH:
status = RMAP_MATCH;
break;
}
- XFREE(MTYPE_TMP, lrm_status);
frrscript_unload(fs);
return status;
diff --git a/bgpd/bgp_script.c b/bgpd/bgp_script.c
index 0cda1927f8..9446a25a05 100644
--- a/bgpd/bgp_script.c
+++ b/bgpd/bgp_script.c
@@ -28,9 +28,8 @@
#include "bgp_aspath.h"
#include "frratomic.h"
#include "frrscript.h"
-#include "frrlua.h"
-static void lua_pushpeer(lua_State *L, const struct peer *peer)
+void lua_pushpeer(lua_State *L, const struct peer *peer)
{
lua_newtable(L);
lua_pushinteger(L, peer->as);
@@ -142,7 +141,7 @@ static void lua_pushpeer(lua_State *L, const struct peer *peer)
lua_setfield(L, -2, "stats");
}
-static void lua_pushattr(lua_State *L, const struct attr *attr)
+void lua_pushattr(lua_State *L, const struct attr *attr)
{
lua_newtable(L);
lua_pushinteger(L, attr->med);
@@ -155,10 +154,8 @@ static void lua_pushattr(lua_State *L, const struct attr *attr)
lua_setfield(L, -2, "localpref");
}
-static void *lua_toattr(lua_State *L, int idx)
+void lua_decode_attr(lua_State *L, int idx, struct attr *attr)
{
- struct attr *attr = XCALLOC(MTYPE_TMP, sizeof(struct attr));
-
lua_getfield(L, -1, "metric");
attr->med = lua_tointeger(L, -1);
lua_pop(L, 1);
@@ -171,7 +168,13 @@ static void *lua_toattr(lua_State *L, int idx)
lua_getfield(L, -1, "localpref");
attr->local_pref = lua_tointeger(L, -1);
lua_pop(L, 1);
+}
+
+void *lua_toattr(lua_State *L, int idx)
+{
+ struct attr *attr = XCALLOC(MTYPE_TMP, sizeof(struct attr));
+ lua_decode_attr(L, idx, attr);
return attr;
}
diff --git a/bgpd/bgp_script.h b/bgpd/bgp_script.h
index 6682c2eebd..f8178aa983 100644
--- a/bgpd/bgp_script.h
+++ b/bgpd/bgp_script.h
@@ -21,14 +21,25 @@
#define __BGP_SCRIPT__
#include <zebra.h>
+#include "bgpd.h"
#ifdef HAVE_SCRIPTING
+#include "frrlua.h"
+
/*
* Initialize scripting stuff.
*/
void bgp_script_init(void);
+void lua_pushpeer(lua_State *L, const struct peer *peer);
+
+void lua_pushattr(lua_State *L, const struct attr *attr);
+
+void lua_decode_attr(lua_State *L, int idx, struct attr *attr);
+
+void *lua_toattr(lua_State *L, int idx);
+
#endif /* HAVE_SCRIPTING */
#endif /* __BGP_SCRIPT__ */
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index b8545188a4..dd3309dad9 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -339,6 +339,7 @@ static unsigned int updgrp_hash_key_make(const void *p)
key);
key = jhash_1word(peer->v_routeadv, key);
key = jhash_1word(peer->change_local_as, key);
+ key = jhash_1word(peer->max_packet_size, key);
if (peer->group)
key = jhash_1word(jhash(peer->group->name,
@@ -572,6 +573,7 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg)
struct update_subgroup *subgrp;
struct peer_af *paf;
struct bgp_filter *filter;
+ struct peer *peer = UPDGRP_PEER(updgrp);
int match = 0;
if (!ctx)
@@ -663,6 +665,9 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg)
CHECK_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH)
? "R"
: "");
+ if (peer)
+ vty_out(vty, " Max packet size: %d\n",
+ peer->max_packet_size);
if (subgrp->peer_count > 0) {
vty_out(vty, " Peers:\n");
SUBGRP_FOREACH_PEER (subgrp, paf)
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index d020e14fb3..9d7e88bb1c 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -470,6 +470,74 @@ int argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index,
return ret;
}
+/*
+ * Convert an afi_t/safi_t pair to matching BGP_DEFAULT_AF* flag.
+ *
+ * afi
+ * address-family identifier
+ *
+ * safi
+ * subsequent address-family identifier
+ *
+ * Returns:
+ * default_af string corresponding to the supplied afi/safi pair.
+ * If afi/safi is invalid or if flag for afi/safi doesn't exist,
+ * return -1.
+ */
+static const char *get_bgp_default_af_flag(afi_t afi, safi_t safi)
+{
+ switch (afi) {
+ case AFI_IP:
+ switch (safi) {
+ case SAFI_UNICAST:
+ return "ipv4-unicast";
+ case SAFI_MULTICAST:
+ return "ipv4-multicast";
+ case SAFI_MPLS_VPN:
+ return "ipv4-vpn";
+ case SAFI_ENCAP:
+ return "ipv4-encap";
+ case SAFI_LABELED_UNICAST:
+ return "ipv4-labeled-unicast";
+ case SAFI_FLOWSPEC:
+ return "ipv4-flowspec";
+ default:
+ return "unknown-afi/safi";
+ }
+ break;
+ case AFI_IP6:
+ switch (safi) {
+ case SAFI_UNICAST:
+ return "ipv6-unicast";
+ case SAFI_MULTICAST:
+ return "ipv6-multicast";
+ case SAFI_MPLS_VPN:
+ return "ipv6-vpn";
+ case SAFI_ENCAP:
+ return "ipv6-encap";
+ case SAFI_LABELED_UNICAST:
+ return "ipv6-labeled-unicast";
+ case SAFI_FLOWSPEC:
+ return "ipv6-flowspec";
+ default:
+ return "unknown-afi/safi";
+ }
+ break;
+ case AFI_L2VPN:
+ switch (safi) {
+ case SAFI_EVPN:
+ return "l2vpn-evpn";
+ default:
+ return "unknown-afi/safi";
+ }
+ case AFI_UNSPEC:
+ case AFI_MAX:
+ return "unknown-afi/safi";
+ }
+ /* all AFIs are accounted for above, so this shouldn't happen */
+ return "unknown-afi/safi";
+}
+
int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
enum bgp_instance_type inst_type)
{
@@ -3740,52 +3808,60 @@ DEFPY (no_bgp_bestpath_bw,
return CMD_SUCCESS;
}
-/* "no bgp default ipv6-unicast". */
-DEFUN(no_bgp_default_ipv6_unicast, no_bgp_default_ipv6_unicast_cmd,
- "no bgp default ipv6-unicast", NO_STR
+DEFPY(bgp_default_afi_safi, bgp_default_afi_safi_cmd,
+ "[no] bgp default <ipv4-unicast|"
+ "ipv4-multicast|"
+ "ipv4-vpn|"
+ "ipv4-labeled-unicast|"
+ "ipv4-flowspec|"
+ "ipv6-unicast|"
+ "ipv6-multicast|"
+ "ipv6-vpn|"
+ "ipv6-labeled-unicast|"
+ "ipv6-flowspec|"
+ "l2vpn-evpn>$afi_safi",
+ NO_STR
"BGP specific commands\n"
"Configure BGP defaults\n"
- "Activate ipv6-unicast for a peer by default\n")
+ "Activate ipv4-unicast for a peer by default\n"
+ "Activate ipv4-multicast for a peer by default\n"
+ "Activate ipv4-vpn for a peer by default\n"
+ "Activate ipv4-labeled-unicast for a peer by default\n"
+ "Activate ipv4-flowspec for a peer by default\n"
+ "Activate ipv6-unicast for a peer by default\n"
+ "Activate ipv6-multicast for a peer by default\n"
+ "Activate ipv6-vpn for a peer by default\n"
+ "Activate ipv6-labeled-unicast for a peer by default\n"
+ "Activate ipv6-flowspec for a peer by default\n"
+ "Activate l2vpn-evpn for a peer by default\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- UNSET_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6);
- return CMD_SUCCESS;
-}
+ char afi_safi_str[strlen(afi_safi) + 1];
+ char *afi_safi_str_tok;
-DEFUN(bgp_default_ipv6_unicast, bgp_default_ipv6_unicast_cmd,
- "bgp default ipv6-unicast",
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "Activate ipv6-unicast for a peer by default\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- SET_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6);
- return CMD_SUCCESS;
-}
+ strlcpy(afi_safi_str, afi_safi, sizeof(afi_safi_str));
+ char *afi_str = strtok_r(afi_safi_str, "-", &afi_safi_str_tok);
+ char *safi_str = strtok_r(NULL, "-", &afi_safi_str_tok);
+ afi_t afi = bgp_vty_afi_from_str(afi_str);
+ safi_t safi;
-/* "no bgp default ipv4-unicast". */
-DEFUN (no_bgp_default_ipv4_unicast,
- no_bgp_default_ipv4_unicast_cmd,
- "no bgp default ipv4-unicast",
- NO_STR
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "Activate ipv4-unicast for a peer by default\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- SET_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4);
- return CMD_SUCCESS;
-}
+ if (strmatch(safi_str, "labeled"))
+ safi = bgp_vty_safi_from_str("labeled-unicast");
+ else
+ safi = bgp_vty_safi_from_str(safi_str);
+
+ if (no)
+ bgp->default_af[afi][safi] = false;
+ else {
+ if ((safi == SAFI_LABELED_UNICAST
+ && bgp->default_af[afi][SAFI_UNICAST])
+ || (safi == SAFI_UNICAST
+ && bgp->default_af[afi][SAFI_LABELED_UNICAST]))
+ bgp_vty_return(vty, BGP_ERR_PEER_SAFI_CONFLICT);
+ else
+ bgp->default_af[afi][safi] = true;
+ }
-DEFUN (bgp_default_ipv4_unicast,
- bgp_default_ipv4_unicast_cmd,
- "bgp default ipv4-unicast",
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "Activate ipv4-unicast for a peer by default\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- UNSET_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4);
return CMD_SUCCESS;
}
@@ -17437,41 +17513,14 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
}
} else {
if (peer->afc[afi][safi]) {
- if ((afi == AFI_IP || afi == AFI_IP6)
- && safi == SAFI_UNICAST) {
- if (afi == AFI_IP
- && CHECK_FLAG(bgp->flags,
- BGP_FLAG_NO_DEFAULT_IPV4)) {
- vty_out(vty, " neighbor %s activate\n",
- addr);
- } else if (afi == AFI_IP6
- && !CHECK_FLAG(
- bgp->flags,
- BGP_FLAG_DEFAULT_IPV6)) {
- vty_out(vty, " neighbor %s activate\n",
- addr);
- }
- } else {
+ if (safi == SAFI_ENCAP)
+ vty_out(vty, " neighbor %s activate\n", addr);
+ else if (!bgp->default_af[afi][safi])
vty_out(vty, " neighbor %s activate\n", addr);
- }
} else {
- if ((afi == AFI_IP || afi == AFI_IP6)
- && safi == SAFI_UNICAST) {
- if (afi == AFI_IP
- && !CHECK_FLAG(bgp->flags,
- BGP_FLAG_NO_DEFAULT_IPV4)) {
- vty_out(vty,
- " no neighbor %s activate\n",
- addr);
- } else if (afi == AFI_IP6
- && CHECK_FLAG(
- bgp->flags,
- BGP_FLAG_DEFAULT_IPV6)) {
- vty_out(vty,
- " no neighbor %s activate\n",
- addr);
- }
- }
+ if (bgp->default_af[afi][safi])
+ vty_out(vty, " no neighbor %s activate\n",
+ addr);
}
}
@@ -17797,6 +17846,8 @@ int bgp_config_write(struct vty *vty)
struct peer *peer;
struct listnode *node, *nnode;
struct listnode *mnode, *mnnode;
+ afi_t afi;
+ safi_t safi;
if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER)
vty_out(vty, "bgp route-map delay-timer %u\n",
@@ -17887,13 +17938,17 @@ int bgp_config_write(struct vty *vty)
? ""
: "no ");
- /* BGP default ipv4-unicast. */
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4))
- vty_out(vty, " no bgp default ipv4-unicast\n");
-
- /* BGP default ipv6-unicast. */
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6))
- vty_out(vty, " bgp default ipv6-unicast\n");
+ /* BGP default <afi>-<safi> */
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (afi == AFI_IP && safi == SAFI_UNICAST) {
+ if (!bgp->default_af[afi][safi])
+ vty_out(vty, " no bgp default %s\n",
+ get_bgp_default_af_flag(afi,
+ safi));
+ } else if (bgp->default_af[afi][safi])
+ vty_out(vty, " bgp default %s\n",
+ get_bgp_default_af_flag(afi, safi));
+ }
/* BGP default local-preference. */
if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
@@ -18587,13 +18642,8 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &bgp_bestpath_bw_cmd);
install_element(BGP_NODE, &no_bgp_bestpath_bw_cmd);
- /* "no bgp default ipv4-unicast" commands. */
- install_element(BGP_NODE, &no_bgp_default_ipv4_unicast_cmd);
- install_element(BGP_NODE, &bgp_default_ipv4_unicast_cmd);
-
- /* "no bgp default ipv6-unicast" commands. */
- install_element(BGP_NODE, &no_bgp_default_ipv6_unicast_cmd);
- install_element(BGP_NODE, &bgp_default_ipv6_unicast_cmd);
+ /* "no bgp default <afi>-<safi>" commands. */
+ install_element(BGP_NODE, &bgp_default_afi_safi_cmd);
/* "bgp network import-check" commands. */
install_element(BGP_NODE, &bgp_network_import_check_cmd);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 5d3176537b..ec71e17034 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -683,7 +683,7 @@ static int if_get_ipv6_global(struct interface *ifp, struct in6_addr *addr)
return 0;
}
-static int if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
+static bool if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
{
struct listnode *cnode;
struct connected *connected;
@@ -695,10 +695,10 @@ static int if_get_ipv6_local(struct interface *ifp, struct in6_addr *addr)
if (cp->family == AF_INET6)
if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6)) {
memcpy(addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
static int if_get_ipv4_address(struct interface *ifp, struct in_addr *addr)
@@ -724,6 +724,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
{
int ret = 0;
struct interface *ifp = NULL;
+ bool v6_ll_avail = true;
memset(nexthop, 0, sizeof(struct bgp_nexthop));
@@ -793,12 +794,20 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
* route-map to
* specify the global IPv6 nexthop.
*/
- if_get_ipv6_local(ifp, &nexthop->v6_global);
+ v6_ll_avail =
+ if_get_ipv6_local(ifp, &nexthop->v6_global);
memcpy(&nexthop->v6_local, &nexthop->v6_global,
IPV6_MAX_BYTELEN);
} else
- if_get_ipv6_local(ifp, &nexthop->v6_local);
+ v6_ll_avail =
+ if_get_ipv6_local(ifp, &nexthop->v6_local);
+ /*
+ * If we are a v4 connection and we are not doing unnumbered
+ * not having a v6 LL address is ok
+ */
+ if (!v6_ll_avail && !peer->conf_if)
+ v6_ll_avail = true;
if (if_lookup_by_ipv4(&remote->sin.sin_addr, peer->bgp->vrf_id))
peer->shared_network = 1;
else
@@ -824,7 +833,8 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
remote->sin6.sin6_scope_id,
peer->bgp->vrf_id);
if (direct)
- if_get_ipv6_local(ifp, &nexthop->v6_local);
+ v6_ll_avail = if_get_ipv6_local(
+ ifp, &nexthop->v6_local);
} else
/* Link-local address. */
{
@@ -871,7 +881,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
/* If we have identified the local interface, there is no error for now.
*/
- return true;
+ return v6_ll_avail;
}
static struct in6_addr *
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index cf38f377b4..acade16ef2 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1369,7 +1369,7 @@ struct peer *peer_new(struct bgp *bgp)
peer->bgp = bgp_lock(bgp);
peer = peer_lock(peer); /* initial reference */
peer->password = NULL;
- peer->max_packet_size = BGP_MAX_PACKET_SIZE;
+ peer->max_packet_size = BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
/* Set default flags. */
FOREACH_AFI_SAFI (afi, safi) {
@@ -1466,6 +1466,8 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
(void)peer_sort(peer_dst);
peer_dst->rmap_type = peer_src->rmap_type;
+ peer_dst->max_packet_size = peer_src->max_packet_size;
+
/* Timers */
peer_dst->holdtime = peer_src->holdtime;
peer_dst->keepalive = peer_src->keepalive;
@@ -1538,7 +1540,7 @@ static int bgp_peer_conf_if_to_su_update_v4(struct peer *peer,
*/
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
if (ifc->address && (ifc->address->family == AF_INET)) {
- PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));
+ prefix_copy(&p, CONNECTED_PREFIX(ifc));
if (p.prefixlen == 30) {
peer->su.sa.sa_family = AF_INET;
addr = ntohl(p.u.prefix4.s_addr);
@@ -1776,22 +1778,15 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
- /* If address family is IPv4 and `bgp default ipv4-unicast` (default),
- * then activate the neighbor for this AF.
- * If address family is IPv6 and `bgp default ipv6-unicast`
- * (non-default), then activate the neighbor for this AF.
+ /* If 'bgp default <afi>-<safi>' is configured, then activate the
+ * neighbor for the corresponding address family. IPv4 Unicast is
+ * the only address family enabled by default without expliict
+ * configuration.
*/
FOREACH_AFI_SAFI (afi, safi) {
- if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST) {
- if ((afi == AFI_IP
- && !CHECK_FLAG(bgp->flags,
- BGP_FLAG_NO_DEFAULT_IPV4))
- || (afi == AFI_IP6
- && CHECK_FLAG(bgp->flags,
- BGP_FLAG_DEFAULT_IPV6))) {
- peer->afc[afi][safi] = 1;
- peer_af_create(peer, afi, safi);
- }
+ if (bgp->default_af[afi][safi]) {
+ peer->afc[afi][safi] = 1;
+ peer_af_create(peer, afi, safi);
}
}
@@ -2585,6 +2580,7 @@ struct peer_group *peer_group_get(struct bgp *bgp, const char *name)
{
struct peer_group *group;
afi_t afi;
+ safi_t safi;
group = peer_group_lookup(bgp, name);
if (group)
@@ -2598,10 +2594,10 @@ struct peer_group *peer_group_get(struct bgp *bgp, const char *name)
for (afi = AFI_IP; afi < AFI_MAX; afi++)
group->listen_range[afi] = list_new();
group->conf = peer_new(bgp);
- if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4))
- group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6))
- group->conf->afc[AFI_IP6][SAFI_UNICAST] = 1;
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (bgp->default_af[afi][safi])
+ group->conf->afc[afi][safi] = 1;
+ }
XFREE(MTYPE_BGP_PEER_HOST, group->conf->host);
group->conf->host = XSTRDUP(MTYPE_BGP_PEER_HOST, name);
group->conf->group = group;
@@ -3243,6 +3239,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
atomic_store_explicit(&bgp->rpkt_quanta, BGP_READ_PACKET_MAX,
memory_order_relaxed);
bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
+ bgp->default_af[AFI_IP][SAFI_UNICAST] = true;
QOBJ_REG(bgp, bgp);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 776f4b0a21..d2e8cce997 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -464,38 +464,41 @@ struct bgp {
#define BGP_FLAG_DETERMINISTIC_MED (1 << 1)
#define BGP_FLAG_MED_MISSING_AS_WORST (1 << 2)
#define BGP_FLAG_MED_CONFED (1 << 3)
-#define BGP_FLAG_NO_DEFAULT_IPV4 (1 << 4)
-#define BGP_FLAG_NO_CLIENT_TO_CLIENT (1 << 5)
-#define BGP_FLAG_COMPARE_ROUTER_ID (1 << 7)
-#define BGP_FLAG_ASPATH_IGNORE (1 << 8)
-#define BGP_FLAG_IMPORT_CHECK (1 << 9)
-#define BGP_FLAG_NO_FAST_EXT_FAILOVER (1 << 10)
-#define BGP_FLAG_LOG_NEIGHBOR_CHANGES (1 << 11)
+#define BGP_FLAG_NO_CLIENT_TO_CLIENT (1 << 4)
+#define BGP_FLAG_COMPARE_ROUTER_ID (1 << 5)
+#define BGP_FLAG_ASPATH_IGNORE (1 << 6)
+#define BGP_FLAG_IMPORT_CHECK (1 << 7)
+#define BGP_FLAG_NO_FAST_EXT_FAILOVER (1 << 8)
+#define BGP_FLAG_LOG_NEIGHBOR_CHANGES (1 << 9)
/* This flag is set when we have full BGP Graceful-Restart mode enable */
-#define BGP_FLAG_GRACEFUL_RESTART (1 << 12)
-
-#define BGP_FLAG_ASPATH_CONFED (1 << 13)
-#define BGP_FLAG_ASPATH_MULTIPATH_RELAX (1 << 14)
-#define BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY (1 << 15)
-#define BGP_FLAG_DISABLE_NH_CONNECTED_CHK (1 << 16)
-#define BGP_FLAG_MULTIPATH_RELAX_AS_SET (1 << 17)
-#define BGP_FLAG_FORCE_STATIC_PROCESS (1 << 18)
-#define BGP_FLAG_SHOW_HOSTNAME (1 << 19)
-#define BGP_FLAG_GR_PRESERVE_FWD (1 << 20)
-#define BGP_FLAG_GRACEFUL_SHUTDOWN (1 << 21)
-#define BGP_FLAG_DELETE_IN_PROGRESS (1 << 22)
-#define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 23)
-#define BGP_FLAG_GR_DISABLE_EOR (1 << 24)
-#define BGP_FLAG_EBGP_REQUIRES_POLICY (1 << 25)
-#define BGP_FLAG_SHOW_NEXTHOP_HOSTNAME (1 << 26)
+#define BGP_FLAG_GRACEFUL_RESTART (1 << 10)
+
+#define BGP_FLAG_ASPATH_CONFED (1 << 11)
+#define BGP_FLAG_ASPATH_MULTIPATH_RELAX (1 << 12)
+#define BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY (1 << 13)
+#define BGP_FLAG_DISABLE_NH_CONNECTED_CHK (1 << 14)
+#define BGP_FLAG_MULTIPATH_RELAX_AS_SET (1 << 15)
+#define BGP_FLAG_FORCE_STATIC_PROCESS (1 << 16)
+#define BGP_FLAG_SHOW_HOSTNAME (1 << 17)
+#define BGP_FLAG_GR_PRESERVE_FWD (1 << 18)
+#define BGP_FLAG_GRACEFUL_SHUTDOWN (1 << 19)
+#define BGP_FLAG_DELETE_IN_PROGRESS (1 << 20)
+#define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 21)
+#define BGP_FLAG_GR_DISABLE_EOR (1 << 22)
+#define BGP_FLAG_EBGP_REQUIRES_POLICY (1 << 23)
+#define BGP_FLAG_SHOW_NEXTHOP_HOSTNAME (1 << 24)
/* This flag is set if the instance is in administrative shutdown */
-#define BGP_FLAG_SHUTDOWN (1 << 27)
-#define BGP_FLAG_SUPPRESS_FIB_PENDING (1 << 28)
-#define BGP_FLAG_SUPPRESS_DUPLICATES (1 << 29)
-#define BGP_FLAG_DEFAULT_IPV6 (1 << 30)
-#define BGP_FLAG_PEERTYPE_MULTIPATH_RELAX (1 << 31)
+#define BGP_FLAG_SHUTDOWN (1 << 25)
+#define BGP_FLAG_SUPPRESS_FIB_PENDING (1 << 26)
+#define BGP_FLAG_SUPPRESS_DUPLICATES (1 << 27)
+#define BGP_FLAG_PEERTYPE_MULTIPATH_RELAX (1 << 29)
+
+ /* BGP default address-families.
+ * New peers inherit enabled afi/safis from bgp instance.
+ */
+ uint16_t default_af[AFI_MAX][SAFI_MAX];
enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE]
[BGP_GLOBAL_GR_EVENT_CMD];
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index f89ef7b0d2..8bed5156b7 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -1613,9 +1613,9 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target,
memset(&rprefix, 0, sizeof(rprefix));
rprefix.prefix.addr_family = target->addr_family;
if (target->addr_family == AF_INET) {
- rprefix.length = 32;
+ rprefix.length = IPV4_MAX_BITLEN;
} else {
- rprefix.length = 128;
+ rprefix.length = IPV6_MAX_BITLEN;
}
pNHE = rfapiEthRouteTable2NextHopList(
@@ -1690,9 +1690,9 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target,
memset(&rprefix, 0, sizeof(rprefix));
rprefix.prefix.addr_family = target->addr_family;
if (target->addr_family == AF_INET) {
- rprefix.length = 32;
+ rprefix.length = IPV4_MAX_BITLEN;
} else {
- rprefix.length = 128;
+ rprefix.length = IPV6_MAX_BITLEN;
}
pNHE = rfapiEthRouteNode2NextHopList(
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index 51e051d688..07aed045ca 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -405,7 +405,7 @@ int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p)
case 8:
if (p) {
p->family = AF_INET;
- p->prefixlen = 32;
+ p->prefixlen = IPV4_MAX_BITLEN;
memcpy(p->u.val, pEncap->value,
4);
}
@@ -414,7 +414,7 @@ int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p)
case 20:
if (p) {
p->family = AF_INET6;
- p->prefixlen = 128;
+ p->prefixlen = IPV6_MAX_BITLEN;
memcpy(p->u.val, pEncap->value,
16);
}
@@ -445,14 +445,14 @@ int rfapiGetUnAddrOfVpnBi(struct bgp_path_info *bpi, struct prefix *p)
if (p) {
p->family = bpi->extra->vnc.import.un_family;
p->u.prefix4 = bpi->extra->vnc.import.un.addr4;
- p->prefixlen = 32;
+ p->prefixlen = IPV4_MAX_BITLEN;
}
return 0;
case AF_INET6:
if (p) {
p->family = bpi->extra->vnc.import.un_family;
p->u.prefix6 = bpi->extra->vnc.import.un.addr6;
- p->prefixlen = 128;
+ p->prefixlen = IPV6_MAX_BITLEN;
}
return 0;
default:
@@ -2519,12 +2519,12 @@ void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p)
switch (p->family = BGP_MP_NEXTHOP_FAMILY(attr->mp_nexthop_len)) {
case AF_INET:
p->u.prefix4 = attr->mp_nexthop_global_in;
- p->prefixlen = 32;
+ p->prefixlen = IPV4_MAX_BITLEN;
break;
case AF_INET6:
p->u.prefix6 = attr->mp_nexthop_global;
- p->prefixlen = 128;
+ p->prefixlen = IPV6_MAX_BITLEN;
break;
default:
@@ -2537,7 +2537,7 @@ void rfapiUnicastNexthop2Prefix(afi_t afi, struct attr *attr, struct prefix *p)
{
if (afi == AFI_IP) {
p->family = AF_INET;
- p->prefixlen = 32;
+ p->prefixlen = IPV4_MAX_BITLEN;
p->u.prefix4 = attr->nexthop;
} else {
rfapiNexthop2Prefix(attr, p);
@@ -2871,12 +2871,12 @@ static int rfapiGetNexthop(struct attr *attr, struct prefix *prefix)
switch (BGP_MP_NEXTHOP_FAMILY(attr->mp_nexthop_len)) {
case AF_INET:
prefix->family = AF_INET;
- prefix->prefixlen = 32;
+ prefix->prefixlen = IPV4_MAX_BITLEN;
prefix->u.prefix4 = attr->mp_nexthop_global_in;
break;
case AF_INET6:
prefix->family = AF_INET6;
- prefix->prefixlen = 128;
+ prefix->prefixlen = IPV6_MAX_BITLEN;
prefix->u.prefix6 = attr->mp_nexthop_global;
break;
default:
diff --git a/bgpd/rfapi/rfapi_private.h b/bgpd/rfapi/rfapi_private.h
index e7825e8bfc..bc0e192ae2 100644
--- a/bgpd/rfapi/rfapi_private.h
+++ b/bgpd/rfapi/rfapi_private.h
@@ -267,9 +267,9 @@ struct rfapi {
#define RFAPI_HOST_PREFIX(prefix) \
(((prefix)->family == AF_INET) \
- ? ((prefix)->prefixlen == 32) \
+ ? ((prefix)->prefixlen == IPV4_MAX_BITLEN) \
: (((prefix)->family == AF_INET6) \
- ? ((prefix)->prefixlen == 128) \
+ ? ((prefix)->prefixlen == IPV6_MAX_BITLEN) \
: 0))
extern int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index 40d5111e8c..45ef7230b5 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -174,12 +174,12 @@ int rfapiQprefix2Raddr(struct prefix *qprefix, struct rfapi_ip_addr *raddr)
raddr->addr_family = qprefix->family;
switch (qprefix->family) {
case AF_INET:
- if (qprefix->prefixlen != 32)
+ if (qprefix->prefixlen != IPV4_MAX_BITLEN)
return -1;
raddr->addr.v4 = qprefix->u.prefix4;
break;
case AF_INET6:
- if (qprefix->prefixlen != 128)
+ if (qprefix->prefixlen != IPV6_MAX_BITLEN)
return -1;
raddr->addr.v6 = qprefix->u.prefix6;
break;
@@ -260,11 +260,11 @@ int rfapiRaddr2Qprefix(struct rfapi_ip_addr *hia, struct prefix *pfx)
switch (hia->addr_family) {
case AF_INET:
- pfx->prefixlen = 32;
+ pfx->prefixlen = IPV4_MAX_BITLEN;
pfx->u.prefix4 = hia->addr.v4;
break;
case AF_INET6:
- pfx->prefixlen = 128;
+ pfx->prefixlen = IPV6_MAX_BITLEN;
pfx->u.prefix6 = hia->addr.v6;
break;
default:
@@ -1734,14 +1734,14 @@ int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, struct prefix *p)
}
switch (p->family) {
case AF_INET:
- if (p->prefixlen != 32) {
+ if (p->prefixlen != IPV4_MAX_BITLEN) {
vty_out(vty, "Not a host address: \"%s\"%s", str,
HVTYNL);
return CMD_WARNING;
}
break;
case AF_INET6:
- if (p->prefixlen != 128) {
+ if (p->prefixlen != IPV6_MAX_BITLEN) {
vty_out(vty, "Not a host address: \"%s\"%s", str,
HVTYNL);
return CMD_WARNING;
diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c
index c90fcf8d72..68dc5a4f60 100644
--- a/bgpd/rfapi/vnc_export_bgp.c
+++ b/bgpd/rfapi/vnc_export_bgp.c
@@ -164,7 +164,7 @@ static int getce(struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce)
memset((uint8_t *)pfx_ce, 0, sizeof(*pfx_ce));
memcpy(&pfx_ce->u.prefix4, ecp + 2, 4);
pfx_ce->family = AF_INET;
- pfx_ce->prefixlen = 32;
+ pfx_ce->prefixlen = IPV4_MAX_BITLEN;
return 0;
}
@@ -597,10 +597,10 @@ encap_attr_export(struct attr *new, struct attr *orig,
orig_nexthop.family =
BGP_MP_NEXTHOP_FAMILY(orig->mp_nexthop_len);
if (orig_nexthop.family == AF_INET) {
- orig_nexthop.prefixlen = 32;
+ orig_nexthop.prefixlen = IPV4_MAX_BITLEN;
orig_nexthop.u.prefix4 = orig->mp_nexthop_global_in;
} else if (orig_nexthop.family == AF_INET6) {
- orig_nexthop.prefixlen = 128;
+ orig_nexthop.prefixlen = IPV6_MAX_BITLEN;
orig_nexthop.u.prefix6 = orig->mp_nexthop_global;
} else {
return -1; /* FAIL - can't compute nexthop */
diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c
index b23c1eda76..0358c8d665 100644
--- a/bgpd/rfapi/vnc_import_bgp.c
+++ b/bgpd/rfapi/vnc_import_bgp.c
@@ -108,9 +108,9 @@ static int is_host_prefix(const struct prefix *p)
{
switch (p->family) {
case AF_INET:
- return (p->prefixlen == 32);
+ return (p->prefixlen == IPV4_MAX_BITLEN);
case AF_INET6:
- return (p->prefixlen == 128);
+ return (p->prefixlen == IPV6_MAX_BITLEN);
}
return 0;
}
@@ -1073,7 +1073,7 @@ static void vnc_import_bgp_del_route_mode_plain(struct bgp *bgp,
vnaddr.addr_family = vn_pfx->family;
switch (vn_pfx->family) {
case AF_INET:
- if (vn_pfx->prefixlen != 32) {
+ if (vn_pfx->prefixlen != IPV4_MAX_BITLEN) {
vnc_zlog_debug_verbose(
"%s: redist VN plen (%d) != 32, skipping",
__func__, vn_pfx->prefixlen);
@@ -1083,7 +1083,7 @@ static void vnc_import_bgp_del_route_mode_plain(struct bgp *bgp,
break;
case AF_INET6:
- if (vn_pfx->prefixlen != 128) {
+ if (vn_pfx->prefixlen != IPV6_MAX_BITLEN) {
vnc_zlog_debug_verbose(
"%s: redist VN plen (%d) != 128, skipping",
__func__, vn_pfx->prefixlen);
@@ -1147,7 +1147,7 @@ static void vnc_import_bgp_del_route_mode_nvegroup(struct bgp *bgp,
vnaddr.addr_family = vn_pfx->family;
switch (vn_pfx->family) {
case AF_INET:
- if (vn_pfx->prefixlen != 32) {
+ if (vn_pfx->prefixlen != IPV4_MAX_BITLEN) {
vnc_zlog_debug_verbose(
"%s: redist VN plen (%d) != 32, skipping",
__func__, vn_pfx->prefixlen);
@@ -1157,7 +1157,7 @@ static void vnc_import_bgp_del_route_mode_nvegroup(struct bgp *bgp,
break;
case AF_INET6:
- if (vn_pfx->prefixlen != 128) {
+ if (vn_pfx->prefixlen != IPV6_MAX_BITLEN) {
vnc_zlog_debug_verbose(
"%s: redist VN plen (%d) != 128, skipping",
__func__, vn_pfx->prefixlen);
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index b254f11ce7..ba849e4e0b 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -105,7 +105,8 @@ static void vnc_redistribute_add(struct prefix *p, uint32_t metric,
vnaddr.addr_family = bgp->rfapi_cfg->rfg_redist->vn_prefix.family;
switch (bgp->rfapi_cfg->rfg_redist->vn_prefix.family) {
case AF_INET:
- if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 32) {
+ if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen
+ != IPV4_MAX_BITLEN) {
vnc_zlog_debug_verbose(
"%s: redist nve group VN prefix len (%d) != 32, skipping",
__func__,
@@ -117,7 +118,8 @@ static void vnc_redistribute_add(struct prefix *p, uint32_t metric,
bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix4;
break;
case AF_INET6:
- if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 128) {
+ if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen
+ != IPV6_MAX_BITLEN) {
vnc_zlog_debug_verbose(
"%s: redist nve group VN prefix len (%d) != 128, skipping",
__func__,
@@ -153,7 +155,7 @@ static void vnc_redistribute_add(struct prefix *p, uint32_t metric,
switch (pfx_un.prefix.addr_family) {
case AF_INET:
- if (pfx_un.length != 32) {
+ if (pfx_un.length != IPV4_MAX_BITLEN) {
vnc_zlog_debug_verbose(
"%s: redist nve group UN prefix len (%d) != 32, skipping",
__func__, pfx_un.length);
@@ -161,7 +163,7 @@ static void vnc_redistribute_add(struct prefix *p, uint32_t metric,
}
break;
case AF_INET6:
- if (pfx_un.length != 128) {
+ if (pfx_un.length != IPV6_MAX_BITLEN) {
vnc_zlog_debug_verbose(
"%s: redist nve group UN prefix len (%d) != 128, skipping",
__func__, pfx_un.length);
diff --git a/changelog-auto.in b/changelog-auto.in
deleted file mode 100644
index 50bd5f6d4d..0000000000
--- a/changelog-auto.in
+++ /dev/null
@@ -1,1487 +0,0 @@
-frr (@VERSION@-0) UNRELEASED; urgency=medium
-
- * autoconf changelog entry -- for git autobuilds only.
- remove and replace when creating releases!
- (tools/tarsource.sh will handle this)
-
- -- FRRouting-Dev <dev@lists.frrouting.org> Thu, 25 Oct 2018 16:36:50 +0200
-
-frr (7.5-0) RELEASED; urgency=medium
- BFD
- Profile support
- Minimum ttl support
- BGP
- rpki VRF support
- GR fixes
- Add wide option to display of routes
- Add `maximum-prefix <num> force`
- Add `bestpath-routes` to neighbor command
- Add `bgp shutdown message MSG...` command
- Add v6 Flowspec support
- Add `neighbor <neigh> shutdown rtt` command
- Allow update-delay to be applied globaly
- EVPN
- Beginning of MultiHoming Support
- ISIS
- Segment Routing Support
- VRF Support
- Guard against adj timer display overflow
- Add support for Anycast-SIDs
- Add support for Topology Independent LFA (TI-LFA)
- Add `lsp-gen-interval 2` to isis configuration
- OSPF
- Segment Routing support for ECMP
- Various LSA fixes
- Prevent crash if transferring config amongst instances
- PBR
- Adding json support to commands
- DSCP/ECN based PBR Matching
- PIM
- Add more json support to commands
- Fix missing mesh-group commands
- MSDP SA forwarding
- Clear (s,g,rpt) ifchannel on (*, G) prune received
- Fix igmp querier election and IP address mapping
- Crash fix when RP is removed
- STATIC
- Northbound Support
- YANG
- Filter and route-map Support
- OSPF model definition
- BGP model definition
- VTYSH
- Speed up output across daemons
- Fix build-time errors for some --enable flags
- Speed up output of configuration across daemons
- ZEBRA
- nexthop group support for FPM
- northbound support for rib model
- Backup nexthop support
- netlink batching support
- Allow upper level protocols to request ARP
- Add json output for zebra ES, ES-EVI and access vlan dumps
-
- Upgrade to using libyang1.0.184
-
- RPM
- Moved RPKI to subpackage
- Added SNMP subpackage
-
- As always there are too many bugfixes to list individually. This release
- compromises just over 1k of commits by the community, with contributors from
- 70 people.
-
- -- FRRouting-Dev <dev@lists.frrouting.org> Tue, 2 Nov 2020 08:04:23 +0400
-
-frr (6.0-2) testing; urgency=medium
-
- * add install-info to build deps
- * remove trailing whitespace from control
- * cleanup tcp-zebra configure options
- * drop unused SMUX client OID MIBs
- * remove /proc check
- * remove --enable-poll
- * remove libtool .la files
- * drop texlive-latex-base, texlive-generic-recommended build deps
- * consistently allow python2 or python3
- * remove bad USE_* options, add WERROR
- * drop libncurses5 dep
- * remove backports mechanism
- * use better dependency for pythontools (binNMU compatible)
- * remove bogus shlib:Depends on frr-dbg
- * create frr-snmp and frr-rpki-rtrlib
- * make frr-pythontools a "Recommends:"
- * use redistclean target
- * update to Debian Policy version 4.2.1
- * raise debhelper compat level to 9
- * ditch development-only files
- * modernise dh_missing and use fail mode
- * disable zeromq and FPM
- * always install /etc/init.d/frr
- * put frr-doc package in 'doc' section
- * install HTML docs, drop tools/
- * fix install for {frr,rfptest,ospfclient}
- * add watch file
- * change python dependency and shebang to python3:any
- * use set -e in maintscripts
- * put myself in as maintainer
- * update copyright file
- * closes: #863249
-
- -- David Lamparter <equinox-debian@diac24.net> Thu, 25 Oct 2018 16:36:50 +0200
-
-frr (6.0-1) RELEASED; urgency=medium
-
- * New Enabled: PIM draft Unnumbered
-
- -- FRRouting-Dev <dev@lists.frrouting.org> Wed, 18 Oct 2017 17:01:42 -0700
-
-frr (3.0-1) RELEASED; urgency=medium
-
- * Added Debian 9 Backport
-
- -- FRRouting-Dev <dev@lists.frrouting.org> Mon, 16 Oct 2017 03:28:00 -0700
-
-frr (3.0-0) RELEASED; urgency=medium
-
- * New Enabled: BGP Shutdown Message
- * New Enabled: BGP Large Community
- * New Enabled: BGP RFC 7432 Partial Support w/ Ethernet VPN
- * New Enabled: BGP EVPN RT-5
- * New Enabled: LDP RFC 5561
- * New Enabled: LDP RFC 5918
- * New Enabled: LDP RFC 5919
- * New Enabled: LDP RFC 6667
- * New Enabled: LDP RFC 7473
- * New Enabled: OSPF RFC 4552
- * New Enabled: ISIS SPF Backoff draft
- * New Enabled: PIM Unnumbered Interfaces
- * New Enabled: PIM RFC 4611
- * New Enabled: PIM Sparse Mode
- * New Enabled: NHRP RFC 2332
- * New Enabled: Label Manager
- * Switched from hardening-wrapper to dpkg-buildflags.
-
- -- FRRouting-Dev <dev@lists.frrouting.org> Fri, 13 Oct 2017 16:17:26 -0700
-
-frr (2.0-0) RELEASED; urgency=medium
-
- * Switchover to FRR
-
- -- FRRouting-Dev <dev@lists.frrouting.org> Mon, 23 Jan 2017 16:30:22 -0400
-
-quagga (0.99.24+cl3u5) RELEASED; urgency=medium
-
- * Closes: CM-12846 - Resolve Memory leaks in 'show ip bgp neighbor json'
- * Closes: CM-5878 - Display all ospf peers with 'show ip ospf neighbor detail all'
- * Closes: CM-5794 - Add support for IPv6 static to null0
- * Closes: CM-13060 - Reduce JSON memory usage.
- * Closes: CM-10394 - protect 'could not get instance' error messages with debug
- * Closes: CM-11173 - Move netlink error messages undeer a debug
- * Closes: CM-13328 - Fixes route missing in hardware after reboot
-
- -- dev-support <dev-support@cumulusnetworks.com> Fri, 11 Nov 2016 22:13:29 -0400
-
-quagga (0.99.24+cl3u4) RELEASED; urgency=medium
-
- * Closes: CM-12687 - Buffer overflow in zebra RA code
-
- -- dev-support <dev-support@cumulusnetworks.com> Wed, 31 Aug 2016 12:36:10 -0400
-
-quagga (0.99.24+cl3u3) RELEASED; urgency=medium
-
- * New Enabled: Merge up-to 0.99.24 code from upstream
- * New Enabled: Additional CLI simplification
- * New Enabled: Various Bug Fixes
-
- -- dev-support <dev-support@cumulusnetworks.com> Thu, 04 Aug 2016 08:43:36 -0700
-
-quagga (0.99.23.1-1+cl3u2) RELEASED; urgency=medium
-
- * New Enabled: VRF - See Documentation for how to use
- * New Enabled: Improved interface statistics
- * New Enabled: Various vtysh improvements
- * New Enabled: Numerous compile warnings and SA fixes
- * New Enabled: Improved priviledge handlingA
- * New Enabled: Various OSPF CLI fixes
- * New Enabled: Prefix-list Performance Improvements.
- * New Enabled: Allow more than 1k peers in Quagga
- and Performance Improvements
- * New Enabled: Systemd integration
- * New Enabled: Various ISIS fixes
- * New Enabled: BGP MRT improvements
- * New Enabled: Lowered default MRAI timers
- * New Enabled: Lowered default 'timers connect'
- * New Enabled: 'bgp log-neighbor-changes' enabled by default
- * New Enabled: BGP default keepalive to 3s and holdtime to 9s
- * New Enabled: OSPF spf timers are now '0 50 5000' by default
- * New Enabled: BGP hostname is displayed by default
- * New Enabled: BGP 'no-as-set' is the default for
- 'bgp as-path multipath-relax"
- * New Enabled: RA is on by default if using 5549 on an interface
- * New Enabled: peer-group restrictions relaxed, update-groups determine
- outbund policy anyway
- * New Enabled: BGP enabled 'maximum-paths 64' by default
- * New Enabled: OSPF "log-adjacency-changes" on by default
- * New Enabled: Zebra: Add IPv6 protocol filtering support
- * and setting src of IPv6 routes.
- * New Enabled: BGP and OSPF JSON commands added.
- * New Enabled: BGP Enable multiple instances support by default
- * New Enabled: 'banner motd file' command
- * New Enabled: Remove bad default passwords from default conf
- * New Enabled: BGP addpath TX
- * New Enabled: Simplified configuration for BGP Unnumbered
-
- * New Deprecated: Remove unused 'show memory XXX' functionality
- * New Deprecated: Remove babel protocol
-
- * Closes: CM-10435 Addition on hidden command
- "bfd multihop/singlehop" and "ptm-enable" per interface command
- * Closes: CM-9974 Get route counts right for show ip route summary
- * Closes: CM-9786 BGP memory leak in peer hostname
- * Closes: CM-9340 BGP: Ensure correct sequence of processing at exit
- * Closes: CM-9270 ripd: Fix crash when a default route is passed to rip
- * Closes: CM-9255 BGPD crash around bgp_config_write ()
- * Closes: CM-9134 ospf6d: Fix for crash when non area 0 network
- entered first
- * Closes: CM-8934 OSPFv3: Check area before scheduling SPF
- * Closes: CM-8514 zebra: Crash upon disabling a link
- * Closes: CM-8295 BGP crash in group_announce_route_walkcb
- * Closes: CM-8191 BGP: crash in update_subgroup_merge()
- * Closes: CM-8015 lib: Memory reporting fails over 2GB
- * Closes: CM-7926 BGP: crash from not NULLing freed pointers
-
- -- dev-support <dev-support@cumulusnetworks.com> Wed, 04 May 2016 16:22:52 -0700
-
-quagga (0.99.23.1-1) unstable; urgency=medium
-
- * New upstream release
- * Added .png figures for info files to quagga-doc package.
- * Changed dependency from iproute to iproute2 (thanks to Andreas
- Henriksson). Closes: #753736
- * Added texlive-fonts-recommended to build-depends to get ecrm1095 font
- (thanks to Christoph Biedl). Closes: #651545
-
- -- Christian Brunotte <ch@debian.org> Tue, 30 Sep 2014 00:20:12 +0200
-
-quagga (0.99.23-1) unstable; urgency=low
-
- * New upstream release
- * Removed debian/patches/readline-6.3.diff which was already in upstream.
-
- -- Christian Hammers <ch@debian.org> Tue, 08 Jul 2014 09:15:48 +0200
-
-quagga (0.99.22.4-4) unstable; urgency=medium
-
- * Fix build failure with readline-6.3 (thanks to Matthias Klose).
- Closes: #741774
-
- -- Christian Hammers <ch@debian.org> Sun, 23 Mar 2014 15:28:42 +0100
-
-quagga (0.99.22.4-3) unstable; urgency=low
-
- * Added status to init script (thanks to Peter J. Holzer). Closes: #730625
- * Init script now sources /lib/lsb/init-functions.
- * Switched from hardening-wrapper to dpkg-buildflags.
-
- -- Christian Hammers <ch@debian.org> Wed, 01 Jan 2014 19:12:01 +0100
-
-quagga (0.99.22.4-2) unstable; urgency=low
-
- * Fixed typo in package description (thanks to Davide Prina).
- Closes: #625860
- * Added Italian Debconf translation (thanks to Beatrice Torracca)
- Closes: #729798
-
- -- Christian Hammers <ch@debian.org> Tue, 26 Nov 2013 00:47:11 +0100
-
-quagga (0.99.22.4-1) unstable; urgency=high
-
- * SECURITY:
- "ospfd: CVE-2013-2236, stack overrun in apiserver
-
- the OSPF API-server (exporting the LSDB and allowing announcement of
- Opaque-LSAs) writes past the end of fixed on-stack buffers. This leads
- to an exploitable stack overflow.
-
- For this condition to occur, the following two conditions must be true:
- - Quagga is configured with --enable-opaque-lsa
- - ospfd is started with the "-a" command line option
-
- If either of these does not hold, the relevant code is not executed and
- the issue does not get triggered."
- Closes: #726724
-
- * New upstream release
- - ospfd: protect vs. VU#229804 (malformed Router-LSA)
- (Quagga is said to be non-vulnerable but still adds some protection)
-
- -- Christian Hammers <ch@debian.org> Thu, 24 Oct 2013 22:58:37 +0200
-
-quagga (0.99.22.1-2) unstable; urgency=low
-
- * Added autopkgtests (thanks to Yolanda Robla). Closes: #710147
- * Added "status" command to init script (thanks to James Andrewartha).
- Closes: #690013
- * Added "libsnmp-dev" to Build-Deps. There not needed for the official
- builds but for people who compile Quagga themselves to activate the
- SNMP feature (which for licence reasons cannot be done by Debian).
- Thanks to Ben Winslow). Closes: #694852
- * Changed watchquagga_options to an array so that quotes can finally
- be used as expected. Closes: #681088
- * Fixed bug that prevented restarting only the watchquagga daemon
- (thanks to Harald Kappe). Closes: #687124
-
- -- Christian Hammers <ch@debian.org> Sat, 27 Jul 2013 16:06:25 +0200
-
-quagga (0.99.22.1-1) unstable; urgency=low
-
- * New upstream release
- - ospfd restore nexthop IP for p2p interfaces
- - ospfd: fix LSA initialization for build without opaque LSA
- - ripd: correctly redistribute ifindex routes (BZ#664)
- - bgpd: fix lost passwords of grouped neighbors
- * Removed 91_ld_as_needed.diff as it was found in the upstream source.
-
- -- Christian Hammers <ch@debian.org> Mon, 22 Apr 2013 22:21:20 +0200
-
-quagga (0.99.22-1) unstable; urgency=low
-
- * New upstream release.
- - [bgpd] The semantics of default-originate route-map have changed.
- The route-map is now used to advertise the default route conditionally.
- The old behaviour which allowed to set attributes on the originated
- default route is no longer supported.
- - [bgpd] this version of bgpd implements draft-idr-error-handling. This was
- added in 0.99.21 and may not be desirable. If you need a version
- without this behaviour, please use 0.99.20.1. There will be a
- runtime configuration switch for this in future versions.
- - [isisd] is in "beta" state.
- - [ospf6d] is in "alpha/experimental" state
- - More changes are documented in the upstream changelog!
- * debian/watch: Adjusted to new savannah.gnu.org site, thanks to Bart
- Martens.
- * debian/patches/99_CVE-2012-1820_bgp_capability_orf.diff removed as its
- in the changelog.
- * debian/patches/99_distribute_list.diff removed as its in the changelog.
- * debian/patches/10_doc__Makefiles__makeinfo-force.diff removed as it
- was just for Debian woody.
-
- -- Christian Hammers <ch@debian.org> Thu, 14 Feb 2013 00:22:00 +0100
-
-quagga (0.99.21-4) unstable; urgency=medium
-
- * Fixed regression bug that caused OSPF "distribute-list" statements to be
- silently ignored. The patch has already been applied upstream but there
- has been no new Quagga release since then.
- Thanks to Hans van Kranenburg for reporting. Closes: #697240
-
- -- Christian Hammers <ch@debian.org> Sun, 06 Jan 2013 15:50:32 +0100
-
-quagga (0.99.21-3) unstable; urgency=high
-
- * SECURITY:
- CVE-2012-1820 - Quagga contained a bug in BGP OPEN message handling.
- A denial-of-service condition could be caused by an attacker controlling
- one of the pre-configured BGP peers. In most cases this means, that the
- attack must be originated from an adjacent network. Closes: #676510
-
- -- Christian Hammers <ch@debian.org> Fri, 08 Jun 2012 01:15:32 +0200
-
-quagga (0.99.21-2) unstable; urgency=low
-
- * Renamed babeld.8 to quagga-babeld.8 as it conflicted with the
- original mapage of the babeld package which users might want to
- install in parallel as it is slightly more capable. Closes: #671916
-
- -- Christian Hammers <ch@debian.org> Thu, 10 May 2012 07:53:01 +0200
-
-quagga (0.99.21-1) unstable; urgency=low
-
- * New upstream release
- - [bgpd] BGP multipath support has been merged
- - [bgpd] SAFI (Multicast topology) support has been extended to propagate
- the topology to zebra.
- - [bgpd] AS path limit functionality has been removed
- - [babeld] a new routing daemon implementing the BABEL ad-hoc mesh routing
- protocol has been merged.
- - [isisd] a major overhaul has been picked up. Please note that isisd is
- STILL NOT SUITABLE FOR PRODUCTION USE.
- - a lot of bugs have been fixed
- * Added watchquagga daemon.
- * Added DEP-3 conforming patch comments.
-
- -- Christian Hammers <ch@debian.org> Sun, 06 May 2012 15:33:33 +0200
-
-quagga (0.99.20.1-1) unstable; urgency=high
-
- * SECURITY:
- CVE-2012-0249 - Quagga ospfd DoS on malformed LS-Update packet
- CVE-2012-0250 - Quagga ospfd DoS on malformed Network-LSA data
- CVE-2012-0255 - Quagga bgpd DoS on malformed OPEN message
- * New upstream release. Closes: #664033
-
- -- Christian Hammers <ch@debian.org> Fri, 16 Mar 2012 22:14:05 +0100
-
-quagga (0.99.20-4) unstable; urgency=low
-
- * Switch to dpkg-source 3.0 (quilt) format.
- * Switch to changelog-format-1.0.
-
- -- Christian Hammers <ch@debian.org> Sat, 25 Feb 2012 18:52:06 +0100
-
-quagga (0.99.20-3) unstable; urgency=low
-
- * Added --sysconfdir back to the configure options (thanks to Sven-Haegar
- Koch). Closes: #645649
-
- -- Christian Hammers <ch@debian.org> Tue, 18 Oct 2011 00:24:37 +0200
-
-quagga (0.99.20-2) unstable; urgency=low
-
- * Bumped standards version to 0.9.2.
- * Migrated to "dh" build system.
- * Added quagga-dbg package.
-
- -- Christian Hammers <ch@debian.org> Fri, 14 Oct 2011 23:59:26 +0200
-
-quagga (0.99.20-1) unstable; urgency=low
-
- * New upstream release:
- "The primary focus of this release is a fix of SEGV regression in ospfd,
- which was introduced in 0.99.19. It also features a series of minor
- improvements, including better RFC compliance in bgpd, better support
- of FreeBSD and some enhancements to isisd."
- * Fixes off-by-one bug (removed 20_ospf6_area_argv.dpatch). Closes: #519488
-
- -- Christian Hammers <ch@debian.org> Fri, 30 Sep 2011 00:59:24 +0200
-
-quagga (0.99.19-1) unstable; urgency=high
-
- * SECURITY:
- "This release provides security fixes, which address assorted
- vulnerabilities in bgpd, ospfd and ospf6d (CVE-2011-3323,
- CVE-2011-3324, CVE-2011-3325, CVE-2011-3326 and CVE-2011-3327).
- * New upstream release.
- * Removed incorporated debian/patches/92_opaque_lsa_enable.dpatch.
- * Removed incorporated debian/patches/93_opaque_lsa_fix.dpatch.
- * Removed obsolete debian/README.Debian.Woody and README.Debian.MD5.
-
- -- Christian Hammers <ch@debian.org> Tue, 27 Sep 2011 00:16:27 +0200
-
-quagga (0.99.18-1) unstable; urgency=low
-
- * SECURITY:
- "This release fixes 2 denial of services in bgpd, which can be remotely
- triggered by malformed AS-Pathlimit or Extended-Community attributes.
- These issues have been assigned CVE-2010-1674 and CVE-2010-1675.
- Support for AS-Pathlimit has been removed with this release."
- * Added Brazilian Portuguese debconf translation. Closes: #617735
- * Changed section for quagga-doc from "doc" to "net".
- * Added patch to fix FTBFS with latest GCC. Closes: #614459
-
- -- Christian Hammers <ch@debian.org> Tue, 22 Mar 2011 23:13:34 +0100
-
-quagga (0.99.17-4) unstable; urgency=low
-
- * Added comment to init script (thanks to Marc Haber). Closes: #599524
-
- -- Christian Hammers <ch@debian.org> Thu, 13 Jan 2011 23:53:29 +0100
-
-quagga (0.99.17-3) unstable; urgency=low
-
- * Fix FTBFS with ld --as-needed (thanks to Matthias Klose at Ubuntu).
- Closes: #609555
-
- -- Christian Hammers <ch@debian.org> Thu, 13 Jan 2011 23:27:06 +0100
-
-quagga (0.99.17-2) unstable; urgency=low
-
- * Added Danisch Debconf translation (thanks to Joe Dalton). Closes: #596259
-
- -- Christian Hammers <ch@debian.org> Sat, 18 Sep 2010 12:20:07 +0200
-
-quagga (0.99.17-1) unstable; urgency=high
-
- * SECURITY:
- "This release provides two important bugfixes, which address remote crash
- possibility in bgpd discovered by CROSS team.":
- 1. Stack buffer overflow by processing certain Route-Refresh messages
- CVE-2010-2948
- 2. DoS (crash) while processing certain BGP update AS path messages
- CVE-2010-2949
- Closes: #594262
-
- -- Christian Hammers <ch@debian.org> Wed, 25 Aug 2010 00:52:48 +0200
-
-quagga (0.99.16-1) unstable; urgency=low
-
- * New upstream release. Closes: #574527
- * Added chrpath to debian/rules to fix rpath problems that lintian spottet.
-
- -- Christian Hammers <ch@debian.org> Sun, 21 Mar 2010 17:05:40 +0100
-
-quagga (0.99.15-2) unstable; urgency=low
-
- * Applied patch for off-by-one bug in ospf6d that caused a segmentation
- fault when using the "area a.b.c.d filter-list prefix" command (thanks
- to Steinar H. Gunderson). Closes: 519488
-
- -- Christian Hammers <ch@debian.org> Sun, 14 Feb 2010 20:02:03 +0100
-
-quagga (0.99.15-1) unstable; urgency=low
-
- * New upstream release
- "This fixes some annoying little ospfd and ospf6d regressions, which made
- 0.99.14 a bit of a problem release (...) This release still contains a
- regression in the "no ip address ..." command, at least on Linux.
- See bug #486, which contains a workaround patch. This release should be
- considered a 1.0.0 release candidate. Please test this release as widely
- as possible."
- * Fixed wrong port number in zebra.8 (thanks to Thijs Kinkhorst).
- Closes: #517860
- * Added Russian Debconf tanslation (thanks to Yuri Kozlov).
- Closes: #539464
- * Removed so-version in build-dep to libreadline-dev on request of
- Matthias Klose.
- * Added README.source with reference to dpatch as suggested by lintian.
- * Bumped standards versionto 3.8.3.
-
- -- Christian Hammers <ch@debian.org> Sun, 13 Sep 2009 18:12:06 +0200
-
-quagga (0.99.14-1) unstable; urgency=low
-
- * New upstream release
- "This release contains a regression fix for ospf6d, various small fixes
- and some hopefully very significant bgpd stability fixes.
- This release should be considered a 1.0.0 release candidate. Please test
- this release as widely as possible."
- * Fixes bug with premature LSA aging in ospf6d. Closes: #535030
- * Fixes section number in zebra.8 manpage. Closes: #517860
-
- -- Christian Hammers <ch@debian.org> Sat, 25 Jul 2009 00:40:38 +0200
-
-quagga (0.99.13-2) unstable; urgency=low
-
- * Added Japanese Debconf translation (thanks to Hideki Yamane).
- Closes: #510714
- * When checking for obsoleted config options in preinst, print filename
- where it occures (thanks to Michael Bussmann). Closes: #339489
-
- -- Christian Hammers <ch@debian.org> Sun, 19 Jul 2009 17:13:23 +0200
-
-quagga (0.99.13-1) unstable; urgency=low
-
- * New upstream release
- "This release is contains a number of small fixes, for potentially
- irritating issues, as well as small enhancements to vtysh and support
- for linking to PCRE (a much faster regex library)."
- * Added build-dep to gawk as configure required it for memtypes.awk
- * Replaced build-dep to gs-gpl with ghostscript as requested by lintian
- * Minor changes to copyright and control files to make lintian happy.
-
- -- Christian Hammers <ch@debian.org> Wed, 24 Jun 2009 17:53:28 +0200
-
-quagga (0.99.12-1) unstable; urgency=high
-
- * New upstream release
- "This release fixes an urgent bug in bgpd where it could hit an assert
- if it received a long AS_PATH with a 4-byte ASN." Noteworthy bugfixes:
- + [bgpd] Fix bgp ipv4/ipv6 accept handling
- + [bgpd] AS4 bugfix by Chris Caputo
- + [bgpd] Allow accepted peers to progress even if realpeer is in Connect
- + [ospfd] Switch Fletcher checksum back to old ospfd version
-
- -- Christian Hammers <ch@debian.org> Mon, 22 Jun 2009 00:16:33 +0200
-
-quagga (0.99.11-1) unstable; urgency=low
-
- * New upstream release
- "Most regressions in 0.99 over 0.98 are now believed to be fixed. This
- release should be considered a release-candidate for a new stable series."
- + bgpd: Preliminary UI and Linux-IPv4 support for TCP-MD5 merged
- + zebra: ignore dead routes in RIB update
- + [ospfd] Default route needs to be refreshed after neighbour state change
- + [zebra:netlink] Set proto/scope on all route update messages
- * Removed debian/patches/20_*bgp*md5*.dpatch due to upstream support.
-
- -- Christian Hammers <ch@debian.org> Thu, 09 Oct 2008 22:56:38 +0200
-
-quagga (0.99.10-1) unstable; urgency=medium
-
- * New upstream release
- + bgpd: 4-Byte AS Number support
- + Sessions were incorrectly reset if a partial AS-Pathlimit attribute
- was received.
- + Advertisement of Multi-Protocol prefixes (i.e. non-IPv4) had been
- broken in the 0.99.9 release. Closes: #467656
-
- -- Christian Hammers <ch@debian.org> Tue, 08 Jul 2008 23:32:42 +0200
-
-quagga (0.99.9-6) unstable; urgency=low
-
- * Fixed FTBFS by adding a build-dep to libpcre3-dev (thanks to Luk Claes).
- Closes: #469891
-
- -- Christian Hammers <ch@debian.org> Sat, 12 Apr 2008 12:53:51 +0200
-
-quagga (0.99.9-5) unstable; urgency=low
-
- * C.J. Adams-Collier and Paul Jakma suggested to build against libpcre3
- which is supposed to be faster.
-
- -- Christian Hammers <ch@debian.org> Sun, 02 Mar 2008 13:19:42 +0100
-
-quagga (0.99.9-4) unstable; urgency=low
-
- * Added hardening-wrapper to the build-deps (thanks to Moritz Muehlenhoff).
-
- -- Christian Hammers <ch@debian.org> Tue, 29 Jan 2008 22:33:56 +0100
-
-quagga (0.99.9-3) unstable; urgency=low
-
- * Replaced the BGP patch by a new one so that the package builds again
- with kernels above 2.6.21!
- * debian/control:
- + Moved quagga-doc to section doc to make lintian happy.
- * Added Spanish debconf translation (thanks to Carlos Galisteo de Cabo).
- Closes: #428574
- * debian/control: (thanks to Marco Rodrigues)
- + Bump Standards-Version to 3.7.3 (no changes needed).
- + Add Homepage field.
-
- -- Christian Hammers <ch@debian.org> Mon, 28 Jan 2008 22:29:18 +0100
-
-quagga (0.99.9-2.1) unstable; urgency=low
-
- * Non-maintainer upload.
- * debian/rules: fixed bashisms. (Closes: #459122)
-
- -- Miguel Angel Ruiz Manzano <debianized@gmail.com> Tue, 22 Jan 2008 14:37:21 -0300
-
-quagga (0.99.9-2) unstable; urgency=low
-
- * Added CVE id for the security bug to the last changelog entry.
- Closes: 442133
-
- -- Christian Hammers <ch@debian.org> Tue, 25 Sep 2007 22:01:31 +0200
-
-quagga (0.99.9-1) unstable; urgency=high
-
- * SECURITY:
- "This release fixes two potential DoS conditions in bgpd, reported by Mu
- Security, where a bgpd could be crashed if a peer sent a malformed OPEN
- message or a malformed COMMUNITY attribute. Only configured peers can do
- this, hence we consider these issues to be very low impact." CVE-2007-4826
-
- -- Christian Hammers <ch@debian.org> Wed, 12 Sep 2007 21:12:41 +0200
-
-quagga (0.99.8-1) unstable; urgency=low
-
- * New upstream version.
-
- -- Christian Hammers <ch@debian.org> Fri, 17 Aug 2007 00:07:04 +0200
-
-quagga (0.99.7-3) unstable; urgency=medium
-
- * Applied patch for FTBFS with linux-libc-dev (thanks to Andrew J. Schorr
- and Lucas Nussbaum). Closes: #429003
-
- -- Christian Hammers <ch@debian.org> Fri, 22 Jun 2007 21:34:55 +0200
-
-quagga (0.99.7-2) unstable; urgency=low
-
- * Added Florian Weimar as co-maintainer. Closes: 421977
- * Added Dutch debconf translation (thanks to Bart Cornelis).
- Closes: #420932
- * Added Portuguese debconf translation (thanks to Rui Branco).
- Closes: #421185
- * Improved package description (thanks to Reuben Thomas).
- Closes: #418933
- * Added CVE Id to 0.99.6-5 changelog entry.
-
- -- Christian Hammers <ch@debian.org> Wed, 02 May 2007 20:27:12 +0200
-
-quagga (0.99.7-1) unstable; urgency=low
-
- * New upstream release. Closes: #421553
-
- -- Christian Hammers <ch@debian.org> Mon, 30 Apr 2007 14:22:34 +0200
-
-quagga (0.99.6-6) unstable; urgency=medium
-
- * Fixes FTBFS with tetex-live. Closes: #420468
-
- -- Christian Hammers <ch@debian.org> Mon, 23 Apr 2007 21:34:13 +0200
-
-quagga (0.99.6-5) unstable; urgency=high
-
- * SECURITY:
- The bgpd daemon was vulnerable to a Denial-of-Service. Configured peers
- could cause a Quagga bgpd to, typically, assert() and abort. The DoS
- could be triggered by peers by sending an UPDATE message with a crafted,
- malformed Multi-Protocol reachable/unreachable NLRI attribute.
- This is CVE-2007-1995 and Quagga Bug#354. Closes: #418323
-
- -- Christian Hammers <ch@debian.org> Thu, 12 Apr 2007 23:21:58 +0200
-
-quagga (0.99.6-4) unstable; urgency=low
-
- * Improved note in README.Debian for SNMP self-builders (thanks to Matthias
- Wamser). Closes: #414788
-
- -- Christian Hammers <ch@debian.org> Wed, 14 Mar 2007 02:18:57 +0100
-
-quagga (0.99.6-3) unstable; urgency=low
-
- * Updated German Debconf translation (thanks to Matthias Julius).
- Closes: #409327
-
- -- Christian Hammers <ch@debian.org> Sat, 10 Feb 2007 15:06:16 +0100
-
-quagga (0.99.6-2) unstable; urgency=low
-
- * Updated config.guess/config.sub as suggested by lintian.
- * Corrected README.Debian text regarding the WANT_SNMP flag.
-
- -- Christian Hammers <ch@debian.org> Sun, 17 Dec 2006 01:45:37 +0100
-
-quagga (0.99.6-1) unstable; urgency=low
-
- * New upstream release. Closes: #402361
-
- -- Christian Hammers <ch@debian.org> Mon, 11 Dec 2006 00:28:09 +0100
-
-quagga (0.99.5-5) unstable; urgency=high
-
- * Changed Depends on adduser to Pre-Depends to avoid uninstallability
- in certain cases (thanks to Steve Langasek, Lucas Nussbaum).
- Closes: #398562
-
- -- Christian Hammers <ch@debian.org> Wed, 15 Nov 2006 17:46:34 +0100
-
-quagga (0.99.5-4) unstable; urgency=low
-
- * Added default PAM file and some explanations regarding PAM authentication
- of vtysh which could prevent the start at boot-time when used wrong.
- Now PAM permits anybody to access the vtysh tool (a malicious user could
- build his own vtysh without PAM anyway) and the access is controled by
- the read/write permissions of the vtysh socket which are only granted to
- users belonging to the quaggavty group (thanks to Wakko Warner).
- Closes: #389496
- * Added "case" to prerm script so that the Debconf question is not called a
- second time in e.g. "new-prerm abort-upgrade" after being NACKed in the
- old-prerm.
-
- -- Christian Hammers <ch@debian.org> Fri, 3 Nov 2006 01:22:15 +0100
-
-quagga (0.99.5-3) unstable; urgency=medium
-
- * Backport CVS fix for an OSPF DD Exchange regression (thanks to Matt
- Brown). Closes: #391040
-
- -- Christian Hammers <ch@debian.org> Wed, 25 Oct 2006 19:47:11 +0200
-
-quagga (0.99.5-2) unstable; urgency=medium
-
- * Added LSB info section to initscript.
- * Removed unnecessary depends to libncurses5 to make checklib happy.
- The one to libcap should remain though as it is just temporarily
- unused.
-
- -- Christian Hammers <ch@debian.org> Thu, 21 Sep 2006 00:04:07 +0200
-
-quagga (0.99.5-1) unstable; urgency=low
-
- * New upstream release. Closes: #38704
- * Upstream fixes ospfd documentary inconsistency. Closes: #347897
- * Changed debconf question in prerm to "high" (thanks to Rafal Pietrak).
-
- -- Christian Hammers <ch@debian.org> Mon, 11 Sep 2006 23:43:42 +0200
-
-quagga (0.99.4-4) unstable; urgency=low
-
- * Recreate /var/run if not present because /var is e.g. on a tmpfs
- filesystem (thanks to Martin Pitt). Closes: #376142
- * Removed nonexistant option from ospfd.8 manpage (thanks to
- David Medberry). Closes: 378274
-
- -- Christian Hammers <ch@debian.org> Sat, 15 Jul 2006 20:22:12 +0200
-
-quagga (0.99.4-3) unstable; urgency=low
-
- * Removed invalid semicolon from rules file (thanks to Philippe Gramoulle).
-
- -- Christian Hammers <ch@debian.org> Tue, 27 Jun 2006 23:36:07 +0200
-
-quagga (0.99.4-2) unstable; urgency=high
-
- * Set urgency to high as 0.99.4-1 fixes a security problem!
- * Fixed building of the info file.
-
- -- Christian Hammers <ch@debian.org> Sun, 14 May 2006 23:04:28 +0200
-
-quagga (0.99.4-1) unstable; urgency=low
-
- * New upstream release to fix a security problem in the telnet interface
- of the BGP daemon which could be used for DoS attacks (CVE-2006-2276).
- Closes: 366980
-
- -- Christian Hammers <ch@debian.org> Sat, 13 May 2006 19:54:40 +0200
-
-quagga (0.99.3-3) unstable; urgency=low
-
- * Added CVE numbers for the security patch in 0.99.3-2.
-
- -- Christian Hammers <ch@debian.org> Sat, 6 May 2006 17:14:22 +0200
-
-quagga (0.99.3-2) unstable; urgency=high
-
- * SECURITY:
- Added security bugfix patch from upstream BTS for security problem
- that could lead to injected routes when using RIPv1.
- CVE-2006-2223 - missing configuration to disable RIPv1 or require
- plaintext or MD5 authentication
- CVE-2006-2224 - lack of enforcement of RIPv2 authentication requirements
- Closes: #365940
- * First amd64 upload.
-
- -- Christian Hammers <ch@debian.org> Thu, 4 May 2006 00:22:09 +0200
-
-quagga (0.99.3-1) unstable; urgency=low
-
- * New upstream release
-
- -- Christian Hammers <ch@debian.org> Wed, 25 Jan 2006 13:37:27 +0100
-
-quagga (0.99.2-1) unstable; urgency=low
-
- * New upstream release
- Closes: #330248, #175553
-
- -- Christian Hammers <ch@debian.org> Wed, 16 Nov 2005 00:25:52 +0100
-
-quagga (0.99.1-7) unstable; urgency=low
-
- * Changed debian/rules check for mounted /proc directory to check
- for /proc/1 as not all systems (e.g. 2.6 arm kernels) have
- /proc/kcore which is a optional feature only (thanks to Lennert
- Buytenhek). Closes: #335695
- * Added Swedish Debconf translation (thanks to Daniel Nylander).
- Closes: #331367
-
- -- Christian Hammers <ch@debian.org> Thu, 27 Oct 2005 20:53:19 +0200
-
-quagga (0.99.1-6) unstable; urgency=low
-
- * Fixed debconf dependency as requested by Joey Hess.
-
- -- Christian Hammers <ch@debian.org> Mon, 26 Sep 2005 20:47:35 +0200
-
-quagga (0.99.1-5) unstable; urgency=low
-
- * Rebuild with libreadline5-dev as build-dep as requested by
- Matthias Klose. Closes: #326306
- * Made initscript more fault tolerant against missing lines in
- /etc/quagga/daemons (thanks to Ralf Hildebrandt). Closes: #323774
- * Added dependency to adduser.
-
- -- Christian Hammers <ch@debian.org> Tue, 13 Sep 2005 21:42:17 +0200
-
-quagga (0.99.1-4) unstable; urgency=low
-
- * Added French Debconf translation (thanks to Mohammed Adnene Trojette).
- Closes: #319324
- * Added Czech Debconf translation (thanks to Miroslav Kure).
- Closes: #318127
-
- -- Christian Hammers <ch@debian.org> Sun, 31 Jul 2005 04:19:41 +0200
-
-quagga (0.99.1-3) unstable; urgency=low
-
- * A Debconf question now asks the admin before upgrading if the daemon
- should really be stopped as this could lead to the loss of network
- connectivity or BGP flaps (thanks to Michael Horn and Achilleas Kotsis).
- Also added a hint about setting Quagga "on hold" to README.Debian.
- Closes: #315467
- * Added patch to build on Linux/ARM.
-
- -- Christian Hammers <ch@debian.org> Sun, 10 Jul 2005 22:19:38 +0200
-
-quagga (0.99.1-2) unstable; urgency=low
-
- * Fixed SNMP enabled command in debian/rules (thanks to Christoph Kluenter).
- Closes: #306840
-
- -- Christian Hammers <ch@debian.org> Sat, 4 Jun 2005 14:04:01 +0200
-
-quagga (0.99.1-1) unstable; urgency=low
-
- * New upstream version. Among others:
- - BGP graceful restart and "match ip route-source" added
- - support for interface renaming
- - improved threading for better responsivness under load
- * Switched to dpatch to make diffs cleaner.
- * Made autoreconf unnecessary.
- * Replaced quagga.dvi and quagga.ps by quagga.pdf in quagga-doc.
- (the PostScript would have needed Makefile corrections and PDF
- is more preferable anyway)
- * Added isisd to the list of daemons in /etc/init.d/quagga (thanks
- to Ernesto Elbe).
- * Added hint for "netlink-listen: overrun" messages (thanks to
- Hasso Tepper).
- * Added preinst check that bails out if old smux options are in use
- as Quagga would not start up else anyway (thanks to Bjorn Mork).
- Closes: #308320
-
- -- Christian Hammers <ch@debian.org> Fri, 13 May 2005 01:18:24 +0200
-
-quagga (0.98.3-7) unstable; urgency=high
-
- * Removed SNMP support as linking against NetSNMP introduced a dependency
- to OpenSSL which is not compatible to the GPL which governs this
- application (thanks to Faidon Liambotis). See README.Debian for more
- information. Closes: #306840
- * Changed listening address of ospf6d and ripngd from 127.0.0.1 to "::1".
- * Added build-dep to groff to let drafz-zebra-00.txt build correctly.
-
- -- Christian Hammers <ch@debian.org> Wed, 4 May 2005 20:08:14 +0200
-
-quagga (0.98.3-6) testing-proposed-updates; urgency=high
-
- * Removed "Recommends kernel-image-2.4" as aptitude then
- installes a kernel-image for an arbitrary architecture as long
- as it fullfill that recommendation which can obviously fatal
- at the next reboot :) Also it is a violation of the policy
- which mandates a reference to real packages (thanks to Holger Levsen).
- Closes: #307281
-
- -- Christian Hammers <ch@debian.org> Tue, 3 May 2005 22:53:39 +0200
-
-quagga (0.98.3-5) unstable; urgency=high
-
- * The patch which tried to remove the OpenSSL dependency, which is
- not only unneccessary but also a violation of the licence and thus RC,
- stopped working a while ago, since autoreconf is no longer run before
- building the binaries. So now ./configure is patched directly (thanks
- to Faidon Liambotis for reporting). Closes: #306840
- * Raised Debhelper compatibility level from 3 to 4. Nothing changed.
- * Added build-dep to texinfo (>= 4.7) to ease work for www.backports.org.
-
- -- Christian Hammers <ch@debian.org> Fri, 29 Apr 2005 02:31:03 +0200
-
-quagga (0.98.3-4) unstable; urgency=low
-
- * Removed Debconf upgrade note as it was considered a Debconf abuse
- and apart from that so obvious that it was not even worth to be
- put into NEWS.Debian (thanks to Steve Langasek). Closes: #306384
-
- -- Christian Hammers <ch@debian.org> Wed, 27 Apr 2005 00:10:24 +0200
-
-quagga (0.98.3-3) unstable; urgency=medium
-
- * Adding the debconf module due to a lintian suggestion is a very
- bad idea if no db_stop is called as the script hangs then (thanks
- to Tore Anderson for reporting). Closes: #306324
-
- -- Christian Hammers <ch@debian.org> Mon, 25 Apr 2005 21:55:58 +0200
-
-quagga (0.98.3-2) unstable; urgency=low
-
- * Added debconf confmodule to postinst as lintian suggested.
-
- -- Christian Hammers <ch@debian.org> Sun, 24 Apr 2005 13:16:00 +0200
-
-quagga (0.98.3-1) unstable; urgency=low
-
- * New upstream release.
- Mmost notably fixes last regression in bgpd (reannounce of prefixes
- with changed attributes works again), race condition in netlink
- handling while using IPv6, MTU changes handling in ospfd and several
- crashes in ospfd, bgpd and ospf6d.
-
- -- Christian Hammers <ch@debian.org> Mon, 4 Apr 2005 12:51:24 +0200
-
-quagga (0.98.2-2) unstable; urgency=low
-
- * Added patch to let Quagga compile with gcc-4.0 (thanks to
- Andreas Jochens). Closes: #300949
-
- -- Christian Hammers <ch@debian.org> Fri, 25 Mar 2005 19:33:30 +0100
-
-quagga (0.98.2-1) unstable; urgency=medium
-
- * Quoting the upstream announcement:
- The 0.98.1 release unfortunately was a brown paper bag release with
- respect to ospfd. [...] 0.98.2 has been released, with one crucial change
- to fix the unfortunate mistake in 0.98.1, which caused problems if
- ospfd became DR.
- * Note: the upstream tarball had a strange problem, apparently redhat.spec
- was twice in it? At least debuild gave a strange error message so I
- unpacked it by hand. No changes were made to the .orig.tar.gz!
-
- -- Christian Hammers <ch@debian.org> Fri, 4 Feb 2005 01:31:36 +0100
-
-quagga (0.98.1-1) unstable; urgency=medium
-
- * New upstream version
- "fixing a fatal OSPF + MD5 auth regression, and a non-fatal high-load
- regression in bgpd which were present in the 0.98.0 release."
- * Upstream version fixes bug in ospfd that could lead to crash when OSPF
- packages had a MTU > 1500. Closes: #290566
- * Added notice regarding capability kernel support to README.Debian
- (thanks to Florian Weimer). Closes: #291509
- * Changed permission setting in postinst script (thanks to Bastian Blank).
- Closes: #292690
-
- -- Christian Hammers <ch@debian.org> Tue, 1 Feb 2005 02:01:27 +0100
-
-quagga (0.98.0-3) unstable; urgency=low
-
- * Fixed problem in init script. Closes: #290317
- * Removed obsolete "smux peer enable" patch.
-
- -- Christian Hammers <ch@debian.org> Fri, 14 Jan 2005 17:37:27 +0100
-
-quagga (0.98.0-2) unstable; urgency=low
-
- * Updated broken TCP MD5 patch for BGP (thanks to John P. Looney
- for telling me).
-
- -- Christian Hammers <ch@debian.org> Thu, 13 Jan 2005 02:03:54 +0100
-
-quagga (0.98.0-1) unstable; urgency=low
-
- * New upstream release
- * Added kernel-image-2.6 as alternative to 2.4 to the recommends
- (thanks to Faidon Liambotis). Closes: #289530
-
- -- Christian Hammers <ch@debian.org> Mon, 10 Jan 2005 19:36:17 +0100
-
-quagga (0.97.5-1) unstable; urgency=low
-
- * New upstream version.
- * Added Czech debconf translation (thanks to Miroslav Kure).
- Closes: #287293
- * Added Brazilian debconf translation (thanks to Andre Luis Lopes).
- Closes: #279352
-
- -- Christian Hammers <ch@debian.org> Wed, 5 Jan 2005 23:49:57 +0100
-
-quagga (0.97.4-2) unstable; urgency=low
-
- * Fixed quagga.info build problem.
-
- -- Christian Hammers <ch@debian.org> Wed, 5 Jan 2005 22:38:01 +0100
-
-quagga (0.97.4-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Christian Hammers <ch@debian.org> Tue, 4 Jan 2005 01:45:22 +0100
-
-quagga (0.97.3-2) unstable; urgency=low
-
- * Included isisd in the daemon list.
- * Wrote an isisd manpage.
- * It is now ensured that zebra is always the last daemon to be stopped.
- * (Thanks to Hasso Tepper for mailing me a long list of suggestions
- which lead to this release)
-
- -- Christian Hammers <ch@debian.org> Sat, 18 Dec 2004 13:14:55 +0100
-
-quagga (0.97.3-1) unstable; urgency=medium
-
- * New upstream version.
- - Fixes important OSPF bug.
- * Added ht-20040911-smux.patch regarding Quagga bug #112.
- * Updated ht-20041109-0.97.3-bgp-md5.patch for BGP with TCP MD5
- (thanks to Matthias Wamser).
-
- -- Christian Hammers <ch@debian.org> Tue, 9 Nov 2004 17:45:26 +0100
-
-quagga (0.97.2-4) unstable; urgency=low
-
- * Added Portuguese debconf translation (thanks to Andre Luis Lopes).
- Closes: #279352
- * Disabled ospfapi server by default on recommendation of Paul Jakma.
-
- -- Christian Hammers <ch@debian.org> Sun, 7 Nov 2004 15:07:05 +0100
-
-quagga (0.97.2-3) unstable; urgency=low
-
- * Added Andrew Schorrs VTY Buffer patch from the [quagga-dev 1729].
-
- -- Christian Hammers <ch@debian.org> Tue, 2 Nov 2004 00:46:56 +0100
-
-quagga (0.97.2-2) unstable; urgency=low
-
- * Changed file and directory permissions and ownerships according to a
- suggestion from Paul Jakma. Still not perfect though.
- * Fixed upstream vtysh.conf.sample file.
- * "ip ospf network broadcast" is now saved correctly. Closes: #244116
- * Daemon options are now in /etc/quagga/debian.conf to be user
- configurable (thanks to Simon Raven and Hasso Tepper). Closes: #266715
-
- -- Christian Hammers <ch@debian.org> Tue, 26 Oct 2004 23:35:45 +0200
-
-quagga (0.97.2-1) unstable; urgency=low
-
- * New upstream version.
- Closes: #254541
- * Fixed warning on unmodular kernels (thanks to Christoph Biedl).
- Closes: #277973
-
- -- Christian Hammers <ch@debian.org> Mon, 25 Oct 2004 00:47:04 +0200
-
-quagga (0.97.1-2) unstable; urgency=low
-
- * Version 0.97 introduced shared libraries. They are now included.
- (thanks to Raf D'Halleweyn). Closes: #277446
-
- -- Christian Hammers <ch@debian.org> Wed, 20 Oct 2004 15:32:06 +0200
-
-quagga (0.97.1-1) unstable; urgency=low
-
- * New upstream version.
- * Removed some obsolete files from debian/patches.
- * Added patch from upstream bug 113. Closes: #254541
- * Added patch from upstream that fixes a compilation problem in the
- ospfclient code (thanks to Hasso Tepper).
- * Updated German debconf translation (thanks to Jens Nachtigall)
- Closes: #277059
-
- -- Christian Hammers <ch@debian.org> Mon, 18 Oct 2004 01:16:35 +0200
-
-quagga (0.96.5-11) unstable; urgency=low
-
- * Fixed /tmp/buildd/* paths in binaries.
- For some unknown reason the upstream Makefile modified a .h file at
- the end of the "debian/rules build" target. During the following
- "make install" one library got thus be re*compiled* - with /tmp/buildd
- paths as sysconfdir (thanks to Peder Chr. Norgaard). Closes: #274050
-
- -- Christian Hammers <ch@debian.org> Fri, 1 Oct 2004 01:21:02 +0200
-
-quagga (0.96.5-10) unstable; urgency=medium
-
- * The BGP routing daemon might freeze on network disturbances when
- their peer is also a Quagga/Zebra router.
- Applied patch from http://bugzilla.quagga.net/show_bug.cgi?id=102
- which has been confirmed by the upstream author.
- (thanks to Gunther Stammwitz)
- * Changed --enable-pam to --with-libpam (thanks to Hasso Tepper).
- Closes: #264562
- * Added patch for vtysh (thanks to Hasso Tepper). Closes: #215919
-
- -- Christian Hammers <ch@debian.org> Mon, 9 Aug 2004 15:33:02 +0200
-
-quagga (0.96.5-9) unstable; urgency=low
-
- * Rewrote the documentation chapter about SNMP support. Closes: #195653
- * Added MPLS docs.
-
- -- Christian Hammers <ch@debian.org> Thu, 29 Jul 2004 21:01:52 +0200
-
-quagga (0.96.5-8) unstable; urgency=low
-
- * Adjusted a grep in the initscript to also match a modprobe message
- from older modutils packages (thanks to Faidon Paravoid).
-
- -- Christian Hammers <ch@debian.org> Wed, 28 Jul 2004 21:19:02 +0200
-
-quagga (0.96.5-7) unstable; urgency=low
-
- * Added a "cd /etc/quagga/" to the init script as quagga tries to load
- the config file first from the current working dir and then from the
- config dir which could lead to confusion (thanks to Marco d'Itri).
- Closes: #255078
- * Removed warning regarding problems with the Debian kernels from
- README.Debian as they are no longer valid (thanks to Raphael Hertzog).
- Closes: #257580
- * Added patch from Hasso Tepper that makes "terminal length 0" work
- in vtysh (thanks to Matthias Wamser). Closes: #252579
-
- -- Christian Hammers <ch@debian.org> Thu, 8 Jul 2004 21:53:21 +0200
-
-quagga (0.96.5-6) unstable; urgency=low
-
- * Try to load the capability module as it is needed now.
-
- -- Christian Hammers <ch@debian.org> Tue, 8 Jun 2004 23:25:29 +0200
-
-quagga (0.96.5-5) unstable; urgency=low
-
- * Changed the homedir of the quagga user to /etc/quagga/ to allow
- admins to put ~/.ssh/authorized_keys there (thanks to Matthias Wamser).
- Closes: #252577
-
- -- Christian Hammers <ch@debian.org> Sat, 5 Jun 2004 14:47:31 +0200
-
-quagga (0.96.5-4) unstable; urgency=medium
-
- * Fixed rules file to use the renamed ./configure option --enable-tcp-md5
- (thanks to Matthias Wamser). Closes: #252141
-
- -- Christian Hammers <ch@debian.org> Tue, 1 Jun 2004 22:58:32 +0200
-
-quagga (0.96.5-3) unstable; urgency=low
-
- * Provided default binary package name to all build depends that were
- virtual packages (thanks to Goswin von Brederlow). Closes: #251625
-
- -- Christian Hammers <ch@debian.org> Sat, 29 May 2004 22:48:53 +0200
-
-quagga (0.96.5-2) unstable; urgency=low
-
- * New upstream version.
- * New md5 patch version (thanks to Niklas Jakobsson and Hasso Tepper).
- Closes: #250985
- * Fixes info file generation (thanks to Peder Chr. Norgaard).
- Closes: #250992
- * Added catalan debconf translation (thanks to Aleix Badia i Bosch).
- Closes: #250118
- * PATCHES:
- This release contains BGP4 MD5 support which requires a kernel patch
- to work. See /usr/share/doc/quagga/README.Debian.MD5.
- (The patch is ht-20040525-0.96.5-bgp-md5.patch from Hasso Tepper)
-
- -- Christian Hammers <ch@debian.org> Thu, 27 May 2004 20:09:37 +0200
-
-quagga (0.96.5-1) unstable; urgency=low
-
- * New upstream version.
- * PATCHES:
- This release contains BGP4 MD5 support which also requires a kernel patch.
- See /usr/share/doc/quagga/README.Debian.MD5 and search for CAN-2004-0230.
-
- -- Christian Hammers <ch@debian.org> Sun, 16 May 2004 17:40:40 +0200
-
-quagga (0.96.4x-10) unstable; urgency=low
-
- * SECURITY:
- This release contains support for MD5 for BGP which is one suggested
- prevention of the actually long known TCP SYN/RST attacks which got
- much news in the last days as ideas were revealed that made them much
- easier probable agains especially the BGP sessions than commonly known.
- There are a lot of arguments agains the MD5 approach but some ISPs
- started to require it.
- See: CAN-2004-0230, http://www.us-cert.gov/cas/techalerts/TA04-111A.html
- * PATCHES:
- This release contains the MD5 patch from Hasso Tepper. It also seems to
- required a kernel patch. See /usr/share/doc/quagga/README.Debian.MD5.
-
- -- Christian Hammers <ch@debian.org> Thu, 29 Apr 2004 01:01:38 +0200
-
-quagga (0.96.4x-9) unstable; urgency=low
-
- * Fixed daemon loading order (thanks to Matt Kemner).
- * Fixed typo in init script (thanks to Charlie Brett). Closes: #238582
-
- -- Christian Hammers <ch@debian.org> Sun, 4 Apr 2004 15:32:18 +0200
-
-quagga (0.96.4x-8) unstable; urgency=low
-
- * Patched upstream source so that quagga header files end up in
- /usr/include/quagga/. Closes: #233792
-
- -- Christian Hammers <ch@debian.org> Mon, 23 Feb 2004 01:42:53 +0100
-
-quagga (0.96.4x-7) unstable; urgency=low
-
- * Fixed info file installation (thanks to Holger Dietze). Closes: #227579
- * Added Japanese translation (thanks to Hideki Yamane). Closes: #227812
-
- -- Christian Hammers <ch@debian.org> Sun, 18 Jan 2004 17:28:29 +0100
-
-quagga (0.96.4x-6) unstable; urgency=low
-
- * Added dependency to iproute.
- * Initscript now checks not only for the pid file but also for the
- daemons presence (thanks to Phil Gregory). Closes: #224389
- * Added my patch to configure file permissions.
-
- -- Christian Hammers <ch@debian.org> Mon, 15 Dec 2003 22:34:29 +0100
-
-quagga (0.96.4x-5) unstable; urgency=low
-
- * Added patch which gives bgpd the CAP_NET_RAW capability to allow it
- to bind to special IPv6 link-local interfaces (Thanks to Bastian Blank).
- Closes: #222930
- * Made woody backport easier by applying Colin Watsons po-debconf hack.
- Thanks to Marc Haber for suggesting it. Closes: #223527
- * Made woody backport easier by applying a patch that removes some
- obscure whitespaces inside an C macro. (Thanks to Marc Haber).
- Closes: #223529
- * Now uses /usr/bin/pager. Closes: #204070
- * Added note about the "official woody backports" on my homepage.
-
- -- Christian Hammers <ch@debian.org> Mon, 15 Dec 2003 20:39:06 +0100
-
-quagga (0.96.4x-4) unstable; urgency=high
-
- * SECURITY:
- Fixes another bug that was originally reported against Zebra.
- .
- http://rhn.redhat.com/errata/RHSA-2003-307.html
- Herbert Xu reported that Zebra can accept spoofed messages sent on the
- kernel netlink interface by other users on the local machine. This could
- lead to a local denial of service attack. The Common Vulnerabilities and
- Exposures project (cve.mitre.org) has assigned the name CAN-2003-0858 to
- this issue.
-
- * Minor improvements to init script (thanks to Iustin Pop).
- Closes: #220938
-
- -- Christian Hammers <ch@debian.org> Sat, 22 Nov 2003 13:27:57 +0100
-
-quagga (0.96.4x-3) unstable; urgency=low
-
- * Changed "more" to "/usr/bin/pager" as default pager if $PAGER or
- $VTYSH_PAGER is not set (thanks to Bastian Blank). Closes: #204070
- * Made the directory (but not the config/log files!) world accessible
- again on user request (thanks to Anand Kumria)). Closes: #213129
- * No longer providing sample configuration in /etc/quagga/. They are
- now only available in /usr/share/doc/quagga/ to avoid accidently
- using them without changing the adresses (thanks to Marc Haber).
- Closes: #215918
-
- -- Christian Hammers <ch@debian.org> Sun, 16 Nov 2003 16:59:30 +0100
-
-quagga (0.96.4x-2) unstable; urgency=low
-
- * Fixed permission problem with pidfile (thanks to Kir Kostuchenko).
- Closes: #220938
-
- -- Christian Hammers <ch@debian.org> Sun, 16 Nov 2003 14:24:08 +0100
-
-quagga (0.96.4x-1) unstable; urgency=low
-
- * Reupload of 0.96.4. Last upload-in-a-hurry produced a totally
- crappy .tar.gz file. Closes: #220621
-
- -- Christian Hammers <ch@debian.org> Fri, 14 Nov 2003 19:45:57 +0100
-
-quagga (0.96.4-1) unstable; urgency=high
-
- * SECURITY: Remote DoS of protocol daemons.
- Fix for a remote triggerable crash in vty layer. The management
- ports ("telnet myrouter ospfd") should not be open to the internet!
-
- * New upstream version.
- - OSPF bugfixes.
- - Some improvements for bgp and rip.
-
- -- Christian Hammers <ch@debian.org> Thu, 13 Nov 2003 11:52:27 +0100
-
-quagga (0.96.3-3) unstable; urgency=low
-
- * Fixed pid file generation by substituting the daemons "-d" by the
- start-stop-daemon option "--background" (thanks to Micha Gaisser).
- Closes: #218103
-
- -- Christian Hammers <ch@debian.org> Wed, 29 Oct 2003 05:17:49 +0100
-
-quagga (0.96.3-2) unstable; urgency=low
-
- * Readded GNOME-PRODUCT-ZEBRA-MIB.
-
- -- Christian Hammers <ch@debian.org> Thu, 23 Oct 2003 06:17:03 +0200
-
-quagga (0.96.3-1) unstable; urgency=medium
-
- * New upstream version.
- * Removed -u and -e in postrm due to problems with debhelper and userdel
- (thanks to Adam Majer and Jaakko Niemi). Closes: #216770
- * Removed SNMP MIBs as they are now included in libsnmp-base (thanks to
- David Engel and Peter Gervai). Closes: #216138, #216086
- * Fixed seq command in init script (thanks to Marc Haber). Closes: #215915
- * Improved /proc check (thanks to Marc Haber). Closes: #212331
-
- -- Christian Hammers <ch@debian.org> Thu, 23 Oct 2003 03:42:02 +0200
-
-quagga (0.96.2-9) unstable; urgency=medium
-
- * Removed /usr/share/info/dir.* which were accidently there and prevented
- the installation by dpkg (thanks to Simon Raven). Closes: #212614
- * Reworded package description (thanks to Anand Kumria). Closes: #213125
- * Added french debconf translation (thanks to Christian Perrier).
- Closes: #212803
-
- -- Christian Hammers <ch@debian.org> Tue, 7 Oct 2003 13:26:58 +0200
-
-quagga (0.96.2-8) unstable; urgency=low
-
- * debian/rules now checks if /proc is mounted as ./configure needs
- it but just fails with an obscure error message if it is absent.
- (Thanks to Norbert Tretkowski). Closes: #212331
-
- -- Christian Hammers <ch@debian.org> Tue, 23 Sep 2003 12:57:38 +0200
-
-quagga (0.96.2-7) unstable; urgency=low
-
- * Last build was rejected due to a buggy dpkg-dev version. Rebuild.
-
- -- Christian Hammers <ch@debian.org> Mon, 22 Sep 2003 20:34:12 +0200
-
-quagga (0.96.2-6) unstable; urgency=low
-
- * Fixed init script so that is is now possible to just start
- the bgpd but not the zebra daemon. Also daemons are now actually
- started in the order defined their priority. (Thanks to Thomas Kaehn
- and Jochen Friedrich) Closes: #210924
-
- -- Christian Hammers <ch@debian.org> Fri, 19 Sep 2003 21:17:02 +0200
-
-quagga (0.96.2-5) unstable; urgency=low
-
- * For using quagga as BGP route server or similar, it is not
- wanted to have the zebra daemon running too. For this reason
- it can now be disabled in /etc/quagga/daemons, too.
- (Thanks to Jochen Friedrich). Closes: #210924
- * Attached *unapplied* patch for the ISIS protocol. I did not dare
- to apply it as long as upstream does not do it but this way give
- users the possibilities to use it if they like to.
- (Thanks to Remco van Mook)
-
- -- Christian Hammers <ch@debian.org> Wed, 17 Sep 2003 19:57:31 +0200
-
-quagga (0.96.2-4) unstable; urgency=low
-
- * Enabled IPV6 router advertisement feature by default on user request
- (thanks to Jochen Friedrich and Hasso Tepper). Closes: #210732
- * Updated GNU autoconf to let it build on hppa/parisc64 (thanks to
- lamont). Closes: #210492
-
- -- Christian Hammers <ch@debian.org> Sat, 13 Sep 2003 14:11:13 +0200
-
-quagga (0.96.2-3) unstable; urgency=medium
-
- * Removed unnecessary "-lcrypto" to avoid dependency against OpenSSL
- which would require further copyright addtions.
-
- -- Christian Hammers <ch@debian.org> Wed, 10 Sep 2003 01:37:28 +0200
-
-quagga (0.96.2-2) unstable; urgency=low
-
- * Added note that config files of quagga are in /etc/quagga and
- not /etc/zebra for the zebra users that migrate to quagga.
- (Thanks to Roberto Suarez Soto for the idea)
- * Fixed setgid rights in /etc/quagga.
-
- -- Christian Hammers <ch@debian.org> Wed, 27 Aug 2003 14:05:39 +0200
-
-quagga (0.96.2-1) unstable; urgency=low
-
- * This package has formally been known as "zebra-pj"!
- * New upstream release.
- Fixes "anoying OSPF problem".
- * Modified group ownerships so that vtysh can now be used by normal
- uses if they are in the quaggavty group.
-
- -- Christian Hammers <ch@debian.org> Mon, 25 Aug 2003 23:40:14 +0200
-
-quagga (0.96.1-1) unstable; urgency=low
-
- * Zebra-pj, the fork of zebra has been renamed to quagga as the original
- upstream author asked the new project membed not to use "zebra" in the
- name. zebra-pj is obsolete.
-
- -- Christian Hammers <ch@debian.org> Mon, 18 Aug 2003 23:37:20 +0200
-
-zebra-pj (0.94+cvs20030721-1) unstable; urgency=low
-
- * New CVS build.
- - OSPF changes (integration of the OSPF API?)
- - code cleanups (for ipv6?)
- * Tightened Build-Deps to gcc-2.95 as 3.x does not compile a stable ospfd.
- This is a known problem and has been discussed on the mailing list.
- No other solutions so far.
-
- -- Christian Hammers <ch@debian.org> Mon, 21 Jul 2003 23:52:00 +0200
-
-zebra-pj (0.94+cvs20030701-1) unstable; urgency=low
-
- * Initial Release.
-
- -- Christian Hammers <ch@debian.org> Tue, 1 Jul 2003 01:58:06 +0200
diff --git a/configure.ac b/configure.ac
index 0ea209bbfa..6108a37522 100644
--- a/configure.ac
+++ b/configure.ac
@@ -280,6 +280,8 @@ if test "$enable_clang_coverage" = "yes"; then
])
fi
+AM_CONDITIONAL([SCRIPTING], [test "$enable_scripting" = "yes"])
+
if test "$enable_scripting" = "yes"; then
AX_PROG_LUA([5.3], [5.4], [], [
AC_MSG_ERROR([Lua 5.3 is required to build with Lua support. No other version is supported.])
@@ -290,7 +292,9 @@ if test "$enable_scripting" = "yes"; then
AX_LUA_LIBS([
AC_DEFINE([HAVE_SCRIPTING], [1], [Have support for scripting])
LIBS="$LIBS $LUA_LIB"
+ SCRIPTING=true
], [
+ SCRIPTING=false
AC_MSG_ERROR([Lua 5.3 libraries are required to build with Lua support. No other version is supported.])
])
fi
@@ -2628,7 +2632,6 @@ AC_CONFIG_FILES([Makefile],[
AC_CONFIG_FILES([
config.version
- changelog-auto
redhat/frr.spec
alpine/APKBUILD
snapcraft/snapcraft.yaml
diff --git a/debian/changelog b/debian/changelog
index 021c52c2f3..99c75106db 120000..100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1 +1,1523 @@
-../changelog-auto \ No newline at end of file
+frr (8.1~dev-1) UNRELEASED; urgency=medium
+
+ * New upstream release...
+
+ -- Ondřej Surý <ondrej@debian.org> Tue, 04 May 2021 22:52:47 +0200
+
+frr (7.5.1-1) unstable; urgency=medium
+
+ * Update the d/gbp.conf for 7.5.1 release
+ * Use wrap-and-sort -a to unify debian/ wrapping and sorting
+ * Work around the sphinx-build error that doesn't copy images to texinfo
+ * Change the upstream-tag in d/gbp.conf to track the upstream tarballs
+
+ -- Ondřej Surý <ondrej@debian.org> Mon, 08 Mar 2021 09:40:19 +0100
+
+frr (7.5-1) unstable; urgency=medium
+
+ * New upstream version 7.5
+
+ -- Ondřej Surý <ondrej@debian.org> Sun, 14 Feb 2021 21:38:50 +0100
+
+frr (7.4-2) unstable; urgency=medium
+
+ * Bump libyang dependency to >= 1.0.184-1~
+ * Make the autopkgtest more resilient (Closes: #980111)
+ * Adjust the ax_python.m4 to hardcode python3.9
+
+ -- Ondřej Surý <ondrej@debian.org> Sun, 07 Feb 2021 13:15:07 +0100
+
+frr (7.4-1.1) unstable; urgency=medium
+
+ * Non-maintainer upload.
+ * Backport upstream fix for FTBFS with Python 3.9. (Closes: #972767)
+
+ -- Adrian Bunk <bunk@debian.org> Thu, 21 Jan 2021 16:06:12 +0200
+
+frr (7.4-1) unstable; urgency=medium
+
+ [ Ondřej Surý ]
+ * Use dh_installinit capabilities to install frr.tmpfile
+ * Remove unused debian/watchfrr.rc file
+ * Add missing lsof dependency
+ * Remove mention of pkg.frr.snmp build profile from debian/README.Debian
+ * Make lsb-base a hard dependency
+ * Update gbp.conf for 7.4 release
+ * Update and simplify d/watch
+ * Change the debian source format from 3.0 (git) to 3.0 (quilt)
+ * Convert the package to dh compat level 10
+ * Add myself to Uploaders
+ * Bump standards version to 4.5.0.2 (latest) - no change
+ * Use wrap-and-sort -a to unify debian/ wrapping and sorting
+ * Work around the sphinx-build error that doesn't copy images to texinfo
+ (Properly closes: #955067)
+ * Depend on debhelper >= 9.20160709 and drop dh-systemd dependency
+ (Closes: #958626)
+
+ -- Ondřej Surý <ondrej@debian.org> Mon, 10 Aug 2020 11:50:45 +0200
+
+frr (7.3.1-1) unstable; urgency=medium
+
+ [ David Lamparter ]
+ * allow cross-compile with sbuild --host
+
+ [ Ondřej Surý ]
+ * Add myself to Uploaders
+ * Add d/gbp.conf
+ * Update changelog for 7.3.1-1~1.gbp2292a4 release
+ * Change the source format from git to quilt to use git-buildpackage
+ * Don't install frr-doc texinfo images, they are gone (Closes: #955067)
+ * Bump the dh_compat to 10
+
+ -- Ondřej Surý <ondrej@debian.org> Mon, 01 Jun 2020 08:41:03 +0200
+
+frr (7.3-1) unstable; urgency=medium
+
+ * new upstream release
+
+ -- David Lamparter <equinox-debian@diac24.net> Tue, 25 Feb 2020 17:45:16 +0100
+
+frr (7.2.1-1) unstable; urgency=medium
+
+ * new upstream release
+ * daemon man pages renamed to frr-* (closes: #944392)
+ * fix/improve multi-arch markers on doc
+ * fix git URLs to point to debian branch
+
+ -- David Lamparter <equinox-debian@diac24.net> Mon, 20 Jan 2020 17:06:21 +0100
+
+frr (7.2-1) unstable; urgency=medium
+
+ * New upstream release
+
+ -- Jafar Al-Gharaibeh <jafar@atcorp.com> Sun, 03 Nov 2019 18:45:23 +0100
+
+frr (6.0.2-2) unstable; urgency=medium
+
+ * remove bogus libjson0 build-dep (closes: #921349)
+ * fix broken systemd dependency spec
+ * add proper Conflicts: for quagga and pimd (closes: #921376)
+
+ -- David Lamparter <equinox-debian@diac24.net> Mon, 04 Feb 2019 22:16:07 +0100
+
+frr (6.0.2-1) unstable; urgency=medium
+
+ * Packaging has been more or less completely reworked, based off the old
+ Quagga packaging that hung around in git. Refer to "changelog-auto.in"
+ in the source root directory for the old changelog.
+ * Initial release of FRR for Debian. (closes: #863249)
+
+ -- David Lamparter <equinox-debian@diac24.net> Sun, 27 Jan 2019 17:27:02 +0100
+
+frr (6.0-2) testing; urgency=medium
+
+ * add install-info to build deps
+ * remove trailing whitespace from control
+ * cleanup tcp-zebra configure options
+ * drop unused SMUX client OID MIBs
+ * remove /proc check
+ * remove --enable-poll
+ * remove libtool .la files
+ * drop texlive-latex-base, texlive-generic-recommended build deps
+ * consistently allow python2 or python3
+ * remove bad USE_* options, add WERROR
+ * drop libncurses5 dep
+ * remove backports mechanism
+ * use better dependency for pythontools (binNMU compatible)
+ * remove bogus shlib:Depends on frr-dbg
+ * create frr-snmp and frr-rpki-rtrlib
+ * make frr-pythontools a "Recommends:"
+ * use redistclean target
+ * update to Debian Policy version 4.2.1
+ * raise debhelper compat level to 9
+ * ditch development-only files
+ * modernise dh_missing and use fail mode
+ * disable zeromq and FPM
+ * always install /etc/init.d/frr
+ * put frr-doc package in 'doc' section
+ * install HTML docs, drop tools/
+ * fix install for {frr,rfptest,ospfclient}
+ * add watch file
+ * change python dependency and shebang to python3:any
+ * use set -e in maintscripts
+ * put myself in as maintainer
+ * update copyright file
+ * closes: #863249
+
+ -- David Lamparter <equinox-debian@diac24.net> Thu, 25 Oct 2018 16:36:50 +0200
+
+frr (6.0-1) RELEASED; urgency=medium
+
+ * New Enabled: PIM draft Unnumbered
+
+ -- FRRouting-Dev <dev@lists.frrouting.org> Wed, 18 Oct 2017 17:01:42 -0700
+
+frr (3.0-1) RELEASED; urgency=medium
+
+ * Added Debian 9 Backport
+
+ -- FRRouting-Dev <dev@lists.frrouting.org> Mon, 16 Oct 2017 03:28:00 -0700
+
+frr (3.0-0) RELEASED; urgency=medium
+
+ * New Enabled: BGP Shutdown Message
+ * New Enabled: BGP Large Community
+ * New Enabled: BGP RFC 7432 Partial Support w/ Ethernet VPN
+ * New Enabled: BGP EVPN RT-5
+ * New Enabled: LDP RFC 5561
+ * New Enabled: LDP RFC 5918
+ * New Enabled: LDP RFC 5919
+ * New Enabled: LDP RFC 6667
+ * New Enabled: LDP RFC 7473
+ * New Enabled: OSPF RFC 4552
+ * New Enabled: ISIS SPF Backoff draft
+ * New Enabled: PIM Unnumbered Interfaces
+ * New Enabled: PIM RFC 4611
+ * New Enabled: PIM Sparse Mode
+ * New Enabled: NHRP RFC 2332
+ * New Enabled: Label Manager
+ * Switched from hardening-wrapper to dpkg-buildflags.
+
+ -- FRRouting-Dev <dev@lists.frrouting.org> Fri, 13 Oct 2017 16:17:26 -0700
+
+frr (2.0-0) RELEASED; urgency=medium
+
+ * Switchover to FRR
+
+ -- FRRouting-Dev <dev@lists.frrouting.org> Mon, 23 Jan 2017 16:30:22 -0400
+
+quagga (0.99.24+cl3u5) RELEASED; urgency=medium
+
+ * Closes: CM-12846 - Resolve Memory leaks in 'show ip bgp neighbor json'
+ * Closes: CM-5878 - Display all ospf peers with 'show ip ospf neighbor detail all'
+ * Closes: CM-5794 - Add support for IPv6 static to null0
+ * Closes: CM-13060 - Reduce JSON memory usage.
+ * Closes: CM-10394 - protect 'could not get instance' error messages with debug
+ * Closes: CM-11173 - Move netlink error messages undeer a debug
+ * Closes: CM-13328 - Fixes route missing in hardware after reboot
+
+ -- dev-support <dev-support@cumulusnetworks.com> Fri, 11 Nov 2016 22:13:29 -0400
+
+quagga (0.99.24+cl3u4) RELEASED; urgency=medium
+
+ * Closes: CM-12687 - Buffer overflow in zebra RA code
+
+ -- dev-support <dev-support@cumulusnetworks.com> Wed, 31 Aug 2016 12:36:10 -0400
+
+quagga (0.99.24+cl3u3) RELEASED; urgency=medium
+
+ * New Enabled: Merge up-to 0.99.24 code from upstream
+ * New Enabled: Additional CLI simplification
+ * New Enabled: Various Bug Fixes
+
+ -- dev-support <dev-support@cumulusnetworks.com> Thu, 04 Aug 2016 08:43:36 -0700
+
+quagga (0.99.23.1-1+cl3u2) RELEASED; urgency=medium
+
+ * New Enabled: VRF - See Documentation for how to use
+ * New Enabled: Improved interface statistics
+ * New Enabled: Various vtysh improvements
+ * New Enabled: Numerous compile warnings and SA fixes
+ * New Enabled: Improved priviledge handlingA
+ * New Enabled: Various OSPF CLI fixes
+ * New Enabled: Prefix-list Performance Improvements.
+ * New Enabled: Allow more than 1k peers in Quagga
+ and Performance Improvements
+ * New Enabled: Systemd integration
+ * New Enabled: Various ISIS fixes
+ * New Enabled: BGP MRT improvements
+ * New Enabled: Lowered default MRAI timers
+ * New Enabled: Lowered default 'timers connect'
+ * New Enabled: 'bgp log-neighbor-changes' enabled by default
+ * New Enabled: BGP default keepalive to 3s and holdtime to 9s
+ * New Enabled: OSPF spf timers are now '0 50 5000' by default
+ * New Enabled: BGP hostname is displayed by default
+ * New Enabled: BGP 'no-as-set' is the default for
+ 'bgp as-path multipath-relax"
+ * New Enabled: RA is on by default if using 5549 on an interface
+ * New Enabled: peer-group restrictions relaxed, update-groups determine
+ outbund policy anyway
+ * New Enabled: BGP enabled 'maximum-paths 64' by default
+ * New Enabled: OSPF "log-adjacency-changes" on by default
+ * New Enabled: Zebra: Add IPv6 protocol filtering support
+ * and setting src of IPv6 routes.
+ * New Enabled: BGP and OSPF JSON commands added.
+ * New Enabled: BGP Enable multiple instances support by default
+ * New Enabled: 'banner motd file' command
+ * New Enabled: Remove bad default passwords from default conf
+ * New Enabled: BGP addpath TX
+ * New Enabled: Simplified configuration for BGP Unnumbered
+
+ * New Deprecated: Remove unused 'show memory XXX' functionality
+ * New Deprecated: Remove babel protocol
+
+ * Closes: CM-10435 Addition on hidden command
+ "bfd multihop/singlehop" and "ptm-enable" per interface command
+ * Closes: CM-9974 Get route counts right for show ip route summary
+ * Closes: CM-9786 BGP memory leak in peer hostname
+ * Closes: CM-9340 BGP: Ensure correct sequence of processing at exit
+ * Closes: CM-9270 ripd: Fix crash when a default route is passed to rip
+ * Closes: CM-9255 BGPD crash around bgp_config_write ()
+ * Closes: CM-9134 ospf6d: Fix for crash when non area 0 network
+ entered first
+ * Closes: CM-8934 OSPFv3: Check area before scheduling SPF
+ * Closes: CM-8514 zebra: Crash upon disabling a link
+ * Closes: CM-8295 BGP crash in group_announce_route_walkcb
+ * Closes: CM-8191 BGP: crash in update_subgroup_merge()
+ * Closes: CM-8015 lib: Memory reporting fails over 2GB
+ * Closes: CM-7926 BGP: crash from not NULLing freed pointers
+
+ -- dev-support <dev-support@cumulusnetworks.com> Wed, 04 May 2016 16:22:52 -0700
+
+quagga (0.99.23.1-1) unstable; urgency=medium
+
+ * New upstream release
+ * Added .png figures for info files to quagga-doc package.
+ * Changed dependency from iproute to iproute2 (thanks to Andreas
+ Henriksson). Closes: #753736
+ * Added texlive-fonts-recommended to build-depends to get ecrm1095 font
+ (thanks to Christoph Biedl). Closes: #651545
+
+ -- Christian Brunotte <ch@debian.org> Tue, 30 Sep 2014 00:20:12 +0200
+
+quagga (0.99.23-1) unstable; urgency=low
+
+ * New upstream release
+ * Removed debian/patches/readline-6.3.diff which was already in upstream.
+
+ -- Christian Hammers <ch@debian.org> Tue, 08 Jul 2014 09:15:48 +0200
+
+quagga (0.99.22.4-4) unstable; urgency=medium
+
+ * Fix build failure with readline-6.3 (thanks to Matthias Klose).
+ Closes: #741774
+
+ -- Christian Hammers <ch@debian.org> Sun, 23 Mar 2014 15:28:42 +0100
+
+quagga (0.99.22.4-3) unstable; urgency=low
+
+ * Added status to init script (thanks to Peter J. Holzer). Closes: #730625
+ * Init script now sources /lib/lsb/init-functions.
+ * Switched from hardening-wrapper to dpkg-buildflags.
+
+ -- Christian Hammers <ch@debian.org> Wed, 01 Jan 2014 19:12:01 +0100
+
+quagga (0.99.22.4-2) unstable; urgency=low
+
+ * Fixed typo in package description (thanks to Davide Prina).
+ Closes: #625860
+ * Added Italian Debconf translation (thanks to Beatrice Torracca)
+ Closes: #729798
+
+ -- Christian Hammers <ch@debian.org> Tue, 26 Nov 2013 00:47:11 +0100
+
+quagga (0.99.22.4-1) unstable; urgency=high
+
+ * SECURITY:
+ "ospfd: CVE-2013-2236, stack overrun in apiserver
+
+ the OSPF API-server (exporting the LSDB and allowing announcement of
+ Opaque-LSAs) writes past the end of fixed on-stack buffers. This leads
+ to an exploitable stack overflow.
+
+ For this condition to occur, the following two conditions must be true:
+ - Quagga is configured with --enable-opaque-lsa
+ - ospfd is started with the "-a" command line option
+
+ If either of these does not hold, the relevant code is not executed and
+ the issue does not get triggered."
+ Closes: #726724
+
+ * New upstream release
+ - ospfd: protect vs. VU#229804 (malformed Router-LSA)
+ (Quagga is said to be non-vulnerable but still adds some protection)
+
+ -- Christian Hammers <ch@debian.org> Thu, 24 Oct 2013 22:58:37 +0200
+
+quagga (0.99.22.1-2) unstable; urgency=low
+
+ * Added autopkgtests (thanks to Yolanda Robla). Closes: #710147
+ * Added "status" command to init script (thanks to James Andrewartha).
+ Closes: #690013
+ * Added "libsnmp-dev" to Build-Deps. There not needed for the official
+ builds but for people who compile Quagga themselves to activate the
+ SNMP feature (which for licence reasons cannot be done by Debian).
+ Thanks to Ben Winslow). Closes: #694852
+ * Changed watchquagga_options to an array so that quotes can finally
+ be used as expected. Closes: #681088
+ * Fixed bug that prevented restarting only the watchquagga daemon
+ (thanks to Harald Kappe). Closes: #687124
+
+ -- Christian Hammers <ch@debian.org> Sat, 27 Jul 2013 16:06:25 +0200
+
+quagga (0.99.22.1-1) unstable; urgency=low
+
+ * New upstream release
+ - ospfd restore nexthop IP for p2p interfaces
+ - ospfd: fix LSA initialization for build without opaque LSA
+ - ripd: correctly redistribute ifindex routes (BZ#664)
+ - bgpd: fix lost passwords of grouped neighbors
+ * Removed 91_ld_as_needed.diff as it was found in the upstream source.
+
+ -- Christian Hammers <ch@debian.org> Mon, 22 Apr 2013 22:21:20 +0200
+
+quagga (0.99.22-1) unstable; urgency=low
+
+ * New upstream release.
+ - [bgpd] The semantics of default-originate route-map have changed.
+ The route-map is now used to advertise the default route conditionally.
+ The old behaviour which allowed to set attributes on the originated
+ default route is no longer supported.
+ - [bgpd] this version of bgpd implements draft-idr-error-handling. This was
+ added in 0.99.21 and may not be desirable. If you need a version
+ without this behaviour, please use 0.99.20.1. There will be a
+ runtime configuration switch for this in future versions.
+ - [isisd] is in "beta" state.
+ - [ospf6d] is in "alpha/experimental" state
+ - More changes are documented in the upstream changelog!
+ * debian/watch: Adjusted to new savannah.gnu.org site, thanks to Bart
+ Martens.
+ * debian/patches/99_CVE-2012-1820_bgp_capability_orf.diff removed as its
+ in the changelog.
+ * debian/patches/99_distribute_list.diff removed as its in the changelog.
+ * debian/patches/10_doc__Makefiles__makeinfo-force.diff removed as it
+ was just for Debian woody.
+
+ -- Christian Hammers <ch@debian.org> Thu, 14 Feb 2013 00:22:00 +0100
+
+quagga (0.99.21-4) unstable; urgency=medium
+
+ * Fixed regression bug that caused OSPF "distribute-list" statements to be
+ silently ignored. The patch has already been applied upstream but there
+ has been no new Quagga release since then.
+ Thanks to Hans van Kranenburg for reporting. Closes: #697240
+
+ -- Christian Hammers <ch@debian.org> Sun, 06 Jan 2013 15:50:32 +0100
+
+quagga (0.99.21-3) unstable; urgency=high
+
+ * SECURITY:
+ CVE-2012-1820 - Quagga contained a bug in BGP OPEN message handling.
+ A denial-of-service condition could be caused by an attacker controlling
+ one of the pre-configured BGP peers. In most cases this means, that the
+ attack must be originated from an adjacent network. Closes: #676510
+
+ -- Christian Hammers <ch@debian.org> Fri, 08 Jun 2012 01:15:32 +0200
+
+quagga (0.99.21-2) unstable; urgency=low
+
+ * Renamed babeld.8 to quagga-babeld.8 as it conflicted with the
+ original mapage of the babeld package which users might want to
+ install in parallel as it is slightly more capable. Closes: #671916
+
+ -- Christian Hammers <ch@debian.org> Thu, 10 May 2012 07:53:01 +0200
+
+quagga (0.99.21-1) unstable; urgency=low
+
+ * New upstream release
+ - [bgpd] BGP multipath support has been merged
+ - [bgpd] SAFI (Multicast topology) support has been extended to propagate
+ the topology to zebra.
+ - [bgpd] AS path limit functionality has been removed
+ - [babeld] a new routing daemon implementing the BABEL ad-hoc mesh routing
+ protocol has been merged.
+ - [isisd] a major overhaul has been picked up. Please note that isisd is
+ STILL NOT SUITABLE FOR PRODUCTION USE.
+ - a lot of bugs have been fixed
+ * Added watchquagga daemon.
+ * Added DEP-3 conforming patch comments.
+
+ -- Christian Hammers <ch@debian.org> Sun, 06 May 2012 15:33:33 +0200
+
+quagga (0.99.20.1-1) unstable; urgency=high
+
+ * SECURITY:
+ CVE-2012-0249 - Quagga ospfd DoS on malformed LS-Update packet
+ CVE-2012-0250 - Quagga ospfd DoS on malformed Network-LSA data
+ CVE-2012-0255 - Quagga bgpd DoS on malformed OPEN message
+ * New upstream release. Closes: #664033
+
+ -- Christian Hammers <ch@debian.org> Fri, 16 Mar 2012 22:14:05 +0100
+
+quagga (0.99.20-4) unstable; urgency=low
+
+ * Switch to dpkg-source 3.0 (quilt) format.
+ * Switch to changelog-format-1.0.
+
+ -- Christian Hammers <ch@debian.org> Sat, 25 Feb 2012 18:52:06 +0100
+
+quagga (0.99.20-3) unstable; urgency=low
+
+ * Added --sysconfdir back to the configure options (thanks to Sven-Haegar
+ Koch). Closes: #645649
+
+ -- Christian Hammers <ch@debian.org> Tue, 18 Oct 2011 00:24:37 +0200
+
+quagga (0.99.20-2) unstable; urgency=low
+
+ * Bumped standards version to 0.9.2.
+ * Migrated to "dh" build system.
+ * Added quagga-dbg package.
+
+ -- Christian Hammers <ch@debian.org> Fri, 14 Oct 2011 23:59:26 +0200
+
+quagga (0.99.20-1) unstable; urgency=low
+
+ * New upstream release:
+ "The primary focus of this release is a fix of SEGV regression in ospfd,
+ which was introduced in 0.99.19. It also features a series of minor
+ improvements, including better RFC compliance in bgpd, better support
+ of FreeBSD and some enhancements to isisd."
+ * Fixes off-by-one bug (removed 20_ospf6_area_argv.dpatch). Closes: #519488
+
+ -- Christian Hammers <ch@debian.org> Fri, 30 Sep 2011 00:59:24 +0200
+
+quagga (0.99.19-1) unstable; urgency=high
+
+ * SECURITY:
+ "This release provides security fixes, which address assorted
+ vulnerabilities in bgpd, ospfd and ospf6d (CVE-2011-3323,
+ CVE-2011-3324, CVE-2011-3325, CVE-2011-3326 and CVE-2011-3327).
+ * New upstream release.
+ * Removed incorporated debian/patches/92_opaque_lsa_enable.dpatch.
+ * Removed incorporated debian/patches/93_opaque_lsa_fix.dpatch.
+ * Removed obsolete debian/README.Debian.Woody and README.Debian.MD5.
+
+ -- Christian Hammers <ch@debian.org> Tue, 27 Sep 2011 00:16:27 +0200
+
+quagga (0.99.18-1) unstable; urgency=low
+
+ * SECURITY:
+ "This release fixes 2 denial of services in bgpd, which can be remotely
+ triggered by malformed AS-Pathlimit or Extended-Community attributes.
+ These issues have been assigned CVE-2010-1674 and CVE-2010-1675.
+ Support for AS-Pathlimit has been removed with this release."
+ * Added Brazilian Portuguese debconf translation. Closes: #617735
+ * Changed section for quagga-doc from "doc" to "net".
+ * Added patch to fix FTBFS with latest GCC. Closes: #614459
+
+ -- Christian Hammers <ch@debian.org> Tue, 22 Mar 2011 23:13:34 +0100
+
+quagga (0.99.17-4) unstable; urgency=low
+
+ * Added comment to init script (thanks to Marc Haber). Closes: #599524
+
+ -- Christian Hammers <ch@debian.org> Thu, 13 Jan 2011 23:53:29 +0100
+
+quagga (0.99.17-3) unstable; urgency=low
+
+ * Fix FTBFS with ld --as-needed (thanks to Matthias Klose at Ubuntu).
+ Closes: #609555
+
+ -- Christian Hammers <ch@debian.org> Thu, 13 Jan 2011 23:27:06 +0100
+
+quagga (0.99.17-2) unstable; urgency=low
+
+ * Added Danisch Debconf translation (thanks to Joe Dalton). Closes: #596259
+
+ -- Christian Hammers <ch@debian.org> Sat, 18 Sep 2010 12:20:07 +0200
+
+quagga (0.99.17-1) unstable; urgency=high
+
+ * SECURITY:
+ "This release provides two important bugfixes, which address remote crash
+ possibility in bgpd discovered by CROSS team.":
+ 1. Stack buffer overflow by processing certain Route-Refresh messages
+ CVE-2010-2948
+ 2. DoS (crash) while processing certain BGP update AS path messages
+ CVE-2010-2949
+ Closes: #594262
+
+ -- Christian Hammers <ch@debian.org> Wed, 25 Aug 2010 00:52:48 +0200
+
+quagga (0.99.16-1) unstable; urgency=low
+
+ * New upstream release. Closes: #574527
+ * Added chrpath to debian/rules to fix rpath problems that lintian spottet.
+
+ -- Christian Hammers <ch@debian.org> Sun, 21 Mar 2010 17:05:40 +0100
+
+quagga (0.99.15-2) unstable; urgency=low
+
+ * Applied patch for off-by-one bug in ospf6d that caused a segmentation
+ fault when using the "area a.b.c.d filter-list prefix" command (thanks
+ to Steinar H. Gunderson). Closes: 519488
+
+ -- Christian Hammers <ch@debian.org> Sun, 14 Feb 2010 20:02:03 +0100
+
+quagga (0.99.15-1) unstable; urgency=low
+
+ * New upstream release
+ "This fixes some annoying little ospfd and ospf6d regressions, which made
+ 0.99.14 a bit of a problem release (...) This release still contains a
+ regression in the "no ip address ..." command, at least on Linux.
+ See bug #486, which contains a workaround patch. This release should be
+ considered a 1.0.0 release candidate. Please test this release as widely
+ as possible."
+ * Fixed wrong port number in zebra.8 (thanks to Thijs Kinkhorst).
+ Closes: #517860
+ * Added Russian Debconf tanslation (thanks to Yuri Kozlov).
+ Closes: #539464
+ * Removed so-version in build-dep to libreadline-dev on request of
+ Matthias Klose.
+ * Added README.source with reference to dpatch as suggested by lintian.
+ * Bumped standards versionto 3.8.3.
+
+ -- Christian Hammers <ch@debian.org> Sun, 13 Sep 2009 18:12:06 +0200
+
+quagga (0.99.14-1) unstable; urgency=low
+
+ * New upstream release
+ "This release contains a regression fix for ospf6d, various small fixes
+ and some hopefully very significant bgpd stability fixes.
+ This release should be considered a 1.0.0 release candidate. Please test
+ this release as widely as possible."
+ * Fixes bug with premature LSA aging in ospf6d. Closes: #535030
+ * Fixes section number in zebra.8 manpage. Closes: #517860
+
+ -- Christian Hammers <ch@debian.org> Sat, 25 Jul 2009 00:40:38 +0200
+
+quagga (0.99.13-2) unstable; urgency=low
+
+ * Added Japanese Debconf translation (thanks to Hideki Yamane).
+ Closes: #510714
+ * When checking for obsoleted config options in preinst, print filename
+ where it occures (thanks to Michael Bussmann). Closes: #339489
+
+ -- Christian Hammers <ch@debian.org> Sun, 19 Jul 2009 17:13:23 +0200
+
+quagga (0.99.13-1) unstable; urgency=low
+
+ * New upstream release
+ "This release is contains a number of small fixes, for potentially
+ irritating issues, as well as small enhancements to vtysh and support
+ for linking to PCRE (a much faster regex library)."
+ * Added build-dep to gawk as configure required it for memtypes.awk
+ * Replaced build-dep to gs-gpl with ghostscript as requested by lintian
+ * Minor changes to copyright and control files to make lintian happy.
+
+ -- Christian Hammers <ch@debian.org> Wed, 24 Jun 2009 17:53:28 +0200
+
+quagga (0.99.12-1) unstable; urgency=high
+
+ * New upstream release
+ "This release fixes an urgent bug in bgpd where it could hit an assert
+ if it received a long AS_PATH with a 4-byte ASN." Noteworthy bugfixes:
+ + [bgpd] Fix bgp ipv4/ipv6 accept handling
+ + [bgpd] AS4 bugfix by Chris Caputo
+ + [bgpd] Allow accepted peers to progress even if realpeer is in Connect
+ + [ospfd] Switch Fletcher checksum back to old ospfd version
+
+ -- Christian Hammers <ch@debian.org> Mon, 22 Jun 2009 00:16:33 +0200
+
+quagga (0.99.11-1) unstable; urgency=low
+
+ * New upstream release
+ "Most regressions in 0.99 over 0.98 are now believed to be fixed. This
+ release should be considered a release-candidate for a new stable series."
+ + bgpd: Preliminary UI and Linux-IPv4 support for TCP-MD5 merged
+ + zebra: ignore dead routes in RIB update
+ + [ospfd] Default route needs to be refreshed after neighbour state change
+ + [zebra:netlink] Set proto/scope on all route update messages
+ * Removed debian/patches/20_*bgp*md5*.dpatch due to upstream support.
+
+ -- Christian Hammers <ch@debian.org> Thu, 09 Oct 2008 22:56:38 +0200
+
+quagga (0.99.10-1) unstable; urgency=medium
+
+ * New upstream release
+ + bgpd: 4-Byte AS Number support
+ + Sessions were incorrectly reset if a partial AS-Pathlimit attribute
+ was received.
+ + Advertisement of Multi-Protocol prefixes (i.e. non-IPv4) had been
+ broken in the 0.99.9 release. Closes: #467656
+
+ -- Christian Hammers <ch@debian.org> Tue, 08 Jul 2008 23:32:42 +0200
+
+quagga (0.99.9-6) unstable; urgency=low
+
+ * Fixed FTBFS by adding a build-dep to libpcre3-dev (thanks to Luk Claes).
+ Closes: #469891
+
+ -- Christian Hammers <ch@debian.org> Sat, 12 Apr 2008 12:53:51 +0200
+
+quagga (0.99.9-5) unstable; urgency=low
+
+ * C.J. Adams-Collier and Paul Jakma suggested to build against libpcre3
+ which is supposed to be faster.
+
+ -- Christian Hammers <ch@debian.org> Sun, 02 Mar 2008 13:19:42 +0100
+
+quagga (0.99.9-4) unstable; urgency=low
+
+ * Added hardening-wrapper to the build-deps (thanks to Moritz Muehlenhoff).
+
+ -- Christian Hammers <ch@debian.org> Tue, 29 Jan 2008 22:33:56 +0100
+
+quagga (0.99.9-3) unstable; urgency=low
+
+ * Replaced the BGP patch by a new one so that the package builds again
+ with kernels above 2.6.21!
+ * debian/control:
+ + Moved quagga-doc to section doc to make lintian happy.
+ * Added Spanish debconf translation (thanks to Carlos Galisteo de Cabo).
+ Closes: #428574
+ * debian/control: (thanks to Marco Rodrigues)
+ + Bump Standards-Version to 3.7.3 (no changes needed).
+ + Add Homepage field.
+
+ -- Christian Hammers <ch@debian.org> Mon, 28 Jan 2008 22:29:18 +0100
+
+quagga (0.99.9-2.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * debian/rules: fixed bashisms. (Closes: #459122)
+
+ -- Miguel Angel Ruiz Manzano <debianized@gmail.com> Tue, 22 Jan 2008 14:37:21 -0300
+
+quagga (0.99.9-2) unstable; urgency=low
+
+ * Added CVE id for the security bug to the last changelog entry.
+ Closes: 442133
+
+ -- Christian Hammers <ch@debian.org> Tue, 25 Sep 2007 22:01:31 +0200
+
+quagga (0.99.9-1) unstable; urgency=high
+
+ * SECURITY:
+ "This release fixes two potential DoS conditions in bgpd, reported by Mu
+ Security, where a bgpd could be crashed if a peer sent a malformed OPEN
+ message or a malformed COMMUNITY attribute. Only configured peers can do
+ this, hence we consider these issues to be very low impact." CVE-2007-4826
+
+ -- Christian Hammers <ch@debian.org> Wed, 12 Sep 2007 21:12:41 +0200
+
+quagga (0.99.8-1) unstable; urgency=low
+
+ * New upstream version.
+
+ -- Christian Hammers <ch@debian.org> Fri, 17 Aug 2007 00:07:04 +0200
+
+quagga (0.99.7-3) unstable; urgency=medium
+
+ * Applied patch for FTBFS with linux-libc-dev (thanks to Andrew J. Schorr
+ and Lucas Nussbaum). Closes: #429003
+
+ -- Christian Hammers <ch@debian.org> Fri, 22 Jun 2007 21:34:55 +0200
+
+quagga (0.99.7-2) unstable; urgency=low
+
+ * Added Florian Weimar as co-maintainer. Closes: 421977
+ * Added Dutch debconf translation (thanks to Bart Cornelis).
+ Closes: #420932
+ * Added Portuguese debconf translation (thanks to Rui Branco).
+ Closes: #421185
+ * Improved package description (thanks to Reuben Thomas).
+ Closes: #418933
+ * Added CVE Id to 0.99.6-5 changelog entry.
+
+ -- Christian Hammers <ch@debian.org> Wed, 02 May 2007 20:27:12 +0200
+
+quagga (0.99.7-1) unstable; urgency=low
+
+ * New upstream release. Closes: #421553
+
+ -- Christian Hammers <ch@debian.org> Mon, 30 Apr 2007 14:22:34 +0200
+
+quagga (0.99.6-6) unstable; urgency=medium
+
+ * Fixes FTBFS with tetex-live. Closes: #420468
+
+ -- Christian Hammers <ch@debian.org> Mon, 23 Apr 2007 21:34:13 +0200
+
+quagga (0.99.6-5) unstable; urgency=high
+
+ * SECURITY:
+ The bgpd daemon was vulnerable to a Denial-of-Service. Configured peers
+ could cause a Quagga bgpd to, typically, assert() and abort. The DoS
+ could be triggered by peers by sending an UPDATE message with a crafted,
+ malformed Multi-Protocol reachable/unreachable NLRI attribute.
+ This is CVE-2007-1995 and Quagga Bug#354. Closes: #418323
+
+ -- Christian Hammers <ch@debian.org> Thu, 12 Apr 2007 23:21:58 +0200
+
+quagga (0.99.6-4) unstable; urgency=low
+
+ * Improved note in README.Debian for SNMP self-builders (thanks to Matthias
+ Wamser). Closes: #414788
+
+ -- Christian Hammers <ch@debian.org> Wed, 14 Mar 2007 02:18:57 +0100
+
+quagga (0.99.6-3) unstable; urgency=low
+
+ * Updated German Debconf translation (thanks to Matthias Julius).
+ Closes: #409327
+
+ -- Christian Hammers <ch@debian.org> Sat, 10 Feb 2007 15:06:16 +0100
+
+quagga (0.99.6-2) unstable; urgency=low
+
+ * Updated config.guess/config.sub as suggested by lintian.
+ * Corrected README.Debian text regarding the WANT_SNMP flag.
+
+ -- Christian Hammers <ch@debian.org> Sun, 17 Dec 2006 01:45:37 +0100
+
+quagga (0.99.6-1) unstable; urgency=low
+
+ * New upstream release. Closes: #402361
+
+ -- Christian Hammers <ch@debian.org> Mon, 11 Dec 2006 00:28:09 +0100
+
+quagga (0.99.5-5) unstable; urgency=high
+
+ * Changed Depends on adduser to Pre-Depends to avoid uninstallability
+ in certain cases (thanks to Steve Langasek, Lucas Nussbaum).
+ Closes: #398562
+
+ -- Christian Hammers <ch@debian.org> Wed, 15 Nov 2006 17:46:34 +0100
+
+quagga (0.99.5-4) unstable; urgency=low
+
+ * Added default PAM file and some explanations regarding PAM authentication
+ of vtysh which could prevent the start at boot-time when used wrong.
+ Now PAM permits anybody to access the vtysh tool (a malicious user could
+ build his own vtysh without PAM anyway) and the access is controled by
+ the read/write permissions of the vtysh socket which are only granted to
+ users belonging to the quaggavty group (thanks to Wakko Warner).
+ Closes: #389496
+ * Added "case" to prerm script so that the Debconf question is not called a
+ second time in e.g. "new-prerm abort-upgrade" after being NACKed in the
+ old-prerm.
+
+ -- Christian Hammers <ch@debian.org> Fri, 3 Nov 2006 01:22:15 +0100
+
+quagga (0.99.5-3) unstable; urgency=medium
+
+ * Backport CVS fix for an OSPF DD Exchange regression (thanks to Matt
+ Brown). Closes: #391040
+
+ -- Christian Hammers <ch@debian.org> Wed, 25 Oct 2006 19:47:11 +0200
+
+quagga (0.99.5-2) unstable; urgency=medium
+
+ * Added LSB info section to initscript.
+ * Removed unnecessary depends to libncurses5 to make checklib happy.
+ The one to libcap should remain though as it is just temporarily
+ unused.
+
+ -- Christian Hammers <ch@debian.org> Thu, 21 Sep 2006 00:04:07 +0200
+
+quagga (0.99.5-1) unstable; urgency=low
+
+ * New upstream release. Closes: #38704
+ * Upstream fixes ospfd documentary inconsistency. Closes: #347897
+ * Changed debconf question in prerm to "high" (thanks to Rafal Pietrak).
+
+ -- Christian Hammers <ch@debian.org> Mon, 11 Sep 2006 23:43:42 +0200
+
+quagga (0.99.4-4) unstable; urgency=low
+
+ * Recreate /var/run if not present because /var is e.g. on a tmpfs
+ filesystem (thanks to Martin Pitt). Closes: #376142
+ * Removed nonexistant option from ospfd.8 manpage (thanks to
+ David Medberry). Closes: 378274
+
+ -- Christian Hammers <ch@debian.org> Sat, 15 Jul 2006 20:22:12 +0200
+
+quagga (0.99.4-3) unstable; urgency=low
+
+ * Removed invalid semicolon from rules file (thanks to Philippe Gramoulle).
+
+ -- Christian Hammers <ch@debian.org> Tue, 27 Jun 2006 23:36:07 +0200
+
+quagga (0.99.4-2) unstable; urgency=high
+
+ * Set urgency to high as 0.99.4-1 fixes a security problem!
+ * Fixed building of the info file.
+
+ -- Christian Hammers <ch@debian.org> Sun, 14 May 2006 23:04:28 +0200
+
+quagga (0.99.4-1) unstable; urgency=low
+
+ * New upstream release to fix a security problem in the telnet interface
+ of the BGP daemon which could be used for DoS attacks (CVE-2006-2276).
+ Closes: 366980
+
+ -- Christian Hammers <ch@debian.org> Sat, 13 May 2006 19:54:40 +0200
+
+quagga (0.99.3-3) unstable; urgency=low
+
+ * Added CVE numbers for the security patch in 0.99.3-2.
+
+ -- Christian Hammers <ch@debian.org> Sat, 6 May 2006 17:14:22 +0200
+
+quagga (0.99.3-2) unstable; urgency=high
+
+ * SECURITY:
+ Added security bugfix patch from upstream BTS for security problem
+ that could lead to injected routes when using RIPv1.
+ CVE-2006-2223 - missing configuration to disable RIPv1 or require
+ plaintext or MD5 authentication
+ CVE-2006-2224 - lack of enforcement of RIPv2 authentication requirements
+ Closes: #365940
+ * First amd64 upload.
+
+ -- Christian Hammers <ch@debian.org> Thu, 4 May 2006 00:22:09 +0200
+
+quagga (0.99.3-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Christian Hammers <ch@debian.org> Wed, 25 Jan 2006 13:37:27 +0100
+
+quagga (0.99.2-1) unstable; urgency=low
+
+ * New upstream release
+ Closes: #330248, #175553
+
+ -- Christian Hammers <ch@debian.org> Wed, 16 Nov 2005 00:25:52 +0100
+
+quagga (0.99.1-7) unstable; urgency=low
+
+ * Changed debian/rules check for mounted /proc directory to check
+ for /proc/1 as not all systems (e.g. 2.6 arm kernels) have
+ /proc/kcore which is a optional feature only (thanks to Lennert
+ Buytenhek). Closes: #335695
+ * Added Swedish Debconf translation (thanks to Daniel Nylander).
+ Closes: #331367
+
+ -- Christian Hammers <ch@debian.org> Thu, 27 Oct 2005 20:53:19 +0200
+
+quagga (0.99.1-6) unstable; urgency=low
+
+ * Fixed debconf dependency as requested by Joey Hess.
+
+ -- Christian Hammers <ch@debian.org> Mon, 26 Sep 2005 20:47:35 +0200
+
+quagga (0.99.1-5) unstable; urgency=low
+
+ * Rebuild with libreadline5-dev as build-dep as requested by
+ Matthias Klose. Closes: #326306
+ * Made initscript more fault tolerant against missing lines in
+ /etc/quagga/daemons (thanks to Ralf Hildebrandt). Closes: #323774
+ * Added dependency to adduser.
+
+ -- Christian Hammers <ch@debian.org> Tue, 13 Sep 2005 21:42:17 +0200
+
+quagga (0.99.1-4) unstable; urgency=low
+
+ * Added French Debconf translation (thanks to Mohammed Adnene Trojette).
+ Closes: #319324
+ * Added Czech Debconf translation (thanks to Miroslav Kure).
+ Closes: #318127
+
+ -- Christian Hammers <ch@debian.org> Sun, 31 Jul 2005 04:19:41 +0200
+
+quagga (0.99.1-3) unstable; urgency=low
+
+ * A Debconf question now asks the admin before upgrading if the daemon
+ should really be stopped as this could lead to the loss of network
+ connectivity or BGP flaps (thanks to Michael Horn and Achilleas Kotsis).
+ Also added a hint about setting Quagga "on hold" to README.Debian.
+ Closes: #315467
+ * Added patch to build on Linux/ARM.
+
+ -- Christian Hammers <ch@debian.org> Sun, 10 Jul 2005 22:19:38 +0200
+
+quagga (0.99.1-2) unstable; urgency=low
+
+ * Fixed SNMP enabled command in debian/rules (thanks to Christoph Kluenter).
+ Closes: #306840
+
+ -- Christian Hammers <ch@debian.org> Sat, 4 Jun 2005 14:04:01 +0200
+
+quagga (0.99.1-1) unstable; urgency=low
+
+ * New upstream version. Among others:
+ - BGP graceful restart and "match ip route-source" added
+ - support for interface renaming
+ - improved threading for better responsivness under load
+ * Switched to dpatch to make diffs cleaner.
+ * Made autoreconf unnecessary.
+ * Replaced quagga.dvi and quagga.ps by quagga.pdf in quagga-doc.
+ (the PostScript would have needed Makefile corrections and PDF
+ is more preferable anyway)
+ * Added isisd to the list of daemons in /etc/init.d/quagga (thanks
+ to Ernesto Elbe).
+ * Added hint for "netlink-listen: overrun" messages (thanks to
+ Hasso Tepper).
+ * Added preinst check that bails out if old smux options are in use
+ as Quagga would not start up else anyway (thanks to Bjorn Mork).
+ Closes: #308320
+
+ -- Christian Hammers <ch@debian.org> Fri, 13 May 2005 01:18:24 +0200
+
+quagga (0.98.3-7) unstable; urgency=high
+
+ * Removed SNMP support as linking against NetSNMP introduced a dependency
+ to OpenSSL which is not compatible to the GPL which governs this
+ application (thanks to Faidon Liambotis). See README.Debian for more
+ information. Closes: #306840
+ * Changed listening address of ospf6d and ripngd from 127.0.0.1 to "::1".
+ * Added build-dep to groff to let drafz-zebra-00.txt build correctly.
+
+ -- Christian Hammers <ch@debian.org> Wed, 4 May 2005 20:08:14 +0200
+
+quagga (0.98.3-6) testing-proposed-updates; urgency=high
+
+ * Removed "Recommends kernel-image-2.4" as aptitude then
+ installes a kernel-image for an arbitrary architecture as long
+ as it fullfill that recommendation which can obviously fatal
+ at the next reboot :) Also it is a violation of the policy
+ which mandates a reference to real packages (thanks to Holger Levsen).
+ Closes: #307281
+
+ -- Christian Hammers <ch@debian.org> Tue, 3 May 2005 22:53:39 +0200
+
+quagga (0.98.3-5) unstable; urgency=high
+
+ * The patch which tried to remove the OpenSSL dependency, which is
+ not only unneccessary but also a violation of the licence and thus RC,
+ stopped working a while ago, since autoreconf is no longer run before
+ building the binaries. So now ./configure is patched directly (thanks
+ to Faidon Liambotis for reporting). Closes: #306840
+ * Raised Debhelper compatibility level from 3 to 4. Nothing changed.
+ * Added build-dep to texinfo (>= 4.7) to ease work for www.backports.org.
+
+ -- Christian Hammers <ch@debian.org> Fri, 29 Apr 2005 02:31:03 +0200
+
+quagga (0.98.3-4) unstable; urgency=low
+
+ * Removed Debconf upgrade note as it was considered a Debconf abuse
+ and apart from that so obvious that it was not even worth to be
+ put into NEWS.Debian (thanks to Steve Langasek). Closes: #306384
+
+ -- Christian Hammers <ch@debian.org> Wed, 27 Apr 2005 00:10:24 +0200
+
+quagga (0.98.3-3) unstable; urgency=medium
+
+ * Adding the debconf module due to a lintian suggestion is a very
+ bad idea if no db_stop is called as the script hangs then (thanks
+ to Tore Anderson for reporting). Closes: #306324
+
+ -- Christian Hammers <ch@debian.org> Mon, 25 Apr 2005 21:55:58 +0200
+
+quagga (0.98.3-2) unstable; urgency=low
+
+ * Added debconf confmodule to postinst as lintian suggested.
+
+ -- Christian Hammers <ch@debian.org> Sun, 24 Apr 2005 13:16:00 +0200
+
+quagga (0.98.3-1) unstable; urgency=low
+
+ * New upstream release.
+ Mmost notably fixes last regression in bgpd (reannounce of prefixes
+ with changed attributes works again), race condition in netlink
+ handling while using IPv6, MTU changes handling in ospfd and several
+ crashes in ospfd, bgpd and ospf6d.
+
+ -- Christian Hammers <ch@debian.org> Mon, 4 Apr 2005 12:51:24 +0200
+
+quagga (0.98.2-2) unstable; urgency=low
+
+ * Added patch to let Quagga compile with gcc-4.0 (thanks to
+ Andreas Jochens). Closes: #300949
+
+ -- Christian Hammers <ch@debian.org> Fri, 25 Mar 2005 19:33:30 +0100
+
+quagga (0.98.2-1) unstable; urgency=medium
+
+ * Quoting the upstream announcement:
+ The 0.98.1 release unfortunately was a brown paper bag release with
+ respect to ospfd. [...] 0.98.2 has been released, with one crucial change
+ to fix the unfortunate mistake in 0.98.1, which caused problems if
+ ospfd became DR.
+ * Note: the upstream tarball had a strange problem, apparently redhat.spec
+ was twice in it? At least debuild gave a strange error message so I
+ unpacked it by hand. No changes were made to the .orig.tar.gz!
+
+ -- Christian Hammers <ch@debian.org> Fri, 4 Feb 2005 01:31:36 +0100
+
+quagga (0.98.1-1) unstable; urgency=medium
+
+ * New upstream version
+ "fixing a fatal OSPF + MD5 auth regression, and a non-fatal high-load
+ regression in bgpd which were present in the 0.98.0 release."
+ * Upstream version fixes bug in ospfd that could lead to crash when OSPF
+ packages had a MTU > 1500. Closes: #290566
+ * Added notice regarding capability kernel support to README.Debian
+ (thanks to Florian Weimer). Closes: #291509
+ * Changed permission setting in postinst script (thanks to Bastian Blank).
+ Closes: #292690
+
+ -- Christian Hammers <ch@debian.org> Tue, 1 Feb 2005 02:01:27 +0100
+
+quagga (0.98.0-3) unstable; urgency=low
+
+ * Fixed problem in init script. Closes: #290317
+ * Removed obsolete "smux peer enable" patch.
+
+ -- Christian Hammers <ch@debian.org> Fri, 14 Jan 2005 17:37:27 +0100
+
+quagga (0.98.0-2) unstable; urgency=low
+
+ * Updated broken TCP MD5 patch for BGP (thanks to John P. Looney
+ for telling me).
+
+ -- Christian Hammers <ch@debian.org> Thu, 13 Jan 2005 02:03:54 +0100
+
+quagga (0.98.0-1) unstable; urgency=low
+
+ * New upstream release
+ * Added kernel-image-2.6 as alternative to 2.4 to the recommends
+ (thanks to Faidon Liambotis). Closes: #289530
+
+ -- Christian Hammers <ch@debian.org> Mon, 10 Jan 2005 19:36:17 +0100
+
+quagga (0.97.5-1) unstable; urgency=low
+
+ * New upstream version.
+ * Added Czech debconf translation (thanks to Miroslav Kure).
+ Closes: #287293
+ * Added Brazilian debconf translation (thanks to Andre Luis Lopes).
+ Closes: #279352
+
+ -- Christian Hammers <ch@debian.org> Wed, 5 Jan 2005 23:49:57 +0100
+
+quagga (0.97.4-2) unstable; urgency=low
+
+ * Fixed quagga.info build problem.
+
+ -- Christian Hammers <ch@debian.org> Wed, 5 Jan 2005 22:38:01 +0100
+
+quagga (0.97.4-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Hammers <ch@debian.org> Tue, 4 Jan 2005 01:45:22 +0100
+
+quagga (0.97.3-2) unstable; urgency=low
+
+ * Included isisd in the daemon list.
+ * Wrote an isisd manpage.
+ * It is now ensured that zebra is always the last daemon to be stopped.
+ * (Thanks to Hasso Tepper for mailing me a long list of suggestions
+ which lead to this release)
+
+ -- Christian Hammers <ch@debian.org> Sat, 18 Dec 2004 13:14:55 +0100
+
+quagga (0.97.3-1) unstable; urgency=medium
+
+ * New upstream version.
+ - Fixes important OSPF bug.
+ * Added ht-20040911-smux.patch regarding Quagga bug #112.
+ * Updated ht-20041109-0.97.3-bgp-md5.patch for BGP with TCP MD5
+ (thanks to Matthias Wamser).
+
+ -- Christian Hammers <ch@debian.org> Tue, 9 Nov 2004 17:45:26 +0100
+
+quagga (0.97.2-4) unstable; urgency=low
+
+ * Added Portuguese debconf translation (thanks to Andre Luis Lopes).
+ Closes: #279352
+ * Disabled ospfapi server by default on recommendation of Paul Jakma.
+
+ -- Christian Hammers <ch@debian.org> Sun, 7 Nov 2004 15:07:05 +0100
+
+quagga (0.97.2-3) unstable; urgency=low
+
+ * Added Andrew Schorrs VTY Buffer patch from the [quagga-dev 1729].
+
+ -- Christian Hammers <ch@debian.org> Tue, 2 Nov 2004 00:46:56 +0100
+
+quagga (0.97.2-2) unstable; urgency=low
+
+ * Changed file and directory permissions and ownerships according to a
+ suggestion from Paul Jakma. Still not perfect though.
+ * Fixed upstream vtysh.conf.sample file.
+ * "ip ospf network broadcast" is now saved correctly. Closes: #244116
+ * Daemon options are now in /etc/quagga/debian.conf to be user
+ configurable (thanks to Simon Raven and Hasso Tepper). Closes: #266715
+
+ -- Christian Hammers <ch@debian.org> Tue, 26 Oct 2004 23:35:45 +0200
+
+quagga (0.97.2-1) unstable; urgency=low
+
+ * New upstream version.
+ Closes: #254541
+ * Fixed warning on unmodular kernels (thanks to Christoph Biedl).
+ Closes: #277973
+
+ -- Christian Hammers <ch@debian.org> Mon, 25 Oct 2004 00:47:04 +0200
+
+quagga (0.97.1-2) unstable; urgency=low
+
+ * Version 0.97 introduced shared libraries. They are now included.
+ (thanks to Raf D'Halleweyn). Closes: #277446
+
+ -- Christian Hammers <ch@debian.org> Wed, 20 Oct 2004 15:32:06 +0200
+
+quagga (0.97.1-1) unstable; urgency=low
+
+ * New upstream version.
+ * Removed some obsolete files from debian/patches.
+ * Added patch from upstream bug 113. Closes: #254541
+ * Added patch from upstream that fixes a compilation problem in the
+ ospfclient code (thanks to Hasso Tepper).
+ * Updated German debconf translation (thanks to Jens Nachtigall)
+ Closes: #277059
+
+ -- Christian Hammers <ch@debian.org> Mon, 18 Oct 2004 01:16:35 +0200
+
+quagga (0.96.5-11) unstable; urgency=low
+
+ * Fixed /tmp/buildd/* paths in binaries.
+ For some unknown reason the upstream Makefile modified a .h file at
+ the end of the "debian/rules build" target. During the following
+ "make install" one library got thus be re*compiled* - with /tmp/buildd
+ paths as sysconfdir (thanks to Peder Chr. Norgaard). Closes: #274050
+
+ -- Christian Hammers <ch@debian.org> Fri, 1 Oct 2004 01:21:02 +0200
+
+quagga (0.96.5-10) unstable; urgency=medium
+
+ * The BGP routing daemon might freeze on network disturbances when
+ their peer is also a Quagga/Zebra router.
+ Applied patch from http://bugzilla.quagga.net/show_bug.cgi?id=102
+ which has been confirmed by the upstream author.
+ (thanks to Gunther Stammwitz)
+ * Changed --enable-pam to --with-libpam (thanks to Hasso Tepper).
+ Closes: #264562
+ * Added patch for vtysh (thanks to Hasso Tepper). Closes: #215919
+
+ -- Christian Hammers <ch@debian.org> Mon, 9 Aug 2004 15:33:02 +0200
+
+quagga (0.96.5-9) unstable; urgency=low
+
+ * Rewrote the documentation chapter about SNMP support. Closes: #195653
+ * Added MPLS docs.
+
+ -- Christian Hammers <ch@debian.org> Thu, 29 Jul 2004 21:01:52 +0200
+
+quagga (0.96.5-8) unstable; urgency=low
+
+ * Adjusted a grep in the initscript to also match a modprobe message
+ from older modutils packages (thanks to Faidon Paravoid).
+
+ -- Christian Hammers <ch@debian.org> Wed, 28 Jul 2004 21:19:02 +0200
+
+quagga (0.96.5-7) unstable; urgency=low
+
+ * Added a "cd /etc/quagga/" to the init script as quagga tries to load
+ the config file first from the current working dir and then from the
+ config dir which could lead to confusion (thanks to Marco d'Itri).
+ Closes: #255078
+ * Removed warning regarding problems with the Debian kernels from
+ README.Debian as they are no longer valid (thanks to Raphael Hertzog).
+ Closes: #257580
+ * Added patch from Hasso Tepper that makes "terminal length 0" work
+ in vtysh (thanks to Matthias Wamser). Closes: #252579
+
+ -- Christian Hammers <ch@debian.org> Thu, 8 Jul 2004 21:53:21 +0200
+
+quagga (0.96.5-6) unstable; urgency=low
+
+ * Try to load the capability module as it is needed now.
+
+ -- Christian Hammers <ch@debian.org> Tue, 8 Jun 2004 23:25:29 +0200
+
+quagga (0.96.5-5) unstable; urgency=low
+
+ * Changed the homedir of the quagga user to /etc/quagga/ to allow
+ admins to put ~/.ssh/authorized_keys there (thanks to Matthias Wamser).
+ Closes: #252577
+
+ -- Christian Hammers <ch@debian.org> Sat, 5 Jun 2004 14:47:31 +0200
+
+quagga (0.96.5-4) unstable; urgency=medium
+
+ * Fixed rules file to use the renamed ./configure option --enable-tcp-md5
+ (thanks to Matthias Wamser). Closes: #252141
+
+ -- Christian Hammers <ch@debian.org> Tue, 1 Jun 2004 22:58:32 +0200
+
+quagga (0.96.5-3) unstable; urgency=low
+
+ * Provided default binary package name to all build depends that were
+ virtual packages (thanks to Goswin von Brederlow). Closes: #251625
+
+ -- Christian Hammers <ch@debian.org> Sat, 29 May 2004 22:48:53 +0200
+
+quagga (0.96.5-2) unstable; urgency=low
+
+ * New upstream version.
+ * New md5 patch version (thanks to Niklas Jakobsson and Hasso Tepper).
+ Closes: #250985
+ * Fixes info file generation (thanks to Peder Chr. Norgaard).
+ Closes: #250992
+ * Added catalan debconf translation (thanks to Aleix Badia i Bosch).
+ Closes: #250118
+ * PATCHES:
+ This release contains BGP4 MD5 support which requires a kernel patch
+ to work. See /usr/share/doc/quagga/README.Debian.MD5.
+ (The patch is ht-20040525-0.96.5-bgp-md5.patch from Hasso Tepper)
+
+ -- Christian Hammers <ch@debian.org> Thu, 27 May 2004 20:09:37 +0200
+
+quagga (0.96.5-1) unstable; urgency=low
+
+ * New upstream version.
+ * PATCHES:
+ This release contains BGP4 MD5 support which also requires a kernel patch.
+ See /usr/share/doc/quagga/README.Debian.MD5 and search for CAN-2004-0230.
+
+ -- Christian Hammers <ch@debian.org> Sun, 16 May 2004 17:40:40 +0200
+
+quagga (0.96.4x-10) unstable; urgency=low
+
+ * SECURITY:
+ This release contains support for MD5 for BGP which is one suggested
+ prevention of the actually long known TCP SYN/RST attacks which got
+ much news in the last days as ideas were revealed that made them much
+ easier probable agains especially the BGP sessions than commonly known.
+ There are a lot of arguments agains the MD5 approach but some ISPs
+ started to require it.
+ See: CAN-2004-0230, http://www.us-cert.gov/cas/techalerts/TA04-111A.html
+ * PATCHES:
+ This release contains the MD5 patch from Hasso Tepper. It also seems to
+ required a kernel patch. See /usr/share/doc/quagga/README.Debian.MD5.
+
+ -- Christian Hammers <ch@debian.org> Thu, 29 Apr 2004 01:01:38 +0200
+
+quagga (0.96.4x-9) unstable; urgency=low
+
+ * Fixed daemon loading order (thanks to Matt Kemner).
+ * Fixed typo in init script (thanks to Charlie Brett). Closes: #238582
+
+ -- Christian Hammers <ch@debian.org> Sun, 4 Apr 2004 15:32:18 +0200
+
+quagga (0.96.4x-8) unstable; urgency=low
+
+ * Patched upstream source so that quagga header files end up in
+ /usr/include/quagga/. Closes: #233792
+
+ -- Christian Hammers <ch@debian.org> Mon, 23 Feb 2004 01:42:53 +0100
+
+quagga (0.96.4x-7) unstable; urgency=low
+
+ * Fixed info file installation (thanks to Holger Dietze). Closes: #227579
+ * Added Japanese translation (thanks to Hideki Yamane). Closes: #227812
+
+ -- Christian Hammers <ch@debian.org> Sun, 18 Jan 2004 17:28:29 +0100
+
+quagga (0.96.4x-6) unstable; urgency=low
+
+ * Added dependency to iproute.
+ * Initscript now checks not only for the pid file but also for the
+ daemons presence (thanks to Phil Gregory). Closes: #224389
+ * Added my patch to configure file permissions.
+
+ -- Christian Hammers <ch@debian.org> Mon, 15 Dec 2003 22:34:29 +0100
+
+quagga (0.96.4x-5) unstable; urgency=low
+
+ * Added patch which gives bgpd the CAP_NET_RAW capability to allow it
+ to bind to special IPv6 link-local interfaces (Thanks to Bastian Blank).
+ Closes: #222930
+ * Made woody backport easier by applying Colin Watsons po-debconf hack.
+ Thanks to Marc Haber for suggesting it. Closes: #223527
+ * Made woody backport easier by applying a patch that removes some
+ obscure whitespaces inside an C macro. (Thanks to Marc Haber).
+ Closes: #223529
+ * Now uses /usr/bin/pager. Closes: #204070
+ * Added note about the "official woody backports" on my homepage.
+
+ -- Christian Hammers <ch@debian.org> Mon, 15 Dec 2003 20:39:06 +0100
+
+quagga (0.96.4x-4) unstable; urgency=high
+
+ * SECURITY:
+ Fixes another bug that was originally reported against Zebra.
+ .
+ http://rhn.redhat.com/errata/RHSA-2003-307.html
+ Herbert Xu reported that Zebra can accept spoofed messages sent on the
+ kernel netlink interface by other users on the local machine. This could
+ lead to a local denial of service attack. The Common Vulnerabilities and
+ Exposures project (cve.mitre.org) has assigned the name CAN-2003-0858 to
+ this issue.
+
+ * Minor improvements to init script (thanks to Iustin Pop).
+ Closes: #220938
+
+ -- Christian Hammers <ch@debian.org> Sat, 22 Nov 2003 13:27:57 +0100
+
+quagga (0.96.4x-3) unstable; urgency=low
+
+ * Changed "more" to "/usr/bin/pager" as default pager if $PAGER or
+ $VTYSH_PAGER is not set (thanks to Bastian Blank). Closes: #204070
+ * Made the directory (but not the config/log files!) world accessible
+ again on user request (thanks to Anand Kumria)). Closes: #213129
+ * No longer providing sample configuration in /etc/quagga/. They are
+ now only available in /usr/share/doc/quagga/ to avoid accidently
+ using them without changing the adresses (thanks to Marc Haber).
+ Closes: #215918
+
+ -- Christian Hammers <ch@debian.org> Sun, 16 Nov 2003 16:59:30 +0100
+
+quagga (0.96.4x-2) unstable; urgency=low
+
+ * Fixed permission problem with pidfile (thanks to Kir Kostuchenko).
+ Closes: #220938
+
+ -- Christian Hammers <ch@debian.org> Sun, 16 Nov 2003 14:24:08 +0100
+
+quagga (0.96.4x-1) unstable; urgency=low
+
+ * Reupload of 0.96.4. Last upload-in-a-hurry produced a totally
+ crappy .tar.gz file. Closes: #220621
+
+ -- Christian Hammers <ch@debian.org> Fri, 14 Nov 2003 19:45:57 +0100
+
+quagga (0.96.4-1) unstable; urgency=high
+
+ * SECURITY: Remote DoS of protocol daemons.
+ Fix for a remote triggerable crash in vty layer. The management
+ ports ("telnet myrouter ospfd") should not be open to the internet!
+
+ * New upstream version.
+ - OSPF bugfixes.
+ - Some improvements for bgp and rip.
+
+ -- Christian Hammers <ch@debian.org> Thu, 13 Nov 2003 11:52:27 +0100
+
+quagga (0.96.3-3) unstable; urgency=low
+
+ * Fixed pid file generation by substituting the daemons "-d" by the
+ start-stop-daemon option "--background" (thanks to Micha Gaisser).
+ Closes: #218103
+
+ -- Christian Hammers <ch@debian.org> Wed, 29 Oct 2003 05:17:49 +0100
+
+quagga (0.96.3-2) unstable; urgency=low
+
+ * Readded GNOME-PRODUCT-ZEBRA-MIB.
+
+ -- Christian Hammers <ch@debian.org> Thu, 23 Oct 2003 06:17:03 +0200
+
+quagga (0.96.3-1) unstable; urgency=medium
+
+ * New upstream version.
+ * Removed -u and -e in postrm due to problems with debhelper and userdel
+ (thanks to Adam Majer and Jaakko Niemi). Closes: #216770
+ * Removed SNMP MIBs as they are now included in libsnmp-base (thanks to
+ David Engel and Peter Gervai). Closes: #216138, #216086
+ * Fixed seq command in init script (thanks to Marc Haber). Closes: #215915
+ * Improved /proc check (thanks to Marc Haber). Closes: #212331
+
+ -- Christian Hammers <ch@debian.org> Thu, 23 Oct 2003 03:42:02 +0200
+
+quagga (0.96.2-9) unstable; urgency=medium
+
+ * Removed /usr/share/info/dir.* which were accidently there and prevented
+ the installation by dpkg (thanks to Simon Raven). Closes: #212614
+ * Reworded package description (thanks to Anand Kumria). Closes: #213125
+ * Added french debconf translation (thanks to Christian Perrier).
+ Closes: #212803
+
+ -- Christian Hammers <ch@debian.org> Tue, 7 Oct 2003 13:26:58 +0200
+
+quagga (0.96.2-8) unstable; urgency=low
+
+ * debian/rules now checks if /proc is mounted as ./configure needs
+ it but just fails with an obscure error message if it is absent.
+ (Thanks to Norbert Tretkowski). Closes: #212331
+
+ -- Christian Hammers <ch@debian.org> Tue, 23 Sep 2003 12:57:38 +0200
+
+quagga (0.96.2-7) unstable; urgency=low
+
+ * Last build was rejected due to a buggy dpkg-dev version. Rebuild.
+
+ -- Christian Hammers <ch@debian.org> Mon, 22 Sep 2003 20:34:12 +0200
+
+quagga (0.96.2-6) unstable; urgency=low
+
+ * Fixed init script so that is is now possible to just start
+ the bgpd but not the zebra daemon. Also daemons are now actually
+ started in the order defined their priority. (Thanks to Thomas Kaehn
+ and Jochen Friedrich) Closes: #210924
+
+ -- Christian Hammers <ch@debian.org> Fri, 19 Sep 2003 21:17:02 +0200
+
+quagga (0.96.2-5) unstable; urgency=low
+
+ * For using quagga as BGP route server or similar, it is not
+ wanted to have the zebra daemon running too. For this reason
+ it can now be disabled in /etc/quagga/daemons, too.
+ (Thanks to Jochen Friedrich). Closes: #210924
+ * Attached *unapplied* patch for the ISIS protocol. I did not dare
+ to apply it as long as upstream does not do it but this way give
+ users the possibilities to use it if they like to.
+ (Thanks to Remco van Mook)
+
+ -- Christian Hammers <ch@debian.org> Wed, 17 Sep 2003 19:57:31 +0200
+
+quagga (0.96.2-4) unstable; urgency=low
+
+ * Enabled IPV6 router advertisement feature by default on user request
+ (thanks to Jochen Friedrich and Hasso Tepper). Closes: #210732
+ * Updated GNU autoconf to let it build on hppa/parisc64 (thanks to
+ lamont). Closes: #210492
+
+ -- Christian Hammers <ch@debian.org> Sat, 13 Sep 2003 14:11:13 +0200
+
+quagga (0.96.2-3) unstable; urgency=medium
+
+ * Removed unnecessary "-lcrypto" to avoid dependency against OpenSSL
+ which would require further copyright addtions.
+
+ -- Christian Hammers <ch@debian.org> Wed, 10 Sep 2003 01:37:28 +0200
+
+quagga (0.96.2-2) unstable; urgency=low
+
+ * Added note that config files of quagga are in /etc/quagga and
+ not /etc/zebra for the zebra users that migrate to quagga.
+ (Thanks to Roberto Suarez Soto for the idea)
+ * Fixed setgid rights in /etc/quagga.
+
+ -- Christian Hammers <ch@debian.org> Wed, 27 Aug 2003 14:05:39 +0200
+
+quagga (0.96.2-1) unstable; urgency=low
+
+ * This package has formally been known as "zebra-pj"!
+ * New upstream release.
+ Fixes "anoying OSPF problem".
+ * Modified group ownerships so that vtysh can now be used by normal
+ uses if they are in the quaggavty group.
+
+ -- Christian Hammers <ch@debian.org> Mon, 25 Aug 2003 23:40:14 +0200
+
+quagga (0.96.1-1) unstable; urgency=low
+
+ * Zebra-pj, the fork of zebra has been renamed to quagga as the original
+ upstream author asked the new project membed not to use "zebra" in the
+ name. zebra-pj is obsolete.
+
+ -- Christian Hammers <ch@debian.org> Mon, 18 Aug 2003 23:37:20 +0200
+
+zebra-pj (0.94+cvs20030721-1) unstable; urgency=low
+
+ * New CVS build.
+ - OSPF changes (integration of the OSPF API?)
+ - code cleanups (for ipv6?)
+ * Tightened Build-Deps to gcc-2.95 as 3.x does not compile a stable ospfd.
+ This is a known problem and has been discussed on the mailing list.
+ No other solutions so far.
+
+ -- Christian Hammers <ch@debian.org> Mon, 21 Jul 2003 23:52:00 +0200
+
+zebra-pj (0.94+cvs20030701-1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- Christian Hammers <ch@debian.org> Tue, 1 Jul 2003 01:58:06 +0200
diff --git a/debian/gbp.conf b/debian/gbp.conf
index 990c4d226e..23917b9b8f 100644
--- a/debian/gbp.conf
+++ b/debian/gbp.conf
@@ -1,4 +1,4 @@
[DEFAULT]
pristine-tar = False
debian-branch = master
-upstream-tree=SLOPPY
+upstream-tree = SLOPPY
diff --git a/debian/tests/py-frr-reload b/debian/tests/py-frr-reload
index e2c97e8744..6dfef33f08 100755
--- a/debian/tests/py-frr-reload
+++ b/debian/tests/py-frr-reload
@@ -22,7 +22,15 @@ sed -e '/^ip route 198.51.100.0\/28 127.0.0.1/ c ip route 198.51.100.64/28 127.0
service frr reload
-vtysh -c 'show running-config' | grep -q 'ip route 198.51.100.64/28 127.0.0.1'
+# wait for the new config to load
+for __t in $(seq 1 10); do
+ if vtysh -c 'show running-config' | grep -q 'ip route 198.51.100.64/28 127.0.0.1'; then
+ break
+ fi
+ sleep "$__t"
+done
+
+# fail if the old config is still loaded
if vtysh -c 'show running-config' | grep -q 'ip route 198.51.100.0/28 127.0.0.1'; then
exit 1
fi
diff --git a/doc/developer/frr-release-procedure.rst b/doc/developer/frr-release-procedure.rst
index 5da73f61f6..08e3057ae6 100644
--- a/doc/developer/frr-release-procedure.rst
+++ b/doc/developer/frr-release-procedure.rst
@@ -49,23 +49,14 @@ FRR Release Procedure
5. Update Changelog for Debian Packages:
- Edit :file:`changelog-auto.in`:
+ Update :file:`debian/changelog`:
- - Change last (top of list) entry from ``@VERSION@`` to the **last**
- released version number. For example, if ``<version>`` is ``7.3`` and the
- last public release was ``7.2``, you would use ``7.2``, changing the file
- like so::
+ - Run following with **last** release version number and debian revision
+ (usually -1) as argument to ``dch --newversion VERSION``. For example, if
+ ``<version>`` is ``7.3`` then you will run ``dch --newversion 7.3-1``.
- frr (@VERSION@) RELEASED; urgency=medium
-
- to::
-
- frr (7.2) RELEASED; urgency=medium
-
- - Add a new entry to the top of the list with a ``@VERSION@`` tag. Make sure
- to watch the format.
-
- - Add the changelog text below this entry.
+ - The ``dch`` will run an editor, and you should add the changelog text below
+ this entry, usually that would be: **New upstream version**.
- Verify the changelog format using ``dpkg-parsechangelog``. In the
repository root:
diff --git a/doc/developer/packaging-debian.rst b/doc/developer/packaging-debian.rst
index b57286d5a1..968e960267 100644
--- a/doc/developer/packaging-debian.rst
+++ b/doc/developer/packaging-debian.rst
@@ -30,28 +30,25 @@ buster.)
.. code-block:: shell
- sudo mk-build-deps --install debian/control
+ sudo mk-build-deps --install --remove debian/control
Alternatively, you can manually install build dependencies for your
platform as outlined in :ref:`building`.
-4. Run ``tools/tarsource.sh -V``:
+4. Install `git-buildpackage` package:
.. code-block:: shell
- ./tools/tarsource.sh -V
-
- This script sets up the ``debian/changelog-auto`` file with proper version
- information.
+ sudo apt-get install git-buildpackage
5. (optional) Append a distribution identifier if needed (see below under
:ref:`multi-dist`.)
-6. Build Debian Package:
+6. Build Debian Binary and/or Source Packages:
.. code-block:: shell
- dpkg-buildpackage $options
+ gbp buildpackage --git-builder=dpkg-buildpackage --git-debian-branch="$(git rev-parse --abbrev-ref HEAD)" $options
Where `$options` may contain any or all of the following items:
@@ -81,6 +78,18 @@ buster.)
(git builds of the `master` or `stable/X.X` branches won't be signed by
default since their target release is set to ``UNRELEASED``.)
+ * the ``--build=type`` accepts following options (see ``dpkg-buildpackage`` manual page):
+
+ * ``source`` builds the source package
+ * ``any`` builds the architecture specific binary packages
+ * ``all`` build the architecture independent binary packages
+ * ``binary`` build the architecture specific and independent binary packages (alias for ``any,all``)
+ * ``full`` builds everything (alias for ``source,any,all``)
+
+ Alternatively, you might want to replace ``dpkg-buildpackage`` with
+ ``debuild`` wrapper that also runs ``lintian`` and ``debsign`` on the final
+ packages.
+
7. Done!
If all worked correctly, then you should end up with the Debian packages in
@@ -97,12 +106,6 @@ buster.)
a manually maintained changelog that contains proper Debian release
versioning.
- Furthermore, official Debian packages are built in ``3.0 (quilt)`` format
- with an "orig" tarball and a "debian" tarball. These tarballs are created
- by the ``tarsource.sh`` tool on any branch. The git repository however
- contains a ``3.0 (git)`` source format specifier to easily allow direct
- git builds.
-
.. _multi-dist:
@@ -111,7 +114,6 @@ Multi-Distribution builds
You can optionally append a distribution identifier in case you want to
make multiple versions of the package available in the same repository.
-Do the following after creating the changelog with `tarsource.sh`:
.. code-block:: shell
diff --git a/doc/developer/scripting.rst b/doc/developer/scripting.rst
index 708f65ff7d..1757d41feb 100644
--- a/doc/developer/scripting.rst
+++ b/doc/developer/scripting.rst
@@ -135,24 +135,20 @@ A typical execution call looks something like this:
int status_ok = 0, status_fail = 1;
struct prefix p = ...;
- struct frrscript_env env[] = {
- {"integer", "STATUS_FAIL", &status_fail},
- {"integer", "STATUS_OK", &status_ok},
- {"prefix", "myprefix", &p},
- {}};
-
- int result = frrscript_call(fs, env);
+ int result = frrscript_call(fs,
+ ("STATUS_FAIL", &status_fail),
+ ("STATUS_OK", &status_ok),
+ ("prefix", &p));
To execute a loaded script, we need to define the inputs. These inputs are
-passed by binding values to variable names that will be accessible within the
+passed in by binding values to variable names that will be accessible within the
Lua environment. Basically, all communication with the script takes place via
global variables within the script, and to provide inputs we predefine globals
-before the script runs. This is done by passing ``frrscript_call()`` an array
-of ``struct frrscript_env``. Each struct has three fields. The first identifies
-the type of the value being passed; more on this later. The second defines the
-name of the global variable within the script environment to bind the third
-argument (the value) to.
+before the script runs. This is done by passing ``frrscript_call()`` a list of
+parenthesized pairs, where the first and second fields identify, respectively,
+the name of the global variable within the script environment and the value it
+is bound to.
The script is then executed and returns a general status code. In the success
case this will be 0, otherwise it will be nonzero. The script itself does not
@@ -162,32 +158,10 @@ determine this code, it is provided by the Lua interpreter.
Querying State
^^^^^^^^^^^^^^
-When a chunk is executed, its state at exit is preserved and can be inspected.
-
-After running a script, results may be retrieved by querying the script's
-state. Again this is done by retrieving the values of global variables, which
-are known to the script author to be "output" variables.
-
-A result is retrieved like so:
-
-.. code-block:: c
-
- struct frrscript_env myresult = {"string", "myresult"};
-
- char *myresult = frrscript_get_result(fs, &myresult);
-
- ... do something ...
-
- XFREE(MTYPE_TMP, myresult);
-
+.. todo::
-As with arguments, results are retrieved by providing a ``struct
-frrscript_env`` specifying a type and a global name. No value is necessary, nor
-is it modified by ``frrscript_get_result()``. That function simply extracts the
-requested value from the script state and returns it.
-
-In most cases the returned value will be allocated with ``MTYPE_TMP`` and will
-need to be freed after use.
+ This section will be updated once ``frrscript_get_result`` has been
+ updated to work with the new ``frrscript_call`` and the rest of the new API.
Unloading
@@ -199,21 +173,14 @@ To destroy a script and its associated state:
frrscript_unload(fs);
-Values returned by ``frrscript_get_result`` are still valid after the script
-they were retrieved from is unloaded.
-
-Note that you must unload and then load the script if you want to reset its
-state, for example to run it again with different inputs. Otherwise the state
-from the previous run carries over into subsequent runs.
-
.. _marshalling:
Marshalling
^^^^^^^^^^^
-Earlier sections glossed over the meaning of the type name field in ``struct
-frrscript_env`` and how data is passed between C and Lua. Lua, as a dynamically
+Earlier sections glossed over the types of values that can be passed into
+``frrscript_call`` and how data is passed between C and Lua. Lua, as a dynamically
typed, garbage collected language, cannot directly use C values without some
kind of marshalling / unmarshalling system to translate types between the two
runtimes.
@@ -222,31 +189,10 @@ Lua communicates with C code using a stack. C code wishing to provide data to
Lua scripts must provide a function that marshalls the C data into a Lua
representation and pushes it on the stack. C code wishing to retrieve data from
Lua must provide a corresponding unmarshalling function that retrieves a Lua
-value from the stack and converts it to the corresponding C type. These two
-functions, together with a chosen name of the type they operate on, are
-referred to as ``codecs`` in FRR.
-
-A codec is defined as:
-
-.. code-block:: c
-
- typedef void (*encoder_func)(lua_State *, const void *);
- typedef void *(*decoder_func)(lua_State *, int);
-
- struct frrscript_codec {
- const char *typename;
- encoder_func encoder;
- decoder_func decoder;
- };
+value from the stack and converts it to the corresponding C type. These
+functions are known as encoders and decoders in FRR.
-A typename string and two function pointers.
-
-``typename`` can be anything you want. For example, for the combined types of
-``struct prefix`` and its equivalent in Lua I have chosen the name ``prefix``.
-There is no restriction on naming here, it is just a human name used as a key
-and specified when passing and retrieving values.
-
-``encoder`` is a function that takes a ``lua_State *`` and a C type and pushes
+An encoder is a function that takes a ``lua_State *`` and a C type and pushes
onto the Lua stack a value representing the C type. For C structs, the usual
case, this will typically be a Lua table (tables are the only datastructure Lua
has). For example, here is the encoder function for ``struct prefix``:
@@ -254,7 +200,7 @@ has). For example, here is the encoder function for ``struct prefix``:
.. code-block:: c
- void lua_pushprefix(lua_State *L, const struct prefix *prefix)
+ void lua_pushprefix(lua_State *L, struct prefix *prefix)
{
char buffer[PREFIX_STRLEN];
@@ -269,17 +215,48 @@ has). For example, here is the encoder function for ``struct prefix``:
lua_setfield(L, -2, "family");
}
-This function pushes a single value onto the Lua stack. It is a table whose equivalent in Lua is:
+This function pushes a single value onto the Lua stack. It is a table whose
+equivalent in Lua is:
.. code-block:: c
{ ["network"] = "1.2.3.4/24", ["prefixlen"] = 24, ["family"] = 2 }
-``decoder`` does the reverse; it takes a ``lua_State *`` and an index into the
-stack, and unmarshalls a Lua value there into the corresponding C type. Again
-for ``struct prefix``:
+Decoders are a bit more involved. They do the reverse; a decoder function takes
+a ``lua_State *``, pops a value off the Lua stack and converts it back into its
+C type.
+However, since Lua programs have the ability to directly modify their inputs
+(i.e. values passed in via ``frrscript_call``), we need two separate decoder
+functions, called ``lua_decode_*`` and ``lua_to*``.
+A ``lua_decode_*`` function takes a ``lua_State*``, an index, and a C type, and
+unmarshalls a Lua value into that C type.
+Again, for ``struct prefix``:
+
+.. code-block:: c
+
+ void lua_decode_prefix(lua_State *L, int idx, struct prefix *prefix)
+ {
+ lua_getfield(L, idx, "network");
+ (void)str2prefix(lua_tostring(L, -1), prefix);
+ lua_pop(L, 1);
+ /* pop the table */
+ lua_pop(L, 1);
+ }
+
+.. warning::
+
+ ``lua_decode_prefix`` functions should leave the Lua stack completely empty
+ when they return.
+ For decoders that unmarshall fields from tables, remember to pop the table
+ at the end.
+
+
+A ``lua_to*`` function perform a similar role except that it first allocates
+memory for the new C type before decoding the value from the Lua stack, then
+returns a pointer to the newly allocated C type.
+This function can and should be implemented using ``lua_decode_*``:
.. code-block:: c
@@ -287,39 +264,70 @@ for ``struct prefix``:
{
struct prefix *p = XCALLOC(MTYPE_TMP, sizeof(struct prefix));
- lua_getfield(L, idx, "network");
- str2prefix(lua_tostring(L, -1), p);
- lua_pop(L, 1);
-
+ lua_decode_prefix(L, idx, p);
return p;
}
-By convention these functions should be called ``lua_to*``, as this is the
-naming convention used by the Lua C library for the basic types e.g.
-``lua_tointeger`` and ``lua_tostring``.
The returned data must always be copied off the stack and the copy must be
allocated with ``MTYPE_TMP``. This way it is possible to unload the script
(destroy the state) without invalidating any references to values stored in it.
+Note that it is the caller's responsibility to free the data.
-To register a new type with its corresponding encoding functions:
-
-.. code-block:: c
-
- struct frrscript_codec frrscript_codecs_lib[] = {
- {.typename = "prefix",
- .encoder = (encoder_func)lua_pushprefix,
- .decoder = lua_toprefix},
- {.typename = "sockunion",
- .encoder = (encoder_func)lua_pushsockunion,
- .decoder = lua_tosockunion},
- ...
- {}};
+For consistency, we should always name functions of the first type
+``lua_decode_*``.
+Functions of the second type should be named ``lua_to*``, as this is the
+naming convention used by the Lua C library for the basic types e.g.
+``lua_tointeger`` and ``lua_tostring``.
- frrscript_register_type_codecs(frrscript_codecs_lib);
+This two-function design allows the compiler to warn if a value passed into
+``frrscript_call`` does not have a encoder and decoder for that type.
+The ``lua_to*`` functions enable us to easily create decoders for nested
+structures.
+
+To register a new type with its corresponding encoding and decoding functions,
+add the mapping in the following macros in ``frrscript.h``:
+
+.. code-block:: diff
+
+ #define ENCODE_ARGS_WITH_STATE(L, value) \
+ _Generic((value), \
+ ...
+ - struct peer * : lua_pushpeer \
+ + struct peer * : lua_pushpeer, \
+ + struct prefix * : lua_pushprefix \
+ )(L, value)
+
+ #define DECODE_ARGS_WITH_STATE(L, value) \
+ _Generic((value), \
+ ...
+ - struct peer * : lua_decode_peer \
+ + struct peer * : lua_decode_peer, \
+ + struct prefix * : lua_decode_prefix \
+ )(L, -1, value)
+
+
+At compile time, the compiler will search for encoders/decoders for the type of
+each value passed in via ``frrscript_call``. If a encoder/decoder cannot be
+found, it will appear as a compile warning. Note that the types must
+match *exactly*.
+In the above example, we defined encoders/decoders for a value of
+``struct prefix *``, but not ``struct prefix`` or ``const struct prefix *``.
+
+``const`` values are a special case. We want to use them in our Lua scripts
+but not modify them, so creating a decoder for them would be meaningless.
+But we still need a decoder for the type of value so that the compiler will be
+satisfied.
+For that, use ``lua_decode_noop``:
+
+.. code-block:: diff
+
+ #define DECODE_ARGS_WITH_STATE(L, value) \
+ _Generic((value), \
+ ...
+ + const struct prefix * : lua_decode_noop \
+ )(L, -1, value)
-From this point on the type names are available to be used when calling any
-script and getting its results.
.. note::
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 73899b08fe..b5950538dd 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1597,16 +1597,67 @@ Configuring Peers
.. clicmd:: bgp default ipv4-unicast
- This command allows the user to specify that v4 peering is turned
- on by default or not. This command defaults to on and is not displayed.
+ This command allows the user to specify that the IPv4 Unicast address
+ family is turned on by default or not. This command defaults to on
+ and is not displayed.
The `no bgp default ipv4-unicast` form of the command is displayed.
+.. clicmd:: bgp default ipv4-multicast
+
+ This command allows the user to specify that the IPv4 Multicast address
+ family is turned on by default or not. This command defaults to off
+ and is not displayed.
+ The `bgp default ipv4-multicast` form of the command is displayed.
+
+.. clicmd:: bgp default ipv4-vpn
+
+ This command allows the user to specify that the IPv4 MPLS VPN address
+ family is turned on by default or not. This command defaults to off
+ and is not displayed.
+ The `bgp default ipv4-vpn` form of the command is displayed.
+
+.. clicmd:: bgp default ipv4-flowspec
+
+ This command allows the user to specify that the IPv4 Flowspec address
+ family is turned on by default or not. This command defaults to off
+ and is not displayed.
+ The `bgp default ipv4-flowspec` form of the command is displayed.
+
.. clicmd:: bgp default ipv6-unicast
- This command allows the user to specify that v6 peering is turned
- on by default or not. This command defaults to off and is not displayed.
+ This command allows the user to specify that the IPv6 Unicast address
+ family is turned on by default or not. This command defaults to off
+ and is not displayed.
The `bgp default ipv6-unicast` form of the command is displayed.
+.. clicmd:: bgp default ipv6-multicast
+
+ This command allows the user to specify that the IPv6 Multicast address
+ family is turned on by default or not. This command defaults to off
+ and is not displayed.
+ The `bgp default ipv6-multicast` form of the command is displayed.
+
+.. clicmd:: bgp default ipv6-vpn
+
+ This command allows the user to specify that the IPv6 MPLS VPN address
+ family is turned on by default or not. This command defaults to off
+ and is not displayed.
+ The `bgp default ipv6-vpn` form of the command is displayed.
+
+.. clicmd:: bgp default ipv6-flowspec
+
+ This command allows the user to specify that the IPv6 Flowspec address
+ family is turned on by default or not. This command defaults to off
+ and is not displayed.
+ The `bgp default ipv6-flowspec` form of the command is displayed.
+
+.. clicmd:: bgp default l2vpn-evpn
+
+ This command allows the user to specify that the L2VPN EVPN address
+ family is turned on by default or not. This command defaults to off
+ and is not displayed.
+ The `bgp default l2vpn-evpn` form of the command is displayed.
+
.. clicmd:: bgp default show-hostname
This command shows the hostname of the peer in certain BGP commands
diff --git a/doc/user/ipv6.rst b/doc/user/ipv6.rst
index 089fae39b1..4f01061e7b 100644
--- a/doc/user/ipv6.rst
+++ b/doc/user/ipv6.rst
@@ -17,6 +17,11 @@ no longer possible.
Router Advertisement
====================
+.. clicmd:: show ipv6 nd ra-interfaces [vrf <VRFNAME|all>]
+
+ Show configured route advertisement interfaces. VRF subcommand only
+ applicable for netns-based vrfs.
+
.. clicmd:: ipv6 nd suppress-ra
Don't send router advertisement messages. The ``no`` form of this command
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index 103760933c..83d19d6188 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -267,10 +267,10 @@ is in a vrf, enter the interface command with the vrf keyword at the end.
:ref:`bfd-pim-peer-config`
-.. _pim-multicast-rib-insertion:
+.. _pim-multicast-rib:
-PIM Multicast RIB insertion:
-============================
+PIM Multicast RIB
+=================
In order to influence Multicast RPF lookup, it is possible to insert
into zebra routes for the Multicast RIB. These routes are only
@@ -317,6 +317,21 @@ MSDP can be setup in different ways:
Commands available for MSDP:
+.. clicmd:: ip msdp timers (2-600) (3-600) [(1-600)]
+
+ Configure global MSDP timers.
+
+ First value is the keep-alive interval and it must be less than the
+ second value which is hold-time. This configures the interval in
+ seconds between keep-alive messages. The default value is 60 seconds.
+
+ Second value is the hold-time and it must be greater than the keep-alive
+ interval. This configures the interval in seconds before closing a non
+ responding connection. The default value is 75.
+
+ Third value is the connection retry interval and it is optional. This
+ configures the interval between connection attempts. The default value
+ is 30 seconds.
.. clicmd:: ip msdp mesh-group WORD member A.B.C.D
diff --git a/docker/ubuntu20-ci/Dockerfile b/docker/ubuntu20-ci/Dockerfile
index 8b7557db1d..47d5b81d3a 100644
--- a/docker/ubuntu20-ci/Dockerfile
+++ b/docker/ubuntu20-ci/Dockerfile
@@ -12,6 +12,7 @@ RUN apt update && \
libcap-dev python2 libelf-dev \
sudo gdb curl iputils-ping time \
libgrpc++-dev libgrpc-dev protobuf-compiler-grpc \
+ lua5.3 liblua5.3-dev \
mininet iproute2 iperf && \
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output /tmp/get-pip.py && \
python2 /tmp/get-pip.py && \
@@ -66,6 +67,7 @@ RUN cd ~/frr && \
--enable-group=frr \
--enable-vty-group=frrvty \
--enable-snmp=agentx \
+ --enable-scripting \
--with-pkg-extra-version=-my-manual-build && \
make -j $(nproc) && \
sudo make install
diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c
index 69dcc20253..9a5fbc52b4 100644
--- a/eigrpd/eigrp_network.c
+++ b/eigrpd/eigrp_network.c
@@ -219,7 +219,7 @@ int eigrp_network_set(struct eigrp *eigrp, struct prefix *p)
}
struct prefix *pref = prefix_new();
- PREFIX_COPY_IPV4(pref, p);
+ prefix_copy(pref, p);
rn->info = (void *)pref;
/* Schedule Router ID Update. */
diff --git a/isisd/isis_route.c b/isisd/isis_route.c
index eb534a543a..bf0079d814 100644
--- a/isisd/isis_route.c
+++ b/isisd/isis_route.c
@@ -221,11 +221,11 @@ isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p,
/* update neighbor router address */
switch (prefix->family) {
case AF_INET:
- if (depth == 2 && prefix->prefixlen == 32)
+ if (depth == 2 && prefix->prefixlen == IPV4_MAX_BITLEN)
adj->router_address = prefix->u.prefix4;
break;
case AF_INET6:
- if (depth == 2 && prefix->prefixlen == 128
+ if (depth == 2 && prefix->prefixlen == IPV6_MAX_BITLEN
&& (!src_p || !src_p->prefixlen)) {
adj->router_address6 = prefix->u.prefix6;
}
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index 2bac8e7fd5..17dbb1903d 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -967,7 +967,7 @@ static int unpack_subtlv_ipv6_source_prefix(enum isis_tlv_context context,
}
p.prefixlen = stream_getc(s);
- if (p.prefixlen > 128) {
+ if (p.prefixlen > IPV6_MAX_BITLEN) {
sbuf_push(log, indent, "Prefixlen %u is implausible for IPv6\n",
p.prefixlen);
return 1;
@@ -2057,7 +2057,7 @@ static int unpack_item_extended_ip_reach(uint16_t mtid, uint8_t len,
rv->down = (control & ISIS_EXTENDED_IP_REACH_DOWN);
rv->prefix.family = AF_INET;
rv->prefix.prefixlen = control & 0x3f;
- if (rv->prefix.prefixlen > 32) {
+ if (rv->prefix.prefixlen > IPV4_MAX_BITLEN) {
sbuf_push(log, indent, "Prefixlen %u is implausible for IPv4\n",
rv->prefix.prefixlen);
goto out;
@@ -2542,7 +2542,7 @@ static int unpack_item_ipv6_reach(uint16_t mtid, uint8_t len, struct stream *s,
rv->prefix.family = AF_INET6;
rv->prefix.prefixlen = stream_getc(s);
- if (rv->prefix.prefixlen > 128) {
+ if (rv->prefix.prefixlen > IPV6_MAX_BITLEN) {
sbuf_push(log, indent, "Prefixlen %u is implausible for IPv6\n",
rv->prefix.prefixlen);
goto out;
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 0142e30b2b..2c05cb8277 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -145,10 +145,11 @@ static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
static int isis_zebra_link_params(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
+ bool changed = false;
- ifp = zebra_interface_link_params_read(zclient->ibuf, vrf_id);
+ ifp = zebra_interface_link_params_read(zclient->ibuf, vrf_id, &changed);
- if (ifp == NULL)
+ if (ifp == NULL || !changed)
return 0;
/* Update TE TLV */
diff --git a/ldpd/labelmapping.c b/ldpd/labelmapping.c
index cee9d527e8..13d3243124 100644
--- a/ldpd/labelmapping.c
+++ b/ldpd/labelmapping.c
@@ -724,9 +724,9 @@ tlv_decode_fec_elm(struct nbr *nbr, struct ldp_msg *msg, char *buf,
map->fec.prefix.prefixlen = buf[off];
off += sizeof(uint8_t);
if ((map->fec.prefix.af == AF_IPV4
- && map->fec.prefix.prefixlen > IPV4_MAX_PREFIXLEN)
+ && map->fec.prefix.prefixlen > IPV4_MAX_BITLEN)
|| (map->fec.prefix.af == AF_IPV6
- && map->fec.prefix.prefixlen > IPV6_MAX_PREFIXLEN)) {
+ && map->fec.prefix.prefixlen > IPV6_MAX_BITLEN)) {
session_shutdown(nbr, S_BAD_TLV_VAL, msg->id,
msg->type);
return (-1);
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 724e83adb2..2d35d097a1 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -751,8 +751,8 @@ lde_update_label(struct fec_node *fn)
/* should we allocate a label for this fec? */
switch (fn->fec.type) {
case FEC_TYPE_IPV4:
- if ((ldeconf->ipv4.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
- fn->fec.u.ipv4.prefixlen != 32)
+ if ((ldeconf->ipv4.flags & F_LDPD_AF_ALLOCHOSTONLY)
+ && fn->fec.u.ipv4.prefixlen != IPV4_MAX_BITLEN)
return (NO_LABEL);
if (lde_acl_check(ldeconf->ipv4.acl_label_allocate_for,
AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
@@ -760,8 +760,8 @@ lde_update_label(struct fec_node *fn)
return (NO_LABEL);
break;
case FEC_TYPE_IPV6:
- if ((ldeconf->ipv6.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
- fn->fec.u.ipv6.prefixlen != 128)
+ if ((ldeconf->ipv6.flags & F_LDPD_AF_ALLOCHOSTONLY)
+ && fn->fec.u.ipv6.prefixlen != IPV6_MAX_BITLEN)
return (NO_LABEL);
if (lde_acl_check(ldeconf->ipv6.acl_label_allocate_for,
AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
diff --git a/ldpd/util.c b/ldpd/util.c
index b4d74f1950..019d846ada 100644
--- a/ldpd/util.c
+++ b/ldpd/util.c
@@ -182,7 +182,7 @@ ldp_prefixcmp(int af, const union ldpd_addr *a, const union ldpd_addr *b,
case AF_INET:
if (prefixlen == 0)
return (0);
- if (prefixlen > 32)
+ if (prefixlen > IPV4_MAX_BITLEN)
fatalx("ldp_prefixcmp: bad IPv4 prefixlen");
mask = htonl(prefixlen2mask(prefixlen));
aa = htonl(a->v4.s_addr) & mask;
@@ -191,7 +191,7 @@ ldp_prefixcmp(int af, const union ldpd_addr *a, const union ldpd_addr *b,
case AF_INET6:
if (prefixlen == 0)
return (0);
- if (prefixlen > 128)
+ if (prefixlen > IPV6_MAX_BITLEN)
fatalx("ldp_prefixcmp: bad IPv6 prefixlen");
for (i = 0; i < prefixlen / 8; i++)
if (a->v6.s6_addr[i] != b->v6.s6_addr[i])
diff --git a/lib/command.c b/lib/command.c
index 560d4a09f8..9dac60599c 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -2428,14 +2428,16 @@ DEFUN(script,
struct prefix p;
(void)str2prefix("1.2.3.4/24", &p);
-
struct frrscript *fs = frrscript_load(argv[1]->arg, NULL);
if (fs == NULL) {
vty_out(vty, "Script '/etc/frr/scripts/%s.lua' not found\n",
argv[1]->arg);
} else {
- int ret = frrscript_call(fs, NULL);
+ int ret = frrscript_call(fs, ("p", &p));
+ char buf[40];
+ prefix2str(&p, buf, sizeof(buf));
+ vty_out(vty, "p: %s\n", buf);
vty_out(vty, "Script result: %d\n", ret);
}
diff --git a/lib/command_match.c b/lib/command_match.c
index e9e8466ffd..5703510148 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -813,7 +813,7 @@ static enum match_type match_ipv4_prefix(const char *str)
str++;
}
- if (atoi(sp) > 32)
+ if (atoi(sp) > IPV4_MAX_BITLEN)
return no_match;
return exact_match;
@@ -948,7 +948,7 @@ static enum match_type match_ipv6_prefix(const char *str, bool prefix)
if (*endptr != '\0')
return no_match;
- if (mask < 0 || mask > 128)
+ if (mask < 0 || mask > IPV6_MAX_BITLEN)
return no_match;
return exact_match;
diff --git a/lib/compiler.h b/lib/compiler.h
index 970ed297fc..bf443906eb 100644
--- a/lib/compiler.h
+++ b/lib/compiler.h
@@ -173,6 +173,29 @@ extern "C" {
#define MACRO_REPEAT(NAME, ...) \
MACRO_VARIANT(_MACRO_REPEAT, ##__VA_ARGS__)(NAME, ##__VA_ARGS__)
+/* per-arglist repeat macro, use like this:
+ * #define foo(...) MAP_LISTS(F, ##__VA_ARGS__)
+ * where F is a n-ary function where n is the number of args in each arglist.
+ * e.g.: MAP_LISTS(f, (a, b), (c, d))
+ * expands to: f(a, b); f(c, d)
+ */
+
+#define ESC(...) __VA_ARGS__
+#define MAP_LISTS(M, ...) \
+ _CONCAT(_MAP_LISTS_, PP_NARG(__VA_ARGS__))(M, ##__VA_ARGS__)
+#define _MAP_LISTS_0(M)
+#define _MAP_LISTS_1(M, _1) ESC(M _1)
+#define _MAP_LISTS_2(M, _1, _2) ESC(M _1; M _2)
+#define _MAP_LISTS_3(M, _1, _2, _3) ESC(M _1; M _2; M _3)
+#define _MAP_LISTS_4(M, _1, _2, _3, _4) ESC(M _1; M _2; M _3; M _4)
+#define _MAP_LISTS_5(M, _1, _2, _3, _4, _5) ESC(M _1; M _2; M _3; M _4; M _5)
+#define _MAP_LISTS_6(M, _1, _2, _3, _4, _5, _6) \
+ ESC(M _1; M _2; M _3; M _4; M _5; M _6)
+#define _MAP_LISTS_7(M, _1, _2, _3, _4, _5, _6, _7) \
+ ESC(M _1; M _2; M _3; M _4; M _5; M _6; M _7)
+#define _MAP_LISTS_8(M, _1, _2, _3, _4, _5, _6, _7, _8) \
+ ESC(M _1; M _2; M _3; M _4; M _5; M _6; M _7; M _8)
+
/*
* for warnings on macros, put in the macro content like this:
* #define MACRO BLA CPP_WARN("MACRO has been deprecated")
diff --git a/lib/filter.c b/lib/filter.c
index b7a935d076..72a66d85ad 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -108,10 +108,14 @@ static int filter_match_cisco(struct filter *mfilter, const struct prefix *p)
masklen2ip(p->prefixlen, &mask);
check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
- if (memcmp(&check_addr, &filter->addr.s_addr, 4) == 0
- && memcmp(&check_mask, &filter->mask.s_addr, 4) == 0)
+ if (memcmp(&check_addr, &filter->addr.s_addr, IPV4_MAX_BYTELEN)
+ == 0
+ && memcmp(&check_mask, &filter->mask.s_addr,
+ IPV4_MAX_BYTELEN)
+ == 0)
return 1;
- } else if (memcmp(&check_addr, &filter->addr.s_addr, 4) == 0)
+ } else if (memcmp(&check_addr, &filter->addr.s_addr, IPV4_MAX_BYTELEN)
+ == 0)
return 1;
return 0;
diff --git a/lib/frrlua.c b/lib/frrlua.c
index d8aaa3aa3c..e97e48121c 100644
--- a/lib/frrlua.c
+++ b/lib/frrlua.c
@@ -52,10 +52,9 @@ int frrlua_table_get_integer(lua_State *L, const char *key)
}
/*
- * Encoders.
- *
* This section has functions that convert internal FRR datatypes into Lua
- * datatypes.
+ * datatypes: one encoder function and two decoder functions for each type.
+ *
*/
void lua_pushprefix(lua_State *L, const struct prefix *prefix)
@@ -71,14 +70,19 @@ void lua_pushprefix(lua_State *L, const struct prefix *prefix)
lua_setfield(L, -2, "family");
}
-void *lua_toprefix(lua_State *L, int idx)
+void lua_decode_prefix(lua_State *L, int idx, struct prefix *prefix)
{
- struct prefix *p = XCALLOC(MTYPE_TMP, sizeof(struct prefix));
-
lua_getfield(L, idx, "network");
- (void)str2prefix(lua_tostring(L, -1), p);
+ (void)str2prefix(lua_tostring(L, -1), prefix);
lua_pop(L, 1);
+ /* pop the table */
+ lua_pop(L, 1);
+}
+void *lua_toprefix(lua_State *L, int idx)
+{
+ struct prefix *p = XCALLOC(MTYPE_TMP, sizeof(struct prefix));
+ lua_decode_prefix(L, idx, p);
return p;
}
@@ -109,10 +113,8 @@ void lua_pushinterface(lua_State *L, const struct interface *ifp)
lua_setfield(L, -2, "linklayer_type");
}
-void *lua_tointerface(lua_State *L, int idx)
+void lua_decode_interface(lua_State *L, int idx, struct interface *ifp)
{
- struct interface *ifp = XCALLOC(MTYPE_TMP, sizeof(struct interface));
-
lua_getfield(L, idx, "name");
strlcpy(ifp->name, lua_tostring(L, -1), sizeof(ifp->name));
lua_pop(L, 1);
@@ -146,13 +148,21 @@ void *lua_tointerface(lua_State *L, int idx)
lua_getfield(L, idx, "linklayer_type");
ifp->ll_type = lua_tointeger(L, -1);
lua_pop(L, 1);
+ /* pop the table */
+ lua_pop(L, 1);
+}
+void *lua_tointerface(lua_State *L, int idx)
+{
+ struct interface *ifp = XCALLOC(MTYPE_TMP, sizeof(struct interface));
+ lua_decode_interface(L, idx, ifp);
return ifp;
}
void lua_pushinaddr(lua_State *L, const struct in_addr *addr)
{
char buf[INET_ADDRSTRLEN];
+
inet_ntop(AF_INET, addr, buf, sizeof(buf));
lua_newtable(L);
@@ -162,14 +172,19 @@ void lua_pushinaddr(lua_State *L, const struct in_addr *addr)
lua_setfield(L, -2, "string");
}
-void *lua_toinaddr(lua_State *L, int idx)
+void lua_decode_inaddr(lua_State *L, int idx, struct in_addr *inaddr)
{
- struct in_addr *inaddr = XCALLOC(MTYPE_TMP, sizeof(struct in_addr));
-
lua_getfield(L, idx, "value");
inaddr->s_addr = lua_tointeger(L, -1);
lua_pop(L, 1);
+ /* pop the table */
+ lua_pop(L, 1);
+}
+void *lua_toinaddr(lua_State *L, int idx)
+{
+ struct in_addr *inaddr = XCALLOC(MTYPE_TMP, sizeof(struct in_addr));
+ lua_decode_inaddr(L, idx, inaddr);
return inaddr;
}
@@ -177,6 +192,7 @@ void *lua_toinaddr(lua_State *L, int idx)
void lua_pushin6addr(lua_State *L, const struct in6_addr *addr)
{
char buf[INET6_ADDRSTRLEN];
+
inet_ntop(AF_INET6, addr, buf, sizeof(buf));
lua_newtable(L);
@@ -186,20 +202,26 @@ void lua_pushin6addr(lua_State *L, const struct in6_addr *addr)
lua_setfield(L, -2, "string");
}
-void *lua_toin6addr(lua_State *L, int idx)
+void lua_decode_in6addr(lua_State *L, int idx, struct in6_addr *in6addr)
{
- struct in6_addr *in6addr = XCALLOC(MTYPE_TMP, sizeof(struct in6_addr));
-
lua_getfield(L, idx, "string");
inet_pton(AF_INET6, lua_tostring(L, -1), in6addr);
lua_pop(L, 1);
+ /* pop the table */
+ lua_pop(L, 1);
+}
+void *lua_toin6addr(lua_State *L, int idx)
+{
+ struct in6_addr *in6addr = XCALLOC(MTYPE_TMP, sizeof(struct in6_addr));
+ lua_decode_in6addr(L, idx, in6addr);
return in6addr;
}
void lua_pushsockunion(lua_State *L, const union sockunion *su)
{
char buf[SU_ADDRSTRLEN];
+
sockunion2str(su, buf, sizeof(buf));
lua_newtable(L);
@@ -210,13 +232,20 @@ void lua_pushsockunion(lua_State *L, const union sockunion *su)
lua_setfield(L, -2, "string");
}
-void *lua_tosockunion(lua_State *L, int idx)
+void lua_decode_sockunion(lua_State *L, int idx, union sockunion *su)
{
- union sockunion *su = XCALLOC(MTYPE_TMP, sizeof(union sockunion));
-
lua_getfield(L, idx, "string");
str2sockunion(lua_tostring(L, -1), su);
+ lua_pop(L, 1);
+ /* pop the table */
+ lua_pop(L, 1);
+}
+
+void *lua_tosockunion(lua_State *L, int idx)
+{
+ union sockunion *su = XCALLOC(MTYPE_TMP, sizeof(union sockunion));
+ lua_decode_sockunion(L, idx, su);
return su;
}
@@ -225,12 +254,17 @@ void lua_pushtimet(lua_State *L, const time_t *time)
lua_pushinteger(L, *time);
}
+void lua_decode_timet(lua_State *L, int idx, time_t *t)
+{
+ *t = lua_tointeger(L, idx);
+ lua_pop(L, 1);
+}
+
void *lua_totimet(lua_State *L, int idx)
{
time_t *t = XCALLOC(MTYPE_TMP, sizeof(time_t));
- *t = lua_tointeger(L, idx);
-
+ lua_decode_timet(L, idx, t);
return t;
}
@@ -239,17 +273,28 @@ void lua_pushintegerp(lua_State *L, const long long *num)
lua_pushinteger(L, *num);
}
-void *lua_tointegerp(lua_State *L, int idx)
+void lua_decode_integerp(lua_State *L, int idx, long long *num)
{
int isnum;
- long long *num = XCALLOC(MTYPE_TMP, sizeof(long long));
-
*num = lua_tonumberx(L, idx, &isnum);
+ lua_pop(L, 1);
assert(isnum);
+}
+
+void *lua_tointegerp(lua_State *L, int idx)
+{
+ long long *num = XCALLOC(MTYPE_TMP, sizeof(long long));
+ lua_decode_integerp(L, idx, num);
return num;
}
+void lua_decode_stringp(lua_State *L, int idx, char *str)
+{
+ strlcpy(str, lua_tostring(L, idx), strlen(str) + 1);
+ lua_pop(L, 1);
+}
+
void *lua_tostringp(lua_State *L, int idx)
{
char *string = XSTRDUP(MTYPE_TMP, lua_tostring(L, idx));
@@ -258,6 +303,13 @@ void *lua_tostringp(lua_State *L, int idx)
}
/*
+ * Decoder for const values, since we cannot modify them.
+ */
+void lua_decode_noop(lua_State *L, int idx, const void *ptr)
+{
+}
+
+/*
* Logging.
*
* Lua-compatible wrappers for FRR logging functions.
diff --git a/lib/frrlua.h b/lib/frrlua.h
index 6fb30938b0..c4de82740c 100644
--- a/lib/frrlua.h
+++ b/lib/frrlua.h
@@ -50,6 +50,8 @@ static inline void lua_pushstring_wrapper(lua_State *L, const char *str)
*/
void lua_pushprefix(lua_State *L, const struct prefix *prefix);
+void lua_decode_prefix(lua_State *L, int idx, struct prefix *prefix);
+
/*
* Converts the Lua value at idx to a prefix.
*
@@ -63,6 +65,8 @@ void *lua_toprefix(lua_State *L, int idx);
*/
void lua_pushinterface(lua_State *L, const struct interface *ifp);
+void lua_decode_interface(lua_State *L, int idx, struct interface *ifp);
+
/*
* Converts the Lua value at idx to an interface.
*
@@ -77,6 +81,8 @@ void *lua_tointerface(lua_State *L, int idx);
*/
void lua_pushinaddr(lua_State *L, const struct in_addr *addr);
+void lua_decode_inaddr(lua_State *L, int idx, struct in_addr *addr);
+
/*
* Converts the Lua value at idx to an in_addr.
*
@@ -90,6 +96,8 @@ void *lua_toinaddr(lua_State *L, int idx);
*/
void lua_pushin6addr(lua_State *L, const struct in6_addr *addr);
+void lua_decode_in6addr(lua_State *L, int idx, struct in6_addr *addr);
+
/*
* Converts the Lua value at idx to an in6_addr.
*
@@ -103,6 +111,8 @@ void *lua_toin6addr(lua_State *L, int idx);
*/
void lua_pushtimet(lua_State *L, const time_t *time);
+void lua_decode_timet(lua_State *L, int idx, time_t *time);
+
/*
* Converts the Lua value at idx to a time_t.
*
@@ -116,6 +126,8 @@ void *lua_totimet(lua_State *L, int idx);
*/
void lua_pushsockunion(lua_State *L, const union sockunion *su);
+void lua_decode_sockunion(lua_State *L, int idx, union sockunion *su);
+
/*
* Converts the Lua value at idx to a sockunion.
*
@@ -129,6 +141,8 @@ void *lua_tosockunion(lua_State *L, int idx);
*/
void lua_pushintegerp(lua_State *L, const long long *num);
+void lua_decode_integerp(lua_State *L, int idx, long long *num);
+
/*
* Converts the Lua value at idx to an int.
*
@@ -137,6 +151,8 @@ void lua_pushintegerp(lua_State *L, const long long *num);
*/
void *lua_tointegerp(lua_State *L, int idx);
+void lua_decode_stringp(lua_State *L, int idx, char *str);
+
/*
* Pop string.
*
@@ -146,6 +162,11 @@ void *lua_tointegerp(lua_State *L, int idx);
void *lua_tostringp(lua_State *L, int idx);
/*
+ * No-op decocder
+ */
+void lua_decode_noop(lua_State *L, int idx, const void *ptr);
+
+/*
* Retrieve an integer from table on the top of the stack.
*
* key
diff --git a/lib/frrscript.c b/lib/frrscript.c
index 10d400886d..1a9f3639dd 100644
--- a/lib/frrscript.c
+++ b/lib/frrscript.c
@@ -104,24 +104,8 @@ static void codec_free(struct codec *c)
/* Generic script APIs */
-int frrscript_call(struct frrscript *fs, struct frrscript_env *env)
+int _frrscript_call(struct frrscript *fs)
{
- struct frrscript_codec c = {};
- const void *arg;
- const char *bindname;
-
- /* Encode script arguments */
- for (int i = 0; env && env[i].val != NULL; i++) {
- bindname = env[i].name;
- c.typename = env[i].typename;
- arg = env[i].val;
-
- struct frrscript_codec *codec = hash_lookup(codec_hash, &c);
- assert(codec && "No encoder for type");
- codec->encoder(fs->L, arg);
-
- lua_setglobal(fs->L, bindname);
- }
int ret = lua_pcall(fs->L, 0, 0, 0);
diff --git a/lib/frrscript.h b/lib/frrscript.h
index f4057f531b..8612c602f3 100644
--- a/lib/frrscript.h
+++ b/lib/frrscript.h
@@ -25,6 +25,7 @@
#include <lua.h>
#include "frrlua.h"
+#include "../bgpd/bgp_script.h"
#ifdef __cplusplus
extern "C" {
@@ -96,6 +97,56 @@ void frrscript_register_type_codecs(struct frrscript_codec *codecs);
*/
void frrscript_init(const char *scriptdir);
+#define ENCODE_ARGS(name, value) \
+ do { \
+ ENCODE_ARGS_WITH_STATE(L, value); \
+ lua_setglobal(L, name); \
+ } while (0)
+
+#define DECODE_ARGS(name, value) \
+ do { \
+ lua_getglobal(L, name); \
+ DECODE_ARGS_WITH_STATE(L, value); \
+ } while (0)
+
+/*
+ * Maps the type of value to its encoder/decoder.
+ * Add new mappings here.
+ *
+ * L
+ * Lua state
+ * scriptdir
+ * Directory in which to look for scripts
+ */
+#define ENCODE_ARGS_WITH_STATE(L, value) \
+ _Generic((value), \
+long long * : lua_pushintegerp, \
+struct prefix * : lua_pushprefix, \
+struct interface * : lua_pushinterface, \
+struct in_addr * : lua_pushinaddr, \
+struct in6_addr * : lua_pushin6addr, \
+union sockunion * : lua_pushsockunion, \
+time_t * : lua_pushtimet, \
+char * : lua_pushstring_wrapper, \
+struct attr * : lua_pushattr, \
+struct peer * : lua_pushpeer, \
+const struct prefix * : lua_pushprefix \
+)(L, value)
+
+#define DECODE_ARGS_WITH_STATE(L, value) \
+ _Generic((value), \
+long long * : lua_decode_integerp, \
+struct prefix * : lua_decode_prefix, \
+struct interface * : lua_decode_interface, \
+struct in_addr * : lua_decode_inaddr, \
+struct in6_addr * : lua_decode_in6addr, \
+union sockunion * : lua_decode_sockunion, \
+time_t * : lua_decode_timet, \
+char * : lua_decode_stringp, \
+struct attr * : lua_decode_attr, \
+struct peer * : lua_decode_noop, \
+const struct prefix * : lua_decode_noop \
+)(L, -1, value)
/*
* Call script.
@@ -103,14 +154,31 @@ void frrscript_init(const char *scriptdir);
* fs
* The script to call; this is obtained from frrscript_load().
*
- * env
- * The script's environment. Specify this as an array of frrscript_env.
- *
* Returns:
* 0 if the script ran successfully, nonzero otherwise.
*/
-int frrscript_call(struct frrscript *fs, struct frrscript_env *env);
+int _frrscript_call(struct frrscript *fs);
+/*
+ * Wrapper for call script. Maps values passed in to their encoder
+ * and decoder types.
+ *
+ * fs
+ * The script to call; this is obtained from frrscript_load().
+ *
+ * Returns:
+ * 0 if the script ran successfully, nonzero otherwise.
+ */
+#define frrscript_call(fs, ...) \
+ ({ \
+ lua_State *L = fs->L; \
+ MAP_LISTS(ENCODE_ARGS, ##__VA_ARGS__); \
+ int ret = _frrscript_call(fs); \
+ if (ret == 0) { \
+ MAP_LISTS(DECODE_ARGS, ##__VA_ARGS__); \
+ } \
+ ret; \
+ })
/*
* Get result from finished script.
diff --git a/lib/prefix.c b/lib/prefix.c
index 370c8dc067..ef7d2e59da 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -577,7 +577,7 @@ int str2prefix_ipv4(const char *str, struct prefix_ipv4 *p)
/* Get prefix length. */
plen = (uint8_t)atoi(++pnt);
- if (plen > IPV4_MAX_PREFIXLEN)
+ if (plen > IPV4_MAX_BITLEN)
return 0;
p->family = AF_INET;
@@ -1129,7 +1129,7 @@ void apply_classful_mask_ipv4(struct prefix_ipv4 *p)
destination = ntohl(p->prefix.s_addr);
- if (p->prefixlen == IPV4_MAX_PREFIXLEN)
+ if (p->prefixlen == IPV4_MAX_BITLEN)
;
/* do nothing for host routes */
else if (IN_CLASSC(destination)) {
@@ -1149,12 +1149,13 @@ in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen)
struct in_addr mask;
masklen2ip(masklen, &mask);
- return (masklen != IPV4_MAX_PREFIXLEN - 1) ?
- /* normal case */
- (hostaddr | ~mask.s_addr)
- :
- /* For prefix 31 return 255.255.255.255 (RFC3021) */
- htonl(0xFFFFFFFF);
+ return (masklen != IPV4_MAX_BITLEN - 1)
+ ?
+ /* normal case */
+ (hostaddr | ~mask.s_addr)
+ :
+ /* For prefix 31 return 255.255.255.255 (RFC3021) */
+ htonl(0xFFFFFFFF);
}
/* Utility function to convert ipv4 netmask to prefixes
diff --git a/lib/prefix.h b/lib/prefix.h
index 217a23d561..bc4cb7f441 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -372,7 +372,6 @@ union prefixconstptr {
/* Max bit/byte length of IPv4 address. */
#define IPV4_MAX_BYTELEN 4
#define IPV4_MAX_BITLEN 32
-#define IPV4_MAX_PREFIXLEN 32
#define IPV4_ADDR_CMP(D,S) memcmp ((D), (S), IPV4_MAX_BYTELEN)
static inline bool ipv4_addr_same(const struct in_addr *a,
@@ -398,7 +397,6 @@ static inline void ipv4_addr_copy(struct in_addr *dst,
/* Max bit/byte length of IPv6 address. */
#define IPV6_MAX_BYTELEN 16
#define IPV6_MAX_BITLEN 128
-#define IPV6_MAX_PREFIXLEN 128
#define IPV6_ADDR_CMP(D,S) memcmp ((D), (S), IPV6_MAX_BYTELEN)
#define IPV6_ADDR_SAME(D,S) (memcmp ((D), (S), IPV6_MAX_BYTELEN) == 0)
#define IPV6_ADDR_COPY(D,S) memcpy ((D), (S), IPV6_MAX_BYTELEN)
@@ -481,11 +479,6 @@ extern void prefix_ipv4_free(struct prefix_ipv4 **p);
extern int str2prefix_ipv4(const char *, struct prefix_ipv4 *);
extern void apply_mask_ipv4(struct prefix_ipv4 *);
-#define PREFIX_COPY(DST, SRC) \
- *((struct prefix *)(DST)) = *((const struct prefix *)(SRC))
-#define PREFIX_COPY_IPV4(DST, SRC) \
- *((struct prefix_ipv4 *)(DST)) = *((const struct prefix_ipv4 *)(SRC))
-
extern int prefix_ipv4_any(const struct prefix_ipv4 *);
extern void apply_classful_mask_ipv4(struct prefix_ipv4 *);
@@ -503,9 +496,6 @@ extern void prefix_ipv6_free(struct prefix_ipv6 **p);
extern int str2prefix_ipv6(const char *, struct prefix_ipv6 *);
extern void apply_mask_ipv6(struct prefix_ipv6 *);
-#define PREFIX_COPY_IPV6(DST, SRC) \
- *((struct prefix_ipv6 *)(DST)) = *((const struct prefix_ipv6 *)(SRC))
-
extern int ip6_masklen(struct in6_addr);
extern void masklen2ip6(const int, struct in6_addr *);
diff --git a/lib/sockunion.c b/lib/sockunion.c
index e6340a1743..c7af458e9e 100644
--- a/lib/sockunion.c
+++ b/lib/sockunion.c
@@ -606,8 +606,7 @@ static void __attribute__((unused)) sockunion_print(const union sockunion *su)
}
}
-static int in6addr_cmp(const struct in6_addr *addr1,
- const struct in6_addr *addr2)
+int in6addr_cmp(const struct in6_addr *addr1, const struct in6_addr *addr2)
{
unsigned int i;
const uint8_t *p1, *p2;
diff --git a/lib/sockunion.h b/lib/sockunion.h
index 2cc80bb70f..9e6719ccf9 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -73,6 +73,7 @@ enum connect_result { connect_error, connect_success, connect_in_progress };
/* Prototypes. */
extern int str2sockunion(const char *, union sockunion *);
extern const char *sockunion2str(const union sockunion *, char *, size_t);
+int in6addr_cmp(const struct in6_addr *addr1, const struct in6_addr *addr2);
extern int sockunion_cmp(const union sockunion *, const union sockunion *);
extern int sockunion_same(const union sockunion *, const union sockunion *);
extern unsigned int sockunion_hash(const union sockunion *);
diff --git a/lib/table.c b/lib/table.c
index dfd92c6189..e6030ca4ca 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -230,7 +230,7 @@ struct route_node *route_node_match_ipv4(struct route_table *table,
memset(&p, 0, sizeof(struct prefix_ipv4));
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.prefix = *addr;
return route_node_match(table, (struct prefix *)&p);
@@ -243,7 +243,7 @@ struct route_node *route_node_match_ipv6(struct route_table *table,
memset(&p, 0, sizeof(struct prefix_ipv6));
p.family = AF_INET6;
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
p.prefix = *addr;
return route_node_match(table, &p);
diff --git a/lib/zclient.c b/lib/zclient.c
index 195ec589d3..dc83227659 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -446,7 +446,7 @@ enum zclient_send_status zclient_send_localsid(struct zclient *zclient,
struct nexthop nh = {};
p.family = AF_INET6;
- p.prefixlen = 128;
+ p.prefixlen = IPV6_MAX_BITLEN;
p.prefix = *sid;
api.vrf_id = VRF_DEFAULT;
@@ -1432,7 +1432,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
STREAM_GETC(s, api->prefix.prefixlen);
switch (api->prefix.family) {
case AF_INET:
- if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
+ if (api->prefix.prefixlen > IPV4_MAX_BITLEN) {
flog_err(
EC_LIB_ZAPI_ENCODE,
"%s: V4 prefixlen is %d which should not be more than 32",
@@ -1441,7 +1441,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
}
break;
case AF_INET6:
- if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
+ if (api->prefix.prefixlen > IPV6_MAX_BITLEN) {
flog_err(
EC_LIB_ZAPI_ENCODE,
"%s: v6 prefixlen is %d which should not be more than 128",
@@ -1460,7 +1460,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
api->src_prefix.family = AF_INET6;
STREAM_GETC(s, api->src_prefix.prefixlen);
- if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
+ if (api->src_prefix.prefixlen > IPV6_MAX_BITLEN) {
flog_err(
EC_LIB_ZAPI_ENCODE,
"%s: SRC Prefix prefixlen received: %d is too large",
@@ -2269,10 +2269,13 @@ stream_failure:
}
struct interface *zebra_interface_link_params_read(struct stream *s,
- vrf_id_t vrf_id)
+ vrf_id_t vrf_id,
+ bool *changed)
{
struct if_link_params *iflp;
+ struct if_link_params iflp_copy;
ifindex_t ifindex;
+ bool params_changed = false;
STREAM_GETL(s, ifindex);
@@ -2285,12 +2288,23 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
return NULL;
}
+ if (ifp->link_params == NULL)
+ params_changed = true;
+
if ((iflp = if_link_params_get(ifp)) == NULL)
return NULL;
+ memcpy(&iflp_copy, iflp, sizeof(iflp_copy));
+
if (link_params_set_value(s, iflp) != 0)
goto stream_failure;
+ if (memcmp(&iflp_copy, iflp, sizeof(iflp_copy)))
+ params_changed = true;
+
+ if (changed)
+ *changed = params_changed;
+
return ifp;
stream_failure:
diff --git a/lib/zclient.h b/lib/zclient.h
index 48de3425be..a25c5800b7 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -1043,7 +1043,8 @@ extern struct interface *zebra_interface_vrf_update_read(struct stream *s,
extern int zebra_router_id_update_read(struct stream *s, struct prefix *rid);
extern struct interface *zebra_interface_link_params_read(struct stream *s,
- vrf_id_t vrf_id);
+ vrf_id_t vrf_id,
+ bool *changed);
extern size_t zebra_interface_link_params_write(struct stream *,
struct interface *);
extern enum zclient_send_status
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index d7307fe375..d4e52f0ede 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -556,7 +556,7 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa)
+ OSPF6_PREFIX_SPACE(external->prefix.prefix_length);
memset(&fwd_addr, 0, sizeof(struct prefix));
fwd_addr.family = AF_INET6;
- fwd_addr.prefixlen = IPV6_MAX_PREFIXLEN;
+ fwd_addr.prefixlen = IPV6_MAX_BITLEN;
memcpy(&fwd_addr.u.prefix6, (caddr_t)external + offset,
sizeof(struct in6_addr));
@@ -1010,53 +1010,55 @@ static void ospf6_asbr_routemap_unset(struct ospf6_redist *red)
static int ospf6_asbr_routemap_update_timer(struct thread *thread)
{
- void **arg;
- int arg_type;
- struct ospf6 *ospf6;
+ struct ospf6 *ospf6 = THREAD_ARG(thread);
struct ospf6_redist *red;
-
- arg = THREAD_ARG(thread);
- ospf6 = (struct ospf6 *)arg[0];
- arg_type = (int)(intptr_t)arg[1];
+ int type;
ospf6->t_distribute_update = NULL;
- red = ospf6_redist_lookup(ospf6, arg_type, 0);
+ for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
+ red = ospf6_redist_lookup(ospf6, type, 0);
- if (red && ROUTEMAP_NAME(red))
- ROUTEMAP(red) = route_map_lookup_by_name(ROUTEMAP_NAME(red));
- if (red && ROUTEMAP(red)) {
- if (IS_OSPF6_DEBUG_ASBR)
- zlog_debug("%s: route-map %s update, reset redist %s",
- __func__, ROUTEMAP_NAME(red),
- ZROUTE_NAME(arg_type));
+ if (!red)
+ continue;
+
+ if (!CHECK_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED))
+ continue;
+
+ if (ROUTEMAP_NAME(red))
+ ROUTEMAP(red) =
+ route_map_lookup_by_name(ROUTEMAP_NAME(red));
+
+ if (ROUTEMAP(red)) {
+ if (IS_OSPF6_DEBUG_ASBR)
+ zlog_debug(
+ "%s: route-map %s update, reset redist %s",
+ __func__, ROUTEMAP_NAME(red),
+ ZROUTE_NAME(type));
+
+ ospf6_zebra_no_redistribute(type, ospf6->vrf_id);
+ ospf6_zebra_redistribute(type, ospf6->vrf_id);
+ }
- ospf6_zebra_no_redistribute(arg_type, ospf6->vrf_id);
- ospf6_zebra_redistribute(arg_type, ospf6->vrf_id);
+ UNSET_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED);
}
- XFREE(MTYPE_OSPF6_DIST_ARGS, arg);
return 0;
}
-void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6)
+void ospf6_asbr_distribute_list_update(struct ospf6 *ospf6,
+ struct ospf6_redist *red)
{
- void **args = NULL;
+ SET_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED);
if (ospf6->t_distribute_update)
return;
- args = XCALLOC(MTYPE_OSPF6_DIST_ARGS, sizeof(void *) * 2);
-
- args[0] = ospf6;
- args[1] = (void *)((ptrdiff_t)type);
-
if (IS_OSPF6_DEBUG_ASBR)
- zlog_debug("%s: trigger redistribute %s reset thread", __func__,
- ZROUTE_NAME(type));
+ zlog_debug("%s: trigger redistribute reset thread", __func__);
ospf6->t_distribute_update = NULL;
- thread_add_timer_msec(master, ospf6_asbr_routemap_update_timer, args,
+ thread_add_timer_msec(master, ospf6_asbr_routemap_update_timer, ospf6,
OSPF_MIN_LS_INTERVAL,
&ospf6->t_distribute_update);
}
@@ -1092,8 +1094,7 @@ void ospf6_asbr_routemap_update(const char *mapname)
type));
route_map_counter_increment(ROUTEMAP(red));
-
- ospf6_asbr_distribute_list_update(type, ospf6);
+ ospf6_asbr_distribute_list_update(ospf6, red);
} else {
/*
* if the mapname matches a
@@ -1131,7 +1132,7 @@ static void ospf6_asbr_routemap_event(const char *name)
red = ospf6_redist_lookup(ospf6, type, 0);
if (red && ROUTEMAP_NAME(red)
&& (strcmp(ROUTEMAP_NAME(red), name) == 0))
- ospf6_asbr_distribute_list_update(type, ospf6);
+ ospf6_asbr_distribute_list_update(ospf6, red);
}
}
}
@@ -1399,7 +1400,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
/* create/update binding in external_id_table */
prefix_id.family = AF_INET;
- prefix_id.prefixlen = 32;
+ prefix_id.prefixlen = IPV4_MAX_BITLEN;
prefix_id.u.prefix4.s_addr = htonl(info->id);
node = route_node_get(ospf6->external_id_table, &prefix_id);
node->info = match;
@@ -1464,7 +1465,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
/* create/update binding in external_id_table */
prefix_id.family = AF_INET;
- prefix_id.prefixlen = 32;
+ prefix_id.prefixlen = IPV4_MAX_BITLEN;
prefix_id.u.prefix4.s_addr = htonl(info->id);
node = route_node_get(ospf6->external_id_table, &prefix_id);
node->info = route;
@@ -1547,7 +1548,7 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
/* remove binding in external_id_table */
prefix_id.family = AF_INET;
- prefix_id.prefixlen = 32;
+ prefix_id.prefixlen = IPV4_MAX_BITLEN;
prefix_id.u.prefix4.s_addr = htonl(info->id);
node = route_node_lookup(ospf6->external_id_table, &prefix_id);
assert(node);
diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h
index 8f2135ef30..7ccd1c992b 100644
--- a/ospf6d/ospf6_asbr.h
+++ b/ospf6d/ospf6_asbr.h
@@ -105,7 +105,8 @@ extern void install_element_ospf6_debug_asbr(void);
extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
struct ospf6_route *route,
struct ospf6 *ospf6);
-extern void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6);
+extern void ospf6_asbr_distribute_list_update(struct ospf6 *ospf6,
+ struct ospf6_redist *red);
struct ospf6_redist *ospf6_redist_lookup(struct ospf6 *ospf6, int type,
unsigned short instance);
extern void ospf6_asbr_routemap_update(const char *mapname);
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 057f89797a..6f40989efd 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -602,7 +602,7 @@ void ospf6_router_id_update(struct ospf6 *ospf6)
if (ospf6->router_id_static != 0)
ospf6->router_id = ospf6->router_id_static;
else
- ospf6->router_id = om6->zebra_router_id;
+ ospf6->router_id = ospf6->router_id_zebra;
}
/* start ospf6 */
@@ -786,8 +786,8 @@ DEFUN(no_ospf6_router_id,
}
}
o->router_id = 0;
- if (o->router_id_zebra.s_addr)
- o->router_id = (uint32_t)o->router_id_zebra.s_addr;
+ if (o->router_id_zebra)
+ o->router_id = o->router_id_zebra;
return CMD_SUCCESS;
}
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index 51df4b6b8e..3eb423f681 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -29,7 +29,6 @@ struct ospf6_master {
struct list *ospf6;
/* OSPFv3 thread master. */
struct thread_master *master;
- in_addr_t zebra_router_id;
};
/* ospf6->config_flags */
@@ -38,9 +37,12 @@ enum {
OSPF6_LOG_ADJACENCY_DETAIL = (1 << 1),
};
+/* For processing route-map change update in the callback */
+#define OSPF6_IS_RMAP_CHANGED 0x01
struct ospf6_redist {
uint8_t instance;
+ uint8_t flag;
/* Redistribute metric info. */
struct {
int type; /* External metric type (E1 or E2). */
@@ -71,7 +73,7 @@ struct ospf6 {
/* static router id */
in_addr_t router_id_static;
- struct in_addr router_id_zebra;
+ in_addr_t router_id_zebra;
/* start time */
struct timeval starttime;
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 170d545c49..a7e15c68ae 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -90,15 +90,16 @@ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
zebra_router_id_update_read(zclient->ibuf, &router_id);
- om6->zebra_router_id = router_id.u.prefix4.s_addr;
+ if (IS_OSPF6_DEBUG_ZEBRA(RECV))
+ zlog_debug("Zebra router-id update %pI4 vrf %s id %u",
+ &router_id.u.prefix4, ospf6_vrf_id_to_name(vrf_id),
+ vrf_id);
+
o = ospf6_lookup_by_vrf_id(vrf_id);
if (o == NULL)
return 0;
- o->router_id_zebra = router_id.u.prefix4;
- if (IS_OSPF6_DEBUG_ZEBRA(RECV))
- zlog_debug("%s: zebra router-id %pI4 update", __func__,
- &router_id.u.prefix4);
+ o->router_id_zebra = router_id.u.prefix4.s_addr;
ospf6_router_id_update(o);
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 2fd195bb6d..192dbe4fc8 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -361,7 +361,7 @@ bool is_valid_summary_addr(struct prefix_ipv4 *p)
return false;
/*Host route shouldn't be configured as summary addres*/
- if (p->prefixlen == IPV4_MAX_PREFIXLEN)
+ if (p->prefixlen == IPV4_MAX_BITLEN)
return false;
return true;
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index b4e318d1d1..029f929c11 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -50,6 +50,7 @@
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_ldp_sync.h"
#include "ospfd/ospf_route.h"
+#include "ospfd/ospf_te.h"
DEFINE_QOBJ_TYPE(ospf_interface);
DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd));
@@ -187,7 +188,7 @@ struct ospf_interface *ospf_if_table_lookup(struct interface *ifp,
struct ospf_interface *rninfo = NULL;
p = *prefix;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
/* route_node_get implicitely locks */
if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) {
@@ -204,7 +205,7 @@ static void ospf_add_to_if(struct interface *ifp, struct ospf_interface *oi)
struct prefix p;
p = *oi->address;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
apply_mask(&p);
rn = route_node_get(IF_OIFS(ifp), &p);
@@ -222,7 +223,7 @@ static void ospf_delete_from_if(struct interface *ifp,
struct prefix p;
p = *oi->address;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
rn = route_node_lookup(IF_OIFS(oi->ifp), &p);
assert(rn);
@@ -565,7 +566,7 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr)
struct route_node *rn;
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.prefix = addr;
rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
if (!rn || !rn->info)
@@ -600,7 +601,7 @@ struct ospf_if_params *ospf_lookup_if_params(struct interface *ifp,
struct route_node *rn;
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.prefix = addr;
rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
@@ -620,7 +621,7 @@ struct ospf_if_params *ospf_get_if_params(struct interface *ifp,
struct route_node *rn;
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.prefix = addr;
apply_mask_ipv4(&p);
@@ -1354,6 +1355,9 @@ static int ospf_ifp_create(struct interface *ifp)
ospf_if_update(ospf, ifp);
+ if (HAS_LINK_PARAMS(ifp))
+ ospf_mpls_te_update_if(ifp);
+
hook_call(ospf_if_update, ifp);
return 0;
@@ -1392,6 +1396,9 @@ static int ospf_ifp_up(struct interface *ifp)
ospf_if_up(oi);
}
+ if (HAS_LINK_PARAMS(ifp))
+ ospf_mpls_te_update_if(ifp);
+
return 0;
}
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index 333fa6a3a1..d95e677f6f 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -1840,7 +1840,7 @@ static void ospf_te_update_subnet(struct ls_ted *ted, struct ls_vertex *vertex,
/**
* Delete Subnet that correspond to the given IPv4 address and export deletion
- * information before removal. Prefix length is fixed to IPV4_MAX_PREFIXLEN.
+ * information before removal. Prefix length is fixed to IPV4_MAX_BITLEN.
*
* @param ted Links State Database
* @param addr IPv4 address
@@ -1852,7 +1852,7 @@ static void ospf_te_delete_subnet(struct ls_ted *ted, struct in_addr addr)
/* Search subnet that correspond to the address/32 as prefix */
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = addr;
subnet = ls_find_subnet(ted, p);
@@ -1944,7 +1944,7 @@ static int ospf_te_parse_router_lsa(struct ls_ted *ted, struct ospf_lsa *lsa)
ntohs(rl->link[i].metric));
/* Add corresponding subnet */
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = rl->link[i].link_data;
metric = ntohs(rl->link[i].metric);
ospf_te_update_subnet(ted, vertex, p, metric);
@@ -1952,7 +1952,7 @@ static int ospf_te_parse_router_lsa(struct ls_ted *ted, struct ospf_lsa *lsa)
case LSA_LINK_TYPE_STUB:
/* Keep only /32 prefix */
p.prefixlen = ip_masklen(rl->link[i].link_data);
- if (p.prefixlen == IPV4_MAX_PREFIXLEN) {
+ if (p.prefixlen == IPV4_MAX_BITLEN) {
p.family = AF_INET;
p.u.prefix4 = rl->link[i].link_id;
metric = ntohs(rl->link[i].metric);
@@ -2086,12 +2086,12 @@ static void ospf_te_update_remote_asbr(struct ls_ted *ted, struct ls_edge *edge)
/* Update corresponding Subnets */
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = attr->standard.local;
ospf_te_update_subnet(ted, edge->source, p, attr->standard.te_metric);
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = attr->standard.remote_addr;
ospf_te_update_subnet(ted, vertex, p, attr->standard.te_metric);
diff --git a/ospfd/ospf_ti_lfa.c b/ospfd/ospf_ti_lfa.c
index 59b3b624e3..347128a4f4 100644
--- a/ospfd/ospf_ti_lfa.c
+++ b/ospfd/ospf_ti_lfa.c
@@ -849,7 +849,7 @@ void ospf_ti_lfa_generate_p_spaces(struct ospf_area *area,
stub_prefix.family = AF_INET;
child_prefix.family = AF_INET;
- child_prefix.prefixlen = IPV4_MAX_PREFIXLEN;
+ child_prefix.prefixlen = IPV4_MAX_BITLEN;
p = ((uint8_t *)root->lsa) + OSPF_LSA_HEADER_SIZE + 4;
lim = ((uint8_t *)root->lsa) + ntohs(root->lsa->length);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 54ce248d89..db8e961b8b 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -6616,7 +6616,7 @@ static void show_lsa_prefix_set(struct vty *vty, struct prefix_ls *lp,
if (id == NULL)
lp->prefixlen = 0;
else if (adv_router == NULL) {
- lp->prefixlen = 32;
+ lp->prefixlen = IPV4_MAX_BITLEN;
lp->id = *id;
} else {
lp->prefixlen = 64;
@@ -10913,6 +10913,8 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
"N E1");
json_object_int_add(json_route, "cost",
er->cost);
+ json_object_int_add(json_route, "tag",
+ er->u.ext.tag);
} else {
vty_out(vty,
"N E1 %-18s [%d] tag: %" ROUTE_TAG_PRI
@@ -10926,6 +10928,10 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
"N E2");
json_object_int_add(json_route, "cost",
er->cost);
+ json_object_int_add(json_route, "type2cost",
+ er->u.ext.type2_cost);
+ json_object_int_add(json_route, "tag",
+ er->u.ext.tag);
} else {
vty_out(vty,
"N E2 %-18s [%d/%d] tag: %" ROUTE_TAG_PRI
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 5853b506f8..017915e0ee 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -138,7 +138,7 @@ static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS)
ifp = c->ifp;
p = *c->address;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
rn = route_node_lookup(IF_OIFS(ifp), &p);
if (!rn) {
@@ -163,10 +163,11 @@ static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS)
static int ospf_interface_link_params(ZAPI_CALLBACK_ARGS)
{
struct interface *ifp;
+ bool changed = false;
- ifp = zebra_interface_link_params_read(zclient->ibuf, vrf_id);
+ ifp = zebra_interface_link_params_read(zclient->ibuf, vrf_id, &changed);
- if (ifp == NULL)
+ if (ifp == NULL || !changed)
return 0;
/* Update TE TLV */
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index eb41bf6043..fc5303c9d8 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -286,11 +286,13 @@ static void route_add_helper(struct zapi_route *api, struct nexthop_group nhg,
api_nh->ifindex = nhop->ifindex;
break;
case NEXTHOP_TYPE_IPV6:
- memcpy(&api_nh->gate.ipv6, &nhop->gate.ipv6, 16);
+ memcpy(&api_nh->gate.ipv6, &nhop->gate.ipv6,
+ IPV6_MAX_BYTELEN);
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
api_nh->ifindex = nhop->ifindex;
- memcpy(&api_nh->gate.ipv6, &nhop->gate.ipv6, 16);
+ memcpy(&api_nh->gate.ipv6, &nhop->gate.ipv6,
+ IPV6_MAX_BYTELEN);
break;
case NEXTHOP_TYPE_BLACKHOLE:
api_nh->bh_type = nhop->bh_type;
@@ -460,13 +462,13 @@ void pbr_send_rnh(struct nexthop *nhop, bool reg)
case NEXTHOP_TYPE_IPV4_IFINDEX:
p.family = AF_INET;
p.u.prefix4.s_addr = nhop->gate.ipv4.s_addr;
- p.prefixlen = 32;
+ p.prefixlen = IPV4_MAX_BITLEN;
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
p.family = AF_INET6;
- memcpy(&p.u.prefix6, &nhop->gate.ipv6, 16);
- p.prefixlen = 128;
+ memcpy(&p.u.prefix6, &nhop->gate.ipv6, IPV6_MAX_BYTELEN);
+ p.prefixlen = IPV6_MAX_BITLEN;
if (IN6_IS_ADDR_LINKLOCAL(&nhop->gate.ipv6))
/*
* Don't bother tracking link locals, just track their
diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c
index ad5257630b..0181e885fd 100644
--- a/pimd/pim_bsm.c
+++ b/pimd/pim_bsm.c
@@ -1253,7 +1253,7 @@ int pim_bsm_process(struct interface *ifp, struct ip *ip_hdr, uint8_t *buf,
bshdr = (struct bsm_hdr *)(buf + PIM_MSG_HEADER_LEN);
pim_inet4_dump("<bsr?>", bshdr->bsr_addr.addr, bsr_str,
sizeof(bsr_str));
- if (bshdr->hm_len > 32) {
+ if (bshdr->hm_len > IPV4_MAX_BITLEN) {
zlog_warn("Bad hashmask length for IPv4; got %hhu, expected value in range 0-32",
bshdr->hm_len);
pim->bsm_dropped++;
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index b3d4444652..cc11a3cc17 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -6323,7 +6323,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
if (!uj && !found_oif) {
vty_out(vty,
- "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
+ "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
src_str, grp_str, state_str, "none", in_ifname,
"none", 0, "--:--:--");
}
@@ -6430,10 +6430,9 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
json_ifp_out);
} else {
vty_out(vty,
- "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
- src_str, grp_str, proto, in_ifname,
- out_ifname, ttl, oif_uptime,
- pim->vrf->name);
+ "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
+ src_str, grp_str, "-", proto, in_ifname,
+ out_ifname, ttl, oif_uptime);
if (first && !fill) {
src_str[0] = '\0';
grp_str[0] = '\0';
@@ -6445,9 +6444,9 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
if (!uj && !found_oif) {
vty_out(vty,
- "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
- src_str, grp_str, proto, in_ifname, "none", 0,
- "--:--:--", pim->vrf->name);
+ "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
+ src_str, grp_str, "-", proto, in_ifname, "none",
+ 0, "--:--:--");
}
}
@@ -9669,15 +9668,14 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
"Desired min transmit interval\n")
#endif /* !HAVE_BFDD */
- DEFUN (ip_msdp_peer,
- ip_msdp_peer_cmd,
- "ip msdp peer A.B.C.D source A.B.C.D",
- IP_STR
- CFG_MSDP_STR
- "Configure MSDP peer\n"
- "peer ip address\n"
- "Source address for TCP connection\n"
- "local ip address\n")
+DEFPY(ip_msdp_peer, ip_msdp_peer_cmd,
+ "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP peer\n"
+ "Peer IP address\n"
+ "Source address for TCP connection\n"
+ "Local IP address\n")
{
const char *vrfname;
char temp_xpath[XPATH_MAXLEN];
@@ -9688,20 +9686,51 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
return CMD_WARNING_CONFIG_FAILED;
snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
+ FRR_PIM_AF_XPATH, "frr-pim:pimd", "pim", vrfname,
+ "frr-routing:ipv4");
snprintf(temp_xpath, sizeof(temp_xpath),
- "/msdp-peer[peer-ip='%s']/source-ip",
- argv[3]->arg);
+ "/msdp-peer[peer-ip='%s']/source-ip", peer_str);
strlcat(msdp_peer_source_xpath, temp_xpath,
sizeof(msdp_peer_source_xpath));
nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
- argv[5]->arg);
+ source_str);
return nb_cli_apply_changes(vty, NULL);
}
+DEFPY(ip_msdp_timers, ip_msdp_timers_cmd,
+ "ip msdp timers (2-600)$keepalive (3-600)$holdtime [(1-600)$connretry]",
+ IP_STR
+ CFG_MSDP_STR
+ "MSDP timers configuration\n"
+ "Keep alive period (in seconds)\n"
+ "Hold time period (in seconds)\n"
+ "Connection retry period (in seconds)\n")
+{
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ snprintf(xpath, sizeof(xpath), FRR_PIM_MSDP_XPATH, "frr-pim:pimd",
+ "pim", vrfname, "frr-routing:ipv4");
+ nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str);
+ nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str);
+ if (connretry_str)
+ nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY,
+ connretry_str);
+ else
+ nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY,
+ NULL);
+
+ nb_cli_apply_changes(vty, xpath);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (no_ip_msdp_peer,
no_ip_msdp_peer_cmd,
"no ip msdp peer A.B.C.D",
@@ -10151,8 +10180,10 @@ static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
json_row = json_object_new_object();
json_object_string_add(json_row, "peer", peer_str);
json_object_string_add(json_row, "local", local_str);
- json_object_string_add(json_row, "meshGroupName",
- mp->mesh_group_name);
+ if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
+ json_object_string_add(json_row,
+ "meshGroupName",
+ mp->mesh_group_name);
json_object_string_add(json_row, "state", state_str);
json_object_string_add(json_row, "upTime", timebuf);
json_object_string_add(json_row, "keepAliveTimer",
@@ -10176,8 +10207,9 @@ static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
} else {
vty_out(vty, "Peer : %s\n", peer_str);
vty_out(vty, " Local : %s\n", local_str);
- vty_out(vty, " Mesh Group : %s\n",
- mp->mesh_group_name);
+ if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
+ vty_out(vty, " Mesh Group : %s\n",
+ mp->mesh_group_name);
vty_out(vty, " State : %s\n", state_str);
vty_out(vty, " Uptime : %s\n", timebuf);
@@ -11322,6 +11354,8 @@ void pim_cmd_init(void)
install_element(CONFIG_NODE, &debug_bsm_cmd);
install_element(CONFIG_NODE, &no_debug_bsm_cmd);
+ install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
+ install_element(VRF_NODE, &ip_msdp_timers_cmd);
install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 353f133001..48b019c8c8 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1139,7 +1139,7 @@ struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
p.family = AF_INET;
p.u.prefix4 = addr;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode,
neigh)) {
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 1bf3a619bf..9ee06edfc1 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -1248,7 +1248,7 @@ int pim_ifchannel_local_membership_add(struct interface *ifp,
AFI_IP, pim->spt.plist);
struct prefix g;
g.family = AF_INET;
- g.prefixlen = IPV4_MAX_PREFIXLEN;
+ g.prefixlen = IPV4_MAX_BITLEN;
g.u.prefix4 = up->sg.grp;
if (prefix_list_apply(plist, &g)
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 3ae7744eb0..afa2db5f15 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -1953,7 +1953,7 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
g.family = AF_INET;
g.u.prefix4 = rec_group;
- g.prefixlen = 32;
+ g.prefixlen = IPV4_MAX_BITLEN;
/* determine filtering status for group */
filtered = pim_is_group_filtered(ifp->info, &rec_group);
diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c
index 47358f38e1..6dda66b79a 100644
--- a/pimd/pim_instance.c
+++ b/pimd/pim_instance.c
@@ -125,6 +125,12 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
pim_instance_mlag_init(pim);
pim->last_route_change_time = -1;
+
+ /* MSDP global timer defaults. */
+ pim->msdp.hold_time = PIM_MSDP_PEER_HOLD_TIME;
+ pim->msdp.keep_alive = PIM_MSDP_PEER_KA_TIME;
+ pim->msdp.connection_retry = PIM_MSDP_PEER_CONNECT_RETRY_TIME;
+
return pim;
}
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index 095c6de549..2a8f0c1216 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -761,25 +761,6 @@ char *pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf,
return buf;
}
-char *pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size,
- bool long_format)
-{
- char peer_str[INET_ADDRSTRLEN];
- char local_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<peer?>", mp->peer, peer_str, sizeof(peer_str));
- if (long_format) {
- pim_inet4_dump("<local?>", mp->local, local_str,
- sizeof(local_str));
- snprintf(buf, buf_size, "MSDP peer %s local %s mg %s", peer_str,
- local_str, mp->mesh_group_name);
- } else {
- snprintf(buf, buf_size, "MSDP peer %s", peer_str);
- }
-
- return buf;
-}
-
static void pim_msdp_peer_state_chg_log(struct pim_msdp_peer *mp)
{
char state_str[PIM_MSDP_STATE_STRLEN];
@@ -937,7 +918,7 @@ static void pim_msdp_peer_hold_timer_setup(struct pim_msdp_peer *mp, bool start)
THREAD_OFF(mp->hold_timer);
if (start) {
thread_add_timer(pim->msdp.master, pim_msdp_peer_hold_timer_cb,
- mp, PIM_MSDP_PEER_HOLD_TIME, &mp->hold_timer);
+ mp, pim->msdp.hold_time, &mp->hold_timer);
}
}
@@ -963,7 +944,7 @@ static void pim_msdp_peer_ka_timer_setup(struct pim_msdp_peer *mp, bool start)
if (start) {
thread_add_timer(mp->pim->msdp.master,
pim_msdp_peer_ka_timer_cb, mp,
- PIM_MSDP_PEER_KA_TIME, &mp->ka_timer);
+ mp->pim->msdp.keep_alive, &mp->ka_timer);
}
}
@@ -1025,9 +1006,9 @@ static void pim_msdp_peer_cr_timer_setup(struct pim_msdp_peer *mp, bool start)
{
THREAD_OFF(mp->cr_timer);
if (start) {
- thread_add_timer(
- mp->pim->msdp.master, pim_msdp_peer_cr_timer_cb, mp,
- PIM_MSDP_PEER_CONNECT_RETRY_TIME, &mp->cr_timer);
+ thread_add_timer(mp->pim->msdp.master,
+ pim_msdp_peer_cr_timer_cb, mp,
+ mp->pim->msdp.connection_retry, &mp->cr_timer);
}
}
@@ -1063,11 +1044,10 @@ static void pim_msdp_addr2su(union sockunion *su, struct in_addr addr)
}
/* 11.2.A1: create a new peer and transition state to listen or connecting */
-static enum pim_msdp_err pim_msdp_peer_new(struct pim_instance *pim,
- struct in_addr peer_addr,
- struct in_addr local_addr,
- const char *mesh_group_name,
- struct pim_msdp_peer **mp_p)
+struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim,
+ const struct in_addr *peer,
+ const struct in_addr *local,
+ const char *mesh_group_name)
{
struct pim_msdp_peer *mp;
@@ -1076,14 +1056,17 @@ static enum pim_msdp_err pim_msdp_peer_new(struct pim_instance *pim,
mp = XCALLOC(MTYPE_PIM_MSDP_PEER, sizeof(*mp));
mp->pim = pim;
- mp->peer = peer_addr;
+ mp->peer = *peer;
pim_inet4_dump("<peer?>", mp->peer, mp->key_str, sizeof(mp->key_str));
pim_msdp_addr2su(&mp->su_peer, mp->peer);
- mp->local = local_addr;
+ mp->local = *local;
/* XXX: originator_id setting needs to move to the mesh group */
- pim->msdp.originator_id = local_addr;
+ pim->msdp.originator_id = *local;
pim_msdp_addr2su(&mp->su_local, mp->local);
- mp->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
+ if (mesh_group_name)
+ mp->mesh_group_name =
+ XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
+
mp->state = PIM_MSDP_INACTIVE;
mp->fd = -1;
strlcpy(mp->last_reset, "-", sizeof(mp->last_reset));
@@ -1112,10 +1095,7 @@ static enum pim_msdp_err pim_msdp_peer_new(struct pim_instance *pim,
} else {
pim_msdp_peer_connect(mp);
}
- if (mp_p) {
- *mp_p = mp;
- }
- return PIM_MSDP_ERR_NONE;
+ return mp;
}
struct pim_msdp_peer *pim_msdp_peer_find(struct pim_instance *pim,
@@ -1127,43 +1107,6 @@ struct pim_msdp_peer *pim_msdp_peer_find(struct pim_instance *pim,
return hash_lookup(pim->msdp.peer_hash, &lookup);
}
-/* add peer configuration if it doesn't already exist */
-enum pim_msdp_err pim_msdp_peer_add(struct pim_instance *pim,
- struct in_addr peer_addr,
- struct in_addr local_addr,
- const char *mesh_group_name,
- struct pim_msdp_peer **mp_p)
-{
- struct pim_msdp_peer *mp;
-
- if (mp_p) {
- *mp_p = NULL;
- }
-
- if (peer_addr.s_addr == local_addr.s_addr) {
- /* skip session setup if config is invalid */
- if (PIM_DEBUG_MSDP_EVENTS) {
- char peer_str[INET_ADDRSTRLEN];
-
- pim_inet4_dump("<peer?>", peer_addr, peer_str,
- sizeof(peer_str));
- zlog_debug("%s add skipped as DIP=SIP", peer_str);
- }
- return PIM_MSDP_ERR_SIP_EQ_DIP;
- }
-
- mp = pim_msdp_peer_find(pim, peer_addr);
- if (mp) {
- if (mp_p) {
- *mp_p = mp;
- }
- return PIM_MSDP_ERR_PEER_EXISTS;
- }
-
- return pim_msdp_peer_new(pim, peer_addr, local_addr, mesh_group_name,
- mp_p);
-}
-
/* release all mem associated with a peer */
static void pim_msdp_peer_free(struct pim_msdp_peer *mp)
{
@@ -1188,36 +1131,38 @@ static void pim_msdp_peer_free(struct pim_msdp_peer *mp)
}
/* delete the peer config */
-static enum pim_msdp_err pim_msdp_peer_do_del(struct pim_msdp_peer *mp)
+void pim_msdp_peer_del(struct pim_msdp_peer **mp)
{
+ if (*mp == NULL)
+ return;
+
/* stop the tcp connection and shutdown all timers */
- pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */);
+ pim_msdp_peer_stop_tcp_conn(*mp, true /* chg_state */);
/* remove the session from various tables */
- listnode_delete(mp->pim->msdp.peer_list, mp);
- hash_release(mp->pim->msdp.peer_hash, mp);
+ listnode_delete((*mp)->pim->msdp.peer_list, *mp);
+ hash_release((*mp)->pim->msdp.peer_hash, *mp);
if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP peer %s deleted", mp->key_str);
+ zlog_debug("MSDP peer %s deleted", (*mp)->key_str);
}
/* free up any associated memory */
- pim_msdp_peer_free(mp);
-
- return PIM_MSDP_ERR_NONE;
+ pim_msdp_peer_free(*mp);
+ *mp = NULL;
}
-enum pim_msdp_err pim_msdp_peer_del(struct pim_instance *pim,
- struct in_addr peer_addr)
+void pim_msdp_peer_change_source(struct pim_msdp_peer *mp,
+ const struct in_addr *addr)
{
- struct pim_msdp_peer *mp;
+ pim_msdp_peer_stop_tcp_conn(mp, true);
- mp = pim_msdp_peer_find(pim, peer_addr);
- if (!mp) {
- return PIM_MSDP_ERR_NO_PEER;
- }
+ mp->local = *addr;
- return pim_msdp_peer_do_del(mp);
+ if (PIM_MSDP_PEER_IS_LISTENER(mp))
+ pim_msdp_peer_listen(mp);
+ else
+ pim_msdp_peer_connect(mp);
}
/* peer hash and peer list helpers */
@@ -1319,7 +1264,7 @@ void pim_msdp_mg_mbr_del(struct pim_msdp_mg *mg, struct pim_msdp_mg_mbr *mbr)
{
/* Delete active peer session if any */
if (mbr->mp) {
- pim_msdp_peer_do_del(mbr->mp);
+ pim_msdp_peer_del(&mbr->mp);
}
listnode_delete(mg->mbr_list, mbr);
@@ -1342,10 +1287,8 @@ static void pim_msdp_src_del(struct pim_msdp_mg *mg)
/* SIP is being removed - tear down all active peer sessions */
for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbr_node, mbr)) {
- if (mbr->mp) {
- pim_msdp_peer_do_del(mbr->mp);
- mbr->mp = NULL;
- }
+ if (mbr->mp)
+ pim_msdp_peer_del(&mbr->mp);
}
if (PIM_DEBUG_MSDP_EVENTS) {
zlog_debug("MSDP mesh-group %s src cleared",
@@ -1396,8 +1339,8 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim,
bool written = false;
for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, mp)) {
- /* Non meshed peers have the group name set to 'default'. */
- if (strcmp(mp->mesh_group_name, "default"))
+ /* Skip meshed group peers. */
+ if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
continue;
vty_out(vty, "%sip msdp peer %pI4 source %pI4\n", spaces,
@@ -1504,8 +1447,8 @@ void pim_msdp_mg_src_add(struct pim_instance *pim, struct pim_msdp_mg *mg,
/* Create data structures and start TCP connection. */
for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbr_node, mbr))
- pim_msdp_peer_add(pim, mbr->mbr_ip, mg->src_ip,
- mg->mesh_group_name, &mbr->mp);
+ mbr->mp = pim_msdp_peer_add(pim, &mbr->mbr_ip, &mg->src_ip,
+ mg->mesh_group_name);
if (PIM_DEBUG_MSDP_EVENTS)
zlog_debug("MSDP mesh-group %s src %pI4 set",
@@ -1524,8 +1467,8 @@ struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_add(struct pim_instance *pim,
/* if valid SIP has been configured add peer session */
if (mg->src_ip.s_addr != INADDR_ANY)
- pim_msdp_peer_add(pim, mbr->mbr_ip, mg->src_ip,
- mg->mesh_group_name, &mbr->mp);
+ mbr->mp = pim_msdp_peer_add(pim, &mbr->mbr_ip, &mg->src_ip,
+ mg->mesh_group_name);
if (PIM_DEBUG_MSDP_EVENTS)
zlog_debug("MSDP mesh-group %s mbr %pI4 created",
diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h
index bb7ee01ad8..a074f21b47 100644
--- a/pimd/pim_msdp.h
+++ b/pimd/pim_msdp.h
@@ -97,7 +97,9 @@ enum pim_msdp_peer_flags {
PIM_MSDP_PEERF_NONE = 0,
PIM_MSDP_PEERF_LISTENER = (1 << 0),
#define PIM_MSDP_PEER_IS_LISTENER(mp) (mp->flags & PIM_MSDP_PEERF_LISTENER)
- PIM_MSDP_PEERF_SA_JUST_SENT = (1 << 1)
+ PIM_MSDP_PEERF_SA_JUST_SENT = (1 << 1),
+ /** Flag to signalize that peer belongs to a group. */
+ PIM_MSDP_PEERF_IN_GROUP = (1 << 2),
};
struct pim_msdp_peer {
@@ -205,6 +207,13 @@ struct pim_msdp {
/** List of mesh groups. */
struct pim_mesh_group_list mglist;
+
+ /** MSDP global hold time period. */
+ uint32_t hold_time;
+ /** MSDP global keep alive period. */
+ uint32_t keep_alive;
+ /** MSDP global connection retry period. */
+ uint32_t connection_retry;
};
#define PIM_MSDP_PEER_READ_ON(mp) \
@@ -222,12 +231,6 @@ struct pim_msdp {
struct pim_instance;
void pim_msdp_init(struct pim_instance *pim, struct thread_master *master);
void pim_msdp_exit(struct pim_instance *pim);
-enum pim_msdp_err pim_msdp_peer_add(struct pim_instance *pim,
- struct in_addr peer, struct in_addr local,
- const char *mesh_group_name,
- struct pim_msdp_peer **mp_p);
-enum pim_msdp_err pim_msdp_peer_del(struct pim_instance *pim,
- struct in_addr peer_addr);
char *pim_msdp_state_dump(enum pim_msdp_peer_state state, char *buf,
int buf_size);
struct pim_msdp_peer *pim_msdp_peer_find(struct pim_instance *pim,
@@ -237,8 +240,6 @@ void pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp);
void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state);
void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str);
int pim_msdp_write(struct thread *thread);
-char *pim_msdp_peer_key_dump(struct pim_msdp_peer *mp, char *buf, int buf_size,
- bool long_format);
int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
const char *spaces);
bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim,
@@ -288,4 +289,33 @@ struct pim_msdp_mg_mbr *pim_msdp_mg_mbr_add(struct pim_instance *pim,
*/
void pim_msdp_mg_mbr_del(struct pim_msdp_mg *mg, struct pim_msdp_mg_mbr *mbr);
+/**
+ * Allocates MSDP peer data structure, adds peer to group name
+ * `mesh_group_name` and starts state machine. If no group name is provided then
+ * the peer will work standalone.
+ *
+ * \param pim PIM instance
+ * \param peer_addr peer address
+ * \param local_addr local listening address
+ * \param mesh_group_name mesh group name (or `NULL` for peers without group).
+ */
+struct pim_msdp_peer *pim_msdp_peer_add(struct pim_instance *pim,
+ const struct in_addr *peer_addr,
+ const struct in_addr *local_addr,
+ const char *mesh_group_name);
+
+/**
+ * Stops peer state machine and free memory.
+ */
+void pim_msdp_peer_del(struct pim_msdp_peer **mp);
+
+/**
+ * Changes peer source address.
+ *
+ * NOTE:
+ * This will cause the connection to drop and start again.
+ */
+void pim_msdp_peer_change_source(struct pim_msdp_peer *mp,
+ const struct in_addr *addr);
+
#endif
diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c
index 4aaf0f53d1..eb5f46951e 100644
--- a/pimd/pim_msdp_packet.c
+++ b/pimd/pim_msdp_packet.c
@@ -505,7 +505,7 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
sg.grp.s_addr = stream_get_ipv4(mp->ibuf);
sg.src.s_addr = stream_get_ipv4(mp->ibuf);
- if (prefix_len != 32) {
+ if (prefix_len != IPV4_MAX_BITLEN) {
/* ignore SA update if the prefix length is not 32 */
flog_err(EC_PIM_MSDP_PACKET,
"rxed sa update with invalid prefix length %d",
@@ -522,11 +522,15 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
* If the message group is not set, i.e. "default", then we assume that
* the message must be forwarded.*/
for (ALL_LIST_ELEMENTS_RO(mp->pim->msdp.peer_list, peer_node, peer)) {
- if (!pim_msdp_peer_rpf_check(peer, rp)
- && (strcmp(mp->mesh_group_name, peer->mesh_group_name)
- || !strcmp(mp->mesh_group_name, "default"))) {
- pim_msdp_pkt_sa_tx_one_to_one_peer(peer, rp, sg);
- }
+ /* Not a RPF peer, so skip it. */
+ if (pim_msdp_peer_rpf_check(peer, rp))
+ continue;
+ /* Don't forward inside the meshed group. */
+ if ((mp->flags & PIM_MSDP_PEERF_IN_GROUP)
+ && strcmp(mp->mesh_group_name, peer->mesh_group_name) == 0)
+ continue;
+
+ pim_msdp_pkt_sa_tx_one_to_one_peer(peer, rp, sg);
}
}
diff --git a/pimd/pim_nb.c b/pimd/pim_nb.c
index ea53f1ef12..6fe078bd8e 100644
--- a/pimd/pim_nb.c
+++ b/pimd/pim_nb.c
@@ -118,6 +118,24 @@ const struct frr_yang_module_info frr_pim_info = {
}
},
{
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time",
+ .cbs = {
+ .modify = pim_msdp_hold_time_modify,
+ }
+ },
+ {
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive",
+ .cbs = {
+ .modify = pim_msdp_keep_alive_modify,
+ }
+ },
+ {
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry",
+ .cbs = {
+ .modify = pim_msdp_connection_retry_modify,
+ }
+ },
+ {
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups",
.cbs = {
.create = pim_msdp_mesh_group_create,
@@ -149,7 +167,6 @@ const struct frr_yang_module_info frr_pim_info = {
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/source-ip",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify,
- .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_destroy,
}
},
{
diff --git a/pimd/pim_nb.h b/pimd/pim_nb.h
index 1959b403ff..f5ebbceb33 100644
--- a/pimd/pim_nb.h
+++ b/pimd/pim_nb.h
@@ -60,6 +60,9 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(
struct nb_cb_destroy_args *args);
+int pim_msdp_hold_time_modify(struct nb_cb_modify_args *args);
+int pim_msdp_keep_alive_modify(struct nb_cb_modify_args *args);
+int pim_msdp_connection_retry_modify(struct nb_cb_modify_args *args);
int pim_msdp_mesh_group_create(struct nb_cb_create_args *args);
int pim_msdp_mesh_group_destroy(struct nb_cb_destroy_args *args);
int pim_msdp_mesh_group_members_create(struct nb_cb_create_args *args);
@@ -72,8 +75,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
struct nb_cb_modify_args *args);
-int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_destroy(
- struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy(
@@ -192,4 +193,6 @@ int routing_control_plane_protocols_name_validate(
#define FRR_IGMP_JOIN_XPATH \
"./frr-igmp:igmp/address-family[address-family='%s']/" \
"static-group[group-addr='%s'][source-addr='%s']"
+#define FRR_PIM_MSDP_XPATH FRR_PIM_AF_XPATH "/msdp"
+
#endif /* _FRR_PIM_NB_H_ */
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index b70656ea7b..dfdbd6dee2 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -243,65 +243,6 @@ static int pim_ssm_cmd_worker(struct pim_instance *pim, const char *plist,
return ret;
}
-static int ip_msdp_peer_cmd_worker(struct pim_instance *pim,
- struct in_addr peer_addr,
- struct in_addr local_addr,
- char *errmsg, size_t errmsg_len)
-{
- enum pim_msdp_err result;
- int ret = NB_OK;
-
- result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
- NULL /* mp_p */);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_OOM:
- ret = NB_ERR;
- snprintf(errmsg, errmsg_len,
- "%% Out of memory");
- break;
- case PIM_MSDP_ERR_PEER_EXISTS:
- ret = NB_ERR;
- snprintf(errmsg, errmsg_len,
- "%% Peer exists");
- break;
- case PIM_MSDP_ERR_MAX_MESH_GROUPS:
- ret = NB_ERR;
- snprintf(errmsg, errmsg_len,
- "%% Only one mesh-group allowed currently");
- break;
- default:
- ret = NB_ERR;
- snprintf(errmsg, errmsg_len,
- "%% peer add failed");
- }
-
- return ret;
-}
-
-static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim,
- struct in_addr peer_addr,
- char *errmsg, size_t errmsg_len)
-{
- enum pim_msdp_err result;
-
- result = pim_msdp_peer_del(pim, peer_addr);
- switch (result) {
- case PIM_MSDP_ERR_NONE:
- break;
- case PIM_MSDP_ERR_NO_PEER:
- snprintf(errmsg, errmsg_len,
- "%% Peer does not exist");
- break;
- default:
- snprintf(errmsg, errmsg_len,
- "%% peer del failed");
- }
-
- return result ? NB_ERR : NB_OK;
-}
-
static int pim_rp_cmd_worker(struct pim_instance *pim,
struct in_addr rp_addr,
struct prefix group, const char *plist,
@@ -1006,6 +947,95 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
/*
* XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/hold-time
+ */
+int pim_msdp_hold_time_modify(struct nb_cb_modify_args *args)
+{
+ struct pim_instance *pim;
+ struct vrf *vrf;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (yang_dnode_get_uint32(args->dnode, NULL)
+ <= yang_dnode_get_uint32(args->dnode, "../keep-alive")) {
+ snprintf(
+ args->errmsg, args->errmsg_len,
+ "Hold time must be greater than keep alive interval");
+ return NB_ERR_VALIDATION;
+ }
+ break;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ pim->msdp.hold_time = yang_dnode_get_uint32(args->dnode, NULL);
+ break;
+ }
+
+ return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/keep-alive
+ */
+int pim_msdp_keep_alive_modify(struct nb_cb_modify_args *args)
+{
+ struct pim_instance *pim;
+ struct vrf *vrf;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ if (yang_dnode_get_uint32(args->dnode, NULL)
+ >= yang_dnode_get_uint32(args->dnode, "../hold-time")) {
+ snprintf(
+ args->errmsg, args->errmsg_len,
+ "Keep alive must be less than hold time interval");
+ return NB_ERR_VALIDATION;
+ }
+ break;
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ pim->msdp.keep_alive = yang_dnode_get_uint32(args->dnode, NULL);
+ break;
+ }
+
+ return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp/connection-retry
+ */
+int pim_msdp_connection_retry_modify(struct nb_cb_modify_args *args)
+{
+ struct pim_instance *pim;
+ struct vrf *vrf;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ pim->msdp.connection_retry =
+ yang_dnode_get_uint32(args->dnode, NULL);
+ break;
+ }
+
+ return NB_OK;
+}
+
+/*
+ * XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-mesh-groups
*/
int pim_msdp_mesh_group_create(struct nb_cb_create_args *args)
@@ -1163,11 +1193,25 @@ int pim_msdp_mesh_group_members_destroy(struct nb_cb_destroy_args *args)
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_create(
struct nb_cb_create_args *args)
{
+ struct pim_msdp_peer *mp;
+ struct pim_instance *pim;
+ struct vrf *vrf;
+ struct ipaddr peer_ip;
+ struct ipaddr source_ip;
+
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
+ break;
case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ yang_dnode_get_ip(&peer_ip, args->dnode, "./peer-ip");
+ yang_dnode_get_ip(&source_ip, args->dnode, "./source-ip");
+ mp = pim_msdp_peer_add(pim, &peer_ip.ipaddr_v4,
+ &source_ip.ipaddr_v4, NULL);
+ nb_running_set_entry(args->dnode, mp);
break;
}
@@ -1177,10 +1221,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(
struct nb_cb_destroy_args *args)
{
- int result;
- struct pim_instance *pim;
- struct ipaddr peer_ip;
- struct vrf *vrf;
+ struct pim_msdp_peer *mp;
switch (args->event) {
case NB_EV_VALIDATE:
@@ -1188,16 +1229,8 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
- vrf = nb_running_get_entry(args->dnode, NULL, true);
- pim = vrf->info;
- yang_dnode_get_ip(&peer_ip, args->dnode, "./peer-ip");
- result = ip_no_msdp_peer_cmd_worker(pim, peer_ip.ip._v4_addr,
- args->errmsg,
- args->errmsg_len);
-
- if (result)
- return NB_ERR_INCONSISTENCY;
-
+ mp = nb_running_unset_entry(args->dnode);
+ pim_msdp_peer_del(&mp);
break;
}
@@ -1210,64 +1243,18 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(
struct nb_cb_modify_args *args)
{
- int result;
- struct vrf *vrf;
- struct pim_instance *pim;
- struct ipaddr peer_ip;
+ struct pim_msdp_peer *mp;
struct ipaddr source_ip;
- const struct lyd_node *mesh_group_name_dnode;
- const char *mesh_group_name;
switch (args->event) {
case NB_EV_VALIDATE:
- mesh_group_name_dnode =
- yang_dnode_get(args->dnode,
- "../../msdp-mesh-group/mesh-group-name");
- if (mesh_group_name_dnode) {
- mesh_group_name =
- yang_dnode_get_string(mesh_group_name_dnode,
- ".");
- if (strcmp(mesh_group_name, "default")) {
- /* currently only one mesh-group can exist at a
- * time
- */
- snprintf(args->errmsg, args->errmsg_len,
- "%% Only one mesh-group allowed currently");
- return NB_ERR_VALIDATION;
- }
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
- vrf = nb_running_get_entry(args->dnode, NULL, true);
- pim = vrf->info;
- yang_dnode_get_ip(&peer_ip, args->dnode, "../peer-ip");
+ mp = nb_running_get_entry(args->dnode, NULL, true);
yang_dnode_get_ip(&source_ip, args->dnode, NULL);
-
- result = ip_msdp_peer_cmd_worker(pim, peer_ip.ip._v4_addr,
- source_ip.ip._v4_addr,
- args->errmsg,
- args->errmsg_len);
-
- if (result)
- return NB_ERR_INCONSISTENCY;
-
- break;
- }
-
- return NB_OK;
-}
-
-int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_destroy(
- struct nb_cb_destroy_args *args)
-{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
+ pim_msdp_peer_change_source(mp, &source_ip.ipaddr_v4);
break;
}
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index 90b69a54f2..9d5b864ab0 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -89,7 +89,7 @@ void pim_register_stop_send(struct interface *ifp, struct prefix_sg *sg,
p.family = AF_INET;
p.u.prefix4 = sg->src;
- p.prefixlen = 32;
+ p.prefixlen = IPV4_MAX_BITLEN;
length = pim_encode_addr_ucast(b1, &p);
b1length += length;
@@ -393,7 +393,7 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
plist = prefix_list_lookup(AFI_IP, pim->register_plist);
src.family = AF_INET;
- src.prefixlen = IPV4_MAX_PREFIXLEN;
+ src.prefixlen = IPV4_MAX_BITLEN;
src.u.prefix4 = sg.src;
if (prefix_list_apply(plist, &src) == PREFIX_DENY) {
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index a31fec036f..b6521132f7 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -124,7 +124,7 @@ void pim_rp_init(struct pim_instance *pim)
}
rp_info->group.family = AF_INET;
rp_info->rp.rpf_addr.family = AF_INET;
- rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN;
+ rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
rp_info->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
listnode_add(pim->rp_list, rp_info);
@@ -417,7 +417,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
rp_info->rp.rpf_addr.family = AF_INET;
- rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_PREFIXLEN;
+ rp_info->rp.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
rp_info->rp.rpf_addr.u.prefix4 = rp_addr;
prefix_copy(&rp_info->group, &group);
rp_info->rp_src = rp_src_flag;
@@ -1036,7 +1036,7 @@ int pim_rp_i_am_rp(struct pim_instance *pim, struct in_addr group)
memset(&g, 0, sizeof(g));
g.family = AF_INET;
- g.prefixlen = 32;
+ g.prefixlen = IPV4_MAX_BITLEN;
g.u.prefix4 = group;
rp_info = pim_rp_find_match_group(pim, &g);
@@ -1059,7 +1059,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group)
memset(&g, 0, sizeof(g));
g.family = AF_INET;
- g.prefixlen = 32;
+ g.prefixlen = IPV4_MAX_BITLEN;
g.u.prefix4 = group;
rp_info = pim_rp_find_match_group(pim, &g);
@@ -1103,7 +1103,7 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, struct in_addr *up,
memset(&g, 0, sizeof(g));
g.family = AF_INET;
- g.prefixlen = 32;
+ g.prefixlen = IPV4_MAX_BITLEN;
g.u.prefix4 = group;
rp_info = pim_rp_find_match_group(pim, &g);
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index f21c369b8d..8e6ff2f3a7 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -481,7 +481,7 @@ int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size)
p->family = AF_INET; /* notice: AF_INET !=
PIM_MSG_ADDRESS_FAMILY_IPV4 */
memcpy(&p->u.prefix4, addr, sizeof(struct in_addr));
- p->prefixlen = IPV4_MAX_PREFIXLEN;
+ p->prefixlen = IPV4_MAX_BITLEN;
addr += sizeof(struct in_addr);
break;
@@ -495,7 +495,7 @@ int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size)
}
p->family = AF_INET6;
- p->prefixlen = IPV6_MAX_PREFIXLEN;
+ p->prefixlen = IPV6_MAX_BITLEN;
memcpy(&p->u.prefix6, addr, sizeof(struct in6_addr));
addr += sizeof(struct in6_addr);
@@ -626,7 +626,7 @@ int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags,
messages
received with any other mask length.
*/
- if (mask_len != 32) {
+ if (mask_len != IPV4_MAX_BITLEN) {
zlog_warn("%s: IPv4 bad source address mask: %d",
__func__, mask_len);
return -4;
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 918a9a9c7d..2b674b4234 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -2174,7 +2174,7 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
np = prefix_list_lookup(AFI_IP, nlist);
g.family = AF_INET;
- g.prefixlen = IPV4_MAX_PREFIXLEN;
+ g.prefixlen = IPV4_MAX_BITLEN;
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (up->sg.src.s_addr != INADDR_ANY)
diff --git a/pimd/pim_util.c b/pimd/pim_util.c
index 15bde256da..decc491ede 100644
--- a/pimd/pim_util.c
+++ b/pimd/pim_util.c
@@ -115,7 +115,7 @@ int pim_is_group_224_0_0_0_24(struct in_addr group_addr)
group.family = AF_INET;
group.u.prefix4 = group_addr;
- group.prefixlen = IPV4_MAX_PREFIXLEN;
+ group.prefixlen = IPV4_MAX_BITLEN;
return prefix_match(&group_224, &group);
}
@@ -134,7 +134,7 @@ int pim_is_group_224_4(struct in_addr group_addr)
group.family = AF_INET;
group.u.prefix4 = group_addr;
- group.prefixlen = 32;
+ group.prefixlen = IPV4_MAX_BITLEN;
return prefix_match(&group_all, &group);
}
@@ -148,7 +148,7 @@ bool pim_is_group_filtered(struct pim_interface *pim_ifp, struct in_addr *grp)
return false;
grp_pfx.family = AF_INET;
- grp_pfx.prefixlen = 32;
+ grp_pfx.prefixlen = IPV4_MAX_BITLEN;
grp_pfx.u.prefix4 = *grp;
pl = prefix_list_lookup(AFI_IP, pim_ifp->boundary_oil_plist);
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index c049ef4029..95882cf58f 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -263,6 +263,17 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
}
}
+ if (pim->msdp.hold_time != PIM_MSDP_PEER_HOLD_TIME
+ || pim->msdp.keep_alive != PIM_MSDP_PEER_KA_TIME
+ || pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME) {
+ vty_out(vty, "%sip msdp timers %u %u", spaces,
+ pim->msdp.hold_time, pim->msdp.keep_alive);
+ if (pim->msdp.connection_retry
+ != PIM_MSDP_PEER_CONNECT_RETRY_TIME)
+ vty_out(vty, " %u", pim->msdp.connection_retry);
+ vty_out(vty, "\n");
+ }
+
return writes;
}
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index 9ccf1fedd4..dce936b8a9 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -276,7 +276,7 @@ static int zclient_read_nexthop(struct pim_instance *pim,
nexthop_tab[num_ifindex].ifindex = stream_getl(s);
p.family = AF_INET6;
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
memcpy(&p.u.prefix6,
&nexthop_tab[num_ifindex].nexthop_addr.u.prefix6,
sizeof(struct in6_addr));
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index bdae2c5ef5..7a8e10f30b 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -160,7 +160,7 @@ static void rip_request_interface_send(struct interface *ifp, uint8_t version)
* destination addr */
to.sin_addr = connected->destination->u.prefix4;
else if (connected->address->prefixlen
- < IPV4_MAX_PREFIXLEN)
+ < IPV4_MAX_BITLEN)
/* calculate the appropriate broadcast
* address */
to.sin_addr.s_addr = ipv4_broadcast_addr(
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 7d940efd9c..ccd4bf1bac 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -2143,7 +2143,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
&rp->p)) {
if ((ifc->address->prefixlen
!= rp->p.prefixlen)
- && (rp->p.prefixlen != 32))
+ && (rp->p.prefixlen
+ != IPV4_MAX_BITLEN))
continue;
} else {
memcpy(&classfull, &rp->p,
@@ -2429,7 +2430,7 @@ static void rip_update_interface(struct connected *ifc, uint8_t version,
/* use specified broadcast or peer destination
* addr */
to.sin_addr = ifc->destination->u.prefix4;
- else if (ifc->address->prefixlen < IPV4_MAX_PREFIXLEN)
+ else if (ifc->address->prefixlen < IPV4_MAX_BITLEN)
/* calculate the appropriate broadcast address
*/
to.sin_addr.s_addr = ipv4_broadcast_addr(
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index a0ea18f3e9..cbd2c22893 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -1194,7 +1194,7 @@ static void ripng_response_process(struct ripng_packet *packet, int size,
/* - is the prefix length valid (i.e., between 0 and 128,
inclusive) */
- if (rte->prefixlen > 128) {
+ if (rte->prefixlen > IPV6_MAX_BITLEN) {
zlog_warn("Invalid prefix length %pI6/%d from %pI6%%%s",
&rte->addr, rte->prefixlen,
&from->sin6_addr, ifp->name);
diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c
index 250151b1fa..b6581cd9e6 100644
--- a/sharpd/sharp_vty.c
+++ b/sharpd/sharp_vty.c
@@ -97,8 +97,8 @@ DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
if (n) {
type_import = false;
- p.prefixlen = 128;
- memcpy(&p.u.prefix6, &nhop, 16);
+ p.prefixlen = IPV6_MAX_BITLEN;
+ memcpy(&p.u.prefix6, &nhop, IPV6_MAX_BYTELEN);
p.family = AF_INET6;
} else {
type_import = true;
@@ -141,7 +141,7 @@ DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
if (n) {
type_import = false;
- p.prefixlen = 32;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = nhop;
p.family = AF_INET;
}
@@ -239,11 +239,11 @@ DEFPY (install_routes,
if (start4.s_addr != INADDR_ANY) {
prefix.family = AF_INET;
- prefix.prefixlen = 32;
+ prefix.prefixlen = IPV4_MAX_BITLEN;
prefix.u.prefix4 = start4;
} else {
prefix.family = AF_INET6;
- prefix.prefixlen = 128;
+ prefix.prefixlen = IPV6_MAX_BITLEN;
prefix.u.prefix6 = start6;
}
sg.r.orig_prefix = prefix;
@@ -383,11 +383,11 @@ DEFPY (install_seg6_routes,
if (start4.s_addr != INADDR_ANY) {
prefix.family = AF_INET;
- prefix.prefixlen = 32;
+ prefix.prefixlen = IPV4_MAX_BITLEN;
prefix.u.prefix4 = start4;
} else {
prefix.family = AF_INET6;
- prefix.prefixlen = 128;
+ prefix.prefixlen = IPV6_MAX_BITLEN;
prefix.u.prefix6 = start6;
}
sg.r.orig_prefix = prefix;
@@ -568,11 +568,11 @@ DEFPY (remove_routes,
if (start4.s_addr != INADDR_ANY) {
prefix.family = AF_INET;
- prefix.prefixlen = 32;
+ prefix.prefixlen = IPV4_MAX_BITLEN;
prefix.u.prefix4 = start4;
} else {
prefix.family = AF_INET6;
- prefix.prefixlen = 128;
+ prefix.prefixlen = IPV6_MAX_BITLEN;
prefix.u.prefix6 = start6;
}
@@ -878,7 +878,7 @@ DEFPY (neigh_discover,
if (dst4.s_addr != INADDR_ANY) {
prefix.family = AF_INET;
- prefix.prefixlen = 32;
+ prefix.prefixlen = IPV4_MAX_BITLEN;
prefix.u.prefix4 = dst4;
} else {
prefix.family = AF_INET6;
diff --git a/staticd/static_nht.c b/staticd/static_nht.c
index feb6e0f993..d42c5c2777 100644
--- a/staticd/static_nht.c
+++ b/staticd/static_nht.c
@@ -52,7 +52,8 @@ static void static_nht_update_path(struct route_node *rn,
nh->nh_valid = !!nh_num;
if (nhp->family == AF_INET6
- && memcmp(&nhp->u.prefix6, &nh->addr.ipv6, 16) == 0)
+ && memcmp(&nhp->u.prefix6, &nh->addr.ipv6, IPV6_MAX_BYTELEN)
+ == 0)
nh->nh_valid = !!nh_num;
if (nh->state == STATIC_START)
diff --git a/tests/.gitignore b/tests/.gitignore
index fb2edc939a..3fad1b0813 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -25,6 +25,8 @@
/lib/test_atomlist
/lib/test_buffer
/lib/test_checksum
+/lib/test_frrscript
+/lib/test_frrlua
/lib/test_graph
/lib/test_heavy
/lib/test_heavy_thread
diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c
index 44b55a2381..45e9912a31 100644
--- a/tests/bgpd/test_peer_attr.c
+++ b/tests/bgpd/test_peer_attr.c
@@ -31,6 +31,7 @@
#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_network.h"
#include "lib/routing_nb.h"
+#include "lib/northbound_cli.h"
#include "bgpd/bgp_nb.h"
#ifdef ENABLE_BGP_VNC
diff --git a/tests/lib/script1.lua b/tests/lib/script1.lua
new file mode 100644
index 0000000000..e9ebc29bd9
--- /dev/null
+++ b/tests/lib/script1.lua
@@ -0,0 +1 @@
+a = a + b
diff --git a/tests/lib/test_frrlua.c b/tests/lib/test_frrlua.c
new file mode 100644
index 0000000000..a81446f9ca
--- /dev/null
+++ b/tests/lib/test_frrlua.c
@@ -0,0 +1,111 @@
+/*
+ * frrlua unit tests
+ * Copyright (C) 2021 Donald Lee
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+#include "string.h"
+#include "stdio.h"
+#include "lib/frrlua.h"
+
+static void test_encode_decode(void)
+{
+ lua_State *L = luaL_newstate();
+
+ long long a = 123;
+ long long b = a;
+
+ lua_pushintegerp(L, &a);
+ lua_decode_integerp(L, -1, &a);
+ assert(a == b);
+ assert(lua_gettop(L) == 0);
+
+ time_t time_a = 100;
+ time_t time_b = time_a;
+
+ lua_pushtimet(L, &time_a);
+ lua_decode_timet(L, -1, &time_a);
+ assert(time_a == time_b);
+ assert(lua_gettop(L) == 0);
+
+ char str_b[] = "Hello", str_a[6];
+
+ strlcpy(str_a, str_b, sizeof(str_b));
+ lua_pushstring_wrapper(L, str_a);
+ lua_decode_stringp(L, -1, str_a);
+ assert(strncmp(str_a, str_b, sizeof(str_b)) == 0);
+ assert(lua_gettop(L) == 0);
+
+ char p_b_str[] = "10.0.0.0/24", p_a_str[12];
+ struct prefix p_a;
+
+ strlcpy(p_a_str, p_b_str, sizeof(p_b_str));
+ str2prefix(p_a_str, &p_a);
+ lua_pushprefix(L, &p_a);
+ lua_decode_prefix(L, -1, &p_a);
+ prefix2str(&p_a, p_a_str, sizeof(p_b_str));
+ assert(strncmp(p_a_str, p_b_str, sizeof(p_b_str)) == 0);
+ assert(lua_gettop(L) == 0);
+
+ struct interface ifp_a;
+ struct interface ifp_b = ifp_a;
+
+ lua_pushinterface(L, &ifp_a);
+ lua_decode_interface(L, -1, &ifp_a);
+ assert(strncmp(ifp_a.name, ifp_b.name, sizeof(ifp_b.name)) == 0);
+ assert(ifp_a.ifindex == ifp_b.ifindex);
+ assert(ifp_a.status == ifp_b.status);
+ assert(ifp_a.flags == ifp_b.flags);
+ assert(ifp_a.metric == ifp_b.metric);
+ assert(ifp_a.speed == ifp_b.speed);
+ assert(ifp_a.mtu == ifp_b.mtu);
+ assert(ifp_a.mtu6 == ifp_b.mtu6);
+ assert(ifp_a.bandwidth == ifp_b.bandwidth);
+ assert(ifp_a.link_ifindex == ifp_b.link_ifindex);
+ assert(ifp_a.ll_type == ifp_b.ll_type);
+ assert(lua_gettop(L) == 0);
+
+ struct in_addr addr_a;
+ struct in_addr addr_b = addr_a;
+
+ lua_pushinaddr(L, &addr_a);
+ lua_decode_inaddr(L, -1, &addr_a);
+ assert(addr_a.s_addr == addr_b.s_addr);
+ assert(lua_gettop(L) == 0);
+
+ struct in6_addr in6addr_a;
+ struct in6_addr in6addr_b = in6addr_a;
+
+ lua_pushin6addr(L, &in6addr_a);
+ lua_decode_in6addr(L, -1, &in6addr_a);
+ assert(in6addr_cmp(&in6addr_a, &in6addr_b) == 0);
+ assert(lua_gettop(L) == 0);
+
+ union sockunion su_a, su_b;
+
+ memset(&su_a, 0, sizeof(union sockunion));
+ memset(&su_b, 0, sizeof(union sockunion));
+ lua_pushsockunion(L, &su_a);
+ lua_decode_sockunion(L, -1, &su_a);
+ assert(sockunion_cmp(&su_a, &su_b) == 0);
+ assert(lua_gettop(L) == 0);
+}
+
+int main(int argc, char **argv)
+{
+ test_encode_decode();
+}
diff --git a/tests/lib/test_frrlua.py b/tests/lib/test_frrlua.py
new file mode 100644
index 0000000000..2f6ddc1c07
--- /dev/null
+++ b/tests/lib/test_frrlua.py
@@ -0,0 +1,14 @@
+import frrtest
+import pytest
+
+if 'S["SCRIPTING_TRUE"]=""\n' not in open("../config.status").readlines():
+ class TestFrrlua:
+ @pytest.mark.skipif(True, reason="Test unsupported")
+ def test_exit_cleanly(self):
+ pass
+else:
+
+ class TestFrrlua(frrtest.TestMultiOut):
+ program = "./test_frrlua"
+
+ TestFrrlua.exit_cleanly()
diff --git a/tests/lib/test_frrscript.c b/tests/lib/test_frrscript.c
new file mode 100644
index 0000000000..bd75cc5552
--- /dev/null
+++ b/tests/lib/test_frrscript.c
@@ -0,0 +1,37 @@
+/*
+ * frrscript unit tests
+ * Copyright (C) 2021 Donald Lee
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "lib/frrscript.h"
+
+int main(int argc, char **argv)
+{
+ frrscript_init("./lib");
+
+ struct frrscript *fs = frrscript_load("script1", NULL);
+ long long a = 100, b = 200;
+ int result = frrscript_call(fs, ("a", &a), ("b", &b));
+
+ assert(result == 0);
+ assert(a == 300);
+ assert(b == 200);
+
+ return 0;
+}
diff --git a/tests/lib/test_frrscript.py b/tests/lib/test_frrscript.py
new file mode 100644
index 0000000000..046d97b014
--- /dev/null
+++ b/tests/lib/test_frrscript.py
@@ -0,0 +1,14 @@
+import frrtest
+import pytest
+
+if 'S["SCRIPTING_TRUE"]=""\n' not in open("../config.status").readlines():
+ class TestFrrscript:
+ @pytest.mark.skipif(True, reason="Test unsupported")
+ def test_exit_cleanly(self):
+ pass
+else:
+
+ class TestFrrscript(frrtest.TestMultiOut):
+ program = "./test_frrscript"
+
+ TestFrrscript.exit_cleanly()
diff --git a/tests/subdir.am b/tests/subdir.am
index ca477851e3..c2153140f5 100644
--- a/tests/subdir.am
+++ b/tests/subdir.am
@@ -59,6 +59,15 @@ TESTS_ZEBRA =
IGNORE_ZEBRA = --ignore=zebra/
endif
+if SCRIPTING
+TESTS_SCRIPTING = \
+ tests/lib/test_frrlua \
+ tests/lib/test_frrscript \
+ #end
+else
+TESTS_SCRIPTING =
+endif
+
clippy_scan += \
tests/lib/cli/test_cli.c \
tests/ospf6d/test_lsdb.c \
@@ -104,6 +113,7 @@ check_PROGRAMS = \
$(TESTS_OSPFD) \
$(TESTS_OSPF6D) \
$(TESTS_ZEBRA) \
+ $(TESTS_SCRIPTING) \
# end
if GRPC
@@ -289,6 +299,16 @@ tests_lib_test_checksum_CFLAGS = $(TESTS_CFLAGS)
tests_lib_test_checksum_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_lib_test_checksum_LDADD = $(ALL_TESTS_LDADD)
tests_lib_test_checksum_SOURCES = tests/lib/test_checksum.c
+if SCRIPTING
+tests_lib_test_frrlua_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_frrlua_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_frrlua_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_frrlua_SOURCES = tests/lib/test_frrlua.c
+tests_lib_test_frrscript_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_frrscript_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_frrscript_LDADD = $(ALL_TESTS_LDADD)
+tests_lib_test_frrscript_SOURCES = tests/lib/test_frrscript.c
+endif
tests_lib_test_graph_CFLAGS = $(TESTS_CFLAGS)
tests_lib_test_graph_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_lib_test_graph_LDADD = $(ALL_TESTS_LDADD)
@@ -464,6 +484,14 @@ EXTRA_DIST += \
tests/zebra/test_lm_plugin.refout \
# end
+
+if SCRIPTING
+EXTRA_DIST += \
+ tests/lib/test_frrscript.py \
+ tests/lib/test_frrlua.py \
+ #end
+endif
+
.PHONY: tests/tests.xml
tests/tests.xml: $(check_PROGRAMS)
( cd tests; $(PYTHON) ../$(srcdir)/tests/runtests.py --junitxml=tests.xml -v ../$(srcdir)/tests $(IGNORE_BGPD) $(IGNORE_ISISD) $(IGNORE_OSPF6D); )
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/__init__.py b/tests/topotests/bgp_default_afi_safi/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/topotests/bgp_default_ipv4_ipv6_unicast/__init__.py
+++ b/tests/topotests/bgp_default_afi_safi/__init__.py
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/bgpd.conf b/tests/topotests/bgp_default_afi_safi/r1/bgpd.conf
index bf39152ea8..bf39152ea8 100644
--- a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/bgpd.conf
+++ b/tests/topotests/bgp_default_afi_safi/r1/bgpd.conf
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/zebra.conf b/tests/topotests/bgp_default_afi_safi/r1/zebra.conf
index 697765168d..697765168d 100644
--- a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/zebra.conf
+++ b/tests/topotests/bgp_default_afi_safi/r1/zebra.conf
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/bgpd.conf b/tests/topotests/bgp_default_afi_safi/r2/bgpd.conf
index abbd1b86fa..abbd1b86fa 100644
--- a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/bgpd.conf
+++ b/tests/topotests/bgp_default_afi_safi/r2/bgpd.conf
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/zebra.conf b/tests/topotests/bgp_default_afi_safi/r2/zebra.conf
index 606c17bec9..606c17bec9 100644
--- a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/zebra.conf
+++ b/tests/topotests/bgp_default_afi_safi/r2/zebra.conf
diff --git a/tests/topotests/bgp_default_afi_safi/r3/bgpd.conf b/tests/topotests/bgp_default_afi_safi/r3/bgpd.conf
new file mode 100644
index 0000000000..f3ec3f06c5
--- /dev/null
+++ b/tests/topotests/bgp_default_afi_safi/r3/bgpd.conf
@@ -0,0 +1,5 @@
+!
+router bgp 65001
+ no bgp default ipv4-unicast
+ bgp default l2vpn-evpn
+!
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/zebra.conf b/tests/topotests/bgp_default_afi_safi/r3/zebra.conf
index e9fdfb70c5..e9fdfb70c5 100644
--- a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/zebra.conf
+++ b/tests/topotests/bgp_default_afi_safi/r3/zebra.conf
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/bgpd.conf b/tests/topotests/bgp_default_afi_safi/r4/bgpd.conf
index a405c047ca..8a6af55ee7 100644
--- a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/bgpd.conf
+++ b/tests/topotests/bgp_default_afi_safi/r4/bgpd.conf
@@ -1,4 +1,5 @@
!
router bgp 65001
bgp default ipv6-unicast
+ bgp default l2vpn-evpn
!
diff --git a/tests/topotests/bgp_default_afi_safi/r4/zebra.conf b/tests/topotests/bgp_default_afi_safi/r4/zebra.conf
new file mode 100644
index 0000000000..e9fdfb70c5
--- /dev/null
+++ b/tests/topotests/bgp_default_afi_safi/r4/zebra.conf
@@ -0,0 +1,6 @@
+!
+interface r3-eth0
+ ip address 192.168.255.3/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/test_bgp-default-ipv4-ipv6-unicast.py b/tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py
index f9aa94fd14..28117b7fe4 100644
--- a/tests/topotests/bgp_default_ipv4_ipv6_unicast/test_bgp-default-ipv4-ipv6-unicast.py
+++ b/tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py
@@ -20,12 +20,13 @@
#
"""
-Test if `bgp default ipv4-unicast` and `bgp default ipv6-unicast`
-commands work as expected.
+Test if `bgp default ipv4-unicast`, `bgp default ipv6-unicast`
+and `bgp default l2vpn-evpn` commands work as expected.
STEP 1: 'Check if neighbor 192.168.255.254 is enabled for ipv4 address-family only'
STEP 2: 'Check if neighbor 192.168.255.254 is enabled for ipv6 address-family only'
-STEP 3: 'Check if neighbor 192.168.255.254 is enabled for ipv4 and ipv6 address-families'
+STEP 3: 'Check if neighbor 192.168.255.254 is enabled for l2vpn evpn address-family only'
+STEP 4: 'Check if neighbor 192.168.255.254 is enabled for ipv4/ipv6 unicast and l2vpn evpn address-families'
"""
import os
@@ -98,7 +99,7 @@ def test_bgp_default_ipv4_ipv6_unicast():
output = json.loads(tgen.gears["r1"].vtysh_cmd("show bgp summary json"))
- if "ipv4Unicast" in output and "ipv6Unicast" not in output:
+ if len(output.keys()) == 1 and "ipv4Unicast" in output:
return True
return False
@@ -113,28 +114,48 @@ def test_bgp_default_ipv4_ipv6_unicast():
output = json.loads(tgen.gears["r2"].vtysh_cmd("show bgp summary json"))
- if "ipv4Unicast" not in output and "ipv6Unicast" in output:
+ if len(output.keys()) == 1 and "ipv6Unicast" in output:
return True
return False
assert _bgp_neighbor_ipv6_af_only() == True
- step(
- "Check if neighbor 192.168.255.254 is enabled for ipv4 and ipv6 address-families"
- )
+ step("Check if neighbor 192.168.255.254 is enabled for evpn address-family only")
- def _bgp_neighbor_ipv4_and_ipv6_af():
+ def _bgp_neighbor_evpn_af_only():
tgen.gears["r3"].vtysh_cmd(
"conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external"
)
output = json.loads(tgen.gears["r3"].vtysh_cmd("show bgp summary json"))
- if "ipv4Unicast" in output and "ipv6Unicast" in output:
+ if len(output.keys()) == 1 and "l2VpnEvpn" in output:
+ return True
+ return False
+
+ assert _bgp_neighbor_evpn_af_only() == True
+
+ step(
+ "Check if neighbor 192.168.255.254 is enabled for ipv4/ipv6 unicast and evpn address-families"
+ )
+
+ def _bgp_neighbor_ipv4_ipv6_and_evpn_af():
+ tgen.gears["r4"].vtysh_cmd(
+ "conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external"
+ )
+
+ output = json.loads(tgen.gears["r4"].vtysh_cmd("show bgp summary json"))
+
+ if (
+ len(output.keys()) == 3
+ and "ipv4Unicast" in output
+ and "ipv6Unicast" in output
+ and "l2VpnEvpn" in output
+ ):
return True
return False
- assert _bgp_neighbor_ipv4_and_ipv6_af() == True
+ assert _bgp_neighbor_ipv4_ipv6_and_evpn_af() == True
if __name__ == "__main__":
diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py
index db7b3586f1..a236a916b5 100644
--- a/tests/topotests/lib/bgp.py
+++ b/tests/topotests/lib/bgp.py
@@ -989,7 +989,7 @@ def modify_bgp_config_when_bgpd_down(tgen, topo, input_dict):
#############################################
# Verification APIs
#############################################
-@retry(attempts=4, wait=2, return_is_str=True)
+@retry(retry_timeout=8)
def verify_router_id(tgen, topo, input_dict, expected=True):
"""
Running command "show ip bgp json" for DUT and reading router-id
@@ -1061,7 +1061,7 @@ def verify_router_id(tgen, topo, input_dict, expected=True):
return True
-@retry(attempts=50, wait=3, return_is_str=True)
+@retry(retry_timeout=150)
def verify_bgp_convergence(tgen, topo, dut=None, expected=True):
"""
API will verify if BGP is converged with in the given time frame.
@@ -1266,7 +1266,7 @@ def verify_bgp_convergence(tgen, topo, dut=None, expected=True):
return True
-@retry(attempts=4, wait=4, return_is_str=True)
+@retry(retry_timeout=16)
def verify_bgp_community(
tgen, addr_type, router, network, input_dict=None, vrf=None, bestpath=False, expected=True
):
@@ -1427,7 +1427,7 @@ def modify_as_number(tgen, topo, input_dict):
return True
-@retry(attempts=4, wait=2, return_is_str=True)
+@retry(retry_timeout=8)
def verify_as_numbers(tgen, topo, input_dict, expected=True):
"""
This API is to verify AS numbers for given DUT by running
@@ -1527,7 +1527,7 @@ def verify_as_numbers(tgen, topo, input_dict, expected=True):
return True
-@retry(attempts=50, wait=3, return_is_str=True)
+@retry(retry_timeout=150)
def verify_bgp_convergence_from_running_config(tgen, dut=None, expected=True):
"""
API to verify BGP convergence b/w loopback and physical interface.
@@ -2083,7 +2083,7 @@ def verify_bgp_timers_and_functionality(tgen, topo, input_dict):
return True
-@retry(attempts=4, wait=4, return_is_str=True)
+@retry(retry_timeout=16)
def verify_bgp_attributes(
tgen,
addr_type,
@@ -2223,7 +2223,7 @@ def verify_bgp_attributes(
return True
-@retry(attempts=4, wait=2, return_is_str=True)
+@retry(retry_timeout=8)
def verify_best_path_as_per_bgp_attribute(
tgen, addr_type, router, input_dict, attribute, expected=True
):
@@ -2429,7 +2429,7 @@ def verify_best_path_as_per_bgp_attribute(
return True
-@retry(attempts=5, wait=2, return_is_str=True)
+@retry(retry_timeout=10)
def verify_best_path_as_per_admin_distance(
tgen, addr_type, router, input_dict, attribute, expected=True
):
@@ -2543,7 +2543,7 @@ def verify_best_path_as_per_admin_distance(
return True
-@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
+@retry(retry_timeout=10, initial_wait=2)
def verify_bgp_rib(
tgen, addr_type, dut, input_dict, next_hop=None, aspath=None, multi_nh=None, expected=True
):
@@ -2846,7 +2846,7 @@ def verify_bgp_rib(
return True
-@retry(attempts=5, wait=2, return_is_str=True)
+@retry(retry_timeout=10)
def verify_graceful_restart(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
"""
This API is to verify verify_graceful_restart configuration of DUT and
@@ -3096,7 +3096,7 @@ def verify_graceful_restart(tgen, topo, addr_type, input_dict, dut, peer, expect
return True
-@retry(attempts=5, wait=2, return_is_str=True)
+@retry(retry_timeout=10)
def verify_r_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
"""
This API is to verify r_bit in the BGP gr capability advertised
@@ -3216,7 +3216,7 @@ def verify_r_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
return True
-@retry(attempts=5, wait=2, return_is_str=True)
+@retry(retry_timeout=10)
def verify_eor(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
"""
This API is to verify EOR
@@ -3379,7 +3379,7 @@ def verify_eor(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
return True
-@retry(attempts=4, wait=2, return_is_str=True)
+@retry(retry_timeout=8)
def verify_f_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
"""
This API is to verify f_bit in the BGP gr capability advertised
@@ -3520,7 +3520,7 @@ def verify_f_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True):
return True
-@retry(attempts=5, wait=2, return_is_str=True)
+@retry(retry_timeout=10)
def verify_graceful_restart_timers(tgen, topo, addr_type, input_dict, dut, peer):
"""
This API is to verify graceful restart timers, configured and recieved
@@ -3648,7 +3648,7 @@ def verify_graceful_restart_timers(tgen, topo, addr_type, input_dict, dut, peer)
return True
-@retry(attempts=4, wait=2, return_is_str=True)
+@retry(retry_timeout=8)
def verify_gr_address_family(tgen, topo, addr_type, addr_family, dut, expected=True):
"""
This API is to verify gr_address_family in the BGP gr capability advertised
@@ -3739,7 +3739,7 @@ def verify_gr_address_family(tgen, topo, addr_type, addr_family, dut, expected=T
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
-@retry(attempts=6, wait=2, return_is_str=True)
+@retry(retry_timeout=12)
def verify_attributes_for_evpn_routes(
tgen,
topo,
@@ -4139,7 +4139,7 @@ def verify_attributes_for_evpn_routes(
return False
-@retry(attempts=5, wait=2, return_is_str=True)
+@retry(retry_timeout=10)
def verify_evpn_routes(
tgen, topo, dut, input_dict, routeType=5, EthTag=0, next_hop=None, expected=True
):
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index 3f78f020bc..d659b8d52d 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -19,7 +19,7 @@
#
from collections import OrderedDict
-from datetime import datetime
+from datetime import datetime, timedelta
from time import sleep
from copy import deepcopy
from subprocess import call
@@ -37,12 +37,14 @@ import socket
import ipaddress
import platform
-if sys.version_info[0] > 2:
- import io
- import configparser
-else:
- import StringIO
+try:
+ # Imports from python2
+ from StringIO import StringIO
import ConfigParser as configparser
+except ImportError:
+ # Imports from python3
+ from io import StringIO
+ import configparser
from lib.topolog import logger, logger_config
from lib.topogen import TopoRouter, get_topogen
@@ -136,6 +138,12 @@ DEBUG_LOGS = {
],
}
+def is_string(value):
+ try:
+ return isinstance(value, basestring)
+ except NameError:
+ return isinstance(value, str)
+
if config.has_option("topogen", "verbosity"):
loglevel = config.get("topogen", "verbosity")
loglevel = loglevel.upper()
@@ -448,16 +456,6 @@ def check_router_status(tgen):
return True
-def getStrIO():
- """
- Return a StringIO object appropriate for the current python version.
- """
- if sys.version_info[0] > 2:
- return io.StringIO()
- else:
- return StringIO.StringIO()
-
-
def reset_config_on_routers(tgen, routerName=None):
"""
Resets configuration on routers to the snapshot created using input JSON
@@ -529,7 +527,7 @@ def reset_config_on_routers(tgen, routerName=None):
raise InvalidCLIError("Unknown error in %s", output)
f = open(dname, "r")
- delta = getStrIO()
+ delta = StringIO()
delta.write("configure terminal\n")
t_delta = f.read()
@@ -563,7 +561,7 @@ def reset_config_on_routers(tgen, routerName=None):
output = router.vtysh_multicmd(delta.getvalue(), pretty_output=False)
delta.close()
- delta = getStrIO()
+ delta = StringIO()
cfg = router.run("vtysh -c 'show running'")
for line in cfg.split("\n"):
line = line.strip()
@@ -714,20 +712,36 @@ def generate_support_bundle():
tgen = get_topogen()
router_list = tgen.routers()
- test_name = sys._getframe(2).f_code.co_name
+ test_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
+
TMPDIR = os.path.join(LOGDIR, tgen.modname)
+ bundle_procs = {}
for rname, rnode in router_list.items():
- logger.info("Generating support bundle for {}".format(rname))
+ logger.info("Spawn collection of support bundle for %s", rname)
rnode.run("mkdir -p /var/log/frr")
+ bundle_procs[rname] = tgen.net[rname].popen(
+ "/usr/lib/frr/generate_support_bundle.py",
+ stdin=None,
+ stdout=SUB_PIPE,
+ stderr=SUB_PIPE,
+ )
- # Support only python3 going forward
- bundle_log = rnode.run("env python3 /usr/lib/frr/generate_support_bundle.py")
-
- logger.info(bundle_log)
-
+ for rname, rnode in router_list.items():
dst_bundle = "{}/{}/support_bundles/{}".format(TMPDIR, rname, test_name)
src_bundle = "/var/log/frr"
+
+ output, error = bundle_procs[rname].communicate()
+
+ logger.info("Saving support bundle for %s", rname)
+ if output:
+ logger.info(
+ "Output from collecting support bundle for %s:\n%s", rname, output
+ )
+ if error:
+ logger.warning(
+ "Error from collecting support bundle for %s:\n%s", rname, error
+ )
rnode.run("rm -rf {}".format(dst_bundle))
rnode.run("mkdir -p {}".format(dst_bundle))
rnode.run("mv -f {}/* {}".format(src_bundle, dst_bundle))
@@ -1619,60 +1633,99 @@ def interface_status(tgen, topo, input_dict):
return True
-def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, return_is_dict=False):
+def retry(retry_timeout, initial_wait=0, expected=True, diag_pct=0.75):
"""
- Retries function execution, if return is an errormsg or exception
-
- * `attempts`: Number of attempts to make
- * `wait`: Number of seconds to wait between each attempt
- * `return_is_str`: Return val is an errormsg in case of failure
- * `initial_wait`: Sleeps for this much seconds before executing function
-
+ Fixture: Retries function while it's return value is an errormsg (str), False, or it raises an exception.
+
+ * `retry_timeout`: Retry for at least this many seconds; after waiting initial_wait seconds
+ * `initial_wait`: Sleeps for this many seconds before first executing function
+ * `expected`: if False then the return logic is inverted, except for exceptions,
+ (i.e., a False or errmsg (str) function return ends the retry loop,
+ and returns that False or str value)
+ * `diag_pct`: Percentage of `retry_timeout` to keep testing after negative result would have
+ been returned in order to see if a positive result comes after. This is an
+ important diagnostic tool, and normally should not be disabled. Calls to wrapped
+ functions though, can override the `diag_pct` value to make it larger in case more
+ diagnostic retrying is appropriate.
"""
def _retry(func):
@wraps(func)
def func_retry(*args, **kwargs):
- _wait = kwargs.pop("wait", wait)
- _attempts = kwargs.pop("attempts", attempts)
- _attempts = int(_attempts)
- if _attempts < 0:
- raise ValueError("attempts must be 0 or greater")
+ # We will continue to retry diag_pct of the timeout value to see if test would have passed with a
+ # longer retry timeout value.
+ saved_failure = None
+
+ retry_sleep = 2
+
+ # Allow the wrapped function's args to override the fixtures
+ _retry_timeout = kwargs.pop("retry_timeout", retry_timeout)
+ _expected = kwargs.pop("expected", expected)
+ _initial_wait = kwargs.pop("initial_wait", initial_wait)
+ _diag_pct = kwargs.pop("diag_pct", diag_pct)
+
+ start_time = datetime.now()
+ retry_until = datetime.now() + timedelta(seconds=_retry_timeout + _initial_wait)
if initial_wait > 0:
logger.info("Waiting for [%s]s as initial delay", initial_wait)
sleep(initial_wait)
- _return_is_str = kwargs.pop("return_is_str", return_is_str)
- _return_is_dict = kwargs.pop("return_is_str", return_is_dict)
- _expected = kwargs.setdefault("expected", True)
- kwargs.pop("expected")
- for i in range(1, _attempts + 1):
+ invert_logic = not _expected
+ while True:
+ seconds_left = (retry_until - datetime.now()).total_seconds()
try:
ret = func(*args, **kwargs)
logger.debug("Function returned %s", ret)
- if _return_is_str and isinstance(ret, bool) and _expected:
- return ret
- if (
- isinstance(ret, str) or isinstance(ret, unicode)
- ) and _expected is False:
- return ret
- if _return_is_dict and isinstance(ret, dict):
- return ret
-
- if _attempts == i:
- generate_support_bundle()
- return ret
- except Exception as err:
- if _attempts == i:
- generate_support_bundle()
- logger.info("Max number of attempts (%r) reached", _attempts)
- raise
- else:
- logger.info("Function returned %s", err)
- if i < _attempts:
- logger.info("Retry [#%r] after sleeping for %ss" % (i, _wait))
- sleep(_wait)
+
+ negative_result = ret is False or is_string(ret)
+ if negative_result == invert_logic:
+ # Simple case, successful result in time
+ if not saved_failure:
+ return ret
+
+ # Positive result, but happened after timeout failure, very important to
+ # note for fixing tests.
+ logger.warning("RETRY DIAGNOSTIC: SUCCEED after FAILED with requested timeout of %.1fs; however, succeeded in %.1fs, investigate timeout timing",
+ _retry_timeout, (datetime.now() - start_time).total_seconds())
+ if isinstance(saved_failure, Exception):
+ raise saved_failure # pylint: disable=E0702
+ return saved_failure
+
+ except Exception as error:
+ logger.info("Function raised exception: %s", str(error))
+ ret = error
+
+ if seconds_left < 0 and saved_failure:
+ logger.info("RETRY DIAGNOSTIC: Retry timeout reached, still failing")
+ if isinstance(saved_failure, Exception):
+ raise saved_failure # pylint: disable=E0702
+ return saved_failure
+
+ if seconds_left < 0:
+ logger.info("Retry timeout of %ds reached", _retry_timeout)
+
+ saved_failure = ret
+ retry_extra_delta = timedelta(seconds=seconds_left + _retry_timeout * _diag_pct)
+ retry_until = datetime.now() + retry_extra_delta
+ seconds_left = retry_extra_delta.total_seconds()
+
+ # Generate bundle after setting remaining diagnostic retry time
+ generate_support_bundle()
+
+ # If user has disabled diagnostic retries return now
+ if not _diag_pct:
+ if isinstance(saved_failure, Exception):
+ raise saved_failure
+ return saved_failure
+
+ if saved_failure:
+ logger.info("RETRY DIAG: [failure] Sleeping %ds until next retry with %.1f retry time left - too see if timeout was too short",
+ retry_sleep, seconds_left)
+ else:
+ logger.info("Sleeping %ds until next retry with %.1f retry time left",
+ retry_sleep, seconds_left)
+ sleep(retry_sleep)
func_retry._original = func
return func_retry
@@ -2881,7 +2934,7 @@ def configure_interface_mac(tgen, input_dict):
#############################################
# Verification APIs
#############################################
-@retry(attempts=6, wait=2, return_is_str=True)
+@retry(retry_timeout=12)
def verify_rib(
tgen,
addr_type,
@@ -3290,7 +3343,7 @@ def verify_rib(
return True
-@retry(attempts=6, wait=2, return_is_str=True)
+@retry(retry_timeout=12)
def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None):
"""
Data will be read from input_dict or input JSON file, API will generate
@@ -3694,7 +3747,7 @@ def verify_prefix_lists(tgen, input_dict):
return True
-@retry(attempts=3, wait=4, return_is_str=True)
+@retry(retry_timeout=12)
def verify_route_maps(tgen, input_dict):
"""
Running "show route-map" command and verifying given route-map
@@ -3746,7 +3799,7 @@ def verify_route_maps(tgen, input_dict):
return True
-@retry(attempts=4, wait=4, return_is_str=True)
+@retry(retry_timeout=16)
def verify_bgp_community(tgen, addr_type, router, network, input_dict=None):
"""
API to veiryf BGP large community is attached in route for any given
@@ -3982,7 +4035,7 @@ def verify_cli_json(tgen, input_dict):
return True
-@retry(attempts=3, wait=4, return_is_str=True)
+@retry(retry_timeout=12)
def verify_evpn_vni(tgen, input_dict):
"""
API to verify evpn vni details using "show evpn vni detail json"
@@ -4100,7 +4153,7 @@ def verify_evpn_vni(tgen, input_dict):
return False
-@retry(attempts=3, wait=4, return_is_str=True)
+@retry(retry_timeout=12)
def verify_vrf_vni(tgen, input_dict):
"""
API to verify vrf vni details using "show vrf vni json"
diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py
index 3f39b93d8c..dc9fe0fcca 100644
--- a/tests/topotests/lib/ospf.py
+++ b/tests/topotests/lib/ospf.py
@@ -579,7 +579,7 @@ def redistribute_ospf(tgen, topo, dut, route_type, **kwargs):
################################
# Verification procs
################################
-@retry(attempts=40, wait=2, return_is_str=True)
+@retry(retry_timeout=80)
def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False, expected=True):
"""
This API is to verify ospf neighborship by running
@@ -774,7 +774,7 @@ def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False, expec
################################
# Verification procs
################################
-@retry(attempts=10, wait=2, return_is_str=True)
+@retry(retry_timeout=20)
def verify_ospf6_neighbor(tgen, topo, dut=None, input_dict=None, lan=False):
"""
This API is to verify ospf neighborship by running
@@ -959,7 +959,7 @@ def verify_ospf6_neighbor(tgen, topo, dut=None, input_dict=None, lan=False):
return result
-@retry(attempts=21, wait=2, return_is_str=True)
+@retry(retry_timeout=40)
def verify_ospf_rib(
tgen, dut, input_dict, next_hop=None, tag=None, metric=None, fib=None, expected=True
):
@@ -1236,7 +1236,7 @@ def verify_ospf_rib(
return result
-@retry(attempts=10, wait=2, return_is_str=True)
+@retry(retry_timeout=20)
def verify_ospf_interface(tgen, topo, dut=None, lan=False, input_dict=None, expected=True):
"""
This API is to verify ospf routes by running
@@ -1326,7 +1326,7 @@ def verify_ospf_interface(tgen, topo, dut=None, lan=False, input_dict=None, expe
return result
-@retry(attempts=11, wait=2, return_is_str=True)
+@retry(retry_timeout=20)
def verify_ospf_database(tgen, topo, dut, input_dict, expected=True):
"""
This API is to verify ospf lsa's by running
@@ -1490,7 +1490,7 @@ def verify_ospf_database(tgen, topo, dut, input_dict, expected=True):
return result
-@retry(attempts=10, wait=2, return_is_str=True)
+@retry(retry_timeout=20)
def verify_ospf_summary(tgen, topo, dut, input_dict, expected=True):
"""
This API is to verify ospf routes by running
@@ -1571,7 +1571,7 @@ def verify_ospf_summary(tgen, topo, dut, input_dict, expected=True):
-@retry(attempts=10, wait=3, return_is_str=True)
+@retry(retry_timeout=30)
def verify_ospf6_rib(tgen, dut, input_dict, next_hop=None,
tag=None, metric=None, fib=None):
"""
@@ -1811,7 +1811,7 @@ def verify_ospf6_rib(tgen, dut, input_dict, next_hop=None,
return result
-@retry(attempts=3, wait=2, return_is_str=True)
+@retry(retry_timeout=6)
def verify_ospf6_interface(tgen, topo, dut=None,lan=False, input_dict=None):
"""
This API is to verify ospf routes by running
@@ -1905,7 +1905,7 @@ def verify_ospf6_interface(tgen, topo, dut=None,lan=False, input_dict=None):
return result
-@retry(attempts=11, wait=2, return_is_str=True)
+@retry(retry_timeout=20)
def verify_ospf6_database(tgen, topo, dut, input_dict):
"""
This API is to verify ospf lsa's by running
@@ -2176,9 +2176,9 @@ def config_ospf6_interface (tgen, topo, input_dict=None, build=False,
config_data = []
for lnk in input_dict[router]['links'].keys():
if "ospf6" not in input_dict[router]['links'][lnk]:
- logger.debug("Router %s: ospf6 configs is not present in"
- "input_dict, passed input_dict", router,
- input_dict)
+ logger.debug("Router %s: ospf6 config is not present in"
+ "input_dict, passed input_dict %s", router,
+ str(input_dict))
continue
ospf_data = input_dict[router]['links'][lnk]['ospf6']
data_ospf_area = ospf_data.setdefault("area", None)
diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py
index ce90717fa4..7de1c7a2f9 100644
--- a/tests/topotests/lib/pim.py
+++ b/tests/topotests/lib/pim.py
@@ -495,7 +495,7 @@ def configure_pim_force_expire(tgen, topo, input_dict, build=False):
#############################################
# Verification APIs
#############################################
-@retry(attempts=6, wait=2, return_is_str=True)
+@retry(retry_timeout=12)
def verify_pim_neighbors(tgen, topo, dut=None, iface=None, nbr_ip=None, expected=True):
"""
Verify all PIM neighbors are up and running, config is verified
@@ -619,7 +619,7 @@ def verify_pim_neighbors(tgen, topo, dut=None, iface=None, nbr_ip=None, expected
return True
-@retry(attempts=21, wait=2, return_is_str=True)
+@retry(retry_timeout=40)
def verify_igmp_groups(tgen, dut, interface, group_addresses, expected=True):
"""
Verify IGMP groups are received from an intended interface
@@ -693,7 +693,7 @@ def verify_igmp_groups(tgen, dut, interface, group_addresses, expected=True):
return True
-@retry(attempts=31, wait=2, return_is_str=True)
+@retry(retry_timeout=60)
def verify_upstream_iif(
tgen, dut, iif, src_address, group_addresses, joinState=None, refCount=1, expected=True
):
@@ -847,7 +847,7 @@ def verify_upstream_iif(
return True
-@retry(attempts=6, wait=2, return_is_str=True)
+@retry(retry_timeout=12)
def verify_join_state_and_timer(tgen, dut, iif, src_address, group_addresses, expected=True):
"""
Verify join state is updated correctly and join timer is
@@ -966,7 +966,7 @@ def verify_join_state_and_timer(tgen, dut, iif, src_address, group_addresses, ex
return True
-@retry(attempts=41, wait=2, return_is_dict=True)
+@retry(retry_timeout=80)
def verify_ip_mroutes(
tgen, dut, src_address, group_addresses, iif, oil, return_uptime=False, mwait=0, expected=True
):
@@ -1163,7 +1163,7 @@ def verify_ip_mroutes(
return True if return_uptime == False else uptime_dict
-@retry(attempts=31, wait=2, return_is_str=True)
+@retry(retry_timeout=60)
def verify_pim_rp_info(
tgen, topo, dut, group_addresses, oif=None, rp=None, source=None, iamrp=None, expected=True
):
@@ -1320,7 +1320,7 @@ def verify_pim_rp_info(
return True
-@retry(attempts=31, wait=2, return_is_str=True)
+@retry(retry_timeout=60)
def verify_pim_state(
tgen, dut, iif, oil, group_addresses, src_address=None, installed_fl=None, expected=True
):
@@ -1490,7 +1490,7 @@ def verify_pim_interface_traffic(tgen, input_dict):
return output_dict
-@retry(attempts=21, wait=2, return_is_str=True)
+@retry(retry_timeout=40)
def verify_pim_interface(tgen, topo, dut, interface=None, interface_ip=None, expected=True):
"""
Verify all PIM interface are up and running, config is verified
@@ -1797,7 +1797,7 @@ def clear_ip_igmp_interfaces(tgen, dut):
return True
-@retry(attempts=10, wait=2, return_is_str=True)
+@retry(retry_timeout=20)
def clear_ip_mroute_verify(tgen, dut, expected=True):
"""
Clear ip mroute by running "clear ip mroute" cli and verify
@@ -2173,7 +2173,7 @@ def find_rp_from_bsrp_info(tgen, dut, bsr, grp=None):
return rp_details
-@retry(attempts=6, wait=2, return_is_str=True)
+@retry(retry_timeout=12)
def verify_pim_grp_rp_source(tgen, topo, dut, grp_addr, rp_source, rpadd=None, expected=True):
"""
Verify pim rp info by running "show ip pim rp-info" cli
@@ -2276,7 +2276,7 @@ def verify_pim_grp_rp_source(tgen, topo, dut, grp_addr, rp_source, rpadd=None, e
return errormsg
-@retry(attempts=31, wait=2, return_is_str=True)
+@retry(retry_timeout=60)
def verify_pim_bsr(tgen, topo, dut, bsr_ip, expected=True):
"""
Verify all PIM interface are up and running, config is verified
@@ -2332,7 +2332,7 @@ def verify_pim_bsr(tgen, topo, dut, bsr_ip, expected=True):
return True
-@retry(attempts=31, wait=2, return_is_str=True)
+@retry(retry_timeout=60)
def verify_ip_pim_upstream_rpf(tgen, topo, dut, interface, group_addresses, rp=None, expected=True):
"""
Verify IP PIM upstream rpf, config is verified
@@ -2530,7 +2530,7 @@ def enable_disable_pim_bsm(tgen, router, intf, enable=True):
return result
-@retry(attempts=31, wait=2, return_is_str=True)
+@retry(retry_timeout=60)
def verify_ip_pim_join(tgen, topo, dut, interface, group_addresses, src_address=None, expected=True):
"""
Verify ip pim join by running "show ip pim join" cli
@@ -2621,7 +2621,7 @@ def verify_ip_pim_join(tgen, topo, dut, interface, group_addresses, src_address=
return True
-@retry(attempts=31, wait=2, return_is_dict=True)
+@retry(retry_timeout=60)
def verify_igmp_config(tgen, input_dict, stats_return=False, expected=True):
"""
Verify igmp interface details, verifying following configs:
@@ -2911,7 +2911,7 @@ def verify_igmp_config(tgen, input_dict, stats_return=False, expected=True):
return True if stats_return == False else igmp_stats
-@retry(attempts=31, wait=2, return_is_str=True)
+@retry(retry_timeout=60)
def verify_pim_config(tgen, input_dict, expected=True):
"""
Verify pim interface details, verifying following configs:
@@ -3037,7 +3037,7 @@ def verify_pim_config(tgen, input_dict, expected=True):
return True
-@retry(attempts=21, wait=2, return_is_dict=True)
+@retry(retry_timeout=40)
def verify_multicast_traffic(tgen, input_dict, return_traffic=False, expected=True):
"""
Verify multicast traffic by running
@@ -3280,7 +3280,7 @@ def get_refCount_for_mroute(tgen, dut, iif, src_address, group_addresses):
return refCount
-@retry(attempts=21, wait=2, return_is_str=True)
+@retry(retry_timeout=40)
def verify_multicast_flag_state(tgen, dut, src_address, group_addresses, flag, expected=True):
"""
Verify flag state for mroutes and make sure (*, G)/(S, G) are having
@@ -3375,7 +3375,7 @@ def verify_multicast_flag_state(tgen, dut, src_address, group_addresses, flag, e
return True
-@retry(attempts=21, wait=2, return_is_str=True)
+@retry(retry_timeout=40)
def verify_igmp_interface(tgen, topo, dut, igmp_iface, interface_ip, expected=True):
"""
Verify all IGMP interface are up and running, config is verified
diff --git a/tests/topotests/msdp_mesh_topo1/r1/pimd.conf b/tests/topotests/msdp_mesh_topo1/r1/pimd.conf
index 49341efa57..30cecee9e1 100644
--- a/tests/topotests/msdp_mesh_topo1/r1/pimd.conf
+++ b/tests/topotests/msdp_mesh_topo1/r1/pimd.conf
@@ -10,6 +10,7 @@ interface r1-eth1
ip igmp
!
ip pim rp 10.254.254.1
+ip msdp timers 10 20 3
ip msdp mesh-group mg-1 source 10.254.254.1
ip msdp mesh-group mg-1 member 10.254.254.2
ip msdp mesh-group mg-1 member 10.254.254.3
diff --git a/tests/topotests/msdp_mesh_topo1/r2/pimd.conf b/tests/topotests/msdp_mesh_topo1/r2/pimd.conf
index 9005263ed7..a51c6d58c7 100644
--- a/tests/topotests/msdp_mesh_topo1/r2/pimd.conf
+++ b/tests/topotests/msdp_mesh_topo1/r2/pimd.conf
@@ -9,6 +9,7 @@ interface r2-eth1
ip pim
!
ip pim rp 10.254.254.2
+ip msdp timers 10 20 3
ip msdp mesh-group mg-1 source 10.254.254.2
ip msdp mesh-group mg-1 member 10.254.254.1
ip msdp mesh-group mg-1 member 10.254.254.3
diff --git a/tests/topotests/msdp_mesh_topo1/r3/pimd.conf b/tests/topotests/msdp_mesh_topo1/r3/pimd.conf
index 30e1148561..663f78620e 100644
--- a/tests/topotests/msdp_mesh_topo1/r3/pimd.conf
+++ b/tests/topotests/msdp_mesh_topo1/r3/pimd.conf
@@ -10,6 +10,7 @@ interface r3-eth1
ip igmp
!
ip pim rp 10.254.254.3
+ip msdp timers 10 20 3
ip msdp mesh-group mg-1 source 10.254.254.3
ip msdp mesh-group mg-1 member 10.254.254.1
ip msdp mesh-group mg-1 member 10.254.254.2
diff --git a/tests/topotests/msdp_mesh_topo1/test_msdp_mesh_topo1.py b/tests/topotests/msdp_mesh_topo1/test_msdp_mesh_topo1.py
index 719ead091c..222fb28ade 100644
--- a/tests/topotests/msdp_mesh_topo1/test_msdp_mesh_topo1.py
+++ b/tests/topotests/msdp_mesh_topo1/test_msdp_mesh_topo1.py
@@ -223,7 +223,7 @@ def test_wait_msdp_convergence():
"show ip msdp peer json",
{peer: {"state": "established", "saCount": sa_count}}
)
- _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ _, result = topotest.run_and_expect(test_func, None, count=40, wait=2)
assertmsg = '"{}" MSDP connection failure'.format(router)
assert result is None, assertmsg
diff --git a/tests/topotests/msdp_topo1/__init__.py b/tests/topotests/msdp_topo1/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/msdp_topo1/__init__.py
diff --git a/tests/topotests/msdp_topo1/r1/bgpd.conf b/tests/topotests/msdp_topo1/r1/bgpd.conf
new file mode 100644
index 0000000000..01d8ddbdfa
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r1/bgpd.conf
@@ -0,0 +1,8 @@
+router bgp 65001
+ no bgp ebgp-requires-policy
+ neighbor 192.168.0.2 remote-as 65002
+ neighbor 192.168.1.2 remote-as 65003
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/msdp_topo1/r1/pimd.conf b/tests/topotests/msdp_topo1/r1/pimd.conf
new file mode 100644
index 0000000000..fc289031f4
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r1/pimd.conf
@@ -0,0 +1,21 @@
+debug pim
+debug pim zebra
+!
+interface lo
+ ip pim
+ ip pim use-source 10.254.254.1
+!
+interface r1-eth0
+ ip pim
+!
+interface r1-eth1
+ ip pim
+!
+interface r1-eth2
+ ip pim
+ ip igmp
+!
+ip msdp timers 10 20 3
+ip msdp peer 192.168.0.2 source 192.168.0.1
+ip msdp peer 192.168.1.2 source 192.168.1.1
+ip pim rp 10.254.254.1
diff --git a/tests/topotests/msdp_topo1/r1/zebra.conf b/tests/topotests/msdp_topo1/r1/zebra.conf
new file mode 100644
index 0000000000..fb6eabccdf
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r1/zebra.conf
@@ -0,0 +1,14 @@
+ip forwarding
+!
+interface r1-eth0
+ ip address 192.168.0.1/24
+!
+interface r1-eth1
+ ip address 192.168.1.1/24
+!
+interface r1-eth2
+ ip address 192.168.10.1/24
+!
+interface lo
+ ip address 10.254.254.1/32
+!
diff --git a/tests/topotests/msdp_topo1/r2/bgpd.conf b/tests/topotests/msdp_topo1/r2/bgpd.conf
new file mode 100644
index 0000000000..987bef40dd
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r2/bgpd.conf
@@ -0,0 +1,8 @@
+router bgp 65002
+ no bgp ebgp-requires-policy
+ neighbor 192.168.0.1 remote-as 65001
+ neighbor 192.168.2.2 remote-as 65004
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/msdp_topo1/r2/pimd.conf b/tests/topotests/msdp_topo1/r2/pimd.conf
new file mode 100644
index 0000000000..ffa80b12d3
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r2/pimd.conf
@@ -0,0 +1,17 @@
+debug pim
+debug pim zebra
+!
+interface lo
+ ip pim
+ ip pim use-source 10.254.254.2
+!
+interface r2-eth0
+ ip pim
+!
+interface r2-eth1
+ ip pim
+!
+ip msdp timers 10 20 3
+ip msdp peer 192.168.0.1 source 192.168.0.2
+ip msdp peer 192.168.2.2 source 192.168.2.1
+ip pim rp 10.254.254.2
diff --git a/tests/topotests/msdp_topo1/r2/zebra.conf b/tests/topotests/msdp_topo1/r2/zebra.conf
new file mode 100644
index 0000000000..527f7dd766
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r2/zebra.conf
@@ -0,0 +1,11 @@
+ip forwarding
+!
+interface r2-eth0
+ ip address 192.168.0.2/24
+!
+interface r2-eth1
+ ip address 192.168.2.1/24
+!
+interface lo
+ ip address 10.254.254.2/32
+!
diff --git a/tests/topotests/msdp_topo1/r3/bgpd.conf b/tests/topotests/msdp_topo1/r3/bgpd.conf
new file mode 100644
index 0000000000..02d685b0e8
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r3/bgpd.conf
@@ -0,0 +1,8 @@
+router bgp 65003
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.1 remote-as 65001
+ neighbor 192.168.3.2 remote-as 65004
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/msdp_topo1/r3/pimd.conf b/tests/topotests/msdp_topo1/r3/pimd.conf
new file mode 100644
index 0000000000..ab12f0573a
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r3/pimd.conf
@@ -0,0 +1,17 @@
+debug pim
+debug pim zebra
+!
+interface lo
+ ip pim
+ ip pim use-source 10.254.254.3
+!
+interface r3-eth0
+ ip pim
+!
+interface r3-eth1
+ ip pim
+!
+ip msdp timers 10 20 3
+ip msdp peer 192.168.1.1 source 192.168.1.2
+ip msdp peer 192.168.3.2 source 192.168.3.1
+ip pim rp 10.254.254.3
diff --git a/tests/topotests/msdp_topo1/r3/zebra.conf b/tests/topotests/msdp_topo1/r3/zebra.conf
new file mode 100644
index 0000000000..688e752f42
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r3/zebra.conf
@@ -0,0 +1,11 @@
+ip forwarding
+!
+interface r3-eth0
+ ip address 192.168.1.2/24
+!
+interface r3-eth1
+ ip address 192.168.3.1/24
+!
+interface lo
+ ip address 10.254.254.3/32
+!
diff --git a/tests/topotests/msdp_topo1/r4/bgpd.conf b/tests/topotests/msdp_topo1/r4/bgpd.conf
new file mode 100644
index 0000000000..633e8db245
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r4/bgpd.conf
@@ -0,0 +1,9 @@
+router bgp 65004
+ no bgp ebgp-requires-policy
+ neighbor 192.168.2.1 remote-as 65002
+ neighbor 192.168.3.1 remote-as 65003
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+!
+
diff --git a/tests/topotests/msdp_topo1/r4/pimd.conf b/tests/topotests/msdp_topo1/r4/pimd.conf
new file mode 100644
index 0000000000..b2e05cb3cb
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r4/pimd.conf
@@ -0,0 +1,21 @@
+debug pim
+debug pim zebra
+!
+interface lo
+ ip pim
+ ip pim use-source 10.254.254.4
+!
+interface r4-eth0
+ ip pim
+!
+interface r4-eth1
+ ip pim
+!
+interface r4-eth2
+ ip pim
+ ip igmp
+!
+ip msdp timers 10 20 3
+ip msdp peer 192.168.2.1 source 192.168.2.2
+ip msdp peer 192.168.3.1 source 192.168.3.2
+ip pim rp 10.254.254.4
diff --git a/tests/topotests/msdp_topo1/r4/zebra.conf b/tests/topotests/msdp_topo1/r4/zebra.conf
new file mode 100644
index 0000000000..1db8132256
--- /dev/null
+++ b/tests/topotests/msdp_topo1/r4/zebra.conf
@@ -0,0 +1,14 @@
+ip forwarding
+!
+interface r4-eth0
+ ip address 192.168.2.2/24
+!
+interface r4-eth1
+ ip address 192.168.3.2/24
+!
+interface r4-eth2
+ ip address 192.168.4.1/24
+!
+interface lo
+ ip address 10.254.254.4/32
+!
diff --git a/tests/topotests/msdp_topo1/test_msdp_topo1.py b/tests/topotests/msdp_topo1/test_msdp_topo1.py
new file mode 100755
index 0000000000..d85e16086d
--- /dev/null
+++ b/tests/topotests/msdp_topo1/test_msdp_topo1.py
@@ -0,0 +1,499 @@
+#!/usr/bin/env python
+
+#
+# test_msdp_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2021 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_msdp_topo1.py: Test the FRR PIM MSDP peer.
+"""
+
+import os
+import sys
+import json
+import socket
+import tempfile
+from functools import partial
+import pytest
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+pytestmark = [pytest.mark.bgpd, pytest.mark.pimd]
+
+#
+# Test global variables:
+# They are used to handle communicating with external application.
+#
+APP_SOCK_PATH = '/tmp/topotests/apps.sock'
+HELPER_APP_PATH = os.path.join(CWD, "../lib/mcast-tester.py")
+app_listener = None
+app_clients = {}
+
+
+def listen_to_applications():
+ "Start listening socket to connect with applications."
+ # Remove old socket.
+ try:
+ os.unlink(APP_SOCK_PATH)
+ except OSError:
+ pass
+
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
+ sock.bind(APP_SOCK_PATH)
+ sock.listen(10)
+ global app_listener
+ app_listener = sock
+
+
+def accept_host(host):
+ "Accept connection from application running in hosts."
+ global app_listener, app_clients
+ conn = app_listener.accept()
+ app_clients[host] = {
+ 'fd': conn[0],
+ 'address': conn[1]
+ }
+
+
+def close_applications():
+ "Signal applications to stop and close all sockets."
+ global app_listener, app_clients
+
+ # Close listening socket.
+ app_listener.close()
+
+ # Remove old socket.
+ try:
+ os.unlink(APP_SOCK_PATH)
+ except OSError:
+ pass
+
+ # Close all host connections.
+ for host in ["h1", "h2"]:
+ if app_clients.get(host) is None:
+ continue
+ app_clients[host]["fd"].close()
+
+
+class MSDPTopo1(Topo):
+ "Test topology builder"
+
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ # Create 4 routers
+ for routern in range(1, 5):
+ tgen.add_router("r{}".format(routern))
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r3"])
+
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r4"])
+
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["r3"])
+ switch.add_link(tgen.gears["r4"])
+
+ switch = tgen.add_switch("s5")
+ switch.add_link(tgen.gears["r4"])
+
+ # Create a host connected and direct at r4:
+ tgen.add_host("h1", "192.168.4.100/24", "192.168.4.1")
+ switch.add_link(tgen.gears["h1"])
+
+ # Create a host connected and direct at r1:
+ switch = tgen.add_switch("s6")
+ tgen.add_host("h2", "192.168.10.100/24", "192.168.10.1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["h2"])
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(MSDPTopo1, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+ for rname, router in router_list.items():
+ daemon_file = "{}/{}/zebra.conf".format(CWD, rname)
+ if os.path.isfile(daemon_file):
+ router.load_config(TopoRouter.RD_ZEBRA, daemon_file)
+
+ daemon_file = "{}/{}/bgpd.conf".format(CWD, rname)
+ if os.path.isfile(daemon_file):
+ router.load_config(TopoRouter.RD_BGP, daemon_file)
+
+ daemon_file = "{}/{}/pimd.conf".format(CWD, rname)
+ if os.path.isfile(daemon_file):
+ router.load_config(TopoRouter.RD_PIM, daemon_file)
+
+ # Initialize all routers.
+ tgen.start_router()
+
+ # Start applications socket.
+ listen_to_applications()
+
+
+def teardown_module(mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+ close_applications()
+ tgen.stop_topology()
+
+
+def test_bgp_convergence():
+ "Wait for BGP protocol convergence"
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("waiting for protocols to converge")
+
+ def expect_loopback_route(router, iptype, route, proto):
+ "Wait until route is present on RIB for protocol."
+ logger.info("waiting route {} in {}".format(route, router))
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears[router],
+ "show {} route json".format(iptype),
+ {route: [{"protocol": proto}]},
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
+ assertmsg = '"{}" convergence failure'.format(router)
+ assert result is None, assertmsg
+
+ # Wait for R1
+ expect_loopback_route("r1", "ip", "10.254.254.2/32", "bgp")
+ expect_loopback_route("r1", "ip", "10.254.254.3/32", "bgp")
+ expect_loopback_route("r1", "ip", "10.254.254.4/32", "bgp")
+
+ # Wait for R2
+ expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp")
+ expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp")
+ expect_loopback_route("r2", "ip", "10.254.254.4/32", "bgp")
+
+ # Wait for R3
+ expect_loopback_route("r3", "ip", "10.254.254.1/32", "bgp")
+ expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp")
+ expect_loopback_route("r3", "ip", "10.254.254.4/32", "bgp")
+
+ # Wait for R4
+ expect_loopback_route("r4", "ip", "10.254.254.1/32", "bgp")
+ expect_loopback_route("r4", "ip", "10.254.254.2/32", "bgp")
+ expect_loopback_route("r4", "ip", "10.254.254.3/32", "bgp")
+
+
+def test_mroute_install():
+ "Test that multicast routes propagated and installed"
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.gears["h1"].run("{} '{}' '{}' '{}' &".format(
+ HELPER_APP_PATH, APP_SOCK_PATH, '229.1.2.3', 'h1-eth0'))
+ accept_host("h1")
+
+ tgen.gears["h2"].run("{} --send='0.7' '{}' '{}' '{}' &".format(
+ HELPER_APP_PATH, APP_SOCK_PATH, '229.1.2.3', 'h2-eth0'))
+ accept_host("h2")
+
+ #
+ # Test R1 mroute
+ #
+ expect_1 = {
+ '229.1.2.3': {
+ '192.168.10.100': {
+ 'iif': 'r1-eth2',
+ 'flags': 'SFT',
+ 'oil': {
+ 'r1-eth0': {
+ 'source': '192.168.10.100',
+ 'group': '229.1.2.3'
+ },
+ 'r1-eth1': None
+ }
+ }
+ }
+ }
+ # Create a deep copy of `expect_1`.
+ expect_2 = json.loads(json.dumps(expect_1))
+ # The route will be either via R2 or R3.
+ expect_2['229.1.2.3']['192.168.10.100']['oil']['r1-eth0'] = None
+ expect_2['229.1.2.3']['192.168.10.100']['oil']['r1-eth1'] = {
+ 'source': '192.168.10.100',
+ 'group': '229.1.2.3'
+ }
+
+ def test_r1_mroute():
+ "Test r1 multicast routing table function"
+ out = tgen.gears['r1'].vtysh_cmd('show ip mroute json', isjson=True)
+ if topotest.json_cmp(out, expect_1) is None:
+ return None
+ return topotest.json_cmp(out, expect_2)
+
+ logger.info('Waiting for R1 multicast routes')
+ _, val = topotest.run_and_expect(test_r1_mroute, None, count=55, wait=2)
+ assert val is None, 'multicast route convergence failure'
+
+ #
+ # Test routers 2 and 3.
+ #
+ # NOTE: only one of the paths will get the multicast route.
+ #
+ expect_r2 = {
+ "229.1.2.3": {
+ "192.168.10.100": {
+ "iif": "r2-eth0",
+ "flags": "S",
+ "oil": {
+ "r2-eth1": {
+ "source": "192.168.10.100",
+ "group": "229.1.2.3",
+ }
+ }
+ }
+ }
+ }
+ expect_r3 = {
+ "229.1.2.3": {
+ "192.168.10.100": {
+ "iif": "r3-eth0",
+ "flags": "S",
+ "oil": {
+ "r3-eth1": {
+ "source": "192.168.10.100",
+ "group": "229.1.2.3",
+ }
+ }
+ }
+ }
+ }
+
+ def test_r2_r3_mroute():
+ "Test r2/r3 multicast routing table function"
+ r2_out = tgen.gears['r2'].vtysh_cmd('show ip mroute json', isjson=True)
+ r3_out = tgen.gears['r3'].vtysh_cmd('show ip mroute json', isjson=True)
+
+ if topotest.json_cmp(r2_out, expect_r2) is not None:
+ return topotest.json_cmp(r3_out, expect_r3)
+
+ return topotest.json_cmp(r2_out, expect_r2)
+
+ logger.info('Waiting for R2 and R3 multicast routes')
+ _, val = topotest.run_and_expect(test_r2_r3_mroute, None, count=55, wait=2)
+ assert val is None, 'multicast route convergence failure'
+
+ #
+ # Test router 4
+ #
+ expect_4 = {
+ "229.1.2.3": {
+ "*": {
+ "iif": "lo",
+ "flags": "SC",
+ "oil": {
+ "pimreg": {
+ "source": "*",
+ "group": "229.1.2.3",
+ "inboundInterface": "lo",
+ "outboundInterface": "pimreg"
+ },
+ "r4-eth2": {
+ "source": "*",
+ "group": "229.1.2.3",
+ "inboundInterface": "lo",
+ "outboundInterface": "r4-eth2"
+ }
+ }
+ },
+ "192.168.10.100": {
+ "iif": "r4-eth0",
+ "flags": "ST",
+ "oil": {
+ "r4-eth2": {
+ "source": "192.168.10.100",
+ "group": "229.1.2.3",
+ "inboundInterface": "r4-eth0",
+ "outboundInterface": "r4-eth2",
+ }
+ }
+ }
+ }
+ }
+
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears['r4'], "show ip mroute json", expect_4,
+ )
+ logger.info('Waiting for R4 multicast routes')
+ _, val = topotest.run_and_expect(test_func, None, count=55, wait=2)
+ assert val is None, 'multicast route convergence failure'
+
+
+def test_msdp():
+ """
+ Test MSDP convergence.
+
+ MSDP non meshed groups must propagate the whole SA database (not just
+ their own) to all peers because not all peers talk with each other.
+
+ This setup leads to a potential loop that can be prevented by checking
+ the route's first AS in AS path: it must match the remote eBGP AS number.
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ r1_expect = {
+ "192.168.0.2": {
+ "peer": "192.168.0.2",
+ "local": "192.168.0.1",
+ "state": "established"
+ },
+ "192.168.1.2": {
+ "peer": "192.168.1.2",
+ "local": "192.168.1.1",
+ "state": "established"
+ }
+ }
+ r1_sa_expect = {
+ "229.1.2.3": {
+ "192.168.10.100": {
+ "source": "192.168.10.100",
+ "group": "229.1.2.3",
+ "rp": "-",
+ "local": "yes",
+ "sptSetup": "-"
+ }
+ }
+ }
+ r2_expect = {
+ "192.168.0.1": {
+ "peer": "192.168.0.1",
+ "local": "192.168.0.2",
+ "state": "established"
+ },
+ "192.168.2.2": {
+ "peer": "192.168.2.2",
+ "local": "192.168.2.1",
+ "state": "established"
+ }
+ }
+ # Only R2 or R3 will get this SA.
+ r2_r3_sa_expect = {
+ "229.1.2.3": {
+ "192.168.10.100": {
+ "source": "192.168.10.100",
+ "group": "229.1.2.3",
+ "rp": "192.168.1.1",
+ "local": "no",
+ "sptSetup": "no",
+ }
+ }
+ }
+ r3_expect = {
+ "192.168.1.1": {
+ "peer": "192.168.1.1",
+ "local": "192.168.1.2",
+ "state": "established"
+ },
+ "192.168.3.2": {
+ "peer": "192.168.3.2",
+ "local": "192.168.3.1",
+ "state": "established"
+ }
+ }
+ r4_expect = {
+ "192.168.2.1": {
+ "peer": "192.168.2.1",
+ "local": "192.168.2.2",
+ "state": "established"
+ },
+ "192.168.3.1": {
+ "peer": "192.168.3.1",
+ "local": "192.168.3.2",
+ "state": "established"
+ }
+ }
+ r4_sa_expect = {
+ "229.1.2.3": {
+ "192.168.10.100": {
+ "source": "192.168.10.100",
+ "group": "229.1.2.3",
+ "rp": "192.168.1.1",
+ "local": "no",
+ "sptSetup": "yes"
+ }
+ }
+ }
+
+ for router in [('r1', r1_expect, r1_sa_expect),
+ ('r2', r2_expect, r2_r3_sa_expect),
+ ('r3', r3_expect, r2_r3_sa_expect),
+ ('r4', r4_expect, r4_sa_expect)]:
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears[router[0]], "show ip msdp peer json", router[1]
+ )
+ logger.info('Waiting for {} msdp peer data'.format(router[0]))
+ _, val = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert val is None, 'multicast route convergence failure'
+
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears[router[0]], "show ip msdp sa json", router[2]
+ )
+ logger.info('Waiting for {} msdp SA data'.format(router[0]))
+ _, val = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert val is None, 'multicast route convergence failure'
+
+
+def test_memory_leak():
+ "Run the memory leak test and report results."
+ tgen = get_topogen()
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py b/tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py
index 199746d5f6..60bd6de35d 100644
--- a/tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py
+++ b/tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py
@@ -456,7 +456,7 @@ def test_starg_mroute_p0(request):
# Verify mroute not installed
step("Verify mroute not installed in l1")
result = verify_ip_mroutes(
- tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, wait=20, expected=False
+ tgen, dut, src_addr, GROUP_ADDRESS, iif, oil, retry_timeout=20, expected=False
)
assert (
result is not True
@@ -705,6 +705,7 @@ def test_RP_priority_p0(request):
), "Testcase {} :Failed \n Error : rp expected {} rp received {}".format(
tc_name,
rp_add1,
+ rp2[group] if group in rp2 else None
)
# Verify if that rp is installed
diff --git a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
index e55e30270d..b880e0e462 100755
--- a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
+++ b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
@@ -526,9 +526,14 @@ def test_multicast_data_traffic_static_RP_send_traffic_then_join_p0(request):
{"dut": "r2", "src_address": source, "iif": "r2-f1-eth0", "oil": "r2-l1-eth2"},
{"dut": "f1", "src_address": source, "iif": "f1-i2-eth1", "oil": "f1-r2-eth3"},
]
+ # On timeout change from default of 80 to 120: failures logs indicate times 90+
+ # seconds for success on the 2nd entry in the above table. Using 100s here restores
+ # previous 80 retries with 2s wait if we assume .5s per vtysh/show ip mroute runtime
+ # (41 * (2 + .5)) == 102.
for data in input_dict:
result = verify_ip_mroutes(
- tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"]
+ tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"],
+ retry_timeout=102
)
assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py
index 7bef57b629..d73e8dc9e8 100755
--- a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py
+++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py
@@ -424,7 +424,7 @@ def test_add_delete_static_RP_p0(request):
step("r1: Verify show ip igmp group without any IGMP join")
dut = "r1"
interface = "r1-r0-eth0"
- result = verify_igmp_groups(tgen, dut, interface, GROUP_ADDRESS)
+ result = verify_igmp_groups(tgen, dut, interface, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: igmp group present without any IGMP join \n Error: {}".format(
@@ -495,7 +495,7 @@ def test_add_delete_static_RP_p0(request):
step("r1: Verify RP info")
result = verify_pim_rp_info(
- tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
+ tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False
)
assert (
result is not True
@@ -504,14 +504,14 @@ def test_add_delete_static_RP_p0(request):
)
step("r1: Verify upstream IIF interface")
- result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
+ result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: upstream IIF interface present \n Error: {}".format(tc_name, result)
)
step("r1: Verify upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: upstream join state is up and join timer is running \n Error: {}".format(
@@ -519,14 +519,15 @@ def test_add_delete_static_RP_p0(request):
)
)
+ # 20
step("r1: Verify PIM state")
- result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
+ result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
assert result is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, result
)
step("r1: Verify ip mroutes")
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n " "r1: mroutes are still present \n Error: {}".format(
@@ -686,7 +687,9 @@ def test_SPT_RPT_path_same_p1(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r3: Verify (S, G) upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
+ )
assert result is not True, (
"Testcase {} : Failed \n "
"r3: (S, G) upstream join state is up and join timer is running\n Error: {}".format(
@@ -819,7 +822,7 @@ def test_not_reachable_static_RP_p0(request):
"r1 : OIL should be same and IIF should be cleared on R1 verify"
"using show ip pim state"
)
- result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
+ result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"OIL is not same and IIF is not cleared on R1 \n Error: {}".format(
@@ -828,7 +831,7 @@ def test_not_reachable_static_RP_p0(request):
)
step("r1: upstream IIF should be unknown , verify using show ip pim" "upstream")
- result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
+ result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: upstream IIF is not unknown \n Error: {}".format(tc_name, result)
@@ -838,7 +841,7 @@ def test_not_reachable_static_RP_p0(request):
"r1: join state should not be joined and join timer should stop,"
"verify using show ip pim upstream"
)
- result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: join state is joined and timer is not stopped \n Error: {}".format(
@@ -861,7 +864,7 @@ def test_not_reachable_static_RP_p0(request):
assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
step("r1: (*, G) cleared from mroute table using show ip mroute")
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: (*, G) are not cleared from mroute table \n Error: {}".format(
@@ -932,7 +935,7 @@ def test_add_RP_after_join_received_p1(request):
rp_address = "1.0.2.17"
iif = "r1-r2-eth1"
result = verify_pim_rp_info(
- tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE
+ tgen, TOPO, dut, GROUP_RANGE_ALL, iif, rp_address, SOURCE, expected=False
)
assert (
result is not True
@@ -959,7 +962,7 @@ def test_add_RP_after_join_received_p1(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r1: Verify upstream IIF interface")
- result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
+ result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: upstream IFF interface is present \n Error: {}".format(tc_name, result)
@@ -967,7 +970,7 @@ def test_add_RP_after_join_received_p1(request):
step("r1: Verify upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: upstream join state is joined and timer is running \n Error: {}".format(
@@ -976,7 +979,7 @@ def test_add_RP_after_join_received_p1(request):
)
step("r1: Verify PIM state")
- result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
+ result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
@@ -984,7 +987,7 @@ def test_add_RP_after_join_received_p1(request):
)
step("r1: Verify ip mroutes")
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
@@ -1114,14 +1117,14 @@ def test_reachable_static_RP_after_join_p0(request):
step("r1 : Verify upstream IIF interface")
iif = "r1-r2-eth1"
- result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS)
+ result = verify_upstream_iif(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: upstream IIF interface is present\n Error: {}".format(tc_name, result)
)
step("r1 : Verify upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(tgen, dut, iif, STAR, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: upstream join state is joined and timer is running\n Error: {}".format(
@@ -1130,7 +1133,7 @@ def test_reachable_static_RP_after_join_p0(request):
)
step("r1 : Verify PIM state")
- result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS)
+ result = verify_pim_state(tgen, dut, iif, oif, GROUP_ADDRESS, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n " "r1: PIM state is up\n Error: {}".format(
@@ -1138,7 +1141,7 @@ def test_reachable_static_RP_after_join_p0(request):
)
step("r1 : Verify ip mroutes")
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n " "r1: mroutes are still present\n Error: {}".format(
@@ -1385,7 +1388,9 @@ def test_send_join_on_higher_preffered_rp_p1(request):
step("r1 : Verify rp-info for group 225.1.1.1")
iif = "r1-r4-eth3"
- result = verify_pim_rp_info(tgen, TOPO, dut, GROUP_RANGE, oif, rp_address_2, SOURCE)
+ result = verify_pim_rp_info(
+ tgen, TOPO, dut, GROUP_RANGE, oif, rp_address_2, SOURCE, expected=False
+ )
assert result is not True, (
"Testcase {} : Failed \n "
"r1: rp-info is present for group 225.1.1.1 \n Error: {}".format(
@@ -1643,7 +1648,9 @@ def test_RP_configured_as_LHR_1_p1(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r3: Verify (S, G) upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
+ )
assert result is not True, (
"Testcase {} : Failed \n "
"r3: (S, G) upstream join state is joined and join"
@@ -1850,7 +1857,9 @@ def test_RP_configured_as_LHR_2_p1(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r3: Verify (S, G) upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
+ )
assert result is not True, (
"Testcase {} : Failed \n "
"r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format(
@@ -2058,7 +2067,9 @@ def test_RP_configured_as_FHR_1_p1(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r3: Verify (S, G) upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
+ )
assert result is not True, (
"Testcase {} : Failed \n "
"r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format(
@@ -2267,7 +2278,9 @@ def test_RP_configured_as_FHR_2_p2(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r3: Verify (S, G) upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
+ )
assert result is not True, (
"Testcase {} : Failed \n "
"r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format(
@@ -2394,7 +2407,9 @@ def test_SPT_RPT_path_different_p1(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r3: Verify (S, G) upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
+ )
assert result is not True, (
"Testcase {} : Failed \n "
"r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format(
@@ -2416,7 +2431,9 @@ def test_SPT_RPT_path_different_p1(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r2: Verify (S, G) upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False
+ )
assert result is not True, (
"Testcase {} : Failed \n "
"r2: (S,G) upstream state is joined and join timer is running\n Error: {}".format(
@@ -2645,7 +2662,8 @@ def test_restart_pimd_process_p2(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("r3: Verify (S, G) upstream join state and join timer")
- result = verify_join_state_and_timer(tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS)
+ result = verify_join_state_and_timer(
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r3: (S,G) upstream state is joined and join timer is running\n Error: {}".format(
@@ -2663,6 +2681,7 @@ def test_restart_pimd_process_p2(request):
oil = "r1-r0-eth0"
logger.info("waiting for 10 sec to make sure old mroute time is higher")
sleep(10)
+ # Why do we then wait 60 seconds below before checking the routes?
uptime_before = verify_ip_mroutes(
tgen, dut, STAR, GROUP_ADDRESS, iif, oil, return_uptime=True, mwait=60
)
@@ -2679,6 +2698,7 @@ def test_restart_pimd_process_p2(request):
logger.info("Waiting for 5sec to get PIMd restarted and mroute" " re-learned..")
sleep(5)
+ # Why do we then wait 10 seconds below before checking the routes?
uptime_after = verify_ip_mroutes(
tgen, dut, STAR, GROUP_ADDRESS, iif, oil, return_uptime=True, mwait=10
)
@@ -2814,7 +2834,7 @@ def test_multiple_groups_same_RP_address_p2(request):
step("r3: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, group_address_list
+ tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -2838,7 +2858,7 @@ def test_multiple_groups_same_RP_address_p2(request):
step("r2: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, group_address_list
+ tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -2959,7 +2979,7 @@ def test_multiple_groups_same_RP_address_p2(request):
step("r2: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, group_address_list
+ tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -2981,7 +3001,7 @@ def test_multiple_groups_same_RP_address_p2(request):
step("r3: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, group_address_list
+ tgen, dut, iif, SOURCE_ADDRESS, group_address_list, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -3163,7 +3183,7 @@ def test_multiple_groups_different_RP_address_p2(request):
step("r2: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -3187,7 +3207,7 @@ def test_multiple_groups_different_RP_address_p2(request):
step("r3: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -3259,7 +3279,7 @@ def test_multiple_groups_different_RP_address_p2(request):
step("r4: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -3283,7 +3303,7 @@ def test_multiple_groups_different_RP_address_p2(request):
step("r3: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False
)
assert result is not True, "Testcase {} :Failed \n Error: {}".format(
tc_name, result
@@ -3436,7 +3456,7 @@ def test_multiple_groups_different_RP_address_p2(request):
step("r2: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -3460,7 +3480,7 @@ def test_multiple_groups_different_RP_address_p2(request):
step("r3: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_1, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -3532,7 +3552,7 @@ def test_multiple_groups_different_RP_address_p2(request):
step("r4: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -3556,7 +3576,7 @@ def test_multiple_groups_different_RP_address_p2(request):
step("r3: Verify (S, G) upstream join state and join timer")
result = verify_join_state_and_timer(
- tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2
+ tgen, dut, iif, SOURCE_ADDRESS, GROUP_ADDRESS_LIST_2, expected=False
)
assert result is not True, (
"Testcase {} : Failed \n "
@@ -3682,14 +3702,14 @@ def test_shutdown_primary_path_p1(request):
step(
"Verify after shut of R1 to R3 link , verify (*,G) entries got"
- "cleared from all the node R1, R2, R3"
+ " cleared from all the node R1, R2, R3"
)
step("r1: Verify (*, G) ip mroutes")
dut = "r1"
iif = "r1-r3-eth2"
oif = "r1-r0-eth0"
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format(
@@ -3701,7 +3721,7 @@ def test_shutdown_primary_path_p1(request):
dut = "r2"
iif = "lo"
oif = "r2-r3-eth1"
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r2: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format(
@@ -3713,7 +3733,7 @@ def test_shutdown_primary_path_p1(request):
dut = "r3"
iif = "r3-r2-eth1"
oif = "r3-r1-eth0"
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r3: (*,G) mroutes are not cleared after shut of R1 to R3 link\n Error: {}".format(
@@ -3878,7 +3898,7 @@ def test_delete_RP_shut_noshut_upstream_interface_p1(request):
dut = "r1"
iif = "r1-r2-eth1"
oif = "r1-r0-eth0"
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format(
@@ -3890,7 +3910,7 @@ def test_delete_RP_shut_noshut_upstream_interface_p1(request):
dut = "r2"
iif = "lo"
oif = "r2-r1-eth0"
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r2: (*,G) mroutes are not cleared after shut of R1 to R0 link\n Error: {}".format(
@@ -4005,7 +4025,7 @@ def test_delete_RP_shut_noshut_RP_interface_p1(request):
dut = "r1"
iif = "r1-r2-eth1"
oif = "r1-r0-eth0"
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r1: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format(
@@ -4017,7 +4037,7 @@ def test_delete_RP_shut_noshut_RP_interface_p1(request):
dut = "r2"
iif = "lo"
oif = "r2-r1-eth0"
- result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif)
+ result = verify_ip_mroutes(tgen, dut, STAR, GROUP_ADDRESS, iif, oif, expected=False)
assert result is not True, (
"Testcase {} : Failed \n "
"r2: (*,G) mroutes are not cleared after shut of R1 to R2 and R3 link\n Error: {}".format(
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py b/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py
index 9c3be58937..a7f2893eab 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py
@@ -257,7 +257,7 @@ def test_ospf_authentication_simple_pass_tc28_p1(request):
sleep(6)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(
- tgen, topo, dut=dut, expected=False, attempts=5
+ tgen, topo, dut=dut, expected=False, retry_timeout=10
)
assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
@@ -395,7 +395,7 @@ def test_ospf_authentication_md5_tc29_p1(request):
sleep(6)
dut = "r1"
ospf_covergence = verify_ospf_neighbor(
- tgen, topo, dut=dut, expected=False, attempts=3
+ tgen, topo, dut=dut, expected=False, retry_timeout=6
)
assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
@@ -460,7 +460,7 @@ def test_ospf_authentication_md5_tc29_p1(request):
sleep(6)
dut = "r2"
ospf_covergence = verify_ospf_neighbor(
- tgen, topo, dut=dut, expected=False, attempts=5
+ tgen, topo, dut=dut, expected=False, retry_timeout=10
)
assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
@@ -610,7 +610,7 @@ def test_ospf_authentication_different_auths_tc30_p1(request):
step("Verify that the neighbour is not FULL between R1 and R2.")
dut = "r1"
ospf_covergence = verify_ospf_neighbor(
- tgen, topo, dut=dut, expected=False, attempts=5
+ tgen, topo, dut=dut, expected=False, retry_timeout=10
)
assert ospf_covergence is not True, "setup_module :Failed \n Error:" " {}".format(
ospf_covergence
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
index 1aabc06db0..49ecaac9f7 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
@@ -326,7 +326,7 @@ def test_ospf_ecmp_tc16_p0(request):
step("Verify that route is withdrawn from R2.")
dut = "r1"
result = verify_ospf_rib(
- tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False
+ tgen, dut, input_dict, next_hop=nh, retry_timeout=10, expected=False
)
assert (
result is not True
@@ -342,7 +342,7 @@ def test_ospf_ecmp_tc16_p0(request):
input_dict,
protocol=protocol,
next_hop=nh,
- attempts=5,
+ retry_timeout=10,
expected=False,
)
assert (
@@ -434,7 +434,7 @@ def test_ospf_ecmp_tc17_p0(request):
step("Verify that route is withdrawn from R2.")
dut = "r1"
result = verify_ospf_rib(
- tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False
+ tgen, dut, input_dict, next_hop=nh, retry_timeout=10, expected=False
)
assert (
result is not True
@@ -450,7 +450,7 @@ def test_ospf_ecmp_tc17_p0(request):
input_dict,
protocol=protocol,
next_hop=nh,
- attempts=5,
+ retry_timeout=10,
expected=False,
)
assert (
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
index e6dc18a434..47c6c45e39 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
@@ -305,7 +305,7 @@ def test_ospf_lan_ecmp_tc18_p0(request):
step("Verify that all the routes are withdrawn from R0")
dut = "r1"
result = verify_ospf_rib(
- tgen, dut, input_dict, next_hop=nh, attempts=5, expected=False
+ tgen, dut, input_dict, next_hop=nh, retry_timeout=10, expected=False
)
assert (
result is not True
@@ -321,7 +321,7 @@ def test_ospf_lan_ecmp_tc18_p0(request):
input_dict,
protocol=protocol,
next_hop=nh,
- attempts=5,
+ retry_timeout=10,
expected=False,
)
assert (
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
index 7864d0307a..0848f6c94a 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
@@ -501,7 +501,7 @@ def test_ospf_routemaps_functionality_tc20_p0(request):
dut = "r1"
protocol = "ospf"
- result = verify_ospf_rib(tgen, dut, input_dict, attempts=2, expected=False)
+ result = verify_ospf_rib(tgen, dut, input_dict, retry_timeout=4, expected=False)
assert (
result is not True
), "Testcase {} : Failed \n " "r1: OSPF routes are present \n Error: {}".format(
@@ -509,7 +509,7 @@ def test_ospf_routemaps_functionality_tc20_p0(request):
)
result = verify_rib(
- tgen, "ipv4", dut, input_dict, protocol=protocol, attempts=2, expected=False
+ tgen, "ipv4", dut, input_dict, protocol=protocol, retry_timeout=4, expected=False
)
assert (
result is not True
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
index 9dfde325f6..f17346d5b1 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
@@ -263,7 +263,7 @@ def test_ospf_redistribution_tc5_p0(request):
input_dict,
protocol=protocol,
next_hop=nh,
- attempts=5,
+ retry_timeout=10,
expected=False,
)
assert result is not True, (
diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py
index bbb4370a93..2c44ec2351 100644
--- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py
+++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py
@@ -690,9 +690,8 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ebgp(request):
next_hop=nh,
protocol=protocol,
fib=True,
+ retry_timeout=6,
expected=False,
- wait=2,
- attempts=3,
)
assert (
result is not True
@@ -804,8 +803,7 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ebgp(request):
protocol=protocol,
fib=True,
expected=False,
- wait=2,
- attempts=3,
+ retry_timeout=6,
)
assert (
result is not True
@@ -1283,8 +1281,7 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc10_ebgp(request):
protocol=protocol,
fib=True,
expected=False,
- wait=2,
- attempts=3,
+ retry_timeout=6,
)
assert (
result is not True
diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py
index ee0e01b411..85b9e8b543 100644
--- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py
+++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py
@@ -695,12 +695,11 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ibgp(request):
protocol=protocol,
fib=True,
expected=False,
- wait=2,
- attempts=3,
+ retry_timeout=6,
)
assert (
result is not True
- ), "Testcase {} : Failed \nError: Routes " " are missing in RIB".format(tc_name)
+ ), "Testcase {} : Failed \nError: Routes " " are present in RIB".format(tc_name)
step(
"Remove the static route configured with nexthop N1 to N8, one"
@@ -808,8 +807,7 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc6_ibgp(request):
protocol=protocol,
fib=True,
expected=False,
- wait=2,
- attempts=3,
+ retry_timeout=6,
)
assert (
result is not True
@@ -1512,8 +1510,7 @@ def test_static_route_8nh_diff_AD_bgp_ecmp_p1_tc10_ibgp(request):
protocol=protocol,
fib=True,
expected=False,
- wait=2,
- attempts=3,
+ retry_timeout=6,
)
assert (
result is not True
diff --git a/tools/build-debian-package.sh b/tools/build-debian-package.sh
index d21f468bf5..3c922c355c 100755
--- a/tools/build-debian-package.sh
+++ b/tools/build-debian-package.sh
@@ -1,27 +1,75 @@
#!/bin/sh
#
# Written by Daniil Baturin, 2018
+# Rewritten by Ondřej Surý, 2020
# This file is public domain
set -e
-cd "`dirname $0`"
-cd ..
+cd "$(dirname "$0")/.."
-if [ "`id -u`" = 0 ]; then
+#
+# Checking requirements
+#
+
+if [ "$(id -u)" = 0 ]; then
echo "Running as root - installing dependencies"
- apt-get install fakeroot debhelper devscripts
+ apt-get install fakeroot debhelper devscripts git-buildpackage lsb-release
mk-build-deps --install debian/control
exit 0
fi
git diff-index --quiet HEAD || echo "Warning: git working directory is not clean!"
-echo "Preparing the build"
-tools/tarsource.sh -V
+############################
+# Build the Debian package #
+############################
-echo "Building the Debian package"
-if test $# -eq 0; then
- dpkg-buildpackage -b -uc -us
-else
- dpkg-buildpackage "$@"
-fi
+#
+# Now we will construct an "upstream" version out of:
+# 1. version in AC_INIT
+# 2. the unix time from the last commit (HEAD)
+# (alternatively %Y%m%d%H%M%S could be used here)
+# 4. Debian version (always -1)
+#
+
+UPSTREAM_VERSION=$(sed -ne 's/AC_INIT(\[frr\],\s\[\([^]]*\)\],.*/\1/p' configure.ac | sed -e 's/-\(\(dev\|alpha\|beta\)\d*\)/~\1/')
+LAST_TIMESTAMP=$(git log --format=format:%ad --date=format:%s -1 "HEAD")
+DEBIAN_VERSION="$UPSTREAM_VERSION-$LAST_TIMESTAMP-1"
+DEBIAN_BRANCH=$(git rev-parse --abbrev-ref HEAD)
+
+#
+# We add a Debian changelog entry, and use artifical "since commit"
+# so there's not a whole git history in the debian/changelog.
+#
+# The --snapshot option appends ~1.<shorthash> to the debian version, so for the
+# release build, this needs to be replaces with --release
+#
+
+echo "Adding new snapshot debian/changelog entry for $DEBIAN_VERSION..."
+
+gbp dch \
+ --debian-branch="$DEBIAN_BRANCH" \
+ --new-version="$DEBIAN_VERSION" \
+ --dch-opt="--force-bad-version" \
+ --since="HEAD~" \
+ --snapshot \
+ --commit \
+ --git-author
+
+echo "Building package..."
+
+#
+# git-buildpackage will use $BUILDER command to just build new binary package
+#
+
+BUILDER="dpkg-buildpackage -uc -us --build=binary --no-check-builddeps --no-pre-clean -sa"
+UPSTREAM_COMPRESSION=xz
+
+gbp buildpackage \
+ --git-export-dir="$WORKDIR" \
+ --git-builder="$BUILDER" \
+ --git-debian-branch="$DEBIAN_BRANCH" \
+ --git-force-create \
+ --git-compression=$UPSTREAM_COMPRESSION \
+ --git-no-pristine-tar \
+ --git-ignore-new
diff --git a/tools/generate_support_bundle.py b/tools/generate_support_bundle.py
index 38fdbd46df..56b2872d1e 100755
--- a/tools/generate_support_bundle.py
+++ b/tools/generate_support_bundle.py
@@ -1,117 +1,89 @@
#!/usr/bin/env python3
+#
+# Copyright (c) 2021, LabN Consulting, L.L.C.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; see the file COPYING; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
########################################################
### Python Script to generate the FRR support bundle ###
########################################################
+import argparse
+import logging
import os
import subprocess
-import datetime
-
-ETC_DIR = "/etc/frr/"
-LOG_DIR = "/var/log/frr/"
-SUCCESS = 1
-FAIL = 0
-
-inputFile = ETC_DIR + "support_bundle_commands.conf"
-
-# Create the output file name
-def createOutputFile(procName):
- fileName = procName + "_support_bundle.log"
- oldFile = LOG_DIR + fileName
- cpFileCmd = "cp " + oldFile + " " + oldFile + ".prev"
- rmFileCmd = "rm -rf " + oldFile
- print("Making backup of " + oldFile)
- os.system(cpFileCmd)
- print("Removing " + oldFile)
- os.system(rmFileCmd)
- return fileName
-
-
-# Open the output file for this process
-def openOutputFile(fileName):
- crt_file_cmd = LOG_DIR + fileName
- print(crt_file_cmd)
- try:
- outputFile = open(crt_file_cmd, "w")
- return outputFile
- except IOError:
- return ()
-
-
-# Close the output file for this process
-def closeOutputFile(f):
- try:
- f.close()
- return SUCCESS
- except IOError:
- return FAIL
-
-
-# Execute the command over vtysh and store in the
-# output file
-def executeCommand(cmd, outputFile):
- cmd_exec_str = 'vtysh -c "' + cmd + '" '
+import tempfile
+
+def open_with_backup(path):
+ if os.path.exists(path):
+ print("Making backup of " + path)
+ subprocess.check_call("mv {0} {0}.prev".format(path))
+ return open(path, "w")
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-c", "--config", default="/etc/frr/support_bundle_commands.conf", help="input config")
+ parser.add_argument("-l", "--log-dir", default="/var/log/frr", help="directory for logfiles")
+ args = parser.parse_args()
+
+ collecting = False # file format has sentinels (seem superfluous)
+ proc_cmds = {}
+ proc = None
+ temp = None
+
+ # Collect all the commands for each daemon
try:
- cmd_output = subprocess.check_output(cmd_exec_str, shell=True)
- try:
- dateTime = datetime.datetime.now()
- outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n")
- outputFile.write(str(cmd_output))
- outputFile.write(
- "########################################################\n"
- )
- outputFile.write("\n")
- except Exception as e:
- print("Writing to output file Failed: ", e)
- except subprocess.CalledProcessError as e:
- dateTime = datetime.datetime.now()
- outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n")
- outputFile.write(e.output)
- outputFile.write("########################################################\n")
- outputFile.write("\n")
- print("Error:" + e.output)
-
-
-# Process the support bundle configuration file
-# and call appropriate functions
-def processConfFile():
-
- lines = list()
- outputFile = None
-
- try:
- with open(inputFile, "r") as supportBundleConfFile:
- for l in supportBundleConfFile:
- lines.append(l.rstrip())
- except IOError:
- print("conf file {} not present".format(inputFile))
- return
-
- for line in lines:
- if len(line) == 0 or line[0] == "#":
- continue
-
- cmd_line = line.split(":")
- if cmd_line[0] == "PROC_NAME":
- outputFileName = createOutputFile(cmd_line[1])
- if outputFileName:
- print(outputFileName, "created for", cmd_line[1])
- elif cmd_line[0] == "CMD_LIST_START":
- outputFile = openOutputFile(outputFileName)
- if outputFile:
- print(outputFileName, "opened")
- else:
- print(outputFileName, "open failed")
- return FAIL
- elif cmd_line[0] == "CMD_LIST_END":
- if closeOutputFile(outputFile):
- print(outputFileName, "closed")
+ for line in open(args.config):
+ line = line.rstrip()
+ if len(line) == 0 or line[0] == "#":
+ continue
+
+ cmd_line = line.split(":")
+ if cmd_line[0] == "PROC_NAME":
+ proc = cmd_line[1]
+ temp = tempfile.NamedTemporaryFile("w+")
+ collecting = False
+ elif cmd_line[0] == "CMD_LIST_START":
+ collecting = True
+ elif cmd_line[0] == "CMD_LIST_END":
+ collecting = False
+ temp.flush()
+ proc_cmds[proc] = open(temp.name)
+ temp.close()
+ elif collecting:
+ temp.write(line + "\n")
else:
- print(outputFileName, "close failed")
- else:
- print("Execute:", cmd_line[0])
- executeCommand(cmd_line[0], outputFile)
-
+ print("Ignoring unexpected input " + line.rstrip())
+ except IOError as error:
+ logging.fatal("Cannot read config file: %s: %s", args.config, str(error))
+ return
-# Main Function
-processConfFile()
+ # Spawn a vtysh to fetch each set of commands
+ procs = []
+ for proc in proc_cmds:
+ ofn = os.path.join(args.log_dir, proc + "_support_bundle.log")
+ p = subprocess.Popen(
+ ["/usr/bin/env", "vtysh", "-t"],
+ stdin=proc_cmds[proc],
+ stdout=open_with_backup(ofn),
+ stderr=subprocess.STDOUT,
+ )
+ procs.append(p)
+
+ for p in procs:
+ p.wait()
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/tarsource.sh b/tools/tarsource.sh
deleted file mode 100755
index 4843fe88b0..0000000000
--- a/tools/tarsource.sh
+++ /dev/null
@@ -1,336 +0,0 @@
-#!/bin/bash
-# 2018 by David Lamparter, placed in the Public Domain
-
-help() {
- cat <<EOF
-FRR tarball/dsc helper, intended to run from a git checkout
-
-Usage:
- ./tarsource.sh [-dDn] [-i GITPATH] [-o OUTDIR] [-S KEYID]
- [-C COMMIT] [-e EXTRAVERSION] [-z gz|xz]
-
-options:
- -i GITPATH path to git working tree or bare repository.
- - default: parent directory containing this script
- -o OUTDIR path to place the generated output files in.
- - default: current directory
- -C COMMIT build tarball for specified git commit
- - default: current HEAD
- -e EXTRAVERSION override automatic package extraversion
- - default "-YYYYMMDD-NN-gGGGGGGGGGGGG", but the script
- autodetects if a release tag is checked out
- -z gz|xz compression format to use
- - default: xz
- -S KEYID sign the output with gpg key
- -d use dirty git tree with local changes
- -D generate Debian .dsc and .debian.tar.xz too
- (note: output files are moved to parent directory)
- -l remove Debian auto-build changelog entry
- (always done for releases)
- -V write version information to config.version and exit
- -n allow executing from non-git source (NOT RECOMMENDED)
- -h show this help text
-
-Note(1) that this script tries very hard to generate a deterministic,
-reproducible tarball by eliminating timestamps and similar things. However,
-since the tarball includes autoconf/automake files, the versions of these
-tools need to be _exactly_ identical to get the same tarball.
-
-Note(2) the debian ".orig" tarball is always identical to the "plain" tarball
-generated without the -D option.
-
-Note(3) if you want the tool to identify github PRs, you need to edit your
-.git/config to fetch PRs from github like this:
-
- [remote "origin"]
- url = git@github.com:frrouting/frr.git
- fetch = +refs/heads/*:refs/remotes/origin/*
-ADD: fetch = +refs/pull/*/head:refs/remotes/origin/pull/*
-EOF
-}
-
-set -e
-
-options=`getopt -o 'hi:o:C:S:e:z:DdnlV' -l help -- "$@"`
-debian=false
-dirty=false
-nongit=false
-zip=xz
-adjchangelog=false
-writeversion=false
-extraset=false
-set - $options
-while test $# -gt 0; do
- arg="$1"; shift; optarg=$1
- case "$arg" in
- -h|--help) help; exit 0;;
- -d) dirty=true;;
- -D) debian=true;;
- -n) nongit=true;;
- -i) eval src=$optarg; shift;;
- -C) eval commit=$optarg; shift;;
- -o) eval outdir=$optarg; shift;;
- -e) eval extraver=$optarg; extraset=true; shift;;
- -z) eval zip=$optarg; shift;;
- -S) eval keyid=$optarg; shift;;
- -l) adjchangelog=true;;
- -V) writeversion=true;;
- --) break;;
- *) echo something went wrong with getopt >&2
- exit 1
- ;;
- esac
-done
-
-cwd="`pwd`"
-outdir="${outdir:-$cwd}"
-
-if test -e "$outdir" -a \! -d "$outdir"; then
- echo "output $outdir must be a directory" >&2
- exit 1
-elif test \! -d "$outdir"; then
- mkdir -p "$outdir"
-fi
-
-cd "$outdir"
-outdir="`pwd`"
-cd "$cwd"
-cd "`dirname $0`/.."
-selfdir="`pwd`"
-src="${src:-$selfdir}"
-
-if $writeversion; then
- if $nongit; then
- echo "The -V option cannot be used without a git tree" >&2
- exit 1
- fi
- dirty=true
-fi
-
-case "$zip" in
-gz) ziptarget=dist-gzip; ziptool="gzip -n -9"; unzip="gzip -k -c";;
-xz) ziptarget=dist-xz; ziptool="xz -z -e"; unzip="xz -d -k -c";;
-*) echo "unknown compression format $zip" >&2
- exit 1
-esac
-
-# always overwrite file ownership in tars
-taropt="--owner=root --group=root"
-
-onexit() {
- rv="$?"
- set +e
- test -n "$tmpdir" -a -d "$tmpdir" && rm -rf "$tmpdir"
-
- if test "$rv" -ne 0; then
- echo -e "\n\033[31;1mfailed\n" >&2
- if test "$dirty" = true; then
- echo please try running the script without the -d option.>&2
- fi
- fi
- exit $rv
-}
-trap onexit EXIT
-tmpdir="`mktemp -d -t frrtar.XXXXXX`"
-
-if test -e "$src/.git"; then
- commit="`git -C \"$src\" rev-parse \"${commit:-HEAD}\"`"
-
- if $dirty; then
- cd "$src"
- echo -e "\033[31;1mgit: using dirty worktree in $src\033[m" >&2
- else
- echo -e "\033[33;1mgit: preparing a clean clone of $src\033[m"
- branch="${tmpdir##*/}"
- cd "$tmpdir"
-
- git -C "$src" branch "$branch" "$commit"
- git clone --single-branch -s -b "$branch" "$src" source
- git -C "$src" branch -D "$branch"
- cd source
- fi
-
- # if we're creating a tarball from git, force the timestamps inside
- # the tar to match the commit date - this makes the tarball itself
- # reproducible
- gitts="`TZ=UTC git show -s --format=%cd --date=local $commit`"
- gitts="`TZ=UTC date -d "$gitts" '+%Y-%m-%dT%H:%M:%SZ'`"
- taropt="--mtime=$gitts $taropt"
-
- # check if we're on a release tag
- gittag="`git -C \"$src\" describe --tags --match 'frr-*' --first-parent --long $commit`"
- gittag="${gittag%-g*}"
- gittag="${gittag%-*}"
-
- # if there have been changes to packaging or tests, it's still the
- # same release
- changes="`git diff --name-only "$gittag" $commit | \
- egrep -v '\.git|^m4/|^config|^README|^alpine/|^debian/|^pkgsrc/|^ports/|^redhat/|^snapcraft/|^solaris/|^tests/|^tools/|^gdb/|^docker/|^\.' | \
- wc -l`"
- if test "$changes" -eq 0; then
- adjchangelog=true
- echo "detected release build for tag $gittag" >&2
- $extraset || extraver=""
- elif ! $adjchangelog; then
- gitdate="`TZ=UTC date -d "$gitts" '+%Y%m%d'`"
- gitrev="`git rev-parse --short $commit`"
- dayseq="`git rev-list --since \"${gitts%T*} 00:00:00 +0000\" $commit | wc -l`"
- dayseq="`printf '%02d' $(( $dayseq - 1 ))`"
-
- $extraset || extraver="-$gitdate-$dayseq-g$gitrev"
-
- git -C "$src" remote -v | grep fetch | sed -e 's% (fetch)$%%' \
- | egrep -i '\b(git@github\.com:frrouting/frr\.git|https://github\.com/FRRouting/frr\.git)$' \
- | while read remote; do
- remote="${remote%% *}"
-
- git -C "$src" var -l | egrep "^remote.$remote.fetch=" \
- | while read fetch; do
- fetch="${fetch#*=}"
- from="${fetch%:*}"
- to="${fetch#*:}"
- if test "$from" = "+refs/pull/*/head"; then
- name="`git -C \"$src\" name-rev --name-only --refs \"$to\" $commit`"
- test "$name" = "undefined" && continue
- realname="${name%~*}"
- realname="${realname%%^*}"
- realname="${realname%%@*}"
- if test "$realname" = "$name"; then
- echo "${name##*/}" > "$tmpdir/.gitpr"
- break
- fi
- fi
- done || true
- test -n "$gitpr" && break
- done || true
- test $extraset = false -a -f "$tmpdir/.gitpr" && extraver="-PR`cat \"$tmpdir/.gitpr\"`$extraver"
- fi
-
- debsrc="git ls-files debian/"
-else
- if $nongit; then
- echo -e "\033[31;1mWARNING: this script should be executed from a git tree\033[m" >&2
- else
- echo -e "\033[31;1mERROR: this script should be executed from a git tree\033[m" >&2
- exit 1
- fi
- debsrc="echo debian"
-fi
-
-if $writeversion; then
- pkgver="`egrep ^AC_INIT configure.ac`"
- pkgver="${pkgver#*,}"
- pkgver="${pkgver%,*}"
- pkgver="`echo $pkgver`" # strip whitespace
- pkgver="${pkgver#[}"
- pkgver="${pkgver%]}"
-
- echo -e "\033[32;1mwriting version ID \033[36;1mfrr-$pkgver$extraver\033[m"
-
- cat > config.version <<EOF
-# config.version override by tarsource.sh
-EXTRAVERSION="$extraver"
-DIST_PACKAGE_VERSION="$pkgver$extraver"
-gitts="$gitts"
-taropt="$taropt"
-EOF
- sed -e "s%@VERSION@%$pkgver$extraver%" \
- < changelog-auto.in \
- > changelog-auto
- exit 0
-fi
-
-echo -e "\033[33;1mpreparing source tree\033[m"
-
-# config.version will also overwrite gitts and taropt when tarsource.sh
-# was used to write the config.version file before - but configure will
-# overwrite config.version down below!
-if test -f config.version; then
- # never executed for clean git build
- . ./config.version
- if $nongit; then
- $extraset || extraver="$EXTRAVERSION"
- fi
-fi
-if test \! -f configure; then
- # always executed for clean git build
- ./bootstrap.sh
-fi
-if test "$EXTRAVERSION" != "$extraver" -o \! -f config.status; then
- # always executed for clean git build
- # options don't matter really - we just want to make a dist tarball
- ./configure --with-pkg-extra-version=$extraver
-fi
-
-. ./config.version
-PACKAGE_VERSION="$DIST_PACKAGE_VERSION"
-
-echo -e "\033[33;1mpacking up \033[36;1mfrr-$PACKAGE_VERSION\033[m"
-
-make GZIP_ENV="-n9" am__tar="tar -chof - $taropt \"\$\$tardir\"" $ziptarget
-mv frr-${PACKAGE_VERSION}.tar.$zip "$outdir" || true
-lsfiles="frr-${PACKAGE_VERSION}.tar.$zip"
-
-if $debian; then
- mkdir -p "$tmpdir/debian/source"
- cat debian/changelog > "$tmpdir/debian/changelog"
- if $adjchangelog; then
- if grep -q 'autoconf changelog entry' debian/changelog; then
- tail -n +9 debian/changelog > "$tmpdir/debian/changelog"
- fi
- fi
- echo '3.0 (quilt)' > "$tmpdir/debian/source/format"
- DEBVER="`dpkg-parsechangelog -l\"$tmpdir/debian/changelog\" -SVersion`"
-
- eval $debsrc | tar -cho $taropt \
- --exclude-vcs --exclude debian/source/format \
- --exclude debian/changelog \
- --exclude debian/changelog-auto \
- --exclude debian/changelog-auto.in \
- --exclude debian/subdir.am \
- -T - -f ../frr_${DEBVER}.debian.tar
- # add specially prepared files from above
- tar -uf ../frr_${DEBVER}.debian.tar $taropt -C "$tmpdir" debian/source/format debian/changelog
-
- test -f ../frr_${DEBVER}.debian.tar.$zip && rm -f ../frr_${DEBVER}.debian.tar.$zip
- $ziptool ../frr_${DEBVER}.debian.tar
-
- # pack up debian files proper
- ln -s "$outdir/frr-${PACKAGE_VERSION}.tar.$zip" ../frr_${PACKAGE_VERSION}.orig.tar.$zip
- dpkg-source -l"$tmpdir/debian/changelog" \
- --format='3.0 (custom)' --target-format='3.0 (quilt)' \
- -b . frr_${PACKAGE_VERSION}.orig.tar.$zip frr_${DEBVER}.debian.tar.$zip
-
- dpkg-genchanges -sa -S > ../frr_${DEBVER}_source.changes
-
- test -n "$keyid" && debsign ../frr_${DEBVER}_source.changes -k"$keyid"
-
- mv ../frr_${DEBVER}_source.changes "$outdir" || true
- mv ../frr_${DEBVER}.dsc "$outdir" || true
- mv ../frr_${DEBVER}.debian.tar.$zip "$outdir" || true
- if test -h ../frr_${PACKAGE_VERSION}.orig.tar.$zip; then
- rm ../frr_${PACKAGE_VERSION}.orig.tar.$zip || true
- fi
- ln -s frr-${PACKAGE_VERSION}.tar.$zip "$outdir/frr_${PACKAGE_VERSION}.orig.tar.$zip" || true
-
- cd "$outdir"
-
- lsfiles="$lsfiles \
- frr_${DEBVER}.dsc \
- frr_${DEBVER}.debian.tar.$zip \
- frr_${PACKAGE_VERSION}.orig.tar.$zip \
- frr_${DEBVER}_source.changes"
-fi
-
-cd "$outdir"
-if test -n "$keyid"; then
- $unzip frr-${PACKAGE_VERSION}.tar.$zip > frr-${PACKAGE_VERSION}.tar
- test -f frr-${PACKAGE_VERSION}.tar.asc && rm frr-${PACKAGE_VERSION}.tar.asc
- if gpg -a --detach-sign -u "$keyid" frr-${PACKAGE_VERSION}.tar; then
- lsfiles="$lsfiles frr-${PACKAGE_VERSION}.tar.asc"
- fi
- rm frr-${PACKAGE_VERSION}.tar
-fi
-
-echo -e "\n\033[32;1mdone: \033[36;1mfrr-$PACKAGE_VERSION\033[m\n"
-ls -l $lsfiles
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 507c6ce882..dd3f448674 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -56,6 +56,9 @@ struct vty *vty;
/* VTY shell pager name. */
char *vtysh_pager_name = NULL;
+/* VTY should add timestamp */
+bool vtysh_add_timestamp;
+
/* VTY shell client structure */
struct vtysh_client {
int fd;
@@ -483,6 +486,13 @@ static int vtysh_execute_func(const char *line, int pager)
}
}
+ if (vtysh_add_timestamp && strncmp(line, "exit", 4)) {
+ char ts[48];
+
+ (void)quagga_timestamp(3, ts, sizeof(ts));
+ vty_out(vty, "%% %s\n\n", ts);
+ }
+
saved_ret = ret = cmd_execute(vty, line, &cmd, 1);
saved_node = vty->node;
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index 71f672554b..e56d482da2 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -113,4 +113,6 @@ extern struct vty *vty;
extern int user_mode;
+extern bool vtysh_add_timestamp;
+
#endif /* VTYSH_H */
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 6d80cf9d96..d22ec3113f 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -560,6 +560,7 @@ static int vtysh_read_file(FILE *confp, bool dry_run)
int vtysh_read_config(const char *config_default_dir, bool dry_run)
{
FILE *confp = NULL;
+ bool save;
int ret;
confp = fopen(config_default_dir, "r");
@@ -570,9 +571,14 @@ int vtysh_read_config(const char *config_default_dir, bool dry_run)
return CMD_ERR_NO_FILE;
}
+ save = vtysh_add_timestamp;
+ vtysh_add_timestamp = false;
+
ret = vtysh_read_file(confp, dry_run);
fclose(confp);
+ vtysh_add_timestamp = save;
+
return (ret);
}
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index fe33bed7f6..20be81b901 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -201,6 +201,7 @@ struct option longopts[] = {
{"writeconfig", no_argument, NULL, 'w'},
{"pathspace", required_argument, NULL, 'N'},
{"user", no_argument, NULL, 'u'},
+ {"timestamp", no_argument, NULL, 't'},
{0}};
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
@@ -308,6 +309,7 @@ int main(int argc, char **argv, char **env)
int opt;
int dryrun = 0;
int boot_flag = 0;
+ bool ts_flag = false;
const char *daemon_name = NULL;
const char *inputfile = NULL;
struct cmd_rec {
@@ -346,7 +348,7 @@ int main(int argc, char **argv, char **env)
/* Option handling. */
while (1) {
- opt = getopt_long(argc, argv, "be:c:d:nf:H:mEhCwN:u", longopts,
+ opt = getopt_long(argc, argv, "be:c:d:nf:H:mEhCwN:ut", longopts,
0);
if (opt == EOF)
@@ -408,6 +410,9 @@ int main(int argc, char **argv, char **env)
case 'u':
user_mode = 1;
break;
+ case 't':
+ ts_flag = true;
+ break;
case 'w':
writeconfig = 1;
break;
@@ -624,6 +629,8 @@ int main(int argc, char **argv, char **env)
if (!user_mode)
vtysh_execute("enable");
+ vtysh_add_timestamp = ts_flag;
+
while (cmd != NULL) {
char *eol;
@@ -712,6 +719,8 @@ int main(int argc, char **argv, char **env)
if (!user_mode)
vtysh_execute("enable");
+ vtysh_add_timestamp = ts_flag;
+
/* Preparation for longjmp() in sigtstp(). */
sigsetjmp(jmpbuf, 1);
jmpflag = 1;
diff --git a/yang/frr-pim.yang b/yang/frr-pim.yang
index 4c4819ac25..6329e45588 100644
--- a/yang/frr-pim.yang
+++ b/yang/frr-pim.yang
@@ -113,6 +113,49 @@ module frr-pim {
"RP keep alive Timer in seconds.";
}
}
+
+ grouping msdp-timers {
+ leaf hold-time {
+ type uint32 {
+ range 3..600;
+ }
+ units seconds;
+ default 75;
+ description
+ "Hold period is started at the MSDP peer connection establishment
+ and is reset every new message. When the period expires the
+ connection is closed.
+
+ This value needs to be greater than `keep-alive-period`.";
+ }
+
+ leaf keep-alive {
+ type uint32 {
+ range 2..600;
+ }
+ units seconds;
+ default 60;
+ description
+ "To maintain a connection established it is necessary to send
+ keep alive messages in a certain frequency and this allows its
+ configuration.
+
+ This value needs to be lesser than `hold-time-period`.";
+ }
+
+ leaf connection-retry {
+ type uint32 {
+ range 1..600;
+ }
+ units seconds;
+ default 30;
+ description
+ "This period is used in the MSDP peer with the highest IP value
+ in the pair and configures the interval between TCP connection
+ attempts.";
+ }
+ }
+
grouping per-af-global-pim-config-attributes {
description
"A grouping defining per address family pim global attributes";
@@ -174,6 +217,12 @@ module frr-pim {
"Enable ssmpingd operation.";
}
+ /* Global timers configuration. */
+ container msdp {
+ description "Global MSDP configuration.";
+ uses msdp-timers;
+ }
+
list msdp-mesh-groups {
key "name";
description
@@ -219,6 +268,7 @@ module frr-pim {
}
leaf source-ip {
+ mandatory true;
type inet:ip-address;
description
"MSDP source IP address.";
diff --git a/zebra/connected.c b/zebra/connected.c
index d110ccf6dd..e1dd0dbdff 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -75,7 +75,7 @@ static void connected_announce(struct interface *ifp, struct connected *ifc)
if (!if_is_loopback(ifp) && ifc->address->family == AF_INET &&
!IS_ZEBRA_IF_VRF(ifp)) {
- if (ifc->address->prefixlen == 32)
+ if (ifc->address->prefixlen == IPV4_MAX_BITLEN)
SET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
else
UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
@@ -198,7 +198,7 @@ static void connected_update(struct interface *ifp, struct connected *ifc)
void connected_up(struct interface *ifp, struct connected *ifc)
{
afi_t afi;
- struct prefix p = {0};
+ struct prefix p;
struct nexthop nh = {
.type = NEXTHOP_TYPE_IFINDEX,
.ifindex = ifp->ifindex,
@@ -225,7 +225,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)
/* Ensure 'down' flag is cleared */
UNSET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
- PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
+ prefix_copy(&p, CONNECTED_PREFIX(ifc));
/* Apply mask to the network. */
apply_mask(&p);
@@ -277,9 +277,9 @@ void connected_up(struct interface *ifp, struct connected *ifc)
* resolve to the same network and mask
*/
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
- struct prefix cp = {0};
+ struct prefix cp;
- PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
+ prefix_copy(&cp, CONNECTED_PREFIX(c));
apply_mask(&cp);
if (prefix_same(&cp, &p) &&
@@ -330,8 +330,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
p = prefix_ipv4_new();
p->family = AF_INET;
p->prefix = *addr;
- p->prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN
- : prefixlen;
+ p->prefixlen =
+ CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_BITLEN : prefixlen;
ifc->address = (struct prefix *)p;
/* If there is a peer address. */
@@ -358,8 +358,7 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
}
/* no destination address was supplied */
- if (!dest && (prefixlen == IPV4_MAX_PREFIXLEN)
- && if_is_pointopoint(ifp))
+ if (!dest && (prefixlen == IPV4_MAX_BITLEN) && if_is_pointopoint(ifp))
zlog_debug(
"PtP interface %s with addr %pI4/%d needs a peer address",
ifp->name, addr, prefixlen);
@@ -412,7 +411,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)
return;
}
- PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
+ prefix_copy(&p, CONNECTED_PREFIX(ifc));
/* Apply mask to the network. */
apply_mask(&p);
@@ -450,7 +449,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)
for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
struct prefix cp;
- PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
+ prefix_copy(&cp, CONNECTED_PREFIX(c));
apply_mask(&cp);
if (prefix_same(&p, &cp) &&
@@ -512,8 +511,8 @@ void connected_delete_ipv4(struct interface *ifp, int flags,
memset(&p, 0, sizeof(struct prefix));
p.family = AF_INET;
p.u.prefix4 = *addr;
- p.prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN
- : prefixlen;
+ p.prefixlen =
+ CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_BITLEN : prefixlen;
if (dest) {
memset(&d, 0, sizeof(struct prefix));
diff --git a/zebra/interface.c b/zebra/interface.c
index 7fd967dd8b..408c016494 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -3055,7 +3055,7 @@ static int ip_address_install(struct vty *vty, struct interface *ifp,
}
if (peer_str) {
- if (lp.prefixlen != 32) {
+ if (lp.prefixlen != IPV4_MAX_BITLEN) {
vty_out(vty,
"%% Local prefix length for P-t-P address must be /32\n");
return CMD_WARNING_CONFIG_FAILED;
@@ -3186,7 +3186,7 @@ static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
}
if (peer_str) {
- if (lp.prefixlen != 32) {
+ if (lp.prefixlen != IPV4_MAX_BITLEN) {
vty_out(vty,
"%% Local prefix length for P-t-P address must be /32\n");
return CMD_WARNING_CONFIG_FAILED;
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 03884a9168..252bf04782 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1066,7 +1066,7 @@ void rtm_read(struct rt_msghdr *rtm)
p.family = AF_INET;
p.u.prefix4 = dest.sin.sin_addr;
if (flags & RTF_HOST)
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
else
p.prefixlen = ip_masklen(mask.sin.sin_addr);
@@ -1079,7 +1079,7 @@ void rtm_read(struct rt_msghdr *rtm)
p.family = AF_INET6;
p.u.prefix6 = dest.sin6.sin6_addr;
if (flags & RTF_HOST)
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
else
p.prefixlen = ip6_masklen(mask.sin6.sin6_addr);
diff --git a/zebra/main.c b/zebra/main.c
index e36af51005..bded50149f 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -186,7 +186,6 @@ static void sigint(void)
work_queue_free_and_null(&zrouter.lsp_process_q);
vrf_terminate();
- rtadv_terminate();
ns_walk_func(zebra_ns_early_shutdown, NULL, NULL);
zebra_ns_notify_close();
diff --git a/zebra/rib.h b/zebra/rib.h
index 957f38602a..b7ffb9ce8d 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -288,16 +288,30 @@ DECLARE_LIST(re_list, struct route_entry, next);
#define RNODE_NEXT_RE(rn, re) RE_DEST_NEXT_ROUTE(rib_dest_from_rnode(rn), re)
#if defined(HAVE_RTADV)
+PREDECL_SORTLIST_UNIQ(adv_if_list);
/* Structure which hold status of router advertisement. */
struct rtadv {
int sock;
- int adv_if_count;
- int adv_msec_if_count;
+ struct adv_if_list_head adv_if;
+ struct adv_if_list_head adv_msec_if;
struct thread *ra_read;
struct thread *ra_timer;
};
+
+/* adv list node */
+struct adv_if {
+ char name[INTERFACE_NAMSIZ];
+ struct adv_if_list_item list_item;
+};
+
+static int adv_if_cmp(const struct adv_if *a, const struct adv_if *b)
+{
+ return if_cmp_name_func(a->name, b->name);
+}
+
+DECLARE_SORTLIST_UNIQ(adv_if_list, struct adv_if, list_item, adv_if_cmp);
#endif /* HAVE_RTADV */
/*
diff --git a/zebra/router-id.c b/zebra/router-id.c
index 3b556c92b5..689b9787ee 100644
--- a/zebra/router-id.c
+++ b/zebra/router-id.c
@@ -81,7 +81,7 @@ int router_id_get(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf)
case AFI_IP:
p->u.prefix4.s_addr = INADDR_ANY;
p->family = AF_INET;
- p->prefixlen = 32;
+ p->prefixlen = IPV4_MAX_BITLEN;
if (zvrf->rid_user_assigned.u.prefix4.s_addr != INADDR_ANY)
p->u.prefix4.s_addr =
zvrf->rid_user_assigned.u.prefix4.s_addr;
@@ -98,7 +98,7 @@ int router_id_get(afi_t afi, struct prefix *p, struct zebra_vrf *zvrf)
case AFI_IP6:
p->u.prefix6 = in6addr_any;
p->family = AF_INET6;
- p->prefixlen = 128;
+ p->prefixlen = IPV6_MAX_BITLEN;
if (!router_id_v6_is_any(&zvrf->rid6_user_assigned))
addr = &zvrf->rid6_user_assigned.u.prefix6;
else if (!list_isempty(zvrf->rid6_lo_sorted_list)) {
@@ -276,7 +276,7 @@ DEFUN (ip_router_id,
if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
return CMD_WARNING_CONFIG_FAILED;
- rid.prefixlen = 32;
+ rid.prefixlen = IPV4_MAX_BITLEN;
rid.family = AF_INET;
argv_find(argv, argc, "NAME", &idx);
@@ -313,7 +313,7 @@ DEFUN (ipv6_router_id,
if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6))
return CMD_WARNING_CONFIG_FAILED;
- rid.prefixlen = 128;
+ rid.prefixlen = IPV6_MAX_BITLEN;
rid.family = AF_INET6;
argv_find(argv, argc, "NAME", &idx);
@@ -342,7 +342,7 @@ DEFUN (ip_router_id_in_vrf,
if (!inet_pton(AF_INET, argv[idx]->arg, &rid.u.prefix4))
return CMD_WARNING_CONFIG_FAILED;
- rid.prefixlen = 32;
+ rid.prefixlen = IPV4_MAX_BITLEN;
rid.family = AF_INET;
router_id_set(AFI_IP, &rid, zvrf);
@@ -372,7 +372,7 @@ DEFUN (ipv6_router_id_in_vrf,
if (!inet_pton(AF_INET6, argv[idx]->arg, &rid.u.prefix6))
return CMD_WARNING_CONFIG_FAILED;
- rid.prefixlen = 128;
+ rid.prefixlen = IPV6_MAX_BITLEN;
rid.family = AF_INET6;
router_id_set(AFI_IP6, &rid, zvrf);
@@ -599,7 +599,7 @@ void router_id_init(struct zebra_vrf *zvrf)
zvrf->rid6_lo_sorted_list->cmp = router_id_v6_cmp;
zvrf->rid_user_assigned.family = AF_INET;
- zvrf->rid_user_assigned.prefixlen = 32;
+ zvrf->rid_user_assigned.prefixlen = IPV4_MAX_BITLEN;
zvrf->rid6_user_assigned.family = AF_INET6;
- zvrf->rid6_user_assigned.prefixlen = 128;
+ zvrf->rid6_user_assigned.prefixlen = IPV6_MAX_BITLEN;
}
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 1e06b3e0e9..976beefab0 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -54,6 +54,7 @@ extern struct zebra_privs_t zserv_privs;
#endif
DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix");
+DEFINE_MTYPE_STATIC(ZEBRA, ADV_IF, "Advertised Interface");
#ifdef OPEN_BSD
#include <netinet/icmp6.h>
@@ -92,11 +93,13 @@ static void rtadv_event(struct zebra_vrf *, enum rtadv_event, int);
static int if_join_all_router(int, struct interface *);
static int if_leave_all_router(int, struct interface *);
-static int rtadv_get_socket(struct zebra_vrf *zvrf)
+static struct zebra_vrf *rtadv_interface_get_zvrf(const struct interface *ifp)
{
- if (zvrf->rtadv.sock > 0)
- return zvrf->rtadv.sock;
- return zrouter.rtadv_sock;
+ /* We use the default vrf for rtadv handling except in netns */
+ if (!vrf_is_backend_netns())
+ return vrf_info_lookup(VRF_DEFAULT);
+
+ return vrf_info_lookup(ifp->vrf_id);
}
static int rtadv_increment_received(struct zebra_vrf *zvrf, ifindex_t *ifindex)
@@ -480,7 +483,7 @@ static int rtadv_timer(struct thread *thread)
int period;
zvrf->rtadv.ra_timer = NULL;
- if (zvrf->rtadv.adv_msec_if_count == 0) {
+ if (adv_if_list_count(&zvrf->rtadv.adv_msec_if) == 0) {
period = 1000; /* 1 s */
rtadv_event(zvrf, RTADV_TIMER, 1 /* 1 s */);
} else {
@@ -520,8 +523,8 @@ static int rtadv_timer(struct thread *thread)
ifp->ifindex);
}
- rtadv_send_packet(rtadv_get_socket(zvrf),
- ifp, RA_ENABLE);
+ rtadv_send_packet(zvrf->rtadv.sock, ifp,
+ RA_ENABLE);
} else {
zif->rtadv.AdvIntervalTimer -= period;
if (zif->rtadv.AdvIntervalTimer <= 0) {
@@ -534,8 +537,8 @@ static int rtadv_timer(struct thread *thread)
zif->rtadv
.MaxRtrAdvInterval;
rtadv_send_packet(
- rtadv_get_socket(zvrf),
- ifp, RA_ENABLE);
+ zvrf->rtadv.sock, ifp,
+ RA_ENABLE);
}
}
}
@@ -546,9 +549,10 @@ static int rtadv_timer(struct thread *thread)
static void rtadv_process_solicit(struct interface *ifp)
{
- struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
+ struct zebra_vrf *zvrf;
struct zebra_if *zif;
+ zvrf = rtadv_interface_get_zvrf(ifp);
assert(zvrf);
zif = ifp->info;
@@ -565,7 +569,7 @@ static void rtadv_process_solicit(struct interface *ifp)
if ((zif->rtadv.UseFastRexmit)
|| (zif->rtadv.AdvIntervalTimer <=
(zif->rtadv.MaxRtrAdvInterval - MIN_DELAY_BETWEEN_RAS))) {
- rtadv_send_packet(rtadv_get_socket(zvrf), ifp, RA_ENABLE);
+ rtadv_send_packet(zvrf->rtadv.sock, ifp, RA_ENABLE);
zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
} else
zif->rtadv.AdvIntervalTimer = MIN_DELAY_BETWEEN_RAS;
@@ -689,7 +693,7 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,
/* Create entry for neighbor if not known. */
p.family = AF_INET6;
IPV6_ADDR_COPY(&p.u.prefix6, &addr->sin6_addr);
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
if (!nbr_connected_check(ifp, &p))
nbr_connected_add_ipv6(ifp, &addr->sin6_addr);
@@ -788,7 +792,7 @@ static int rtadv_read(struct thread *thread)
zvrf->rtadv.ra_read = NULL;
/* Register myself. */
- rtadv_event(zvrf, RTADV_READ, sock);
+ rtadv_event(zvrf, RTADV_READ, 0);
len = rtadv_recv_packet(zvrf, sock, buf, sizeof(buf), &from, &ifindex,
&hoplimit);
@@ -862,6 +866,201 @@ static int rtadv_make_socket(ns_id_t ns_id)
return sock;
}
+static struct adv_if *adv_if_new(const char *name)
+{
+ struct adv_if *new;
+
+ new = XCALLOC(MTYPE_ADV_IF, sizeof(struct adv_if));
+
+ strlcpy(new->name, name, sizeof(new->name));
+
+ return new;
+}
+
+static void adv_if_free(struct adv_if *adv_if)
+{
+ XFREE(MTYPE_ADV_IF, adv_if);
+}
+
+static bool adv_if_is_empty_internal(const struct adv_if_list_head *adv_if_head)
+{
+ return adv_if_list_count(adv_if_head) ? false : true;
+}
+
+static struct adv_if *adv_if_add_internal(struct adv_if_list_head *adv_if_head,
+ const char *name)
+{
+ struct adv_if adv_if_lookup = {};
+ struct adv_if *adv_if = NULL;
+
+ strlcpy(adv_if_lookup.name, name, sizeof(adv_if_lookup.name));
+ adv_if = adv_if_list_find(adv_if_head, &adv_if_lookup);
+
+ if (adv_if != NULL)
+ return adv_if;
+
+ adv_if = adv_if_new(adv_if_lookup.name);
+ adv_if_list_add(adv_if_head, adv_if);
+
+ return NULL;
+}
+
+static struct adv_if *adv_if_del_internal(struct adv_if_list_head *adv_if_head,
+ const char *name)
+{
+ struct adv_if adv_if_lookup = {};
+ struct adv_if *adv_if = NULL;
+
+ strlcpy(adv_if_lookup.name, name, sizeof(adv_if_lookup.name));
+ adv_if = adv_if_list_find(adv_if_head, &adv_if_lookup);
+
+ if (adv_if == NULL)
+ return NULL;
+
+ adv_if_list_del(adv_if_head, adv_if);
+
+ return adv_if;
+}
+
+static void adv_if_clean_internal(struct adv_if_list_head *adv_if_head)
+{
+ struct adv_if *node = NULL;
+
+ if (!adv_if_is_empty_internal(adv_if_head)) {
+ frr_each_safe (adv_if_list, adv_if_head, node) {
+ adv_if_list_del(adv_if_head, node);
+ adv_if_free(node);
+ }
+ }
+
+ adv_if_list_fini(adv_if_head);
+}
+
+
+/*
+ * Add to list. On Success, return NULL, otherwise return already existing
+ * adv_if.
+ */
+static struct adv_if *adv_if_add(struct zebra_vrf *zvrf, const char *name)
+{
+ struct adv_if *adv_if = NULL;
+
+ adv_if = adv_if_add_internal(&zvrf->rtadv.adv_if, name);
+
+ if (adv_if != NULL)
+ return adv_if;
+
+ if (IS_ZEBRA_DEBUG_EVENT) {
+ struct vrf *vrf = zvrf->vrf;
+
+ zlog_debug("%s: %s:%u IF %s count: %zu", __func__,
+ VRF_LOGNAME(vrf), zvrf_id(zvrf), name,
+ adv_if_list_count(&zvrf->rtadv.adv_if));
+ }
+
+ return NULL;
+}
+
+/*
+ * Del from list. On Success, return the adv_if, otherwise return NULL. Caller
+ * frees.
+ */
+static struct adv_if *adv_if_del(struct zebra_vrf *zvrf, const char *name)
+{
+ struct adv_if *adv_if = NULL;
+
+ adv_if = adv_if_del_internal(&zvrf->rtadv.adv_if, name);
+
+ if (adv_if == NULL)
+ return NULL;
+
+ if (IS_ZEBRA_DEBUG_EVENT) {
+ struct vrf *vrf = zvrf->vrf;
+
+ zlog_debug("%s: %s:%u IF %s count: %zu", __func__,
+ VRF_LOGNAME(vrf), zvrf_id(zvrf), name,
+ adv_if_list_count(&zvrf->rtadv.adv_if));
+ }
+
+ return adv_if;
+}
+
+/*
+ * Add to list. On Success, return NULL, otherwise return already existing
+ * adv_if.
+ */
+static struct adv_if *adv_msec_if_add(struct zebra_vrf *zvrf, const char *name)
+{
+ struct adv_if *adv_if = NULL;
+
+ adv_if = adv_if_add_internal(&zvrf->rtadv.adv_msec_if, name);
+
+ if (adv_if != NULL)
+ return adv_if;
+
+ if (IS_ZEBRA_DEBUG_EVENT) {
+ struct vrf *vrf = zvrf->vrf;
+
+ zlog_debug("%s: %s:%u IF %s count: %zu", __func__,
+ VRF_LOGNAME(vrf), zvrf_id(zvrf), name,
+ adv_if_list_count(&zvrf->rtadv.adv_msec_if));
+ }
+
+ return NULL;
+}
+
+/*
+ * Del from list. On Success, return the adv_if, otherwise return NULL. Caller
+ * frees.
+ */
+static struct adv_if *adv_msec_if_del(struct zebra_vrf *zvrf, const char *name)
+{
+ struct adv_if *adv_if = NULL;
+
+ adv_if = adv_if_del_internal(&zvrf->rtadv.adv_msec_if, name);
+
+ if (adv_if == NULL)
+ return NULL;
+
+ if (IS_ZEBRA_DEBUG_EVENT) {
+ struct vrf *vrf = zvrf->vrf;
+
+ zlog_debug("%s: %s:%u IF %s count: %zu", __func__,
+ VRF_LOGNAME(vrf), zvrf_id(zvrf), name,
+ adv_if_list_count(&zvrf->rtadv.adv_msec_if));
+ }
+
+ return adv_if;
+}
+
+/* Clean adv_if list, called on vrf terminate */
+static void adv_if_clean(struct zebra_vrf *zvrf)
+{
+ if (IS_ZEBRA_DEBUG_EVENT) {
+ struct vrf *vrf = zvrf->vrf;
+
+ zlog_debug("%s: %s:%u count: %zu -> 0", __func__,
+ VRF_LOGNAME(vrf), zvrf_id(zvrf),
+ adv_if_list_count(&zvrf->rtadv.adv_if));
+ }
+
+ adv_if_clean_internal(&zvrf->rtadv.adv_if);
+}
+
+/* Clean adv_msec_if list, called on vrf terminate */
+static void adv_msec_if_clean(struct zebra_vrf *zvrf)
+{
+ if (IS_ZEBRA_DEBUG_EVENT) {
+ struct vrf *vrf = zvrf->vrf;
+
+ zlog_debug("%s: %s:%u count: %zu -> 0", __func__,
+ VRF_LOGNAME(vrf), zvrf_id(zvrf),
+ adv_if_list_count(&zvrf->rtadv.adv_msec_if));
+ }
+
+ adv_if_clean_internal(&zvrf->rtadv.adv_msec_if);
+}
+
static struct rtadv_prefix *rtadv_prefix_new(void)
{
return XCALLOC(MTYPE_RTADV_PREFIX, sizeof(struct rtadv_prefix));
@@ -1006,30 +1205,34 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
{
struct zebra_if *zif;
struct zebra_vrf *zvrf;
+ struct adv_if *adv_if = NULL;
zif = ifp->info;
- zvrf = vrf_info_lookup(ifp->vrf_id);
+
+ zvrf = rtadv_interface_get_zvrf(ifp);
if (status == RA_SUPPRESS) {
/* RA is currently enabled */
if (zif->rtadv.AdvSendAdvertisements) {
- rtadv_send_packet(rtadv_get_socket(zvrf), ifp,
- RA_SUPPRESS);
+ rtadv_send_packet(zvrf->rtadv.sock, ifp, RA_SUPPRESS);
zif->rtadv.AdvSendAdvertisements = 0;
zif->rtadv.AdvIntervalTimer = 0;
- zvrf->rtadv.adv_if_count--;
- if_leave_all_router(rtadv_get_socket(zvrf), ifp);
+ adv_if = adv_if_del(zvrf, ifp->name);
+ if (adv_if == NULL)
+ return; /* Nothing to delete */
+
+ adv_if_free(adv_if);
+
+ if_leave_all_router(zvrf->rtadv.sock, ifp);
- if (zvrf->rtadv.adv_if_count == 0)
+ if (adv_if_list_count(&zvrf->rtadv.adv_if) == 0)
rtadv_event(zvrf, RTADV_STOP, 0);
}
} else {
if (!zif->rtadv.AdvSendAdvertisements) {
zif->rtadv.AdvSendAdvertisements = 1;
zif->rtadv.AdvIntervalTimer = 0;
- zvrf->rtadv.adv_if_count++;
-
if ((zif->rtadv.MaxRtrAdvInterval >= 1000)
&& zif->rtadv.UseFastRexmit) {
/*
@@ -1041,11 +1244,14 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
RTADV_NUM_FAST_REXMITS;
}
- if_join_all_router(rtadv_get_socket(zvrf), ifp);
+ adv_if = adv_if_add(zvrf, ifp->name);
+ if (adv_if != NULL)
+ return; /* Alread added */
+
+ if_join_all_router(zvrf->rtadv.sock, ifp);
- if (zvrf->rtadv.adv_if_count == 1)
- rtadv_event(zvrf, RTADV_START,
- rtadv_get_socket(zvrf));
+ if (adv_if_list_count(&zvrf->rtadv.adv_if) == 1)
+ rtadv_event(zvrf, RTADV_START, 0);
}
}
}
@@ -1092,7 +1298,7 @@ static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
zebra_route_string(client->proto));
return;
}
- if (ifp->vrf_id != zvrf_id(zvrf)) {
+ if (vrf_is_backend_netns() && ifp->vrf_id != zvrf_id(zvrf)) {
struct vrf *vrf = zvrf->vrf;
zlog_debug(
@@ -1136,10 +1342,10 @@ void rtadv_stop_ra(struct interface *ifp)
struct zebra_vrf *zvrf;
zif = ifp->info;
- zvrf = vrf_info_lookup(ifp->vrf_id);
+ zvrf = rtadv_interface_get_zvrf(ifp);
if (zif->rtadv.AdvSendAdvertisements)
- rtadv_send_packet(rtadv_get_socket(zvrf), ifp, RA_SUPPRESS);
+ rtadv_send_packet(zvrf->rtadv.sock, ifp, RA_SUPPRESS);
}
/*
@@ -1179,6 +1385,76 @@ void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS)
zebra_interface_radv_set(client, hdr, msg, zvrf, 1);
}
+static void show_zvrf_rtadv_adv_if_helper(struct vty *vty,
+ struct adv_if_list_head *adv_if_head)
+{
+ struct adv_if *node = NULL;
+
+ if (!adv_if_is_empty_internal(adv_if_head)) {
+ frr_each (adv_if_list, adv_if_head, node) {
+ vty_out(vty, " %s\n", node->name);
+ }
+ }
+
+ vty_out(vty, "\n");
+}
+
+static void show_zvrf_rtadv_helper(struct vty *vty, struct zebra_vrf *zvrf)
+{
+ vty_out(vty, "VRF: %s\n", zvrf_name(zvrf));
+ vty_out(vty, " Interfaces:\n");
+ show_zvrf_rtadv_adv_if_helper(vty, &zvrf->rtadv.adv_if);
+
+ vty_out(vty, " Interfaces(msec):\n");
+ show_zvrf_rtadv_adv_if_helper(vty, &zvrf->rtadv.adv_msec_if);
+}
+
+DEFPY(show_ipv6_nd_ra_if, show_ipv6_nd_ra_if_cmd,
+ "show ipv6 nd ra-interfaces [vrf<NAME$vrf_name|all$vrf_all>]",
+ SHOW_STR IP6_STR
+ "Neighbor discovery\n"
+ "Route Advertisement Interfaces\n" VRF_FULL_CMD_HELP_STR)
+{
+ struct zebra_vrf *zvrf = NULL;
+
+ if (!vrf_is_backend_netns() && (vrf_name || vrf_all)) {
+ vty_out(vty,
+ "%% VRF subcommand only applicable for netns-based vrfs.\n");
+ return CMD_WARNING;
+ }
+
+ if (vrf_all) {
+ struct vrf *vrf;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ struct zebra_vrf *zvrf;
+
+ zvrf = vrf->info;
+ if (!zvrf)
+ continue;
+
+ show_zvrf_rtadv_helper(vty, zvrf);
+ }
+
+ return CMD_SUCCESS;
+ }
+
+ if (vrf_name)
+ zvrf = zebra_vrf_lookup_by_name(vrf_name);
+ else
+ zvrf = zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME);
+
+ if (!zvrf) {
+ vty_out(vty, "%% VRF '%s' specified does not exist\n",
+ vrf_name);
+ return CMD_WARNING;
+ }
+
+ show_zvrf_rtadv_helper(vty, zvrf);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (ipv6_nd_ra_fast_retrans,
ipv6_nd_ra_fast_retrans_cmd,
"ipv6 nd ra-fast-retrans",
@@ -1379,8 +1655,9 @@ DEFUN (ipv6_nd_ra_interval_msec,
unsigned interval;
struct zebra_if *zif = ifp->info;
struct zebra_vrf *zvrf;
+ struct adv_if *adv_if;
- zvrf = vrf_info_lookup(ifp->vrf_id);
+ zvrf = rtadv_interface_get_zvrf(ifp);
interval = strtoul(argv[idx_number]->arg, NULL, 10);
if ((zif->rtadv.AdvDefaultLifetime != -1
@@ -1390,11 +1667,14 @@ DEFUN (ipv6_nd_ra_interval_msec,
return CMD_WARNING_CONFIG_FAILED;
}
- if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zvrf->rtadv.adv_msec_if_count--;
+ if (zif->rtadv.MaxRtrAdvInterval % 1000) {
+ adv_if = adv_msec_if_del(zvrf, ifp->name);
+ if (adv_if != NULL)
+ adv_if_free(adv_if);
+ }
if (interval % 1000)
- zvrf->rtadv.adv_msec_if_count++;
+ (void)adv_msec_if_add(zvrf, ifp->name);
SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
zif->rtadv.MaxRtrAdvInterval = interval;
@@ -1417,8 +1697,9 @@ DEFUN (ipv6_nd_ra_interval,
unsigned interval;
struct zebra_if *zif = ifp->info;
struct zebra_vrf *zvrf;
+ struct adv_if *adv_if;
- zvrf = vrf_info_lookup(ifp->vrf_id);
+ zvrf = rtadv_interface_get_zvrf(ifp);
interval = strtoul(argv[idx_number]->arg, NULL, 10);
if ((zif->rtadv.AdvDefaultLifetime != -1
@@ -1428,8 +1709,11 @@ DEFUN (ipv6_nd_ra_interval,
return CMD_WARNING_CONFIG_FAILED;
}
- if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zvrf->rtadv.adv_msec_if_count--;
+ if (zif->rtadv.MaxRtrAdvInterval % 1000) {
+ adv_if = adv_msec_if_del(zvrf, ifp->name);
+ if (adv_if != NULL)
+ adv_if_free(adv_if);
+ }
/* convert to milliseconds */
interval = interval * 1000;
@@ -1456,11 +1740,15 @@ DEFUN (no_ipv6_nd_ra_interval,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct zebra_if *zif = ifp->info;
struct zebra_vrf *zvrf = NULL;
+ struct adv_if *adv_if;
- zvrf = vrf_info_lookup(ifp->vrf_id);
+ zvrf = rtadv_interface_get_zvrf(ifp);
- if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zvrf->rtadv.adv_msec_if_count--;
+ if (zif->rtadv.MaxRtrAdvInterval % 1000) {
+ adv_if = adv_msec_if_del(zvrf, ifp->name);
+ if (adv_if != NULL)
+ adv_if_free(adv_if);
+ }
UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
@@ -2451,7 +2739,7 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp)
static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
{
- struct rtadv *rtadv = &zvrf->rtadv;
+ struct rtadv *rtadv;
if (IS_ZEBRA_DEBUG_EVENT) {
struct vrf *vrf = zvrf->vrf;
@@ -2460,9 +2748,11 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
VRF_LOGNAME(vrf), event, val);
}
+ rtadv = &zvrf->rtadv;
+
switch (event) {
case RTADV_START:
- thread_add_read(zrouter.master, rtadv_read, zvrf, val,
+ thread_add_read(zrouter.master, rtadv_read, zvrf, rtadv->sock,
&rtadv->ra_read);
thread_add_event(zrouter.master, rtadv_timer, zvrf, 0,
&rtadv->ra_timer);
@@ -2480,7 +2770,7 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
&rtadv->ra_timer);
break;
case RTADV_READ:
- thread_add_read(zrouter.master, rtadv_read, zvrf, val,
+ thread_add_read(zrouter.master, rtadv_read, zvrf, rtadv->sock,
&rtadv->ra_read);
break;
default:
@@ -2489,37 +2779,27 @@ static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
return;
}
-void rtadv_init(struct zebra_vrf *zvrf)
+void rtadv_vrf_init(struct zebra_vrf *zvrf)
{
- if (vrf_is_backend_netns()) {
- zvrf->rtadv.sock = rtadv_make_socket(zvrf->zns->ns_id);
- zrouter.rtadv_sock = -1;
- } else {
- zvrf->rtadv.sock = -1;
- if (zrouter.rtadv_sock < 0)
- zrouter.rtadv_sock =
- rtadv_make_socket(zvrf->zns->ns_id);
- }
+ if (!vrf_is_backend_netns() && (zvrf_id(zvrf) != VRF_DEFAULT))
+ return;
+
+ zvrf->rtadv.sock = rtadv_make_socket(zvrf->zns->ns_id);
}
void rtadv_vrf_terminate(struct zebra_vrf *zvrf)
{
+ if (!vrf_is_backend_netns() && (zvrf_id(zvrf) != VRF_DEFAULT))
+ return;
+
rtadv_event(zvrf, RTADV_STOP, 0);
if (zvrf->rtadv.sock >= 0) {
close(zvrf->rtadv.sock);
zvrf->rtadv.sock = -1;
}
- zvrf->rtadv.adv_if_count = 0;
- zvrf->rtadv.adv_msec_if_count = 0;
-}
-
-void rtadv_terminate(void)
-{
- if (zrouter.rtadv_sock >= 0) {
- close(zrouter.rtadv_sock);
- zrouter.rtadv_sock = -1;
- }
+ adv_if_clean(zvrf);
+ adv_msec_if_clean(zvrf);
}
void rtadv_cmd_init(void)
@@ -2527,6 +2807,8 @@ void rtadv_cmd_init(void)
hook_register(zebra_if_extra_info, nd_dump_vty);
hook_register(zebra_if_config_wr, rtadv_config_write);
+ install_element(VIEW_NODE, &show_ipv6_nd_ra_if_cmd);
+
install_element(INTERFACE_NODE, &ipv6_nd_ra_fast_retrans_cmd);
install_element(INTERFACE_NODE, &no_ipv6_nd_ra_fast_retrans_cmd);
install_element(INTERFACE_NODE, &ipv6_nd_ra_retrans_interval_cmd);
@@ -2629,14 +2911,11 @@ static int if_leave_all_router(int sock, struct interface *ifp)
}
#else
-void rtadv_init(struct zebra_vrf *zvrf)
-{
- /* Empty.*/;
-}
-void rtadv_terminate(void)
+void rtadv_vrf_init(struct zebra_vrf *zvrf)
{
/* Empty.*/;
}
+
void rtadv_cmd_init(void)
{
/* Empty.*/;
diff --git a/zebra/rtadv.h b/zebra/rtadv.h
index d7a1ccfb29..7b71ee45a2 100644
--- a/zebra/rtadv.h
+++ b/zebra/rtadv.h
@@ -152,9 +152,8 @@ enum ipv6_nd_suppress_ra_status {
RA_SUPPRESS,
};
-extern void rtadv_init(struct zebra_vrf *zvrf);
+extern void rtadv_vrf_init(struct zebra_vrf *zvrf);
extern void rtadv_vrf_terminate(struct zebra_vrf *zvrf);
-extern void rtadv_terminate(void);
extern void rtadv_stop_ra(struct interface *ifp);
extern void rtadv_stop_ra_all(void);
extern void rtadv_cmd_init(void);
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index d5969ab9bb..8f2aa2fb09 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -480,7 +480,7 @@ void nbr_connected_add_ipv6(struct interface *ifp, struct in6_addr *address)
p.family = AF_INET6;
IPV6_ADDR_COPY(&p.u.prefix6, address);
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
ifc = listnode_head(ifp->nbr_connected);
if (!ifc) {
@@ -505,7 +505,7 @@ void nbr_connected_delete_ipv6(struct interface *ifp, struct in6_addr *address)
p.family = AF_INET6;
IPV6_ADDR_COPY(&p.u.prefix6, address);
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
ifc = nbr_connected_check(ifp, &p);
if (!ifc)
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index a5d672987d..04411fa0d2 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -2537,8 +2537,7 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
*/
memcpy(&p.u, &pw->nexthop, sizeof(pw->nexthop));
p.family = pw->af;
- p.prefixlen = ((pw->af == AF_INET) ?
- IPV4_MAX_PREFIXLEN : IPV6_MAX_PREFIXLEN);
+ p.prefixlen = ((pw->af == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN);
afi = (pw->af == AF_INET) ? AFI_IP : AFI_IP6;
table = zebra_vrf_table(afi, SAFI_UNICAST, pw->vrf_id);
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index a4576b310e..a2d1513ce4 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -613,7 +613,7 @@ static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
/* Lookup nexthop in IPv4 routing table. */
memset(&p, 0, sizeof(struct prefix_ipv4));
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.prefix = nexthop->gate.ipv4;
rn = route_node_match(table, (struct prefix *)&p);
@@ -662,7 +662,7 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
/* Lookup nexthop in IPv6 routing table. */
memset(&p, 0, sizeof(struct prefix_ipv6));
p.family = AF_INET6;
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
p.prefix = nexthop->gate.ipv6;
rn = route_node_match(table, (struct prefix *)&p);
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index face0ef3bc..af86263a16 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -2048,11 +2048,13 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe,
return 1;
}
- if (top &&
- ((top->family == AF_INET && top->prefixlen == 32
- && nexthop->gate.ipv4.s_addr == top->u.prefix4.s_addr)
- || (top->family == AF_INET6 && top->prefixlen == 128
- && memcmp(&nexthop->gate.ipv6, &top->u.prefix6, 16) == 0))) {
+ if (top
+ && ((top->family == AF_INET && top->prefixlen == IPV4_MAX_BITLEN
+ && nexthop->gate.ipv4.s_addr == top->u.prefix4.s_addr)
+ || (top->family == AF_INET6 && top->prefixlen == IPV6_MAX_BITLEN
+ && memcmp(&nexthop->gate.ipv6, &top->u.prefix6,
+ IPV6_MAX_BYTELEN)
+ == 0))) {
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug(
" :%s: Attempting to install a max prefixlength route through itself",
@@ -2118,12 +2120,12 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe,
switch (afi) {
case AFI_IP:
p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = *ipv4;
break;
case AFI_IP6:
p.family = AF_INET6;
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
p.u.prefix6 = nexthop->gate.ipv6;
break;
default:
@@ -2150,8 +2152,10 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe,
* host route.
*/
if (prefix_same(&rn->p, top))
- if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
- || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) {
+ if (((afi == AFI_IP)
+ && (rn->p.prefixlen != IPV4_MAX_BITLEN))
+ || ((afi == AFI_IP6)
+ && (rn->p.prefixlen != IPV6_MAX_BITLEN))) {
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug(
" %s: Matched against ourself and prefix length is not max bit length",
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 73c2c3dda3..7bcd097371 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -925,8 +925,8 @@ static const char *zebra_pbr_prefix2str(union prefixconstptr pu,
const struct prefix *p = pu.p;
char buf[PREFIX2STR_BUFFER];
- if ((p->family == AF_INET && p->prefixlen == IPV4_MAX_PREFIXLEN) ||
- (p->family == AF_INET6 && p->prefixlen == IPV6_MAX_PREFIXLEN)) {
+ if ((p->family == AF_INET && p->prefixlen == IPV4_MAX_BITLEN)
+ || (p->family == AF_INET6 && p->prefixlen == IPV6_MAX_BITLEN)) {
snprintf(str, size, "%s", inet_ntop(p->family, &p->u.prefix,
buf, PREFIX2STR_BUFFER));
return str;
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index d0acf77936..12cc0b4e8a 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -349,10 +349,10 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
p.family = afi;
if (afi == AFI_IP) {
p.u.prefix4 = addr->ipv4;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefixlen = IPV4_MAX_BITLEN;
} else {
p.u.prefix6 = addr->ipv6;
- p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefixlen = IPV6_MAX_BITLEN;
}
rn = route_node_match(table, &p);
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 5a00f3155d..d930f59866 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -268,8 +268,6 @@ void zebra_router_init(bool asic_offload, bool notify_on_ack)
zrouter.packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS;
- zrouter.rtadv_sock = -1;
-
zebra_vxlan_init();
zebra_mlag_init();
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index 08c5fcaf8d..408f9cbee5 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -162,9 +162,6 @@ struct zebra_router {
struct hash *iptable_hash;
- /* used if vrf backend is not network namespace */
- int rtadv_sock;
-
/* A sequence number used for tracking routes */
_Atomic uint32_t sequence_num;
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index a0c63e4202..2430b51989 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -131,7 +131,7 @@ static int zebra_vrf_enable(struct vrf *vrf)
else
zvrf->zns = zebra_ns_lookup(NS_DEFAULT);
#if defined(HAVE_RTADV)
- rtadv_init(zvrf);
+ rtadv_vrf_init(zvrf);
#endif
/* Inform clients that the VRF is now active. This is an
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 51f19a3c03..b204b30ca7 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -915,6 +915,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object_string_add(json_route, "prefix",
srcdest_rnode2str(rn, buf, sizeof(buf)));
+ json_object_int_add(json_route, "prefixLen", rn->p.prefixlen);
json_object_string_add(json_route, "protocol",
zebra_route_string(re->type));
@@ -1121,8 +1122,10 @@ static void vty_show_ip_route_detail_json(struct vty *vty,
prefix2str(&rn->p, buf, sizeof(buf));
json_object_object_add(json, buf, json_prefix);
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY
+ | JSON_C_TO_STRING_NOSLASHESCAPE));
json_object_free(json);
}
@@ -1234,8 +1237,11 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf,
}
if (use_json) {
- vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
- JSON_C_TO_STRING_PRETTY));
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json,
+ JSON_C_TO_STRING_PRETTY
+ | JSON_C_TO_STRING_NOSLASHESCAPE));
json_object_free(json);
}
}