]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #8508 from opensourcerouting/systemd-no-lib
authorQuentin Young <qlyoung@users.noreply.github.com>
Tue, 6 Jul 2021 14:54:25 +0000 (14:54 +0000)
committerGitHub <noreply@github.com>
Tue, 6 Jul 2021 14:54:25 +0000 (14:54 +0000)
211 files changed:
.gitignore
Makefile.am
babeld/babel_interface.c
babeld/kernel.c
babeld/util.c
babeld/util.h
bfdd/dplane.c
bgpd/bgp_aspath.c
bgpd/bgp_attr.c
bgpd/bgp_encap_tlv.c
bgpd/bgp_evpn.c
bgpd/bgp_evpn_mh.c
bgpd/bgp_evpn_vty.c
bgpd/bgp_flowspec_util.c
bgpd/bgp_fsm.c
bgpd/bgp_label.c
bgpd/bgp_mpath.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_network.c
bgpd/bgp_nht.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_routemap_nb_config.c
bgpd/bgp_script.c
bgpd/bgp_script.h
bgpd/bgp_updgrp.c
bgpd/bgp_updgrp_adv.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h
bgpd/rfapi/rfapi.c
bgpd/rfapi/rfapi_import.c
bgpd/rfapi/rfapi_private.h
bgpd/rfapi/rfapi_vty.c
bgpd/rfapi/vnc_export_bgp.c
bgpd/rfapi/vnc_import_bgp.c
bgpd/rfapi/vnc_zebra.c
changelog-auto.in [deleted file]
configure.ac
debian/changelog [changed from symlink to file mode: 0644]
debian/gbp.conf
debian/tests/py-frr-reload
doc/developer/frr-release-procedure.rst
doc/developer/packaging-debian.rst
doc/developer/scripting.rst
doc/user/basic.rst
doc/user/bgp.rst
doc/user/ipv6.rst
doc/user/ospf6d.rst
doc/user/ospfd.rst
doc/user/pim.rst
doc/user/zebra.rst
docker/ubuntu20-ci/Dockerfile
eigrpd/eigrp_network.c
isisd/isis_route.c
isisd/isis_tlvs.c
isisd/isis_zebra.c
ldpd/labelmapping.c
ldpd/lde.c
ldpd/util.c
lib/buffer.c
lib/command.c
lib/command_match.c
lib/compiler.h
lib/csv.c
lib/filter.c
lib/frrlua.c
lib/frrlua.h
lib/frrscript.c
lib/frrscript.h
lib/link_state.c
lib/network.c
lib/ntop.c
lib/prefix.c
lib/prefix.h
lib/routemap.h
lib/sockopt.c
lib/sockunion.c
lib/sockunion.h
lib/stream.c
lib/table.c
lib/zclient.c
lib/zclient.h
ospf6d/ospf6_asbr.c
ospf6d/ospf6_asbr.h
ospf6d/ospf6_interface.c
ospf6d/ospf6_interface.h
ospf6d/ospf6_lsa.c
ospf6d/ospf6_message.c
ospf6d/ospf6_top.c
ospf6d/ospf6_top.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6d.c
ospf6d/subdir.am
ospfd/ospf_asbr.c
ospfd/ospf_interface.c
ospfd/ospf_te.c
ospfd/ospf_ti_lfa.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
pbrd/pbr_zebra.c
pimd/pim_bsm.c
pimd/pim_cmd.c
pimd/pim_iface.c
pimd/pim_ifchannel.c
pimd/pim_igmpv3.c
pimd/pim_instance.c
pimd/pim_msdp.c
pimd/pim_msdp.h
pimd/pim_msdp_packet.c
pimd/pim_nb.c
pimd/pim_nb.h
pimd/pim_nb_config.c
pimd/pim_register.c
pimd/pim_rp.c
pimd/pim_tlv.c
pimd/pim_upstream.c
pimd/pim_util.c
pimd/pim_vty.c
pimd/pim_zlookup.c
ripd/rip_interface.c
ripd/ripd.c
ripngd/ripngd.c
sharpd/sharp_vty.c
staticd/static_nht.c
tests/.gitignore
tests/bgpd/test_peer_attr.c
tests/lib/script1.lua [new file with mode: 0644]
tests/lib/test_frrlua.c [new file with mode: 0644]
tests/lib/test_frrlua.py [new file with mode: 0644]
tests/lib/test_frrscript.c [new file with mode: 0644]
tests/lib/test_frrscript.py [new file with mode: 0644]
tests/subdir.am
tests/topotests/bgp_default_afi_safi/__init__.py [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/r3/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/r3/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/r4/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/r4/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py [new file with mode: 0644]
tests/topotests/bgp_default_ipv4_ipv6_unicast/__init__.py [deleted file]
tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/bgpd.conf [deleted file]
tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/zebra.conf [deleted file]
tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/bgpd.conf [deleted file]
tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/zebra.conf [deleted file]
tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/bgpd.conf [deleted file]
tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/zebra.conf [deleted file]
tests/topotests/bgp_default_ipv4_ipv6_unicast/test_bgp-default-ipv4-ipv6-unicast.py [deleted file]
tests/topotests/lib/bgp.py
tests/topotests/lib/common_config.py
tests/topotests/lib/ospf.py
tests/topotests/lib/pim.py
tests/topotests/msdp_mesh_topo1/r1/pimd.conf
tests/topotests/msdp_mesh_topo1/r2/pimd.conf
tests/topotests/msdp_mesh_topo1/r3/pimd.conf
tests/topotests/msdp_mesh_topo1/test_msdp_mesh_topo1.py
tests/topotests/msdp_topo1/__init__.py [new file with mode: 0644]
tests/topotests/msdp_topo1/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r1/pimd.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r1/zebra.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r2/pimd.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r2/zebra.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r3/bgpd.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r3/pimd.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r3/zebra.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r4/bgpd.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r4/pimd.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/r4/zebra.conf [new file with mode: 0644]
tests/topotests/msdp_topo1/test_msdp_topo1.py [new file with mode: 0755]
tests/topotests/multicast_pim_bsm_topo2/test_mcast_pim_bsmp_02.py
tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py
tests/topotests/ospf_basic_functionality/test_ospf_authentication.py
tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py
tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py
tools/build-debian-package.sh
tools/coccinelle/xcalloc-xmalloc.cocci [new file with mode: 0644]
tools/generate_support_bundle.py
tools/tarsource.sh [deleted file]
vtysh/vtysh.c
vtysh/vtysh.h
vtysh/vtysh_config.c
vtysh/vtysh_main.c
yang/frr-pim.yang
zebra/connected.c
zebra/interface.c
zebra/kernel_socket.c
zebra/main.c
zebra/rib.h
zebra/router-id.c
zebra/rtadv.c
zebra/rtadv.h
zebra/zapi_msg.c
zebra/zebra_dplane.c
zebra/zebra_mpls.c
zebra/zebra_nhg.c
zebra/zebra_pbr.c
zebra/zebra_rib.c
zebra/zebra_router.c
zebra/zebra_router.h
zebra/zebra_vrf.c
zebra/zebra_vty.c

index 33d03296dbc8d20a79870f7fe856890cf5298999..40f6475a26f66518fbbd573c063ec5b86b35ac1f 100644 (file)
@@ -28,7 +28,6 @@
 /aclocal.m4
 /libtool
 /libtool.orig
-/changelog-auto
 /test-driver
 /test-suite.log
 
index 8c9d7df77c9678c91721ccb7dc2e48c001b5cf1c..9bc5dd7d2241f1b0bdc0613f8a334dc371c13f8a 100644 (file)
@@ -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 \
index 41391c51ac9b99e2017addec8e3c29f247558dbd..43ed97cf17d2152b144f46da81d9cad5854567fa 100644 (file)
@@ -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,
index e3c76bdd921099851db8218601e38ffea05ecd5a..3941db8d5f88d74306735a61f8283e3e01707462 100644 (file)
@@ -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:
index e99bd861dc87697114f640e22192bbc4c9b86905..e2db75996e2e684d60b71c817354a0272d57b277 100644 (file)
@@ -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
index 037ebe3666e8bbbeecfe94a7a476a11e50c78eab..ef1387364c5c21e1b03f7441e012d4ecefcf3860 100644 (file)
@@ -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);
index 6fb301d46a89a4a6be208f10057c7779b3ec4f8e..4b7f9ba7ace568af64493e1b1b850a8744720ec4 100644 (file)
@@ -651,8 +651,6 @@ static struct bfd_dplane_ctx *bfd_dplane_ctx_new(int sock)
        struct bfd_dplane_ctx *bdc;
 
        bdc = XCALLOC(MTYPE_BFDD_DPLANE_CTX, sizeof(*bdc));
-       if (bdc == NULL)
-               return NULL;
 
        bdc->sock = sock;
        bdc->inbuf = stream_new(BFD_DPLANE_CLIENT_BUF_SIZE);
index 25109e030b8d705ecb3cc4ae46c86672ae03a97a..3c67017dc7209856f52a995f63c469e25a60119f 100644 (file)
@@ -193,7 +193,8 @@ static struct assegment *assegment_prepend_asns(struct assegment *seg,
        if (num >= AS_SEGMENT_MAX)
                return seg; /* we don't do huge prepends */
 
-       if ((newas = assegment_data_new(seg->length + num)) == NULL)
+       newas = assegment_data_new(seg->length + num);
+       if (newas == NULL)
                return seg;
 
        for (i = 0; i < num; i++)
index 2f0751a5f045ed1ed98c589aa0c93761e1519b07..1bf48b225b17be0ee8ae4cb1bdafcabae9648e4d 100644 (file)
@@ -3317,7 +3317,8 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
        }
 
        /* Check all mandatory well-known attributes are present */
-       if ((ret = bgp_attr_check(peer, attr)) < 0)
+       ret = bgp_attr_check(peer, attr);
+       if (ret < 0)
                goto done;
 
        /*
index 964adec9b64a257e5dae978ac7c136e6362a8a31..fd429120e69575b1f168ea352f446592ee1d5c12 100644 (file)
@@ -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);
index 5ef593b9c023caefeb8ad8992336197d2a86083d..c99f539c7b72ec6d9e157f610b0a12a22b7c61b5 100644 (file)
@@ -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;
        }
 
index 4b90937f627ceaa7eb573d132e0325d092f85a20..34094a0bde9831d3d49154a658066c10bb651d47 100644 (file)
@@ -1311,7 +1311,7 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
        bool old_active;
        bool new_active;
 
-       old_active = !!CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
+       old_active = CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
        /* currently we need an active EVI reference to use the VTEP as
         * a nexthop. this may change...
         */
@@ -1320,7 +1320,7 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
        else
                UNSET_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
 
-       new_active = !!CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
+       new_active = CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
 
        if ((old_active != new_active) || (new_active && param_change)) {
 
@@ -3119,7 +3119,7 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
        bool new_active;
        uint32_t ead_activity_flags;
 
-       old_active = !!CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
+       old_active = CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
 
        if (bgp_mh_info->ead_evi_rx)
                /* Both EAD-per-ES and EAD-per-EVI routes must be rxed from a PE
@@ -3135,7 +3135,7 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
        else
                UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
 
-       new_active = !!CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
+       new_active = CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
 
        if (old_active == new_active)
                return;
index 190323859f323c7d593cd5f7e781d30af1da6aa9..2bda5dbf9a962153af6e662e254bde978e48139a 100644 (file)
@@ -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;
 }
 
index 23baa0184e4e2980e71b80e7404d0b8c603787ab..348dc7c9d1428c8d7ab11217cd47796e204a25fd 100644 (file)
@@ -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:
index 4cc096d8e7c4ff90276f882f9e0dc2ee29d8d74b..79dc0aec9d0850000199c09bb79449a58732b480 100644 (file)
@@ -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;
index 73ca9f07e02f3cc786382579febe9829bf5ac58a..3c8f2f36684a55abf7ac9864b7083597339f9929 100644 (file)
@@ -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 */
index d5fce115de4273a39493892a0c7fa60a4cb40b2a..8127428bc71dc8597f1e980cad539a7993e38024 100644 (file)
@@ -411,7 +411,8 @@ static void bgp_path_info_mpath_lb_update(struct bgp_path_info *path, bool set,
 {
        struct bgp_path_info_mpath *mpath;
 
-       if ((mpath = path->mpath) == NULL) {
+       mpath = path->mpath;
+       if (mpath == NULL) {
                if (!set || (cum_bw == 0 && !all_paths_lb))
                        return;
 
index 564424a082a3b8fa2395887b1a29cfbbb14ace9f..0de48dcf78f5941f4267458ef1fb349cf7f73fb0 100644 (file)
@@ -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)) {
index a51816116e530a3ce2e592b1fe819c3d223b3968..3c061ef1e0ece77a90256282224639d4a78cb0ff 100644 (file)
@@ -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);
index 742ef217d97b224ec60d60421bbcc2b038ad3e17..eb00a4641c8393d6d43a2e3a288cfe94d2743dda 100644 (file)
@@ -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;
                }
@@ -1042,7 +1053,7 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
                    || path->attr->srte_color != 0)
                        SET_FLAG(path->flags, BGP_PATH_IGP_CHANGED);
 
-               path_valid = !!CHECK_FLAG(path->flags, BGP_PATH_VALID);
+               path_valid = CHECK_FLAG(path->flags, BGP_PATH_VALID);
                if (path_valid != bnc_is_valid_nexthop) {
                        if (path_valid) {
                                /* No longer valid, clear flag; also for EVPN
index 4637cef3eb8055778ed3727fb0e025164d5c147b..107aa1eb12e93d5adfb023dbf87c685b2cde64eb 100644 (file)
@@ -11643,7 +11643,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
                        if (!table)
                                continue;
 
-                       if ((rm = bgp_node_match(table, &match)) == NULL)
+                       rm = bgp_node_match(table, &match);
+                       if (rm == NULL)
                                continue;
 
                        const struct prefix *rm_p = bgp_dest_get_prefix(rm);
@@ -11735,7 +11736,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
                                json_object_free(json_paths);
                }
        } else {
-               if ((dest = bgp_node_match(rib, &match)) != NULL) {
+               dest = bgp_node_match(rib, &match);
+               if (dest != NULL) {
                        const struct prefix *dest_p = bgp_dest_get_prefix(dest);
                        if (!prefix_check
                            || dest_p->prefixlen == match.prefixlen) {
@@ -14377,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;
        }
 
@@ -14758,7 +14761,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
                        table = bgp_dest_get_bgp_table_info(dest);
                        if (!table)
                                continue;
-                       if ((rm = bgp_node_match(table, &match)) == NULL)
+                       rm = bgp_node_match(table, &match);
+                       if (rm == NULL)
                                continue;
 
                        const struct prefix *rm_p = bgp_dest_get_prefix(dest);
@@ -14782,8 +14786,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
                        bgp_dest_unlock_node(rm);
                }
        } else {
-               if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
-                   != NULL) {
+               dest = bgp_node_match(bgp->rib[afi][safi], &match);
+               if (dest != NULL) {
                        const struct prefix *dest_p = bgp_dest_get_prefix(dest);
 
                        if (!prefix_check
index 9a7b7b3cf29be3b22352233c46fc5df018c3809b..529abcbea07b35a393c578e71be6f5448be38c73 100644 (file)
@@ -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;
index e541d117bee8b48447d006642ac5dabf514f2be1..88e3f6438f547299887441b85406f2a3ad6afc05 100644 (file)
@@ -70,8 +70,8 @@ static int bgp_route_match_delete(struct route_map_index *index,
        if (type != RMAP_EVENT_MATCH_DELETED) {
                /* ignore the mundane, the types without any dependency */
                if (arg == NULL) {
-                       if ((tmpstr = route_map_get_match_arg(index, command))
-                                       != NULL)
+                       tmpstr = route_map_get_match_arg(index, command);
+                       if (tmpstr != NULL)
                                dep_name =
                                        XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
                } else {
index 0cda1927f8316c1974259917eab5ef3eb6b04491..9446a25a05c950b16235eb9dd0b77ebd7aa01ed8 100644 (file)
@@ -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;
 }
 
index 6682c2eebdcc8fa1998956a1c925c1ccbcd0d50a..f8178aa98385ed47a67ead573d8770af1743d4d8 100644 (file)
 #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__ */
index b8545188a438400bceb6ae7ce18e7e1ff8fb161f..dd3309dad9c7b61242d3b1af2e0e70d7fce81a1d 100644 (file)
@@ -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)
index 18829aa7477a944debe9e28d48da67d9df2f64ff..9c2288cba3999dbbf9dc35e3223a0f4e8913689e 100644 (file)
@@ -572,7 +572,8 @@ void bgp_adj_out_unset_subgroup(struct bgp_dest *dest,
                return;
 
        /* Lookup existing adjacency */
-       if ((adj = adj_lookup(dest, subgrp, addpath_tx_id)) != NULL) {
+       adj = adj_lookup(dest, subgrp, addpath_tx_id);
+       if (adj != NULL) {
                /* Clean up previous advertisement.  */
                if (adj->adv)
                        bgp_advertise_clean_subgroup(subgrp, adj);
index de4f5a59b646a22879b2037143dce70a00a6ea41..9d7e88bb1ca08348378d90e45a117e56ef6f7abf 100644 (file)
@@ -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)
 {
@@ -1789,9 +1857,8 @@ void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode,
                uint32_t med_admin_val;
 
                vty_out(vty, " bgp max-med administrative");
-               if ((med_admin_val =
-                            yang_dnode_get_uint32(dnode, "./max-med-admin"))
-                   != BGP_MAXMED_VALUE_DEFAULT)
+               med_admin_val = yang_dnode_get_uint32(dnode, "./max-med-admin");
+               if (med_admin_val != BGP_MAXMED_VALUE_DEFAULT)
                        vty_out(vty, " %u", med_admin_val);
                vty_out(vty, "\n");
        }
@@ -3741,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;
 }
 
@@ -10120,7 +10195,8 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name,
                        if (table == NULL)
                                continue;
 
-                       if ((rm = bgp_node_match(table, &match)) != NULL) {
+                       rm = bgp_node_match(table, &match);
+                       if (rm != NULL) {
                                const struct prefix *rm_p =
                                        bgp_dest_get_prefix(rm);
 
@@ -10133,7 +10209,8 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name,
                        }
                }
        } else {
-               if ((dest = bgp_node_match(rib, &match)) != NULL) {
+               dest = bgp_node_match(rib, &match);
+               if (dest != NULL) {
                        const struct prefix *dest_p = bgp_dest_get_prefix(dest);
 
                        if (dest_p->prefixlen == match.prefixlen) {
@@ -17436,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);
                }
        }
 
@@ -17796,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",
@@ -17886,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)
@@ -18586,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);
index 5d3176537bb2816fddaffc14000498035419afad..ec71e17034d31d6d6e785f024aa5a6a24e404029 100644 (file)
@@ -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 *
index 49562e587467da16e402ae7634cc28841a20ea95..acade16ef27fb8cebf0de2e67def58ec6621731f 100644 (file)
@@ -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;
@@ -3103,8 +3099,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
        afi_t afi;
        safi_t safi;
 
-       if ((bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp))) == NULL)
-               return NULL;
+       bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp));
 
        if (BGP_DEBUG(zebra, ZEBRA)) {
                if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
@@ -3244,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);
 
index 776f4b0a21c8ed7a98e37fe8e594a0d1444f49d1..d2e8cce997b9aab54e2bc27262ecdd18ea4872cc 100644 (file)
@@ -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];
index f89ef7b0d256e5d6c022c5127baf0c8355cd2610..8bed5156b75096fc0127b64fc4a27d45e70b1e2c 100644 (file)
@@ -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(
index 51e051d68897a817878616c65819dd51d0932fc8..07aed045cab1a807b84934a8d497efd2ede6a648 100644 (file)
@@ -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:
index e7825e8bfcbc93fbce8e94bfdbace7a24bccabae..bc0e192ae2d59a92d02058fa40270a6bb9946d27 100644 (file)
@@ -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,
index 40d5111e8c75a1a51fb0f1c51228a5b0f46d9774..45ef7230b503ffd4e4ee802b102c8453f6ec4368 100644 (file)
@@ -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;
index c90fcf8d72fc8a5e1898c5b06bcace23417b088e..68dc5a4f60cb24eef0f862c44ef6029b40160cd0 100644 (file)
@@ -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 */
index b23c1eda76c6f6adc233ba28bd9366e159d9c2c7..0358c8d665cafe8aedf3a9b02f3b8320c476fc75 100644 (file)
@@ -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);
index b254f11ce7c9cdfe1d12cec3e3de83ffce194fae..ba849e4e0b000a8ccd54508dc7341d967a1e4d47 100644 (file)
@@ -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 (file)
index 50bd5f6..0000000
+++ /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
index a39549cdb7578334225f50609ec82197541119b2..a23011b7558d86dd6d94c215f4b6ec2ab2fb8537 100644 (file)
@@ -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
@@ -2613,7 +2617,6 @@ AC_CONFIG_FILES([Makefile],[
 
 AC_CONFIG_FILES([
          config.version
-         changelog-auto
          redhat/frr.spec
          alpine/APKBUILD
          snapcraft/snapcraft.yaml
deleted file mode 120000 (symlink)
index 021c52c2f33eeebb10921eabb82db2ad670f5def..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../changelog-auto
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..99c75106db1d77e58eb06749c1fa4c87c344835e
--- /dev/null
+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
index 990c4d226e03628d57f887118de8a51d16e4ab1b..23917b9b8f610cea808769f23796b9cd430d7eac 100644 (file)
@@ -1,4 +1,4 @@
 [DEFAULT]
 pristine-tar = False
 debian-branch = master
-upstream-tree=SLOPPY
+upstream-tree = SLOPPY
index e2c97e8744e978f6ee4cfbfc7ba96567220070c5..6dfef33f08d980fc6a5bc29f4dacbebf6f428fc4 100755 (executable)
@@ -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
index 5da73f61f6c99d5e64762fe8d25ef580336fb066..08e3057ae69caad6f782e8b47c98519ff9350643 100644 (file)
@@ -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:
index be05d599efd02d41cbf376d92459664108725be7..a81e05249015d7f2be26169c892fb19561b54404 100644 (file)
@@ -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:
 
@@ -73,6 +70,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
@@ -89,12 +98,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:
 
@@ -103,7 +106,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
 
index 708f65ff7d081e22d16e56640e6921922e83a205..1757d41feb22b69933098f2d23249d85dde2bf9f 100644 (file)
@@ -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::
 
index 92357bec8398ee959ddd4e47f040e31259e9f2a0..16708adb50990dd84b8d986ec4f9f835f106336b 100644 (file)
@@ -66,10 +66,6 @@ Basic Config Commands
    Set domainname of the router. It is only for current ``vtysh``, it will not
    be saved to any configuration file even with ``write file``.
 
-.. clicmd:: domainname DOMAINNAME
-
-   Set domainname of the router.
-
 .. clicmd:: password PASSWORD
 
    Set password for vty interface. The ``no`` form of the command deletes the
index 7f23f7a633837bea8f72d9d6e2fff8e6acca2bd8..b5950538dd25b8a858706f361d1202104c7e9afa 100644 (file)
@@ -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
@@ -2727,10 +2778,12 @@ Host1 MAC/IP as type-2 route which is used to resolve host1 gateway IP.
 PE2 receives this type-5 route and imports it into the vrf based on route
 targets. BGP prefix imported into the vrf uses gateway IP as its BGP nexthop.
 This route is installed into zebra if following conditions are satisfied:
+
 1. Gateway IP nexthop is L3 reachable.
 2. PE2 has received EVPN type-2 route with IP field set to gateway IP.
 
 Topology requirements:
+
 1. This feature is supported for asymmetric routing model only. While
    sending packets to SN1, ingress PE (PE2) performs routing and
    egress PE (PE1) performs only bridging.
@@ -2749,8 +2802,7 @@ route with gateway IP.
 1. CLI to add gateway IP while generating EVPN type-5 route from a BGP IPv4/IPv6
 prefix:
 
-.. index:: advertise <ipv4|ipv6> unicast [gateway-ip]
-.. clicmd:: [no] advertise <ipv4|ipv6> unicast [gateway-ip]
+.. clicmd:: advertise <ipv4|ipv6> unicast [gateway-ip]
 
 When this CLI is configured for a BGP vrf under L2VPN EVPN address family, EVPN
 type-5 routes are generated for BGP prefixes in the vrf. Nexthop of the BGP
@@ -2761,8 +2813,7 @@ routes are generated without overlay index.
 
 2. Add gateway IP to EVPN type-5 route using a route-map:
 
-.. index:: set evpn gateway-ip <ipv4|ipv6> <addr>
-.. clicmd:: [no] set evpn gateway-ip <ipv4|ipv6> <addr>
+.. clicmd:: set evpn gateway-ip <ipv4|ipv6> <addr>
 
 When route-map with above set clause is applied as outbound policy in BGP, it
 will set the gateway-ip in EVPN type-5 NLRI.
@@ -2786,8 +2837,7 @@ A PE that receives a type-5 route with gateway IP overlay index should have
 "enable-resolve-overlay-index" configuration enabled to recursively resolve the
 overlay index nexthop and install the prefix into zebra.
 
-.. index:: enable-resolve-overlay-index
-.. clicmd:: [no] enable-resolve-overlay-index
+.. clicmd:: enable-resolve-overlay-index
 
 Example configuration:
 
index 089fae39b1feb31333cfd5447ba3fe14faab693a..4f01061e7b03c5315e0fed174680b4af48212217 100644 (file)
@@ -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
index 1e8c66ab2eb887aea57ad808d97a7895fc09d0b3..04ee1643d8085cd4b5d8d79941b7ceb320f8bbfb 100644 (file)
@@ -77,14 +77,20 @@ OSPF6 router
    of packets to process before returning. The default value of this parameter
    is 20.
 
+.. clicmd:: clear ipv6 ospf6 process [vrf NAME]
+
+   This command clears up the database and routing tables and resets the
+   neighborship by restarting the interface state machine. This will be
+   helpful when there is a change in router-id and if user wants the router-id
+   change to take effect, user can use this cli instead of restarting the
+   ospf6d daemon.
 
 .. _ospf6-area:
 
 OSPF6 area
 ==========
 
-.. index:: [no] area A.B.C.D nssa
-.. clicmd:: [no] area A.B.C.D nssa
+.. clicmd:: area A.B.C.D nssa
 
 NSSA Support in OSPFv3
 =======================
index 692ce8c1b2b225c66cb445d85ca7cffe54f55dfe..8d67ec865fa2ff03a4280546909a0acdf6f4549f 100644 (file)
@@ -80,11 +80,13 @@ Routers
 
 To start OSPF process you have to specify the OSPF router.
 
-.. clicmd:: router ospf [(1-65535)] vrf NAME
+.. clicmd:: router ospf [{(1-65535)|vrf NAME}]
 
 
    Enable or disable the OSPF process.
 
+   Multiple instances don't support `vrf NAME`.
+
 .. clicmd:: ospf router-id A.B.C.D
 
 
index 103760933cf8f0ad6a5a0c137119962bead2b838..83d19d61880e768763fe65000b6074ce95d2ee4e 100644 (file)
@@ -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
 
index ee9da63445d4c937486b338920d92feef7e5f671..36548011009c2ebdd4fa62ae8a632fd157ae1960 100644 (file)
@@ -647,7 +647,6 @@ FRR's cli or frr.conf or zebra.conf. This section shows how
 to configure SRv6 on FRR. Of course SRv6 can be used as standalone,
 and this section also helps that case.
 
-.. index:: show segment-routing srv6 locator [json]
 .. clicmd:: show segment-routing srv6 locator [json]
 
    This command dump SRv6-locator configured on zebra.  SRv6-locator is used
@@ -666,7 +665,6 @@ and this section also helps that case.
    loc1                       1 2001:db8:1:1::/64        Up
    loc2                       2 2001:db8:2:2::/64        Up
 
-.. index:: show segment-routing srv6 locator NAME detail [json]
 .. clicmd:: show segment-routing srv6 locator NAME detail [json]
 
    As shown in the example, by specifying the name of the locator, you
@@ -696,29 +694,24 @@ and this section also helps that case.
    Chunks:
    - prefix: 2001:db8:2:2::/64, owner: sharp
 
-.. index:: segment-routing
 .. clicmd:: segment-routing
 
    Move from configure mode to segment-routing node.
 
-.. index:: srv6
 .. clicmd:: srv6
 
    Move from segment-routing node to srv6 node.
 
-.. index:: locators
 .. clicmd:: locators
 
    Move from srv6 node to locator node. In this locator node, user can
    configure detailed settings such as the actual srv6 locator.
 
-.. index:: locator NAME
 .. clicmd:: locator NAME
 
    Create a new locator. If the name of an existing locator is specified,
    move to specified locator's configuration node to change the settings it.
 
-.. index:: prefix X:X::X:X/M [function-bits-length 32]
 .. clicmd:: prefix X:X::X:X/M [function-bits-length 32]
 
    Set the ipv6 prefix block of the locator. SRv6 locator is defined by
index c94a31173a71c2ed8aff8ccc38f5a81afdc16db0..b5df98f23e24327c656ef374203c0ce95e4e5bf2 100644 (file)
@@ -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
index 69dcc2025394af0efbf54910b2c2f053fe389b63..9a5fbc52b4da37d241c83367a30aa4d3e1242ad0 100644 (file)
@@ -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. */
index eb534a543a2be222c85ec3ac6b15ae90257712c2..bf0079d8145202dec3756c2c5d53cd8faac11ac2 100644 (file)
@@ -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;
                        }
index 2bac8e7fd58e8dff0ffffa2c447c05f6f4489c25..17dbb1903d518bc7cbba19546f932caf88a17de8 100644 (file)
@@ -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;
index 0142e30b2be63aa647931e852bcc229c76fd6add..2c05cb827797e5c0a377cea98d6d04d968860c4a 100644 (file)
@@ -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 */
index cee9d527e859a95dd27d8ab3de21638c297cdb02..13d3243124cfeaf0613a48275f14fc15d5a97273 100644 (file)
@@ -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);
index 724e83adb29b4ae476034785b4e6f1fd448f4691..2d35d097a1cdf57158daea4ff4c5105864afaf69 100644 (file)
@@ -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,
index b4d74f1950ec69b78ea1b7a1ec2ace93471ee69b..019d846ada441d0191d3523b85b7024f39525762 100644 (file)
@@ -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])
index 7929b3709dc1d7cfc239533f42e5997d81efcfdd..41b1adc9fc0d2dc9e333ac84e1ffb4495a0bd859 100644 (file)
@@ -357,7 +357,8 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width,
 
                        iov_size =
                                ((iov_index > IOV_MAX) ? IOV_MAX : iov_index);
-                       if ((nbytes = writev(fd, c_iov, iov_size)) < 0) {
+                       nbytes = writev(fd, c_iov, iov_size);
+                       if (nbytes < 0) {
                                flog_err(EC_LIB_SOCKET,
                                         "%s: writev to fd %d failed: %s",
                                         __func__, fd, safe_strerror(errno));
@@ -370,7 +371,8 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width,
                }
        }
 #else  /* IOV_MAX */
-       if ((nbytes = writev(fd, iov, iov_index)) < 0)
+       nbytes = writev(fd, iov, iov_index);
+       if (nbytes < 0)
                flog_err(EC_LIB_SOCKET, "%s: writev to fd %d failed: %s",
                         __func__, fd, safe_strerror(errno));
 #endif /* IOV_MAX */
@@ -472,13 +474,17 @@ buffer_status_t buffer_write(struct buffer *b, int fd, const void *p,
                /* Buffer is not empty, so do not attempt to write the new data.
                 */
                nbytes = 0;
-       else if ((nbytes = write(fd, p, size)) < 0) {
-               if (ERRNO_IO_RETRY(errno))
-                       nbytes = 0;
-               else {
-                       flog_err(EC_LIB_SOCKET, "%s: write error on fd %d: %s",
-                                __func__, fd, safe_strerror(errno));
-                       return BUFFER_ERROR;
+       else {
+               nbytes = write(fd, p, size);
+               if (nbytes < 0) {
+                       if (ERRNO_IO_RETRY(errno))
+                               nbytes = 0;
+                       else {
+                               flog_err(EC_LIB_SOCKET,
+                                        "%s: write error on fd %d: %s",
+                                        __func__, fd, safe_strerror(errno));
+                               return BUFFER_ERROR;
+                       }
                }
        }
        /* Add any remaining data to the buffer. */
index e00d84a051dd524d4ebfa8696971d10fa3f4113a..9dac60599c27ad0c18609d1120ea0919422f4dbc 100644 (file)
@@ -255,6 +255,9 @@ static bool cmd_hash_cmp(const void *a, const void *b)
 /* Install top node of command vector. */
 void install_node(struct cmd_node *node)
 {
+#define CMD_HASH_STR_SIZE 256
+       char hash_name[CMD_HASH_STR_SIZE];
+
        vector_set_index(cmdvec, node->node, node);
        node->cmdgraph = graph_new();
        node->cmd_vector = vector_init(VECTOR_MIN_SIZE);
@@ -263,8 +266,10 @@ void install_node(struct cmd_node *node)
                cmd_token_new(START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
        graph_new_node(node->cmdgraph, token,
                       (void (*)(void *)) & cmd_token_del);
-       node->cmd_hash = hash_create_size(16, cmd_hash_key, cmd_hash_cmp,
-                                         "Command Hash");
+
+       snprintf(hash_name, sizeof(hash_name), "Command Hash: %s", node->name);
+       node->cmd_hash =
+               hash_create_size(16, cmd_hash_key, cmd_hash_cmp, hash_name);
 }
 
 /* Return prompt character of specified node. */
@@ -2423,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);
        }
 
index e9e8466ffde51a43d549ef00e07e174d79475a2f..57035101484127315814e05777ae83744e546d60 100644 (file)
@@ -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;
index 970ed297fc7142a7616ca759bacd020eb0a9d1e3..bf443906ebbaa628b11b720fbed317d449589374 100644 (file)
@@ -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")
index b48b79792e6ed7f728831ee14e6434f9684c3850..05b9dbe39ee283b736ea050db9da3594cfe0caaa 100644 (file)
--- a/lib/csv.c
+++ b/lib/csv.c
@@ -641,7 +641,8 @@ static int get_memory_usage(pid_t pid)
        char *vm;
 
        snprintf(status_child, sizeof(status_child), "/proc/%d/status", pid);
-       if ((fd = open(status_child, O_RDONLY)) < 0)
+       fd = open(status_child, O_RDONLY);
+       if (fd < 0)
                return -1;
 
        read(fd, buf, 4095);
index b7a935d0768dbbd576b77f6343e1ec796aace32b..72a66d85ad7d073a323326fcbd35b7fc13cd8ad4 100644 (file)
@@ -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;
index d8aaa3aa3c6d9abeefff0ad3f966029232e6813d..e97e48121c8aba1be0e7f944da18425b4b1e69d5 100644 (file)
@@ -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));
@@ -257,6 +302,13 @@ void *lua_tostringp(lua_State *L, int idx)
        return string;
 }
 
+/*
+ * Decoder for const values, since we cannot modify them.
+ */
+void lua_decode_noop(lua_State *L, int idx, const void *ptr)
+{
+}
+
 /*
  * Logging.
  *
index 6fb30938b061d5bedd4cc5328cd90f850bb68f72..c4de82740c3c709bc321ef37c64c76e618cd4149 100644 (file)
@@ -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.
  *
@@ -145,6 +161,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.
  *
index 10d400886d835de6e55b5d8459d76b5c1e1527d1..1a9f3639dd66ed7d2be326fa7772bdb62b369f81 100644 (file)
@@ -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);
 
index f4057f531bd4b6b73d57afac34bb886cfc59d817..8612c602f3ca317a2115186b54720f48bfec487d 100644 (file)
@@ -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.
index e8a6b89f8910a794e5e7436c93ccf1f68d205dc5..062384aac7ab388b8d22d15584a4fd86e6eeffde 100644 (file)
@@ -538,8 +538,6 @@ struct ls_edge *ls_edge_add(struct ls_ted *ted,
 
        /* Create Edge and add it to the TED */
        new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_edge));
-       if (!new)
-               return NULL;
 
        new->attributes = attributes;
        new->key = key;
@@ -804,8 +802,6 @@ struct ls_ted *ls_ted_new(const uint32_t key, const char *name,
        struct ls_ted *new;
 
        new = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_ted));
-       if (new == NULL)
-               return new;
 
        /* Set basic information for this ted */
        new->key = key;
@@ -1005,8 +1001,6 @@ static struct ls_node *ls_parse_node(struct stream *s)
        size_t len;
 
        node = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_node));
-       if (node == NULL)
-               return NULL;
 
        STREAM_GET(&node->adv, s, sizeof(struct ls_node_id));
        STREAM_GETW(s, node->flags);
@@ -1051,8 +1045,6 @@ static struct ls_attributes *ls_parse_attributes(struct stream *s)
        size_t len;
 
        attr = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_attributes));
-       if (attr == NULL)
-               return NULL;
        attr->srlgs = NULL;
 
        STREAM_GET(&attr->adv, s, sizeof(struct ls_node_id));
@@ -1157,8 +1149,6 @@ static struct ls_prefix *ls_parse_prefix(struct stream *s)
        size_t len;
 
        ls_pref = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_prefix));
-       if (ls_pref == NULL)
-               return NULL;
 
        STREAM_GET(&ls_pref->adv, s, sizeof(struct ls_node_id));
        STREAM_GETW(s, ls_pref->flags);
@@ -1193,8 +1183,6 @@ struct ls_message *ls_parse_msg(struct stream *s)
        struct ls_message *msg;
 
        msg = XCALLOC(MTYPE_LS_DB, sizeof(struct ls_message));
-       if (msg == NULL)
-               return NULL;
 
        /* Read LS Message header */
        STREAM_GETC(s, msg->event);
index 411661a5e1bca1764803289f0edad2f373794acf..b60ad9a57c3800f97bae4cdde4708c133bd15e29 100644 (file)
@@ -78,7 +78,8 @@ int set_nonblocking(int fd)
        /* According to the Single UNIX Spec, the return value for F_GETFL
           should
           never be negative. */
-       if ((flags = fcntl(fd, F_GETFL)) < 0) {
+       flags = fcntl(fd, F_GETFL);
+       if (flags < 0) {
                flog_err(EC_LIB_SYSTEM_CALL,
                         "fcntl(F_GETFL) failed for fd %d: %s", fd,
                         safe_strerror(errno));
index ccbf8793d38e2ce3fd3b208f87b6eacaebbea3bf..1b2dd7a6d12da7be9afbc9e79cb494ea3ab1cdee 100644 (file)
@@ -40,14 +40,18 @@ static inline void putbyte(uint8_t bytex, char **posx)
        bool zero = false;
        int byte = bytex, tmp, a, b;
 
-       if ((tmp = byte - 200) >= 0) {
+       tmp = byte - 200;
+       if (tmp >= 0) {
                *pos++ = '2';
                zero = true;
                byte = tmp;
-       } else if ((tmp = byte - 100) >= 0) {
-               *pos++ = '1';
-               zero = true;
-               byte = tmp;
+       } else {
+               tmp = byte - 100;
+               if (tmp >= 0) {
+                       *pos++ = '1';
+                       zero = true;
+                       byte = tmp;
+               }
        }
 
        /* make sure the compiler knows the value range of "byte" */
index 7dbb5f07f0fd53af930d3fb0eb3bbc3a33c6adee..ef7d2e59daaded2799853c70c510a36ab50576d4 100644 (file)
@@ -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;
@@ -1034,7 +1034,8 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
                l = strlen(buf);
                buf[l++] = '/';
                byte = p->prefixlen;
-               if ((tmp = p->prefixlen - 100) >= 0) {
+               tmp = p->prefixlen - 100;
+               if (tmp >= 0) {
                        buf[l++] = '1';
                        z = true;
                        byte = tmp;
@@ -1128,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)) {
@@ -1148,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
index 217a23d561c061951370991fc8871d4d93be1fa5..bc4cb7f441c2007c746d86c3d90ecb9ab30c12bd 100644 (file)
@@ -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 *);
 
index 4d76ae153666c6a6b91881ca2c697dbe7380a03e..4a40ec08b9ffdd639c51279070b87b2f8ad531ee 100644 (file)
@@ -194,6 +194,11 @@ struct route_map_index {
 };
 DECLARE_QOBJ_TYPE(route_map_index);
 
+/* route map maximum length. Not strictly the maximum xpath length but cannot be
+ * greater
+ */
+#define RMAP_NAME_MAXLEN XPATH_MAXLEN
+
 /* Route map list structure. */
 struct route_map {
        /* Name of route map. */
index 98bfda507964931393d5b30e410892bd16672e93..150736e00c9393eb3ce12d9dbf05059d90f84074 100644 (file)
@@ -379,14 +379,14 @@ static int setsockopt_ipv4_ifindex(int sock, ifindex_t val)
        int ret;
 
 #if defined(IP_PKTINFO)
-       if ((ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val)))
-           < 0)
+       ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
+       if (ret < 0)
                flog_err(EC_LIB_SOCKET,
                         "Can't set IP_PKTINFO option for fd %d to %d: %s",
                         sock, val, safe_strerror(errno));
 #elif defined(IP_RECVIF)
-       if ((ret = setsockopt(sock, IPPROTO_IP, IP_RECVIF, &val, sizeof(val)))
-           < 0)
+       ret = setsockopt(sock, IPPROTO_IP, IP_RECVIF, &val, sizeof(val));
+       if (ret < 0)
                flog_err(EC_LIB_SOCKET,
                         "Can't set IP_RECVIF option for fd %d to %d: %s", sock,
                         val, safe_strerror(errno));
@@ -639,12 +639,8 @@ int sockopt_tcp_signature_ext(int sock, union sockunion *su, uint16_t prefixlen,
 
 #endif /* GNU_LINUX */
 
-       if ((ret = setsockopt(sock, IPPROTO_TCP, optname, &md5sig,
-                             sizeof(md5sig)))
-           < 0) {
-               /* ENOENT is harmless.  It is returned when we clear a password
-                  for which
-                  one was not previously set. */
+       ret = setsockopt(sock, IPPROTO_TCP, optname, &md5sig, sizeof(md5sig));
+       if (ret < 0) {
                if (ENOENT == errno)
                        ret = 0;
                else
index e6340a1743dc00d0ed232aa6f1ba91f3433cc71f..c7af458e9eaac739a43c21bd94524b0287cdb542 100644 (file)
@@ -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;
index 2cc80bb70f48f8999908cb70800908f541b71667..9e6719ccf9562c0ae1316416fb26a5661487811e 100644 (file)
@@ -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 *);
index 904ee73b10ce2da231791cfbda1786960d45db1a..1557500c607171c955f26e234bf2acd1e2a183eb 100644 (file)
@@ -1097,7 +1097,8 @@ ssize_t stream_read_try(struct stream *s, int fd, size_t size)
                return -1;
        }
 
-       if ((nbytes = read(fd, s->data + s->endp, size)) >= 0) {
+       nbytes = read(fd, s->data + s->endp, size);
+       if (nbytes >= 0) {
                s->endp += nbytes;
                return nbytes;
        }
@@ -1126,9 +1127,8 @@ ssize_t stream_recvfrom(struct stream *s, int fd, size_t size, int flags,
                return -1;
        }
 
-       if ((nbytes = recvfrom(fd, s->data + s->endp, size, flags, from,
-                              fromlen))
-           >= 0) {
+       nbytes = recvfrom(fd, s->data + s->endp, size, flags, from, fromlen);
+       if (nbytes >= 0) {
                s->endp += nbytes;
                return nbytes;
        }
index dfd92c6189f58c47ba2ebc1a22ac7b775978642f..e6030ca4cab732ff3e4c0074b99629607883d5f1 100644 (file)
@@ -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);
index 4a70881b579ad58f3982d0fad0fb65ec80d1432e..dc832276590d599cc65cc31a3e6bd91cdfa7a5c5 100644 (file)
@@ -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:
@@ -3798,7 +3812,8 @@ static int zclient_read(struct thread *thread)
        zclient->t_read = NULL;
 
        /* Read zebra header (if we don't have it already). */
-       if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
+       already = stream_get_endp(zclient->ibuf);
+       if (already < ZEBRA_HEADER_SIZE) {
                ssize_t nbyte;
                if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
                                              ZEBRA_HEADER_SIZE - already))
@@ -3811,7 +3826,6 @@ static int zclient_read(struct thread *thread)
                        return zclient_failed(zclient);
                }
                if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
-                       /* Try again later. */
                        zclient_event(ZCLIENT_READ, zclient);
                        return 0;
                }
index 48de3425be24808eaae30ebf3948c381517feee9..a25c5800b720fe1742319b86d3859317232e9cc0 100644 (file)
@@ -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
index ba355a347e3b1922bbef3029af72ac8f974ff352..d4e52f0ede8c4f32d10b46f782b08237e64c3439 100644 (file)
@@ -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));
 
-               ospf6_zebra_no_redistribute(arg_type, ospf6->vrf_id);
-               ospf6_zebra_redistribute(arg_type, ospf6->vrf_id);
+               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);
+               }
+
+               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);
@@ -2478,7 +2479,7 @@ void ospf6_asbr_init(void)
        install_element(OSPF6_NODE, &no_ospf6_redistribute_cmd);
 }
 
-void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6)
+void ospf6_asbr_redistribute_disable(struct ospf6 *ospf6)
 {
        int type;
        struct ospf6_redist *red;
@@ -2500,6 +2501,35 @@ void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6)
        }
 }
 
+void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6)
+{
+       int type;
+       struct ospf6_redist *red;
+       char buf[RMAP_NAME_MAXLEN];
+
+       for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+               buf[0] = '\0';
+               if (type == ZEBRA_ROUTE_OSPF6)
+                       continue;
+               red = ospf6_redist_lookup(ospf6, type, 0);
+               if (!red)
+                       continue;
+
+               if (type == DEFAULT_ROUTE) {
+                       ospf6_redistribute_default_set(
+                               ospf6, ospf6->default_originate);
+                       continue;
+               }
+               if (ROUTEMAP_NAME(red))
+                       strlcpy(buf, ROUTEMAP_NAME(red), sizeof(buf));
+
+               ospf6_asbr_redistribute_unset(ospf6, red, type);
+               if (buf[0])
+                       ospf6_asbr_routemap_set(red, buf);
+               ospf6_asbr_redistribute_set(ospf6, type);
+       }
+}
+
 void ospf6_asbr_terminate(void)
 {
        /* Cleanup route maps */
index 418c157f368912f1fa878a1864c1dfc334c8d5e7..7ccd1c992b3aaba0e6b03c703bd8ea999c561970 100644 (file)
@@ -93,6 +93,7 @@ extern int ospf6_redistribute_config_write(struct vty *vty,
                                           struct ospf6 *ospf6);
 
 extern void ospf6_asbr_init(void);
+extern void ospf6_asbr_redistribute_disable(struct ospf6 *ospf6);
 extern void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6);
 extern void ospf6_asbr_terminate(void);
 extern void ospf6_asbr_send_externals_to_area(struct ospf6_area *);
@@ -104,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);
index 553967e2e3364c5fd0a5b30b4b440621ae4ecea7..1e75fc60f68b7473af033e64a3c8fe5317400543 100644 (file)
@@ -2695,7 +2695,7 @@ void ospf6_interface_init(void)
 }
 
 /* Clear the specified interface structure */
-static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
+void ospf6_interface_clear(struct interface *ifp)
 {
        struct ospf6_interface *oi;
 
@@ -2733,7 +2733,7 @@ DEFUN (clear_ipv6_ospf6_interface,
        if (argc == 4) /* Clear all the ospfv3 interfaces. */
        {
                FOR_ALL_INTERFACES (vrf, ifp)
-                       ospf6_interface_clear(vty, ifp);
+                       ospf6_interface_clear(ifp);
        } else /* Interface name is specified. */
        {
                if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
@@ -2743,7 +2743,7 @@ DEFUN (clear_ipv6_ospf6_interface,
                                argv[idx_ifname]->arg);
                        return CMD_WARNING;
                }
-               ospf6_interface_clear(vty, ifp);
+               ospf6_interface_clear(ifp);
        }
 
        return CMD_SUCCESS;
index 530efc3bd24edcd6c9eeaa70c328e57b425fe37b..c9cd74b6919a95b1e60c5a6f7c08599ed139546b 100644 (file)
@@ -213,6 +213,7 @@ extern int backup_seen(struct thread *);
 extern int neighbor_change(struct thread *);
 
 extern void ospf6_interface_init(void);
+extern void ospf6_interface_clear(struct interface *ifp);
 
 extern void install_element_ospf6_clear_interface(void);
 
index d62719425289a05f9fdde8d8243f4b896de21003..bab5fdaae8fefc41b31672af9488f7ce590870a9 100644 (file)
@@ -659,7 +659,7 @@ void ospf6_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
                                       adv_router);
                json_object_int_add(json_obj, "lsSequenceNumber",
                                    (unsigned long)ntohl(lsa->header->seqnum));
-               json_object_int_add(json_obj, "checkSum",
+               json_object_int_add(json_obj, "checksum",
                                    ntohs(lsa->header->checksum));
                json_object_int_add(json_obj, "length",
                                    ntohs(lsa->header->length));
index 5f23aab80af7ecbdec80664dc1d9db0f584be2eb..817e5372ead14c1850f654d16cecb2babff2b4ac 100644 (file)
@@ -1709,6 +1709,13 @@ static int ospf6_read_helper(int sockfd, struct ospf6 *ospf6)
                return OSPF6_READ_CONTINUE;
        }
 
+       /*
+        * Drop packet destined to another VRF.
+        * This happens when raw_l3mdev_accept is set to 1.
+        */
+       if (ospf6->vrf_id != oi->interface->vrf_id)
+               return OSPF6_READ_CONTINUE;
+
        oh = (struct ospf6_header *)recvbuf;
        if (ospf6_rxpacket_examin(oi, oh, len) != MSG_OK)
                return OSPF6_READ_CONTINUE;
index 6cea5032bdce2b9d726b66ded12cebbcad000455..6f40989efddc9ffcb025d4d0dab91ba1f0700e41 100644 (file)
@@ -63,6 +63,10 @@ FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
        { .val_bool = false },
 );
 
+#ifndef VTYSH_EXTRACT_PL
+#include "ospf6d/ospf6_top_clippy.c"
+#endif
+
 /* global ospf6d variable */
 static struct ospf6_master ospf6_master;
 struct ospf6_master *om6;
@@ -512,7 +516,7 @@ static void ospf6_disable(struct ospf6 *o)
 
                /* XXX: This also changes persistent settings */
                /* Unregister redistribution */
-               ospf6_asbr_redistribute_reset(o);
+               ospf6_asbr_redistribute_disable(o);
 
                ospf6_lsdb_remove_all(o->lsdb);
                ospf6_route_remove_all(o->route_table);
@@ -598,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 */
@@ -649,6 +653,78 @@ DEFUN(no_router_ospf6, no_router_ospf6_cmd, "no router ospf6 [vrf NAME]",
        return CMD_SUCCESS;
 }
 
+static void ospf6_db_clear(struct ospf6 *ospf6)
+{
+       struct ospf6_interface *oi;
+       struct interface *ifp;
+       struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
+       struct listnode *node, *nnode;
+       struct ospf6_area *oa;
+
+       FOR_ALL_INTERFACES (vrf, ifp) {
+               if (if_is_operative(ifp) && ifp->info != NULL) {
+                       oi = (struct ospf6_interface *)ifp->info;
+                       ospf6_lsdb_remove_all(oi->lsdb);
+                       ospf6_lsdb_remove_all(oi->lsdb_self);
+                       ospf6_lsdb_remove_all(oi->lsupdate_list);
+                       ospf6_lsdb_remove_all(oi->lsack_list);
+               }
+       }
+
+       for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
+               ospf6_lsdb_remove_all(oa->lsdb);
+               ospf6_lsdb_remove_all(oa->lsdb_self);
+
+               ospf6_spf_table_finish(oa->spf_table);
+               ospf6_route_remove_all(oa->route_table);
+       }
+
+       ospf6_lsdb_remove_all(ospf6->lsdb);
+       ospf6_lsdb_remove_all(ospf6->lsdb_self);
+       ospf6_route_remove_all(ospf6->route_table);
+       ospf6_route_remove_all(ospf6->brouter_table);
+}
+
+static void ospf6_process_reset(struct ospf6 *ospf6)
+{
+       struct interface *ifp;
+       struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
+
+       ospf6_flush_self_originated_lsas_now(ospf6);
+       ospf6->inst_shutdown = 0;
+       ospf6_db_clear(ospf6);
+
+       ospf6_router_id_update(ospf6);
+
+       ospf6_asbr_redistribute_reset(ospf6);
+       FOR_ALL_INTERFACES (vrf, ifp)
+               ospf6_interface_clear(ifp);
+}
+
+DEFPY (clear_router_ospf6,
+       clear_router_ospf6_cmd,
+       "clear ipv6 ospf6 process [vrf NAME$name]",
+       CLEAR_STR
+       IP6_STR
+       OSPF6_STR
+       "Reset OSPF Process\n"
+       VRF_CMD_HELP_STR)
+{
+       struct ospf6 *ospf6;
+       const char *vrf_name = VRF_DEFAULT_NAME;
+
+       if (name != NULL)
+               vrf_name = name;
+
+       ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
+       if (ospf6 == NULL)
+               vty_out(vty, "OSPFv3 is not configured\n");
+       else
+               ospf6_process_reset(ospf6);
+
+       return CMD_SUCCESS;
+}
+
 /* change Router_ID commands. */
 DEFUN(ospf6_router_id,
       ospf6_router_id_cmd,
@@ -679,7 +755,7 @@ DEFUN(ospf6_router_id,
        for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) {
                if (oa->full_nbrs) {
                        vty_out(vty,
-                               "For this router-id change to take effect, save config and restart ospf6d\n");
+                               "For this router-id change to take effect, run the \"clear ipv6 ospf6 process\" command\n");
                        return CMD_SUCCESS;
                }
        }
@@ -705,13 +781,13 @@ DEFUN(no_ospf6_router_id,
        for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) {
                if (oa->full_nbrs) {
                        vty_out(vty,
-                               "For this router-id change to take effect, save config and restart ospf6d\n");
+                               "For this router-id change to take effect, run the \"clear ipv6 ospf6 process\" command\n");
                        return CMD_SUCCESS;
                }
        }
        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;
 }
@@ -1708,6 +1784,11 @@ static struct cmd_node ospf6_node = {
        .config_write = config_write_ospf6,
 };
 
+void install_element_ospf6_clear_process(void)
+{
+       install_element(ENABLE_NODE, &clear_router_ospf6_cmd);
+}
+
 /* Install ospf related commands. */
 void ospf6_top_init(void)
 {
index 5b739ac76b098bd0b8b9668a9eed2751775daaeb..3eb423f68155816e6f80cc3f8e73bdd5748f9553 100644 (file)
@@ -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;
@@ -173,6 +175,7 @@ extern struct ospf6_master *om6;
 
 /* prototypes */
 extern void ospf6_master_init(struct thread_master *master);
+extern void install_element_ospf6_clear_process(void);
 extern void ospf6_top_init(void);
 extern void ospf6_delete(struct ospf6 *o);
 extern void ospf6_router_id_update(struct ospf6 *ospf6);
index 170d545c49cdd0c909bbb27f14cb1af5fc711b28..a7e15c68ae81f35b6fba3a446de1acdd38804d2a 100644 (file)
@@ -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);
 
index 65f0aa664e786dd215fa35c365f2afd3edae052d..fb6ac4402a9bb11487c4ef7d7514b3080705568a 100644 (file)
@@ -1425,6 +1425,7 @@ void ospf6_init(struct thread_master *master)
        install_element_ospf6_debug_flood();
        install_element_ospf6_debug_nssa();
 
+       install_element_ospf6_clear_process();
        install_element_ospf6_clear_interface();
 
        install_element(ENABLE_NODE, &show_debugging_ospf6_cmd);
index 2e1891be7189daa8955c3d588f746afeb160882e..2b7bce53924a100059c94c58f44cd1bd43833c73 100644 (file)
@@ -88,6 +88,7 @@ ospf6d_ospf6d_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
 ospf6d_ospf6d_snmp_la_LIBADD = lib/libfrrsnmp.la
 
 clippy_scan += \
+       ospf6d/ospf6_top.c \
        ospf6d/ospf6_asbr.c \
        # end
 
index 2fd195bb6d10461092720cc53f9a74b8dd894c04..192dbe4fc8c0d8bffef6280fc148359a1088c946 100644 (file)
@@ -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;
index b4e318d1d1d1bef3efcf30a158d0243a3f65e310..029f929c110d784cdaab4731c58ff91b47600a44 100644 (file)
@@ -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;
 }
 
index 333fa6a3a18d75bb041b7d4ada5a70b7b826b0ff..d95e677f6f2bdb20d5d18930a0431dec3c95f128 100644 (file)
@@ -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);
 
index 59b3b624e3903f016130172c440aec9b2c394a62..347128a4f428b0275161e89d3d1fdbaf81df0ddf 100644 (file)
@@ -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);
index 54ce248d89efe5225ffc0ffb9ac7b37bcec52922..db8e961b8b8b4436d38b1c3b4abf0bcbd1c357fc 100644 (file)
@@ -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
index 5853b506f81959467103f37e85c97917f85222c8..017915e0ee3bbb57556388303d147fa94cb96e31 100644 (file)
@@ -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 */
index eb41bf604365975965c218b1ee2344810599549b..fc5303c9d81ee01bb7f9b62ff752f3ddc9065e06 100644 (file)
@@ -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
index ad5257630bb130246258125a496596b6aad13e1a..0181e885fd6df721abc7ea1ae89662fe76138a1b 100644 (file)
@@ -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++;
index b3d44446521bf8384a51ef15bd8852e2072a4677..cc11a3cc172b01d5345cdfa80544625a538ab023 100644 (file)
@@ -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);
index 353f1330015f570244db5c4613cd8c158ab9da61..48b019c8c8877a85c13f61292a01e338f10ce7af 100644 (file)
@@ -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)) {
index 1bf3a619bf69c710c53e33a1aecb8facafe624df..9ee06edfc191cb80d7024e0a6c4276014a4ca10b 100644 (file)
@@ -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)
index 3ae7744eb0adb37e3ad75ebc8dcc5eedb5e3e4a4..afa2db5f151d2aee63ba7324efe6787a78c58e3a 100644 (file)
@@ -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);
index 47358f38e1f17b7acdae70e5f7532ed5a6861d43..6dda66b79a689efd3791db3ce1cc6cd1ce71a766 100644 (file)
@@ -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;
 }
 
index 095c6de549a120c4dbd77eabab3860f3a91c6a98..2a8f0c121640f47837b2e2ad812709ef7689dd5b 100644 (file)
@@ -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",
index bb7ee01ad819a1a0fb0d33c3f3f8833fee3b2e4f..a074f21b47a64277e28084a5686f3398047c72da 100644 (file)
@@ -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
index 4aaf0f53d178905c754c47d7f47f90a677155075..eb5f46951e8f5e63dd314a80846cd3b5438f46b7 100644 (file)
@@ -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);
        }
 }
 
index ea53f1ef1212c874e55ef6b41bc8862536843150..6fe078bd8e604c136789804c55b9f86211b5c15f 100644 (file)
@@ -117,6 +117,24 @@ const struct frr_yang_module_info frr_pim_info = {
                                .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy,
                        }
                },
+               {
+                       .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 = {
@@ -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,
                        }
                },
                {
index 1959b403ff6545b624d602c7cbdbb3d9b61855e2..f5ebbceb33dd509536ec0091642f2ec820a21543 100644 (file)
@@ -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_ */
index b70656ea7b81f8d2d394e5cec09f94592e531af0..dfdbd6dee204e1fea5108d154a74d5673cdd5162 100644 (file)
@@ -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,
@@ -1004,6 +945,95 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
        return NB_OK;
 }
 
+/*
+ * 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
@@ -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;
        }
 
index 90b69a54f2cd18da27b7bed221a3e8ec3e658a8a..9d5b864ab0e1415c003b0cac48f08acb9cc97cf2 100644 (file)
@@ -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) {
index a31fec036fc6a1ef7d36ca586c3193773cfc4b10..b6521132f70fe0fca585ecf64cef22b1df36b34d 100644 (file)
@@ -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);
index f21c369b8d84f20fe5516ee99d154a33a4aef507..8e6ff2f3a7ce87cdc6fc22e8cb7fa71d7c5cce4a 100644 (file)
@@ -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;
index 918a9a9c7d7630e6f8840b22da3c279cbcf03000..2b674b4234d7548d8181c9d6d1adf1a2d0145ff5 100644 (file)
@@ -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)
index 15bde256daf77ee3888507ad6442c7aa44e6c46d..decc491edec766fd522d2b7abe07c44c336ca3ed 100644 (file)
@@ -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);
index c049ef4029e8213a742a4f0a8902f32ffa897d5f..95882cf58f96e464b4dca7cb2296d84dbae5418c 100644 (file)
@@ -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;
 }
 
index 9ccf1fedd421171d2c44e31deccc61bceaf0c40b..dce936b8a99ba9d4cf9ba1b54c5d4ea6f800d4d5 100644 (file)
@@ -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));
index bdae2c5ef5fa9d717338817c26eab3a6a52be598..7a8e10f30b35c1a817ac245dd88f6ca53b3b6a19 100644 (file)
@@ -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(
index 7d940efd9c615ea19c355f44b1966913c0885231..ccd4bf1bacec389af6aaa5e6766389c8fabcd09a 100644 (file)
@@ -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(
index a0ea18f3e9b801195b869bb3bc0ba4b83ad96d93..cbd2c22893adc4cbcd40ae04a302c97c83a34c79 100644 (file)
@@ -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);
index 250151b1fa44316daaa5c890423e39213c6756f3..b6581cd9e6185691a04592b30bd436bdd2e327bc 100644 (file)
@@ -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;
index feb6e0f9935d7260f8892b70ad60d5095ae66cfa..d42c5c2777fa76006e1eeb836a252c145dd300c9 100644 (file)
@@ -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)
index fb2edc939af59ac2bb25c87f2070d1960c62a279..3fad1b081320e3f96e87394a7d87a4783496c6b3 100644 (file)
@@ -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
index 44b55a23813dae9f0eb345f7376f07efdb20aa47..45e9912a31d48641badacbdf3b66edb0d26d48f0 100644 (file)
@@ -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 (file)
index 0000000..e9ebc29
--- /dev/null
@@ -0,0 +1 @@
+a = a + b
diff --git a/tests/lib/test_frrlua.c b/tests/lib/test_frrlua.c
new file mode 100644 (file)
index 0000000..a81446f
--- /dev/null
@@ -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 (file)
index 0000000..2f6ddc1
--- /dev/null
@@ -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 (file)
index 0000000..bd75cc5
--- /dev/null
@@ -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 (file)
index 0000000..046d97b
--- /dev/null
@@ -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()
index ca477851e393199b82fc163b0cf12a303efa0143..c2153140f5403e2c3db29518599de7f0066ba64c 100644 (file)
@@ -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_afi_safi/__init__.py b/tests/topotests/bgp_default_afi_safi/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_default_afi_safi/r1/bgpd.conf b/tests/topotests/bgp_default_afi_safi/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..bf39152
--- /dev/null
@@ -0,0 +1,3 @@
+!
+router bgp 65001
+!
diff --git a/tests/topotests/bgp_default_afi_safi/r1/zebra.conf b/tests/topotests/bgp_default_afi_safi/r1/zebra.conf
new file mode 100644 (file)
index 0000000..6977651
--- /dev/null
@@ -0,0 +1,7 @@
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
+
diff --git a/tests/topotests/bgp_default_afi_safi/r2/bgpd.conf b/tests/topotests/bgp_default_afi_safi/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..abbd1b8
--- /dev/null
@@ -0,0 +1,5 @@
+!
+router bgp 65001
+ no bgp default ipv4-unicast
+ bgp default ipv6-unicast
+!
diff --git a/tests/topotests/bgp_default_afi_safi/r2/zebra.conf b/tests/topotests/bgp_default_afi_safi/r2/zebra.conf
new file mode 100644 (file)
index 0000000..606c17b
--- /dev/null
@@ -0,0 +1,6 @@
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
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 (file)
index 0000000..f3ec3f0
--- /dev/null
@@ -0,0 +1,5 @@
+!
+router bgp 65001
+ no bgp default ipv4-unicast
+ bgp default l2vpn-evpn
+!
diff --git a/tests/topotests/bgp_default_afi_safi/r3/zebra.conf b/tests/topotests/bgp_default_afi_safi/r3/zebra.conf
new file mode 100644 (file)
index 0000000..e9fdfb7
--- /dev/null
@@ -0,0 +1,6 @@
+!
+interface r3-eth0
+ ip address 192.168.255.3/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default_afi_safi/r4/bgpd.conf b/tests/topotests/bgp_default_afi_safi/r4/bgpd.conf
new file mode 100644 (file)
index 0000000..8a6af55
--- /dev/null
@@ -0,0 +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 (file)
index 0000000..e9fdfb7
--- /dev/null
@@ -0,0 +1,6 @@
+!
+interface r3-eth0
+ ip address 192.168.255.3/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py b/tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py
new file mode 100644 (file)
index 0000000..28117b7
--- /dev/null
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2021 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+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 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
+import sys
+import json
+import pytest
+import functools
+
+pytestmark = [pytest.mark.bgpd]
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+from lib.common_config import step
+
+
+class TemplateTopo(Topo):
+    def build(self, *_args, **_opts):
+        tgen = get_topogen(self)
+
+        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.add_link(tgen.gears["r3"])
+        switch.add_link(tgen.gears["r4"])
+
+
+def setup_module(mod):
+    tgen = Topogen(TemplateTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    for i, (rname, router) in enumerate(router_list.items(), 1):
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+        )
+
+    tgen.start_router()
+
+
+def teardown_module(mod):
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def test_bgp_default_ipv4_ipv6_unicast():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    step("Check if neighbor 192.168.255.254 is enabled for ipv4 address-family only")
+
+    def _bgp_neighbor_ipv4_af_only():
+        tgen.gears["r1"].vtysh_cmd(
+            "conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external"
+        )
+
+        output = json.loads(tgen.gears["r1"].vtysh_cmd("show bgp summary json"))
+
+        if len(output.keys()) == 1 and "ipv4Unicast" in output:
+            return True
+        return False
+
+    assert _bgp_neighbor_ipv4_af_only() == True
+
+    step("Check if neighbor 192.168.255.254 is enabled for ipv6 address-family only")
+
+    def _bgp_neighbor_ipv6_af_only():
+        tgen.gears["r2"].vtysh_cmd(
+            "conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external"
+        )
+
+        output = json.loads(tgen.gears["r2"].vtysh_cmd("show bgp summary json"))
+
+        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 evpn address-family only")
+
+    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 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_ipv6_and_evpn_af() == True
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/__init__.py b/tests/topotests/bgp_default_ipv4_ipv6_unicast/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/bgpd.conf b/tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/bgpd.conf
deleted file mode 100644 (file)
index bf39152..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-!
-router bgp 65001
-!
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/zebra.conf b/tests/topotests/bgp_default_ipv4_ipv6_unicast/r1/zebra.conf
deleted file mode 100644 (file)
index 6977651..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-!
-interface r1-eth0
- ip address 192.168.255.1/24
-!
-ip forwarding
-!
-
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/bgpd.conf b/tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/bgpd.conf
deleted file mode 100644 (file)
index abbd1b8..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-!
-router bgp 65001
- no bgp default ipv4-unicast
- bgp default ipv6-unicast
-!
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/zebra.conf b/tests/topotests/bgp_default_ipv4_ipv6_unicast/r2/zebra.conf
deleted file mode 100644 (file)
index 606c17b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-!
-interface r2-eth0
- ip address 192.168.255.2/24
-!
-ip forwarding
-!
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/bgpd.conf b/tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/bgpd.conf
deleted file mode 100644 (file)
index a405c04..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-!
-router bgp 65001
- bgp default ipv6-unicast
-!
diff --git a/tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/zebra.conf b/tests/topotests/bgp_default_ipv4_ipv6_unicast/r3/zebra.conf
deleted file mode 100644 (file)
index e9fdfb7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-!
-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_ipv4_ipv6_unicast/test_bgp-default-ipv4-ipv6-unicast.py
deleted file mode 100644 (file)
index f9aa94f..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/usr/bin/env python
-
-#
-# Copyright (c) 2021 by
-# Donatas Abraitis <donatas.abraitis@gmail.com>
-#
-# Permission to use, copy, modify, and/or distribute this software
-# for any purpose with or without fee is hereby granted, provided
-# that the above copyright notice and this permission notice appear
-# in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-#
-
-"""
-Test if `bgp default ipv4-unicast` and `bgp default ipv6-unicast`
-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'
-"""
-
-import os
-import sys
-import json
-import pytest
-import functools
-
-pytestmark = [pytest.mark.bgpd]
-
-CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(CWD, "../"))
-
-# pylint: disable=C0413
-from lib import topotest
-from lib.topogen import Topogen, TopoRouter, get_topogen
-from lib.topolog import logger
-from mininet.topo import Topo
-from lib.common_config import step
-
-
-class TemplateTopo(Topo):
-    def build(self, *_args, **_opts):
-        tgen = get_topogen(self)
-
-        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.add_link(tgen.gears["r3"])
-        switch.add_link(tgen.gears["r4"])
-
-
-def setup_module(mod):
-    tgen = Topogen(TemplateTopo, mod.__name__)
-    tgen.start_topology()
-
-    router_list = tgen.routers()
-
-    for i, (rname, router) in enumerate(router_list.items(), 1):
-        router.load_config(
-            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
-        )
-        router.load_config(
-            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
-        )
-
-    tgen.start_router()
-
-
-def teardown_module(mod):
-    tgen = get_topogen()
-    tgen.stop_topology()
-
-
-def test_bgp_default_ipv4_ipv6_unicast():
-    tgen = get_topogen()
-
-    if tgen.routers_have_failure():
-        pytest.skip(tgen.errors)
-
-    step("Check if neighbor 192.168.255.254 is enabled for ipv4 address-family only")
-
-    def _bgp_neighbor_ipv4_af_only():
-        tgen.gears["r1"].vtysh_cmd(
-            "conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external"
-        )
-
-        output = json.loads(tgen.gears["r1"].vtysh_cmd("show bgp summary json"))
-
-        if "ipv4Unicast" in output and "ipv6Unicast" not in output:
-            return True
-        return False
-
-    assert _bgp_neighbor_ipv4_af_only() == True
-
-    step("Check if neighbor 192.168.255.254 is enabled for ipv6 address-family only")
-
-    def _bgp_neighbor_ipv6_af_only():
-        tgen.gears["r2"].vtysh_cmd(
-            "conf t\nrouter bgp\nneighbor 192.168.255.254 remote-as external"
-        )
-
-        output = json.loads(tgen.gears["r2"].vtysh_cmd("show bgp summary json"))
-
-        if "ipv4Unicast" not in output 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"
-    )
-
-    def _bgp_neighbor_ipv4_and_ipv6_af():
-        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:
-            return True
-        return False
-
-    assert _bgp_neighbor_ipv4_and_ipv6_af() == True
-
-
-if __name__ == "__main__":
-    args = ["-s"] + sys.argv[1:]
-    sys.exit(pytest.main(args))
index db7b3586f13af630877d1d8dc8ae73bf26f96793..a236a916b58c31470520e4a1357f1974a625d18a 100644 (file)
@@ -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
 ):
index 3f78f020bccdb2892ab6c355968c3bfba5ef3a1a..d659b8d52df01ef1d1bba3abe28ae888a540d631 100644 (file)
@@ -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"
index 3f39b93d8cd7ae258fcf0b7e363d389ced206b00..dc9fe0fccaeb008e328e7d55cbb7a3e19b05f3e4 100644 (file)
@@ -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)
index ce90717fa4b5023311d47cf1bd989e0f2b81495e..7de1c7a2f9a5b8e1987672ebd00f05da979e9b93 100644 (file)
@@ -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
index 49341efa5797a7d6b452d0d5f4764ca8607f744d..30cecee9e1ecf55722a158fe55708ad8724fc7dc 100644 (file)
@@ -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
index 9005263ed7ef559096c90ddb22058124d3d9e52b..a51c6d58c759da09f896457eb86797a9842d20a3 100644 (file)
@@ -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
index 30e114856156e745e3fb24e146491a255f6ced28..663f78620e1334eb26dca55f3297c0b01328c336 100644 (file)
@@ -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
index 719ead091c652225389f47280bdc88c6b171adcb..222fb28ade355463508ce8a0f43fddf59dc50490 100644 (file)
@@ -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 (file)
index 0000000..e69de29
diff --git a/tests/topotests/msdp_topo1/r1/bgpd.conf b/tests/topotests/msdp_topo1/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..01d8ddb
--- /dev/null
@@ -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 (file)
index 0000000..fc28903
--- /dev/null
@@ -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 (file)
index 0000000..fb6eabc
--- /dev/null
@@ -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 (file)
index 0000000..987bef4
--- /dev/null
@@ -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 (file)
index 0000000..ffa80b1
--- /dev/null
@@ -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 (file)
index 0000000..527f7dd
--- /dev/null
@@ -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 (file)
index 0000000..02d685b
--- /dev/null
@@ -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 (file)
index 0000000..ab12f05
--- /dev/null
@@ -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 (file)
index 0000000..688e752
--- /dev/null
@@ -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 (file)
index 0000000..633e8db
--- /dev/null
@@ -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 (file)
index 0000000..b2e05cb
--- /dev/null
@@ -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 (file)
index 0000000..1db8132
--- /dev/null
@@ -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 (executable)
index 0000000..d85e160
--- /dev/null
@@ -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))
index 199746d5f6c130b4bd30557878649691b648f0a2..60bd6de35d9ff343667a9e14f9eeee39340a4e21 100644 (file)
@@ -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
index e55e30270d65aac5a62659d4a145e1b02afcd18a..b880e0e46283a23a21d9ab97dc1a8ad4ded357e8 100755 (executable)
@@ -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)
 
index 7bef57b62918c940fb5d893d568e50a30ef90f06..d73e8dc9e82020e505aa02701a285ef285eb15fd 100755 (executable)
@@ -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(
index 9c3be5893707ebfdfd9e701dd14d512a7bb56c6f..a7f2893eab260a21bbd44685138427aed7a5c469 100644 (file)
@@ -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
index 1aabc06db02781f15f53f75b073545bf9177bc65..49ecaac9f78c83535804d421b7ed0cb7750257a7 100644 (file)
@@ -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 (
index e6dc18a4345c11586695ceb105214d8e76b179e9..47c6c45e391cdc5c13854afde2a87c8d03e66e6d 100644 (file)
@@ -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 (
index 7864d0307a58680f9afa1bd3a92e49cdb7ab0127..0848f6c94afa28dba2f92d0d50f2d2b7568ad1cf 100644 (file)
@@ -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
index 9dfde325f6795cf4b4788178818f267da5f0e19a..f17346d5b1dd6a2484dfa857e8552c7489fcc9a8 100644 (file)
@@ -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, (
index bbb4370a9304e93f8400bf5669828299ae259d94..2c44ec2351063d15c55b6979e900e4dbb5ec84d1 100644 (file)
@@ -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
index ee0e01b4112c1e5e1e74a3b1d9c4a2817dd94e01..85b9e8b543032195a5e7ced67fc4bda3dce6f4ef 100644 (file)
@@ -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
index d21f468bf5f8ae8e3b37fdd177dfb006dbc15379..3c922c355ce881a7e7bef16a0cde82a41f80e8ba 100755 (executable)
@@ -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/coccinelle/xcalloc-xmalloc.cocci b/tools/coccinelle/xcalloc-xmalloc.cocci
new file mode 100644 (file)
index 0000000..2a091d4
--- /dev/null
@@ -0,0 +1,17 @@
+// No need checking against NULL for XMALLOC/XCALLOC.
+// If that happens, we have more problems with memory.
+
+@@
+type T;
+T *ptr;
+@@
+
+ptr =
+(
+XCALLOC(...)
+|
+XMALLOC(...)
+)
+...
+- if (ptr == NULL)
+- return ...;
index 38fdbd46df4b2070d285be7e1353b9e262742906..56b2872d1e72ebc8cdc028bee67d2b37b013c0f8 100755 (executable)
 #!/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 (executable)
index 4843fe8..0000000
+++ /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
index 507c6ce8821e09c4283b280897fa191c3a048de4..dd3f44867406e8a2f3a1608cd3b99a03d30f28ba 100644 (file)
@@ -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;
 
index 71f672554bb2c2cdfffe4e6a785f9320bfbc1de1..e56d482da2dda8d00872c0fe5e88bf72337f63c8 100644 (file)
@@ -113,4 +113,6 @@ extern struct vty *vty;
 
 extern int user_mode;
 
+extern bool vtysh_add_timestamp;
+
 #endif /* VTYSH_H */
index 6d80cf9d9693e57590d78f90255e7efb37049963..d22ec3113f010f4a159ef92bd6070febf47f5058 100644 (file)
@@ -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);
 }
 
index fe33bed7f65da19367acb0049410dd3af5b35dfa..20be81b901a0500a15312dfd5604140767d9070f 100644 (file)
@@ -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;
index 4c4819ac25ac54689d08495d07d404dd73103553..6329e45588990849249e144d74eafba4b7c1a156 100644 (file)
@@ -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.";
index d110ccf6dde002f7b43b41e55ed75ed92d5de922..e1dd0dbdff048ab4470988a42db5038c18a88ec2 100644 (file)
@@ -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));
index 7fd967dd8b7cdeb7e870aabcb936b6397cb7fc05..408c016494d2039c4e422e3b211fab987e10483c 100644 (file)
@@ -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;
index 03884a916820e2d200649029b93f453d772c86e3..252bf04782b294796b3db6b13ffc24dfc8e88aa6 100644 (file)
@@ -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);
 
index e36af51005b587f790e0cf6b2a2f2fb42f063eff..bded50149f14069d120a8e38ff83869270bf075b 100644 (file)
@@ -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();
index 957f38602ab67699de322151498add27ba43250d..b7ffb9ce8da558e80094e576e99f56bee9010922 100644 (file)
@@ -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 */
 
 /*
index 3b556c92b5f18e7c0e669e62f13a337eb09e76c0..689b9787ee0bb7684c32d58362cdf38e5f930592 100644 (file)
@@ -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;
 }
index 1e06b3e0e94432805a047c0257aca5d0cd6ebc8d..976beefab05fa0dc894c0f04cd78ba1a30a2affb 100644 (file)
@@ -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.*/;
index d7a1ccfb29ee16942e551000faaa2c4ebd2b56b3..7b71ee45a217e00028a33f607b1504d6e7e89897 100644 (file)
@@ -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);
index d5969ab9bb62b78029e78fd959d7ba3d3bb5a8c9..8f2aa2fb09e596bf7cba50db4894fef067dc43a7 100644 (file)
@@ -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)
index a5d672987d3382177ed3c504f95aa629257f9e3d..04411fa0d208b1c77781cda0d8eda5a6734e6e36 100644 (file)
@@ -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);
index a4576b310e15c119f10fb4c8a0da257160f8a311..a2d1513ce4874530b71676f10bec90bcd5c001d6 100644 (file)
@@ -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);
index face0ef3bccfe7a79b4d24ca315251d3f854609c..af86263a16b3e82230d2f3fc68a49d09d7456ecc 100644 (file)
@@ -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",
index 73c2c3dda3a04bc3a5cbc05ba84f661699a6c78c..7bcd097371778c416bddb11c943d260761ce5f6a 100644 (file)
@@ -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;
index d0acf779368a3055e35bafa78433296cb011ba6a..12cc0b4e8a85663d57c67dc9df2010a978098acd 100644 (file)
@@ -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);
index 5a00f3155d75071d2484fef4675773b08ed9b771..d930f598663dba0d900a3879757898c1b71c00af 100644 (file)
@@ -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();
 
index 08c5fcaf8d982d787a40b182a376c19d2190f1f0..408f9cbee5c1d025cd188d59c7a202c7f0fe39ef 100644 (file)
@@ -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;
 
index a0c63e4202e5034226f78abeef1128ed7a0a74b7..2430b519892b476128b62dbb81c285e34dd0001e 100644 (file)
@@ -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
index 51f19a3c03f91b4b76130843ef2bda80a63d2841..b204b30ca7a4bd2f59f9b7aa5e0a20d80acbc199 100644 (file)
@@ -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);
        }
 }