]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #11981 from proelbtn/add-support-to-change-function-length
authorRuss White <russ@riw.us>
Wed, 12 Oct 2022 12:44:29 +0000 (08:44 -0400)
committerGitHub <noreply@github.com>
Wed, 12 Oct 2022 12:44:29 +0000 (08:44 -0400)
bgpd: Add support to change Segment Routing function length

138 files changed:
babeld/babel_zebra.c
bfdd/bfdd_vty.c
bgpd/IMPLEMENTATION.txt [deleted file]
bgpd/bgp_attr.c
bgpd/bgp_conditional_adv.c
bgpd/bgp_conditional_adv.h
bgpd/bgp_debug.c
bgpd/bgp_debug.h
bgpd/bgp_ecommunity.c
bgpd/bgp_evpn_mh.c
bgpd/bgp_evpn_vty.c
bgpd/bgp_fsm.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_network.c
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_open.c
bgpd/bgp_packet.c
bgpd/bgp_rd.c
bgpd/bgp_route.c
bgpd/bgp_rpki.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.conf.sample2 [deleted file]
bgpd/bgpd.h
bgpd/rfapi/bgp_rfapi_cfg.c
bgpd/rfapi/rfapi.c
bgpd/rfapi/rfapi_import.c
bgpd/rfapi/rfapi_rib.c
bgpd/rfapi/rfapi_vty.c
bgpd/rfapi/rfapi_vty.h
configure.ac
debian/changelog
doc/user/bgp.rst
doc/user/ospfd.rst
doc/user/overview.rst
doc/user/pimv6.rst
doc/user/setup.rst
doc/user/vtysh.rst
docker/alpine/Dockerfile
docker/alpine/build.sh
eigrpd/eigrp_dump.c
include/linux/rtnetlink.h
isisd/fabricd.c
isisd/isis_nb_config.c
isisd/isisd.c
isisd/isisd.h
ldpd/ldp_vty_cmds.c
lib/command.c
lib/command.h
lib/plist.c
lib/prefix.h
lib/routemap.c
lib/routemap.h
lib/sockopt.c
lib/sockopt.h
lib/typesafe.h
nhrpd/nhrp_vty.c
ospf6d/ospf6d.c
ospfd/ospf_dump.c
ospfd/ospf_vty.c
pathd/path_cli.c
pathd/path_ted.c
pbrd/pbr_vty.c
pimd/pim6_cmd.c
pimd/pim6_main.c
pimd/pim6_mld.c
pimd/pim_addr.h
pimd/pim_cmd.c
pimd/pim_cmd_common.c
pimd/pim_hello.c
pimd/pim_iface.c
pimd/pim_igmp.c
pimd/pim_igmp.h
pimd/pim_nb_config.c
pimd/pim_tlv.c
pimd/pim_tlv.h
pimd/pim_vty.c
pimd/pimd.h
redhat/frr.spec.in
ripd/rip_debug.c
ripngd/ripng_debug.c
sharpd/sharp_vty.c
staticd/static_vty.c
tests/lib/test_typelist.h
tests/topotests/bgp_basic_functionality_topo1/test_bgp_basic_functionality.py
tests/topotests/bgp_communities_topo1/test_bgp_communities.py
tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py
tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py
tests/topotests/bgp_ecmp_topo2/test_ebgp_ecmp_topo2.py
tests/topotests/bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py
tests/topotests/bgp_ecmp_topo3/test_ibgp_ecmp_topo3.py
tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py
tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py
tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py
tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py
tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py
tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py
tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py
tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py
tests/topotests/bgp_gr_functionality_topo3/bgp_gr_functionality_topo3.py
tests/topotests/bgp_gr_restart_retain_routes/__init__.py [new file with mode: 0644]
tests/topotests/bgp_gr_restart_retain_routes/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_gr_restart_retain_routes/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_gr_restart_retain_routes/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_gr_restart_retain_routes/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_restart_retain_routes.py [new file with mode: 0644]
tests/topotests/bgp_gshut_topo1/test_ebgp_gshut_topo1.py
tests/topotests/bgp_gshut_topo1/test_ibgp_gshut_topo1.py
tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py
tests/topotests/bgp_local_as/__init__.py [new file with mode: 0644]
tests/topotests/bgp_local_as/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_local_as/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_local_as/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_local_as/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_local_as/r3/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_local_as/r3/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_local_as/test_bgp_local_as.py [new file with mode: 0644]
tests/topotests/bgp_prefix_list_topo1/test_prefix_lists.py
tests/topotests/bgp_route_map/test_route_map_topo1.py
tests/topotests/bgp_route_map/test_route_map_topo2.py
tools/coccinelle/route_map_apply.cocci [new file with mode: 0644]
tools/frr-reload.py
tools/frr.service.in
tools/frr@.service.in
vrrpd/vrrp_vty.c
vtysh/vtysh_config.c
watchfrr/watchfrr_vty.c
zebra/debug.c
zebra/if_ioctl.c
zebra/if_netlink.c
zebra/if_sysctl.c
zebra/kernel_socket.c
zebra/rib.h
zebra/rtadv.c
zebra/zebra_fpm.c
zebra/zebra_rib.c

index d0da93e50747d0fd972c5dea2ccc4991f68b0d89..daaa870a646a700959f0fa11c4e84b9adcdbaa84 100644 (file)
@@ -225,6 +225,8 @@ DEFUN_NOSH (show_debugging_babel,
 
        debug_babel_config_write(vty);
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index 21429f06cfbf269c4630bd38d4c527a80089d794..4a2c5bf662b9b44f43dae3b29d3db9a58af431d3 100644 (file)
@@ -973,6 +973,8 @@ DEFUN_NOSH(show_debugging_bfd,
        if (bglobal.debug_network)
                vty_out(vty, "  Network layer debugging is on.\n");
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
diff --git a/bgpd/IMPLEMENTATION.txt b/bgpd/IMPLEMENTATION.txt
deleted file mode 100644 (file)
index 5822dbb..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-$Id: IMPLEMENTATION.txt,v 1.2 2005/02/15 17:10:03 gdt Exp $
-
-This file contains notes about the internals of the BGP
-implementation.  The initial impetus is understanding the memory usage
-of Quagga'a BGP implementation.  There may be some inaccuracies; it is
-in the repository in the hopes that it will be significantly more
-helpful than not.
-
-* FILES
-
-bgp_advertise.[hc]:
-  data structures: advertised prefixes, attributes
-
-bgp_aspath.[hc]:
-  struct aspath:
-    These are stored in a hash, apparently in wire format.
-bgp_attr.[hc]:
-  struct attr: contains all attributes
-    size(ILP32) 26 words/104 bytes (poor packing, v6/multicast is 10)
-
-  bgp_attr_parse: origin, aspath, next hop probably most of interest
-  bgp_attr_origin: set flag bit
-  bgp_attr_aspath: put in refcounted hash table, so share pointer
-  bgp_attr_nexthop: store in attribute structure
-
-bgp_btoa.c: ? test program
-
-bgp_clist.[hc]:
-  data structures: community lists (including permit/deny state)
-
-bgp_community.[hc]:
-  data structures: community atttributes (multiple communities per struct)
-
-bgp_damp.[hc]:
-  per-route damping data, and damping control information
-
-bgp_debug.[hc]:
-  debugging support (vty config, dump of packets)
-
-bgp_dump.[hc]:
-  MRT-compatible dump format routines
-
-bgp_ecommunity.[hc]:
-  Extended communities attributes (multiple ecommmunities per struct)
-
-bgp_filter.[hc]:
-  AS path access list filtering
-
-bgp_fsm.[hc]:
-  Per-peer state machine for TCP connection, hold time, etc.
-
-bgp_main.c:
-  Daemon startup.
-
-bgp_mplsvpn.[hc]:
-  parsing of attribute structures for MPLS VPNs [need better description]
-
-bgp_network.[hc]:
-  Opening and binding of sockets, finding addresses for interfaces
-
-bgp_nexthop.[hc]:
-  data structures: Nexthop cache [not clear how used, if truly cache
-  in sense of memoization, or something else]
-
-  importing EGP routes into IGP (thread created)
-  "scanning" (thread created)
-  bgp_scan: has useful clues to data structure complexity.  Scanning
-  process iterates over database of received advertisements, and
-  builds 'cache' structure.
-bgp_open.[ch]:
-  Open messages, and capability negotiation
-
-bgp_packet.[hc]
-  sending and receiving of UPDATE/WITHDRAW
-  collision resolution for simultanteous opens
-  bgp_read: top-level read routine: reads whole packet (nonblocking)
-    and dispatches to per-message-type receive
-
-  bgp_update_receive:
-    calls bgp_attr_parse
-    reads nrli into struct bgp_nrli update
-
-    uninterning of aspath, community, ecommmunity, cluster,
-    transit which were interned in bgp_attr_parse
-
-bgp_regex.[ch]:
-  Glue to convert BGP regexps to standard (_ means many things).
-
-bgp_route.[hc]:
-  data structures: routes as received, static routes
-  Application of filters.  Lots of route processing.
-  bgp_nlri_parse:
-    sanity checks, then calls bgp_update with peer, prefix, attributes pointer
-
-  bgp_update: bgp_update_main, then RS processing
-
-  bgp_update_main:
-    find 'struct bgp_node *' for this afi/safi
-    look for route in table, then 'intern' attributes
-    ** interning is process of
-      looking for data in hash table, and putting there if missing, refcnt
-      using pointer to existing data
-    many validity checks
-    get new struct bgp_path_info
-    call bgp_path_info_add with rn and bgp_path_info
-    call bgp_process
-
-bgp_routemap.c
-  implementation of route maps (match and set)
-
-bgp_snmp.c
-  SNMP glue.  Not particularly interesting except to add variables or
-  debug SNMP.
-
-bgp_table.[hc]
-  data structures: struct bgp_table, struct bgp_node
-  allocation/lookup/utility operations - not a lot of protocol processin
-
-bgp_vty.[hc]
-  protocol-wide vty hooks
-
-bgp_zebra.[hc]
-  Processing interface events from zebra, redistribution of routes.
-
-bgpd.h
-  struct bgp_master: daemon main data structure 
-  struct bgp: per-instance structure
-  struct peer_group
-  struct bgp_notify: (in-core representation of wire format?)
-  struct bgp_nexthop: (v4 and v6 addresses, *ifp)
-  struct bgp_filter: distribute, prefix, aslist, route_maps
-  struct peer: neighbor structure (very rich/complex)
-  struct bgp_nlri: reference to wire format
-  #define of protocol constants
-    attribute type codes
-  fsm states/events
-  timer values
-
-bgpd.c
-  instance/peer allocation
-  configuration
-  initialization/termination
-
-* DATA STRUCTURE SIZES
-
-Question: How much memory does quagga's bgpd use as a function of
-state received from peers?
-
-It seems that a struct bgp_path_info is kept for each prefix.  The "struct
-attr *" is interned, and variables within that are interned.  So, 40
-bytes are kept per received prefix, plus interned shared values.  This
-could be 36 if 'int suppress' where changed to a u_char and moved to
-be with the other u_chars.  Without MPLS, this could be 32 bytes.
-Note that 8 bytes of this is linked list overhead, meaning that 24
-bytes are the raw per-prefix storage requirements.
-
-Also, a struct bgp_damp_info is apparently maintained per route; this
-is fairly large (about 44 bytes).
-
-[TODO: the role of struct bgp_node.]
-
-* TIME COMPLEXITY
-
-It appears that received prefixes from each peer are stored in a
-linked list.
index d91c717f37cde3e993a5672956ce6d26ae954027..b7d0958bac02b3e10140061ef95a3618f67f74d9 100644 (file)
@@ -983,7 +983,7 @@ struct attr *bgp_attr_aggregate_intern(
 {
        struct attr attr;
        struct attr *new;
-       int ret;
+       route_map_result_t ret;
 
        memset(&attr, 0, sizeof(attr));
 
index fc44e86cbc479c359cf4300a648bdceabbaf9c4b..2598361ad2c584fa924d5349febc0aac80fac9a6 100644 (file)
@@ -53,18 +53,16 @@ bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table,
 
                        if (ret == RMAP_PERMITMATCH) {
                                bgp_dest_unlock_node(dest);
-                               if (BGP_DEBUG(update, UPDATE_OUT))
-                                       zlog_debug(
-                                               "%s: Condition map routes present in BGP table",
-                                               __func__);
+                               bgp_cond_adv_debug(
+                                       "%s: Condition map routes present in BGP table",
+                                       __func__);
 
                                return ret;
                        }
                }
        }
 
-       if (BGP_DEBUG(update, UPDATE_OUT))
-               zlog_debug("%s: Condition map routes not present in BGP table",
+       bgp_cond_adv_debug("%s: Condition map routes not present in BGP table",
                           __func__);
 
        return ret;
@@ -98,8 +96,7 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi,
        subgrp->pscount = 0;
        SET_FLAG(subgrp->sflags, SUBGRP_STATUS_TABLE_REPARSING);
 
-       if (BGP_DEBUG(update, UPDATE_OUT))
-               zlog_debug("%s: %s routes to/from %s for %s", __func__,
+       bgp_cond_adv_debug("%s: %s routes to/from %s for %s", __func__,
                           update_type == UPDATE_TYPE_ADVERTISE ? "Advertise"
                                                                : "Withdraw",
                           peer->host, get_afi_safi_str(afi, safi, false));
@@ -224,7 +221,7 @@ static void bgp_conditional_adv_timer(struct thread *t)
                            && !peer->advmap_table_change)
                                continue;
 
-                       if (BGP_DEBUG(update, UPDATE_OUT)) {
+                       if (BGP_DEBUG(cond_adv, COND_ADV)) {
                                if (peer->advmap_table_change)
                                        zlog_debug(
                                                "%s: %s - routes changed in BGP table.",
@@ -269,10 +266,9 @@ static void bgp_conditional_adv_timer(struct thread *t)
                                            .advmap.update_type !=
                                    filter->advmap.update_type)) {
                                /* Handle change to peer advmap */
-                               if (BGP_DEBUG(update, UPDATE_OUT))
-                                       zlog_debug(
-                                               "%s: advmap.update_type changed for peer %s, adjusting update_group.",
-                                               __func__, peer->host);
+                               bgp_cond_adv_debug(
+                                       "%s: advmap.update_type changed for peer %s, adjusting update_group.",
+                                       __func__, peer->host);
 
                                update_group_adjust_peer(paf);
                        }
@@ -283,12 +279,10 @@ static void bgp_conditional_adv_timer(struct thread *t)
                         */
                        if (peer->advmap_config_change[afi][safi]) {
 
-                               if (BGP_DEBUG(update, UPDATE_OUT))
-                                       zlog_debug(
-                                               "%s: Configuration is changed on peer %s for %s, send the normal update first.",
-                                               __func__, peer->host,
-                                               get_afi_safi_str(afi, safi,
-                                                                false));
+                               bgp_cond_adv_debug(
+                                       "%s: Configuration is changed on peer %s for %s, send the normal update first.",
+                                       __func__, peer->host,
+                                       get_afi_safi_str(afi, safi, false));
                                if (paf) {
                                        update_subgroup_split_peer(paf, NULL);
                                        subgrp = paf->subgroup;
@@ -325,8 +319,7 @@ void bgp_conditional_adv_enable(struct peer *peer, afi_t afi, safi_t safi)
         * neighbors (AFI/SAFI). So just increment the counter.
         */
        if (++bgp->condition_filter_count > 1) {
-               if (BGP_DEBUG(update, UPDATE_OUT))
-                       zlog_debug("%s: condition_filter_count %d", __func__,
+               bgp_cond_adv_debug("%s: condition_filter_count %d", __func__,
                                   bgp->condition_filter_count);
 
                return;
@@ -349,8 +342,7 @@ void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, safi_t safi)
         * So there's nothing to do except decrementing the counter.
         */
        if (--bgp->condition_filter_count != 0) {
-               if (BGP_DEBUG(update, UPDATE_OUT))
-                       zlog_debug("%s: condition_filter_count %d", __func__,
+               bgp_cond_adv_debug("%s: condition_filter_count %d", __func__,
                                   bgp->condition_filter_count);
 
                return;
@@ -359,3 +351,164 @@ void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, safi_t safi)
        /* Last filter removed. So cancel conditional routes polling thread. */
        THREAD_OFF(bgp->t_condition_check);
 }
+
+static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi,
+                                            safi_t safi, const char *amap_name,
+                                            struct route_map *amap,
+                                            const char *cmap_name,
+                                            struct route_map *cmap,
+                                            bool condition, bool set)
+{
+       struct bgp_filter *filter;
+       bool filter_exists = false;
+
+       filter = &peer->filter[afi][safi];
+
+       /* advertise-map is already configured. */
+       if (filter->advmap.aname) {
+               filter_exists = true;
+               XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname);
+               XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname);
+       }
+
+       route_map_counter_decrement(filter->advmap.amap);
+
+       /* Removed advertise-map configuration */
+       if (!set) {
+               memset(&filter->advmap, 0, sizeof(filter->advmap));
+
+               /* decrement condition_filter_count delete timer if
+                * this is the last advertise-map to be removed.
+                */
+               if (filter_exists)
+                       bgp_conditional_adv_disable(peer, afi, safi);
+
+               /* Process peer route updates. */
+               peer_on_policy_change(peer, afi, safi, 1);
+
+               return;
+       }
+
+       /* Update filter data with newly configured values. */
+       filter->advmap.aname = XSTRDUP(MTYPE_BGP_FILTER_NAME, amap_name);
+       filter->advmap.cname = XSTRDUP(MTYPE_BGP_FILTER_NAME, cmap_name);
+       filter->advmap.amap = amap;
+       filter->advmap.cmap = cmap;
+       filter->advmap.condition = condition;
+       route_map_counter_increment(filter->advmap.amap);
+       peer->advmap_config_change[afi][safi] = true;
+
+       /* Increment condition_filter_count and/or create timer. */
+       if (!filter_exists) {
+               filter->advmap.update_type = UPDATE_TYPE_ADVERTISE;
+               bgp_conditional_adv_enable(peer, afi, safi);
+       }
+
+       /* Process peer route updates. */
+       peer_on_policy_change(peer, afi, safi, 1);
+}
+
+/* Set advertise-map to the peer. */
+int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
+                          const char *advertise_name,
+                          struct route_map *advertise_map,
+                          const char *condition_name,
+                          struct route_map *condition_map, bool condition)
+{
+       struct peer *member;
+       struct listnode *node, *nnode;
+
+       /* Set configuration on peer. */
+       peer_advertise_map_filter_update(peer, afi, safi, advertise_name,
+                                        advertise_map, condition_name,
+                                        condition_map, condition, true);
+
+       /* Check if handling a regular peer & Skip peer-group mechanics. */
+       if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+               /* Set override-flag and process peer route updates. */
+               SET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
+                        PEER_FT_ADVERTISE_MAP);
+               return 0;
+       }
+
+       /*
+        * Set configuration on all peer-group members, unless they are
+        * explicitly overriding peer-group configuration.
+        */
+       for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
+               /* Skip peers with overridden configuration. */
+               if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
+                              PEER_FT_ADVERTISE_MAP))
+                       continue;
+
+               /* Set configuration on peer-group member. */
+               peer_advertise_map_filter_update(
+                       member, afi, safi, advertise_name, advertise_map,
+                       condition_name, condition_map, condition, true);
+       }
+
+       return 0;
+}
+
+/* Unset advertise-map from the peer. */
+int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
+                            const char *advertise_name,
+                            struct route_map *advertise_map,
+                            const char *condition_name,
+                            struct route_map *condition_map, bool condition)
+{
+       struct peer *member;
+       struct listnode *node, *nnode;
+
+       /* advertise-map is not configured */
+       if (!peer->filter[afi][safi].advmap.aname)
+               return 0;
+
+       /* Unset override-flag unconditionally. */
+       UNSET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
+                  PEER_FT_ADVERTISE_MAP);
+
+       /* Inherit configuration from peer-group if peer is member. */
+       if (peer_group_active(peer)) {
+               PEER_STR_ATTR_INHERIT(peer, peer->group,
+                                     filter[afi][safi].advmap.aname,
+                                     MTYPE_BGP_FILTER_NAME);
+               PEER_ATTR_INHERIT(peer, peer->group,
+                                 filter[afi][safi].advmap.amap);
+       } else
+               peer_advertise_map_filter_update(
+                       peer, afi, safi, advertise_name, advertise_map,
+                       condition_name, condition_map, condition, false);
+
+       /* Check if handling a regular peer and skip peer-group mechanics. */
+       if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+               /* Process peer route updates. */
+               bgp_cond_adv_debug("%s: Send normal update to %s for %s",
+                                  __func__, peer->host,
+                                  get_afi_safi_str(afi, safi, false));
+
+               return 0;
+       }
+
+       /*
+        * Remove configuration on all peer-group members, unless they are
+        * explicitly overriding peer-group configuration.
+        */
+       for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
+               /* Skip peers with overridden configuration. */
+               if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
+                              PEER_FT_ADVERTISE_MAP))
+                       continue;
+               /* Remove configuration on peer-group member. */
+               peer_advertise_map_filter_update(
+                       member, afi, safi, advertise_name, advertise_map,
+                       condition_name, condition_map, condition, false);
+
+               /* Process peer route updates. */
+               bgp_cond_adv_debug("%s: Send normal update to %s for %s ",
+                                  __func__, member->host,
+                                  get_afi_safi_str(afi, safi, false));
+       }
+
+       return 0;
+}
index 371ae856c2cd02962c45bbaa66acee2aa0bfcd54..a4f1403a441ac3428c2d5fe15b2d5200206ec3bd 100644 (file)
 extern "C" {
 #endif
 
+/* Macro to log debug message */
+#define bgp_cond_adv_debug(...)                                                \
+       do {                                                                   \
+               if (BGP_DEBUG(cond_adv, COND_ADV))                             \
+                       zlog_debug("" __VA_ARGS__);                            \
+       } while (0)
+
 /* Polling time for monitoring condition-map routes in route table */
 #define DEFAULT_CONDITIONAL_ROUTES_POLL_TIME 60
 
@@ -40,6 +47,18 @@ extern void bgp_conditional_adv_enable(struct peer *peer, afi_t afi,
                                       safi_t safi);
 extern void bgp_conditional_adv_disable(struct peer *peer, afi_t afi,
                                        safi_t safi);
+extern int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
+                                 const char *advertise_name,
+                                 struct route_map *advertise_map,
+                                 const char *condition_name,
+                                 struct route_map *condition_map,
+                                 bool condition);
+extern int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
+                                   const char *advertise_name,
+                                   struct route_map *advertise_map,
+                                   const char *condition_name,
+                                   struct route_map *condition_map,
+                                   bool condition);
 #ifdef __cplusplus
 }
 #endif
index d0ab88ee1b5875188b51f53e0afa9cf1caeec206..264dd85fbc66901c865f64d1bb9a6dd2f8a3429d 100644 (file)
@@ -70,6 +70,7 @@ unsigned long conf_bgp_debug_pbr;
 unsigned long conf_bgp_debug_graceful_restart;
 unsigned long conf_bgp_debug_evpn_mh;
 unsigned long conf_bgp_debug_bfd;
+unsigned long conf_bgp_debug_cond_adv;
 
 unsigned long term_bgp_debug_as4;
 unsigned long term_bgp_debug_neighbor_events;
@@ -90,6 +91,7 @@ unsigned long term_bgp_debug_pbr;
 unsigned long term_bgp_debug_graceful_restart;
 unsigned long term_bgp_debug_evpn_mh;
 unsigned long term_bgp_debug_bfd;
+unsigned long term_bgp_debug_cond_adv;
 
 struct list *bgp_debug_neighbor_events_peers = NULL;
 struct list *bgp_debug_keepalive_peers = NULL;
@@ -2108,6 +2110,33 @@ DEFPY(debug_bgp_bfd, debug_bgp_bfd_cmd,
        return CMD_SUCCESS;
 }
 
+DEFPY (debug_bgp_cond_adv,
+       debug_bgp_cond_adv_cmd,
+       "[no$no] debug bgp conditional-advertisement",
+       NO_STR
+       DEBUG_STR
+       BGP_STR
+       "BGP conditional advertisement\n")
+{
+       if (vty->node == CONFIG_NODE) {
+               if (no)
+                       DEBUG_OFF(cond_adv, COND_ADV);
+               else
+                       DEBUG_ON(cond_adv, COND_ADV);
+       } else {
+               if (no) {
+                       TERM_DEBUG_OFF(cond_adv, COND_ADV);
+                       vty_out(vty,
+                               "BGP conditional advertisement debugging is off\n");
+               } else {
+                       TERM_DEBUG_ON(cond_adv, COND_ADV);
+                       vty_out(vty,
+                               "BGP conditional advertisement debugging is on\n");
+               }
+       }
+       return CMD_SUCCESS;
+}
+
 DEFUN (no_debug_bgp,
        no_debug_bgp_cmd,
        "no debug bgp",
@@ -2152,6 +2181,7 @@ DEFUN (no_debug_bgp,
        TERM_DEBUG_OFF(evpn_mh, EVPN_MH_ES);
        TERM_DEBUG_OFF(evpn_mh, EVPN_MH_RT);
        TERM_DEBUG_OFF(bfd, BFD_LIB);
+       TERM_DEBUG_OFF(cond_adv, COND_ADV);
 
        vty_out(vty, "All possible debugging has been turned off\n");
 
@@ -2244,6 +2274,12 @@ DEFUN_NOSH (show_debugging_bgp,
        if (BGP_DEBUG(bfd, BFD_LIB))
                vty_out(vty, "  BGP BFD library debugging is on\n");
 
+       if (BGP_DEBUG(cond_adv, COND_ADV))
+               vty_out(vty,
+                       "  BGP conditional advertisement debugging is on\n");
+
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
@@ -2373,6 +2409,11 @@ static int bgp_config_write_debug(struct vty *vty)
                write++;
        }
 
+       if (CONF_BGP_DEBUG(cond_adv, COND_ADV)) {
+               vty_out(vty, "debug bgp conditional-advertisement\n");
+               write++;
+       }
+
        return write;
 }
 
@@ -2501,6 +2542,10 @@ void bgp_debug_init(void)
        /* debug bgp bfd */
        install_element(ENABLE_NODE, &debug_bgp_bfd_cmd);
        install_element(CONFIG_NODE, &debug_bgp_bfd_cmd);
+
+       /* debug bgp conditional advertisement */
+       install_element(ENABLE_NODE, &debug_bgp_cond_adv_cmd);
+       install_element(CONFIG_NODE, &debug_bgp_cond_adv_cmd);
 }
 
 /* Return true if this prefix is on the per_prefix_list of prefixes to debug
@@ -2662,7 +2707,6 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
                                    struct bgp_route_evpn *overlay_index,
                                    char *str, int size)
 {
-       char rd_buf[RD_ADDRSTRLEN];
        char tag_buf[30];
        char overlay_index_buf[INET6_ADDRSTRLEN + 14];
        const struct prefix_evpn *evp;
@@ -2720,8 +2764,7 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
        }
 
        if (prd)
-               snprintfrr(str, size, "RD %s %pFX%s%s%s %s %s",
-                          prefix_rd2str(prd, rd_buf, sizeof(rd_buf)), pu.p,
+               snprintfrr(str, size, "RD %pRD %pFX%s%s%s %s %s", prd, pu.p,
                           overlay_index_buf, tag_buf, pathid_buf, afi2str(afi),
                           safi2str(safi));
        else if (safi == SAFI_FLOWSPEC) {
index 62f5340dfd53b2f78831744c222c9c733a66538c..be5ed0afdc8d0f8178c13ce33205cebabdcdfa04 100644 (file)
@@ -80,6 +80,7 @@ extern unsigned long conf_bgp_debug_pbr;
 extern unsigned long conf_bgp_debug_graceful_restart;
 extern unsigned long conf_bgp_debug_evpn_mh;
 extern unsigned long conf_bgp_debug_bfd;
+extern unsigned long conf_bgp_debug_cond_adv;
 
 extern unsigned long term_bgp_debug_as4;
 extern unsigned long term_bgp_debug_neighbor_events;
@@ -98,6 +99,7 @@ extern unsigned long term_bgp_debug_pbr;
 extern unsigned long term_bgp_debug_graceful_restart;
 extern unsigned long term_bgp_debug_evpn_mh;
 extern unsigned long term_bgp_debug_bfd;
+extern unsigned long term_bgp_debug_cond_adv;
 
 extern struct list *bgp_debug_neighbor_events_peers;
 extern struct list *bgp_debug_keepalive_peers;
@@ -143,6 +145,7 @@ struct bgp_debug_filter {
 #define BGP_DEBUG_GRACEFUL_RESTART     0x01
 
 #define BGP_DEBUG_BFD_LIB             0x01
+#define BGP_DEBUG_COND_ADV 0x01
 
 #define CONF_DEBUG_ON(a, b)    (conf_bgp_debug_ ## a |= (BGP_DEBUG_ ## b))
 #define CONF_DEBUG_OFF(a, b)   (conf_bgp_debug_ ## a &= ~(BGP_DEBUG_ ## b))
index f57e9ae88beec9ab8fcb9c455ffb209796037904..589d9af1e5efb0610761bf85ae39eacb0c4c9313 100644 (file)
@@ -1383,7 +1383,7 @@ bool ecommunity_del_val(struct ecommunity *ecom, struct ecommunity_val *eval)
                XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val);
                ecom->val = p;
        } else
-               ecom->val = NULL;
+               XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val);
 
        return true;
 }
index de63618580bd73880a7a59b3041f5e74be1e3a0c..1d40664aebd108bf71a9cf5b3dee2de8fba894f4 100644 (file)
@@ -2402,16 +2402,13 @@ static void bgp_evpn_es_json_frag_fill(json_object *json_frags,
                                       struct bgp_evpn_es *es)
 {
        json_object *json_frag;
-       char buf1[RD_ADDRSTRLEN];
        struct listnode *node;
        struct bgp_evpn_es_frag *es_frag;
 
        for (ALL_LIST_ELEMENTS_RO(es->es_frag_list, node, es_frag)) {
                json_frag = json_object_new_object();
 
-               json_object_string_add(
-                       json_frag, "rd",
-                       prefix_rd2str(&es_frag->prd, buf1, sizeof(buf1)));
+               json_object_string_addf(json_frag, "rd", "%pRD", &es_frag->prd);
                json_object_int_add(json_frag, "eviCount",
                                    listcount(es_frag->es_evi_frag_list));
 
@@ -2423,12 +2420,10 @@ static void bgp_evpn_es_frag_show_detail(struct vty *vty,
                                         struct bgp_evpn_es *es)
 {
        struct listnode *node;
-       char buf1[RD_ADDRSTRLEN];
        struct bgp_evpn_es_frag *es_frag;
 
        for (ALL_LIST_ELEMENTS_RO(es->es_frag_list, node, es_frag)) {
-               vty_out(vty, "  %s EVIs: %d\n",
-                       prefix_rd2str(&es_frag->prd, buf1, sizeof(buf1)),
+               vty_out(vty, "  %pRD EVIs: %d\n", &es_frag->prd,
                        listcount(es_frag->es_evi_frag_list));
        }
 }
@@ -2533,7 +2528,6 @@ static void bgp_evpn_es_vteps_show_detail(struct vty *vty,
 static void bgp_evpn_es_show_entry(struct vty *vty,
                struct bgp_evpn_es *es, json_object *json)
 {
-       char buf1[RD_ADDRSTRLEN];
        struct listnode *node;
        struct bgp_evpn_es_vtep *es_vtep;
 
@@ -2543,10 +2537,8 @@ static void bgp_evpn_es_show_entry(struct vty *vty,
 
                json_object_string_add(json, "esi", es->esi_str);
                if (es->es_base_frag)
-                       json_object_string_add(
-                               json, "rd",
-                               prefix_rd2str(&es->es_base_frag->prd, buf1,
-                                             sizeof(buf1)));
+                       json_object_string_addf(json, "rd", "%pRD",
+                                               &es->es_base_frag->prd);
 
                if (es->flags & (BGP_EVPNES_LOCAL | BGP_EVPNES_REMOTE)) {
                        json_types = json_object_new_array();
@@ -2583,15 +2575,9 @@ static void bgp_evpn_es_show_entry(struct vty *vty,
 
                bgp_evpn_es_vteps_str(vtep_str, es, sizeof(vtep_str));
 
-               if (es->es_base_frag)
-                       prefix_rd2str(&es->es_base_frag->prd, buf1,
-                                     sizeof(buf1));
-               else
-                       strlcpy(buf1, "-", sizeof(buf1));
-
-               vty_out(vty, "%-30s %-5s %-21s %-8d %s\n",
-                               es->esi_str, type_str, buf1,
-                               listcount(es->es_evi_list), vtep_str);
+               vty_out(vty, "%-30s %-5s %-21pRD %-8d %s\n", es->esi_str,
+                       type_str, &es->es_base_frag->prd,
+                       listcount(es->es_evi_list), vtep_str);
        }
 }
 
@@ -2657,7 +2643,6 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
        } else {
                char incons_str[BGP_EVPNES_INCONS_STR_SZ];
                char type_str[4];
-               char buf1[RD_ADDRSTRLEN];
 
                type_str[0] = '\0';
                if (es->flags & BGP_EVPNES_LOCAL)
@@ -2665,15 +2650,9 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
                if (es->flags & BGP_EVPNES_REMOTE)
                        strlcat(type_str, "R", sizeof(type_str));
 
-               if (es->es_base_frag)
-                       prefix_rd2str(&es->es_base_frag->prd, buf1,
-                                     sizeof(buf1));
-               else
-                       strlcpy(buf1, "-", sizeof(buf1));
-
                vty_out(vty, "ESI: %s\n", es->esi_str);
                vty_out(vty, " Type: %s\n", type_str);
-               vty_out(vty, " RD: %s\n", buf1);
+               vty_out(vty, " RD: %pRD\n", &es->es_base_frag->prd);
                vty_out(vty, " Originator-IP: %pI4\n", &es->originator_ip);
                if (es->flags & BGP_EVPNES_LOCAL)
                        vty_out(vty, " Local ES DF preference: %u\n",
@@ -4032,18 +4011,14 @@ static void bgp_evpn_es_evi_show_entry(struct vty *vty,
 static void bgp_evpn_es_evi_show_entry_detail(struct vty *vty,
                struct bgp_evpn_es_evi *es_evi, json_object *json)
 {
-       char buf1[RD_ADDRSTRLEN];
-
        if (json) {
                json_object *json_flags;
 
                /* Add the "brief" info first */
                bgp_evpn_es_evi_show_entry(vty, es_evi, json);
                if (es_evi->es_frag)
-                       json_object_string_add(
-                               json, "esFragmentRd",
-                               prefix_rd2str(&es_evi->es_frag->prd, buf1,
-                                             sizeof(buf1)));
+                       json_object_string_addf(json, "esFragmentRd", "%pRD",
+                                               &es_evi->es_frag->prd);
                if (es_evi->flags & BGP_EVPNES_EVI_INCONS_VTEP_LIST) {
                        json_flags = json_object_new_array();
                        json_array_string_add(json_flags, "es-vtep-mismatch");
@@ -4067,9 +4042,8 @@ static void bgp_evpn_es_evi_show_entry_detail(struct vty *vty,
                                es_evi->vpn->vni, es_evi->es->esi_str);
                vty_out(vty, " Type: %s\n", type_str);
                if (es_evi->es_frag)
-                       vty_out(vty, " ES fragment RD: %s\n",
-                               prefix_rd2str(&es_evi->es_frag->prd, buf1,
-                                             sizeof(buf1)));
+                       vty_out(vty, " ES fragment RD: %pRD\n",
+                               &es_evi->es_frag->prd);
                vty_out(vty, " Inconsistencies: %s\n",
                        (es_evi->flags & BGP_EVPNES_EVI_INCONS_VTEP_LIST) ?
                        "es-vtep-mismatch":"-");
index f6b87dccdb668006b769697e040d903131e01cf9..5ad5cf8bff3b78c9ac01bd3cafa72c240d69e02f 100644 (file)
@@ -386,9 +386,7 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
                json_object_int_add(json, "vni", bgp_vrf->l3vni);
                json_object_string_add(json, "type", "L3");
                json_object_string_add(json, "inKernel", "True");
-               json_object_string_add(
-                       json, "rd",
-                       prefix_rd2str(&bgp_vrf->vrf_prd, buf1, RD_ADDRSTRLEN));
+               json_object_string_addf(json, "rd", "%pRD", &bgp_vrf->vrf_prd);
                json_object_string_addf(json, "originatorIp", "%pI4",
                                        &bgp_vrf->originator_ip);
                json_object_string_add(json, "advertiseGatewayMacip", "n/a");
@@ -412,8 +410,7 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
                vty_out(vty, "  Type: %s\n", "L3");
                vty_out(vty, "  Tenant VRF: %s\n",
                        vrf_id_to_name(bgp_vrf->vrf_id));
-               vty_out(vty, "  RD: %s\n",
-                       prefix_rd2str(&bgp_vrf->vrf_prd, buf1, RD_ADDRSTRLEN));
+               vty_out(vty, "  RD: %pRD\n", &bgp_vrf->vrf_prd);
                vty_out(vty, "  Originator IP: %pI4\n",
                        &bgp_vrf->originator_ip);
                vty_out(vty, "  Advertise-gw-macip : %s\n", "n/a");
@@ -471,7 +468,6 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
 
 static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
 {
-       char buf1[RD_ADDRSTRLEN];
        char *ecom_str;
        struct listnode *node, *nnode;
        struct ecommunity *ecom;
@@ -488,9 +484,7 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
                json_object_string_add(json, "type", "L2");
                json_object_string_add(json, "inKernel",
                                       is_vni_live(vpn) ? "True" : "False");
-               json_object_string_add(
-                       json, "rd",
-                       prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
+               json_object_string_addf(json, "rd", "%pRD", &vpn->prd);
                json_object_string_addf(json, "originatorIp", "%pI4",
                                        &vpn->originator_ip);
                json_object_string_addf(json, "mcastGroup", "%pI4",
@@ -531,8 +525,7 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
                vty_out(vty, "  Type: %s\n", "L2");
                vty_out(vty, "  Tenant-Vrf: %s\n",
                        vrf_id_to_name(vpn->tenant_vrf_id));
-               vty_out(vty, "  RD: %s\n",
-                       prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
+               vty_out(vty, "  RD: %pRD\n", &vpn->prd);
                vty_out(vty, "  Originator IP: %pI4\n", &vpn->originator_ip);
                vty_out(vty, "  Mcast group: %pI4\n", &vpn->mcast_grp);
                if (!vpn->advertise_gw_macip &&
@@ -941,9 +934,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
                json_object_string_add(json_vni, "inKernel", "True");
                json_object_string_addf(json_vni, "originatorIp", "%pI4",
                                        &bgp->originator_ip);
-               json_object_string_add(
-                       json_vni, "rd",
-                       prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN));
+               json_object_string_addf(json_vni, "rd", "%pRD", &bgp->vrf_prd);
                json_object_string_add(json_vni, "advertiseGatewayMacip",
                                       "n/a");
                json_object_string_add(json_vni, "advertiseSviMacIp", "n/a");
@@ -959,8 +950,8 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
                        json_vni, "rmac",
                        prefix_mac2str(&bgp->rmac, buf2, sizeof(buf2)));
        } else {
-               vty_out(vty, "%-1s %-10u %-4s %-21s", buf1, bgp->l3vni, "L3",
-                       prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN));
+               vty_out(vty, "%-1s %-10u %-4s %-21pRD", buf1, bgp->l3vni, "L3",
+                       &bgp->vrf_prd);
        }
 
        for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode, ecom)) {
@@ -1038,7 +1029,6 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[])
        json_object *json_export_rtl = NULL;
        struct bgpevpn *vpn = (struct bgpevpn *)bucket->data;
        char buf1[10];
-       char buf2[RD_ADDRSTRLEN];
        char rt_buf[25];
        char *ecom_str;
        struct listnode *node, *nnode;
@@ -1065,9 +1055,7 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[])
                json_object_string_add(json_vni, "type", "L2");
                json_object_string_add(json_vni, "inKernel",
                                       is_vni_live(vpn) ? "True" : "False");
-               json_object_string_add(
-                       json_vni, "rd",
-                       prefix_rd2str(&vpn->prd, buf2, sizeof(buf2)));
+               json_object_string_addf(json_vni, "rd", "%pRD", &vpn->prd);
                json_object_string_addf(json_vni, "originatorIp", "%pI4",
                                        &vpn->originator_ip);
                json_object_string_addf(json_vni, "mcastGroup", "%pI4",
@@ -1097,8 +1085,8 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[])
                        json_object_string_add(json_vni, "advertiseSviMacIp",
                                               "Disabled");
        } else {
-               vty_out(vty, "%-1s %-10u %-4s %-21s", buf1, vpn->vni, "L2",
-                       prefix_rd2str(&vpn->prd, buf2, RD_ADDRSTRLEN));
+               vty_out(vty, "%-1s %-10u %-4s %-21pRD", buf1, vpn->vni, "L2",
+                       &vpn->prd);
        }
 
        for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode, ecom)) {
@@ -2629,7 +2617,6 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
        afi_t afi;
        safi_t safi;
        uint32_t prefix_cnt, path_cnt;
-       char rd_str[RD_ADDRSTRLEN];
        json_object *json_rd = NULL;
        int add_rd_to_json = 0;
 
@@ -2637,8 +2624,6 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
        safi = SAFI_EVPN;
        prefix_cnt = path_cnt = 0;
 
-       prefix_rd2str(prd, rd_str, sizeof(rd_str));
-
        rd_dest = bgp_node_lookup(bgp->rib[afi][safi], (struct prefix *)prd);
        if (!rd_dest)
                return;
@@ -2651,7 +2636,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
 
        if (json) {
                json_rd = json_object_new_object();
-               json_object_string_add(json_rd, "rd", rd_str);
+               json_object_string_addf(json_rd, "rd", "%pRD", prd);
        }
 
        bgp_dest_unlock_node(rd_dest);
@@ -2732,7 +2717,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
 
        if (json) {
                if (add_rd_to_json)
-                       json_object_object_add(json, rd_str, json_rd);
+                       json_object_object_addf(json, json_rd, "%pRD", prd);
                else {
                        json_object_free(json_rd);
                        json_rd = NULL;
@@ -3307,7 +3292,6 @@ static void evpn_unset_advertise_autort_rfc8365(struct bgp *bgp)
 
 static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
 {
-       char buf1[RD_ADDRSTRLEN];
        char *ecom_str;
        struct listnode *node, *nnode;
        struct ecommunity *ecom;
@@ -3315,8 +3299,7 @@ static void write_vni_config(struct vty *vty, struct bgpevpn *vpn)
        if (is_vni_configured(vpn)) {
                vty_out(vty, "  vni %d\n", vpn->vni);
                if (is_rd_configured(vpn))
-                       vty_out(vty, "   rd %s\n",
-                               prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
+                       vty_out(vty, "   rd %pRD\n", &vpn->prd);
 
                if (is_import_rt_configured(vpn)) {
                        for (ALL_LIST_ELEMENTS(vpn->import_rtl, node, nnode,
@@ -5697,7 +5680,6 @@ DEFUN (show_bgp_vrf_l3vni_info,
        JSON_STR)
 {
        char buf[ETHER_ADDR_STRLEN];
-       char buf1[INET6_ADDRSTRLEN];
        int idx_vrf = 3;
        const char *name = NULL;
        struct bgp *bgp = NULL;
@@ -5761,8 +5743,7 @@ DEFUN (show_bgp_vrf_l3vni_info,
                for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, ecom))
                        vty_out(vty, "%s  ", ecommunity_str(ecom));
                vty_out(vty, "\n");
-               vty_out(vty, "  RD: %s\n",
-                       prefix_rd2str(&bgp->vrf_prd, buf1, RD_ADDRSTRLEN));
+               vty_out(vty, "  RD: %pRD\n", &bgp->vrf_prd);
        } else {
                json_object_string_add(json, "vrf", name);
                json_object_string_addf(json, "local-ip", "%pI4",
@@ -5796,9 +5777,7 @@ DEFUN (show_bgp_vrf_l3vni_info,
                                json_import_rts,
                                json_object_new_string(ecommunity_str(ecom)));
                json_object_object_add(json, "import-rts", json_import_rts);
-               json_object_string_add(
-                       json, "rd",
-                       prefix_rd2str(&bgp->vrf_prd, buf1, RD_ADDRSTRLEN));
+               json_object_string_addf(json, "rd", "%pRD", &bgp->vrf_prd);
        }
 
        if (uj)
@@ -6031,6 +6010,7 @@ DEFUN(no_bgp_evpn_ead_es_rt, no_bgp_evpn_ead_es_rt_cmd,
 
        if (!bgp_evpn_rt_matches_existing(bgp_mh_info->ead_es_export_rtl,
                                          ecomdel)) {
+               ecommunity_free(&ecomdel);
                vty_out(vty,
                        "%% RT specified does not match EAD-ES RT configuration\n");
                return CMD_WARNING;
@@ -6165,6 +6145,7 @@ DEFUN (no_bgp_evpn_vni_rt,
 
        if (rt_type == RT_TYPE_IMPORT) {
                if (!bgp_evpn_rt_matches_existing(vpn->import_rtl, ecomdel)) {
+                       ecommunity_free(&ecomdel);
                        vty_out(vty,
                                "%% RT specified does not match configuration for this VNI\n");
                        return CMD_WARNING;
@@ -6172,6 +6153,7 @@ DEFUN (no_bgp_evpn_vni_rt,
                evpn_unconfigure_import_rt(bgp, vpn, ecomdel);
        } else if (rt_type == RT_TYPE_EXPORT) {
                if (!bgp_evpn_rt_matches_existing(vpn->export_rtl, ecomdel)) {
+                       ecommunity_free(&ecomdel);
                        vty_out(vty,
                                "%% RT specified does not match configuration for this VNI\n");
                        return CMD_WARNING;
@@ -6191,6 +6173,7 @@ DEFUN (no_bgp_evpn_vni_rt,
                }
 
                if (!found_ecomdel) {
+                       ecommunity_free(&ecomdel);
                        vty_out(vty,
                                "%% RT specified does not match configuration for this VNI\n");
                        return CMD_WARNING;
@@ -6267,7 +6250,6 @@ static int vni_cmp(const void **a, const void **b)
 void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
                                safi_t safi)
 {
-       char buf1[RD_ADDRSTRLEN];
        char buf2[INET6_ADDRSTRLEN];
 
        if (bgp->advertise_all_vni)
@@ -6433,8 +6415,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
                }
        }
        if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_RD_CFGD))
-               vty_out(vty, "  rd %s\n",
-                       prefix_rd2str(&bgp->vrf_prd, buf1, sizeof(buf1)));
+               vty_out(vty, "  rd %pRD\n", &bgp->vrf_prd);
 
        /* import route-target */
        if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) {
index a8accc25f505f3c33f46141bf38b992b6acefd09..ddda10077456bfc11094932a1b27519b92a053d2 100644 (file)
@@ -1464,6 +1464,11 @@ int bgp_stop(struct peer *peer)
 
                                /* There is no pending EOR message */
                                if (gr_info->eor_required == 0) {
+                                       if (gr_info->t_select_deferral) {
+                                               void *info = THREAD_ARG(
+                                                       gr_info->t_select_deferral);
+                                               XFREE(MTYPE_TMP, info);
+                                       }
                                        THREAD_OFF(gr_info->t_select_deferral);
                                        gr_info->eor_received = 0;
                                }
index 9fce46ae1753fc27b82359e659da7c849f28571a..08748d2ebac027b2c47d76f48af279f7b8b44f9a 100644 (file)
@@ -2048,9 +2048,15 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
                        bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
                        prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
                                      sizeof(buf));
-                       bgp->vpn_policy[afi].rtlist[edir] =
-                               ecommunity_str2com(buf,
-                                                  ECOMMUNITY_ROUTE_TARGET, 0);
+
+                       /* free up pre-existing memory if any and allocate
+                        *  the ecommunity attribute with new RD/RT
+                        */
+                       if (bgp->vpn_policy[afi].rtlist[edir])
+                               ecommunity_free(
+                                       &bgp->vpn_policy[afi].rtlist[edir]);
+                       bgp->vpn_policy[afi].rtlist[edir] = ecommunity_str2com(
+                               buf, ECOMMUNITY_ROUTE_TARGET, 0);
 
                        /* Update import_vrf rt_list */
                        ecom = bgp->vpn_policy[afi].rtlist[edir];
index 9ecc2ae4e42667a9c08a37bcc936ae3037f181d5..9582ec01ed757a9edef1d78c71ccf84365eb80f3 100644 (file)
@@ -207,6 +207,25 @@ int bgp_md5_set(struct peer *peer)
        return bgp_md5_set_password(peer, peer->password);
 }
 
+static void bgp_update_setsockopt_tcp_keepalive(struct bgp *bgp, int fd)
+{
+       if (!bgp)
+               return;
+       if (bgp->tcp_keepalive_idle != 0) {
+               int ret;
+
+               ret = setsockopt_tcp_keepalive(fd, bgp->tcp_keepalive_idle,
+                                              bgp->tcp_keepalive_intvl,
+                                              bgp->tcp_keepalive_probes);
+               if (ret < 0)
+                       zlog_err(
+                               "Can't set TCP keepalive on socket %d, idle %u intvl %u probes %u",
+                               fd, bgp->tcp_keepalive_idle,
+                               bgp->tcp_keepalive_intvl,
+                               bgp->tcp_keepalive_probes);
+       }
+}
+
 int bgp_md5_unset(struct peer *peer)
 {
        /* Unset the password from listen socket. */
@@ -415,6 +434,9 @@ static void bgp_accept(struct thread *thread)
 
        bgp_socket_set_buffer_size(bgp_sock);
 
+       /* Set TCP keepalive when TCP keepalive is enabled */
+       bgp_update_setsockopt_tcp_keepalive(bgp, bgp_sock);
+
        /* Check remote IP address */
        peer1 = peer_lookup(bgp, &su);
 
@@ -718,12 +740,16 @@ int bgp_connect(struct peer *peer)
 
        bgp_socket_set_buffer_size(peer->fd);
 
+       /* Set TCP keepalive when TCP keepalive is enabled */
+       bgp_update_setsockopt_tcp_keepalive(peer->bgp, peer->fd);
+
        if (bgp_set_socket_ttl(peer, peer->fd) < 0) {
                peer->last_reset = PEER_DOWN_SOCKET_ERROR;
                if (bgp_debug_neighbor_events(peer))
                        zlog_debug("%s: Failure to set socket ttl for connection to %s, error received: %s(%d)",
                                   __func__, peer->host, safe_strerror(errno),
                                   errno);
+
                return -1;
        }
 
index 971b1817c818e566267ba13682f5a27893e80667..075350cd2b8e8571faad871a42c7d0f9c5f4d9d1 100644 (file)
@@ -743,7 +743,6 @@ static void bgp_show_nexthop_paths(struct vty *vty, struct bgp *bgp,
        safi_t safi;
        struct bgp_table *table;
        struct bgp *bgp_path;
-       char buf1[BUFSIZ];
 
        vty_out(vty, "  Paths:\n");
        LIST_FOREACH (path, &(bnc->paths), nh_thread) {
@@ -754,12 +753,13 @@ static void bgp_show_nexthop_paths(struct vty *vty, struct bgp *bgp,
                safi = table->safi;
                bgp_path = table->bgp;
 
-               if (dest->pdest) {
-                       prefix_rd2str((struct prefix_rd *)bgp_dest_get_prefix(dest->pdest),
-                                       buf1, sizeof(buf1));
-                       vty_out(vty, "    %d/%d %pBD RD %s %s flags 0x%x\n",
-                               afi, safi, dest, buf1, bgp_path->name_pretty, path->flags);
-               } else
+               if (dest->pdest)
+                       vty_out(vty, "    %d/%d %pBD RD %pRD %s flags 0x%x\n",
+                               afi, safi, dest,
+                               (struct prefix_rd *)bgp_dest_get_prefix(
+                                       dest->pdest),
+                               bgp_path->name_pretty, path->flags);
+               else
                        vty_out(vty, "    %d/%d %pBD %s flags 0x%x\n",
                                afi, safi, dest, bgp_path->name_pretty, path->flags);
        }
@@ -865,7 +865,6 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
        }
        tbuf = time(NULL) - (monotime(NULL) - bnc->last_update);
        vty_out(vty, "  Last update: %s", ctime(&tbuf));
-       vty_out(vty, "\n");
 
        /* show paths dependent on nexthop, if needed. */
        if (specific)
@@ -912,6 +911,7 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
                struct prefix nhop;
                struct bgp_nexthop_cache_head (*tree)[AFI_MAX];
                struct bgp_nexthop_cache *bnc;
+               bool found = false;
 
                if (!str2prefix(nhopip_str, &nhop)) {
                        vty_out(vty, "nexthop address is malformed\n");
@@ -919,12 +919,16 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
                }
                tree = import_table ? &bgp->import_check_table
                                    : &bgp->nexthop_cache_table;
-               bnc = bnc_find(tree[family2afi(nhop.family)], &nhop, 0, 0);
-               if (!bnc) {
-                       vty_out(vty, "specified nexthop does not have entry\n");
-                       return CMD_SUCCESS;
+               frr_each (bgp_nexthop_cache, &(*tree)[family2afi(nhop.family)],
+                         bnc) {
+                       if (prefix_cmp(&bnc->prefix, &nhop))
+                               continue;
+                       bgp_show_nexthop(vty, bgp, bnc, true);
+                       found = true;
                }
-               bgp_show_nexthop(vty, bgp, bnc, true);
+               if (!found)
+                       vty_out(vty, "nexthop %s does not have entry\n",
+                               nhopip_str);
        } else
                bgp_show_nexthops(vty, bgp, import_table);
 
index b38e5b7a9a65e5815f4e223340704d23baf104fa..7274bcdb21db07c183730e0df397188d7c3f9c7d 100644 (file)
@@ -1145,16 +1145,14 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
                }
 
                if (BGP_DEBUG(nht, NHT)) {
-                       char buf1[RD_ADDRSTRLEN];
-
-                       if (dest->pdest) {
-                               prefix_rd2str((struct prefix_rd *)bgp_dest_get_prefix(dest->pdest),
-                                       buf1, sizeof(buf1));
+                       if (dest->pdest)
                                zlog_debug(
-                                       "... eval path %d/%d %pBD RD %s %s flags 0x%x",
-                                       afi, safi, dest, buf1,
+                                       "... eval path %d/%d %pBD RD %pRD %s flags 0x%x",
+                                       afi, safi, dest,
+                                       (struct prefix_rd *)bgp_dest_get_prefix(
+                                               dest->pdest),
                                        bgp_path->name_pretty, path->flags);
-                       else
+                       else
                                zlog_debug(
                                        "... eval path %d/%d %pBD %s flags 0x%x",
                                        afi, safi, dest, bgp_path->name_pretty,
index 7248f034a5a02c27a84e21f604f873fa9df2ef19..d1667fac2612f1a3b8e634d2789284cdc1013773 100644 (file)
@@ -1185,15 +1185,30 @@ as_t peek_for_as4_capability(struct peer *peer, uint16_t length)
                uint8_t opt_type;
                uint16_t opt_length;
 
-               /* Check the length. */
-               if (stream_get_getp(s) + 2 > end)
+               /* Ensure we can read the option type */
+               if (stream_get_getp(s) + 1 > end)
                        goto end;
 
-               /* Fetch option type and length. */
+               /* Fetch the option type */
                opt_type = stream_getc(s);
-               opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
-                                    ? stream_getw(s)
-                                    : stream_getc(s);
+
+               /*
+                * Check the length and fetch the opt_length
+                * If the peer is BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
+                * then we do a getw which is 2 bytes.  So we need to
+                * ensure that we can read that as well
+                */
+               if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) {
+                       if (stream_get_getp(s) + 2 > end)
+                               goto end;
+
+                       opt_length = stream_getw(s);
+               } else {
+                       if (stream_get_getp(s) + 1 > end)
+                               goto end;
+
+                       opt_length = stream_getc(s);
+               }
 
                /* Option length check. */
                if (stream_get_getp(s) + opt_length > end)
@@ -1263,19 +1278,40 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length,
                uint8_t opt_type;
                uint16_t opt_length;
 
-               /* Must have at least an OPEN option header */
-               if (STREAM_READABLE(s) < 2) {
+               /*
+                * Check that we can read the opt_type and fetch it
+                */
+               if (STREAM_READABLE(s) < 1) {
                        zlog_info("%s Option length error", peer->host);
                        bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
                                        BGP_NOTIFY_OPEN_MALFORMED_ATTR);
                        return -1;
                }
-
-               /* Fetch option type and length. */
                opt_type = stream_getc(s);
-               opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
-                                    ? stream_getw(s)
-                                    : stream_getc(s);
+
+               /*
+                * Check the length of the stream to ensure that
+                * FRR can properly read the opt_length. Then read it
+                */
+               if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) {
+                       if (STREAM_READABLE(s) < 2) {
+                               zlog_info("%s Option length error", peer->host);
+                               bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+                                               BGP_NOTIFY_OPEN_MALFORMED_ATTR);
+                               return -1;
+                       }
+
+                       opt_length = stream_getw(s);
+               } else {
+                       if (STREAM_READABLE(s) < 1) {
+                               zlog_info("%s Option length error", peer->host);
+                               bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+                                               BGP_NOTIFY_OPEN_MALFORMED_ATTR);
+                               return -1;
+                       }
+
+                       opt_length = stream_getc(s);
+               }
 
                /* Option length check. */
                if (STREAM_READABLE(s) < opt_length) {
index 90695219a7ea37c518c325b914182400e64a1c54..8ae31bf2e695ac56044428435322f9210ed9cf38 100644 (file)
@@ -360,6 +360,31 @@ int bgp_nlri_parse(struct peer *peer, struct attr *attr,
        return BGP_NLRI_PARSE_ERROR;
 }
 
+
+/*
+ * Check if route-refresh request from peer is pending (received before EoR),
+ * and process it now.
+ */
+static void bgp_process_pending_refresh(struct peer *peer, afi_t afi,
+                                       safi_t safi)
+{
+       if (CHECK_FLAG(peer->af_sflags[afi][safi],
+                      PEER_STATUS_REFRESH_PENDING)) {
+               UNSET_FLAG(peer->af_sflags[afi][safi],
+                          PEER_STATUS_REFRESH_PENDING);
+               bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
+                                      BGP_ROUTE_REFRESH_BORR);
+               if (bgp_debug_neighbor_events(peer))
+                       zlog_debug(
+                               "%pBP sending route-refresh (BoRR) for %s/%s (for pending REQUEST)",
+                               peer, afi2str(afi), safi2str(safi));
+
+               SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_BORR_SEND);
+               UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EORR_SEND);
+               bgp_announce_route(peer, afi, safi, true);
+       }
+}
+
 /*
  * Checks a variety of conditions to determine whether the peer needs to be
  * rescheduled for packet generation again, and does so if necessary.
@@ -558,6 +583,9 @@ void bgp_generate_updgrp_packets(struct thread *thread)
                                                        BGP_UPDATE_EOR_PKT(
                                                                peer, afi, safi,
                                                                s);
+                                                       bgp_process_pending_refresh(
+                                                               peer, afi,
+                                                               safi);
                                                }
                                        }
                                }
@@ -2026,6 +2054,11 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
                                                        gr_info->eor_required,
                                                        "EOR RCV",
                                                        gr_info->eor_received);
+                                       if (gr_info->t_select_deferral) {
+                                               void *info = THREAD_ARG(
+                                                       gr_info->t_select_deferral);
+                                               XFREE(MTYPE_TMP, info);
+                                       }
                                        THREAD_OFF(gr_info->t_select_deferral);
                                        gr_info->eor_required = 0;
                                        gr_info->eor_received = 0;
@@ -2564,6 +2597,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
                                                "%pBP rcvd route-refresh (REQUEST) for %s/%s before EoR",
                                                peer, afi2str(afi),
                                                safi2str(safi));
+                               /* Can't send BoRR now, postpone after EoR */
+                               SET_FLAG(peer->af_sflags[afi][safi],
+                                        PEER_STATUS_REFRESH_PENDING);
                                return BGP_PACKET_NOOP;
                        }
 
index 9ab48aedc6e71266c857707a64bca1ae2a6b4398..b4bcbdb8046627c4ddf153a55fc7cf724e9a0edd 100644 (file)
@@ -211,3 +211,17 @@ void form_auto_rd(struct in_addr router_id,
        snprintfrr(buf, sizeof(buf), "%pI4:%hu", &router_id, rd_id);
        (void)str2prefix_rd(buf, prd);
 }
+
+printfrr_ext_autoreg_p("RD", printfrr_prd);
+static ssize_t printfrr_prd(struct fbuf *buf, struct printfrr_eargs *ea,
+                           const void *ptr)
+{
+       char rd_buf[RD_ADDRSTRLEN];
+
+       if (!ptr)
+               return bputs(buf, "(null)");
+
+       prefix_rd2str(ptr, rd_buf, sizeof(rd_buf));
+
+       return bputs(buf, rd_buf);
+}
index 162a7ed881f4f7ae29db227fe1fa66caf91e07f6..a07c3b331e251fed80c847c9fcbce6d8f3323b56 100644 (file)
@@ -3854,8 +3854,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
        int do_loop_check = 1;
        int has_valid_label = 0;
        afi_t nh_afi;
-       uint8_t pi_type = 0;
-       uint8_t pi_sub_type = 0;
        bool force_evpn_import = false;
        safi_t orig_safi = safi;
        bool leak_success = true;
@@ -4059,15 +4057,10 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
                        bgp_attr_add_gshut_community(&new_attr);
        }
 
-       if (pi) {
-               pi_type = pi->type;
-               pi_sub_type = pi->sub_type;
-       }
-
        /* next hop check.  */
-       if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
-           && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
-                                         &new_attr, dest)) {
+       if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
+           bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
+                                      &new_attr, dest)) {
                peer->stat_pfx_nh_invalid++;
                reason = "martian or self next-hop;";
                bgp_attr_flush(&new_attr);
@@ -5620,8 +5613,8 @@ void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
                                                if (bgp_debug_neighbor_events(
                                                            peer))
                                                        zlog_debug(
-                                                               "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
-                                                               peer->host,
+                                                               "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
+                                                               peer,
                                                                afi2str(afi),
                                                                safi2str(safi),
                                                                bgp_dest_get_prefix(
@@ -5649,9 +5642,8 @@ void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
                                                   BGP_PATH_UNUSEABLE)) {
                                        if (bgp_debug_neighbor_events(peer))
                                                zlog_debug(
-                                                       "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
-                                                       peer->host,
-                                                       afi2str(afi),
+                                                       "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
+                                                       peer, afi2str(afi),
                                                        safi2str(safi),
                                                        bgp_dest_get_prefix(
                                                                dest));
@@ -6014,6 +6006,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
                        /* Unintern original. */
                        aspath_unintern(&attr.aspath);
                        bgp_static_withdraw(bgp, p, afi, safi);
+                       bgp_dest_unlock_node(dest);
                        return;
                }
 
@@ -6340,6 +6333,7 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
                        aspath_unintern(&attr.aspath);
                        bgp_static_withdraw_safi(bgp, p, afi, safi,
                                                 &bgp_static->prd);
+                       bgp_dest_unlock_node(dest);
                        return;
                }
 
@@ -10081,14 +10075,12 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
                        dest = parent_ri->net;
                        if (dest && dest->pdest) {
                                pdest = dest->pdest;
-                               prefix_rd2str(
-                                       (struct prefix_rd *)bgp_dest_get_prefix(
-                                               pdest),
-                                       buf1, sizeof(buf1));
                                if (is_pi_family_evpn(parent_ri)) {
                                        vty_out(vty,
-                                               "  Imported from %s:%pFX, VNI %s",
-                                               buf1,
+                                               "  Imported from %pRD:%pFX, VNI %s",
+                                               (struct prefix_rd *)
+                                                       bgp_dest_get_prefix(
+                                                               pdest),
                                                (struct prefix_evpn *)
                                                        bgp_dest_get_prefix(
                                                                dest),
@@ -10103,8 +10095,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
 
                                } else
                                        vty_out(vty,
-                                               "  Imported from %s:%pFX\n",
-                                               buf1,
+                                               "  Imported from %pRD:%pFX\n",
+                                               (struct prefix_rd *)
+                                                       bgp_dest_get_prefix(
+                                                               pdest),
                                                (struct prefix_evpn *)
                                                        bgp_dest_get_prefix(
                                                                dest));
@@ -10286,11 +10280,17 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
 
        /* Display the IGP cost or 'inaccessible' */
        if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
-               if (json_paths)
+               bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
+
+               if (json_paths) {
                        json_object_boolean_false_add(json_nexthop_global,
                                                      "accessible");
-               else
-                       vty_out(vty, " (inaccessible)");
+                       json_object_boolean_add(json_nexthop_global,
+                                               "importCheckEnabled", import);
+               } else {
+                       vty_out(vty, " (inaccessible%s)",
+                               import ? ", import-check enabled" : "");
+               }
        } else {
                if (path->extra && path->extra->igpmetric) {
                        if (json_paths)
@@ -11798,7 +11798,6 @@ static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
 {
        struct bgp_path_info *pi;
        int header = 1;
-       char rdbuf[RD_ADDRSTRLEN];
        json_object *json_header = NULL;
        json_object *json_paths = NULL;
        const struct prefix *p = bgp_dest_get_prefix(bgp_node);
@@ -11817,10 +11816,9 @@ static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
                if (json && !json_paths) {
                        /* Instantiate json_paths only if path is valid */
                        json_paths = json_object_new_array();
-                       if (pfx_rd) {
-                               prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
+                       if (pfx_rd)
                                json_header = json_object_new_object();
-                       else
+                       else
                                json_header = json;
                }
 
@@ -11846,7 +11844,8 @@ static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
                json_object_object_add(json_header, "paths", json_paths);
 
                if (pfx_rd)
-                       json_object_object_add(json, rdbuf, json_header);
+                       json_object_object_addf(json, json_header, "%pRD",
+                                               pfx_rd);
        }
 }
 
@@ -12197,8 +12196,10 @@ DEFUN (show_ip_bgp_large_community,
                return CMD_WARNING;
 
        if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
-               if (argv_find(argv, argc, "exact-match", &idx))
+               if (argv_find(argv, argc, "exact-match", &idx)) {
+                       argc--;
                        exact_match = 1;
+               }
                return bgp_show_lcommunity(vty, bgp, argc, argv,
                                        exact_match, afi, safi, uj);
        } else
@@ -15195,7 +15196,6 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
        const struct prefix_rd *prd;
        struct bgp_static *bgp_static;
        mpls_label_t label;
-       char rdbuf[RD_ADDRSTRLEN];
 
        /* Network configuration. */
        for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
@@ -15215,10 +15215,9 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
                                pdest);
 
                        /* "network" configuration display.  */
-                       prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
                        label = decode_label(&bgp_static->label);
 
-                       vty_out(vty, "  network %pFX rd %s", p, rdbuf);
+                       vty_out(vty, "  network %pFX rd %pRD", p, prd);
                        if (safi == SAFI_MPLS_VPN)
                                vty_out(vty, " label %u", label);
 
@@ -15245,7 +15244,6 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
        struct bgp_static *bgp_static;
        char buf[PREFIX_STRLEN * 2];
        char buf2[SU_ADDRSTRLEN];
-       char rdbuf[RD_ADDRSTRLEN];
        char esi_buf[ESI_STR_LEN];
 
        /* Network configuration. */
@@ -15273,7 +15271,6 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
                        prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
 
                        /* "network" configuration display.  */
-                       prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
                        if (p->u.prefix_evpn.route_type == 5) {
                                char local_buf[PREFIX_STRLEN];
                                uint8_t family = is_evpn_prefix_ipaddr_v4((
@@ -15296,9 +15293,8 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
                                          &bgp_static->gatewayIp.u.prefix, buf2,
                                          sizeof(buf2));
                        vty_out(vty,
-                               "  network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
-                               buf, rdbuf,
-                               p->u.prefix_evpn.prefix_addr.eth_tag,
+                               "  network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
+                               buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
                                decode_label(&bgp_static->label), esi_buf, buf2,
                                macrouter);
 
index b90c09c68b2175620a3f4ff386f54e8d2ee82263..cb7afd89677ec7b2ca21066e347bbdd573164c5d 100644 (file)
@@ -592,7 +592,7 @@ static int bgp_rpki_module_init(void)
 
        hook_register(bgp_rpki_prefix_status, rpki_validate_prefix);
        hook_register(frr_late_init, bgp_rpki_init);
-       hook_register(frr_early_fini, &bgp_rpki_fini);
+       hook_register(frr_early_fini, bgp_rpki_fini);
 
        return 0;
 }
@@ -1688,7 +1688,7 @@ DEFUN_YANG (no_match_rpki,
        const char *xpath =
                "./match-condition[condition='frr-bgp-route-map:rpki']";
 
-       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
        return nb_cli_apply_changes(vty, NULL);
 }
 
index 79fc7247f9a023ae529f8ed29e2db62438c6de51..89010b61bbb087501f3ba40dba7b85ddbdb8fb67 100644 (file)
@@ -298,7 +298,6 @@ static int bgp_srv6_locator_unset(struct bgp *bgp)
        struct srv6_locator_chunk *chunk, *tovpn_sid_locator;
        struct bgp_srv6_function *func;
        struct bgp *bgp_vrf;
-       struct in6_addr *tovpn_sid;
 
        /* release chunk notification via ZAPI */
        ret = bgp_zebra_srv6_manager_release_locator_chunk(
@@ -324,16 +323,12 @@ static int bgp_srv6_locator_unset(struct bgp *bgp)
                        continue;
 
                /* refresh vpnv4 tovpn_sid */
-               tovpn_sid = bgp_vrf->vpn_policy[AFI_IP].tovpn_sid;
-               if (tovpn_sid)
-                       XFREE(MTYPE_BGP_SRV6_SID,
-                             bgp_vrf->vpn_policy[AFI_IP].tovpn_sid);
+               XFREE(MTYPE_BGP_SRV6_SID,
+                     bgp_vrf->vpn_policy[AFI_IP].tovpn_sid);
 
                /* refresh vpnv6 tovpn_sid */
-               tovpn_sid = bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid;
-               if (tovpn_sid)
-                       XFREE(MTYPE_BGP_SRV6_SID,
-                             bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid);
+               XFREE(MTYPE_BGP_SRV6_SID,
+                     bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid);
        }
 
        /* update vpn bgp processes */
@@ -881,9 +876,6 @@ int bgp_vty_return(struct vty *vty, enum bgp_create_error_code ret)
        case BGP_ERR_REMOVE_PRIVATE_AS:
                str = "remove-private-AS cannot be configured for IBGP peers";
                break;
-       case BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP:
-               str = "Local-AS allowed only for EBGP peers";
-               break;
        case BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS:
                str = "Cannot have local-as same as BGP AS number";
                break;
@@ -944,9 +936,6 @@ int bgp_vty_return(struct vty *vty, enum bgp_create_error_code ret)
        case BGP_ERR_AF_UNCONFIGURED:
                str = "AFI/SAFI specified is not currently configured.";
                break;
-       case BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS:
-               str = "AS specified for local as is the same as the remote as and this is not allowed.";
-               break;
        case BGP_ERR_INVALID_AS:
                str = "Confederation AS specified is the same AS as our AS.";
                break;
@@ -2362,6 +2351,15 @@ void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp)
                vty_out(vty, " coalesce-time %u\n", bgp->coalesce_time);
 }
 
+/* BGP TCP keepalive */
+static void bgp_config_tcp_keepalive(struct vty *vty, struct bgp *bgp)
+{
+       if (bgp->tcp_keepalive_idle) {
+               vty_out(vty, " bgp tcp-keepalive %u %u %u\n",
+                       bgp->tcp_keepalive_idle, bgp->tcp_keepalive_intvl,
+                       bgp->tcp_keepalive_probes);
+       }
+}
 
 DEFUN (bgp_coalesce_time,
        bgp_coalesce_time_cmd,
@@ -2585,6 +2583,38 @@ DEFUN(no_bgp_minimum_holdtime, no_bgp_minimum_holdtime_cmd,
        return CMD_SUCCESS;
 }
 
+DEFPY(bgp_tcp_keepalive, bgp_tcp_keepalive_cmd,
+      "bgp tcp-keepalive (1-65535)$idle (1-65535)$intvl (1-30)$probes",
+      BGP_STR
+      "TCP keepalive parameters\n"
+      "TCP keepalive idle time (seconds)\n"
+      "TCP keepalive interval (seconds)\n"
+      "TCP keepalive maximum probes\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+       bgp_tcp_keepalive_set(bgp, (uint16_t)idle, (uint16_t)intvl,
+                             (uint16_t)probes);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(no_bgp_tcp_keepalive, no_bgp_tcp_keepalive_cmd,
+      "no bgp tcp-keepalive [(1-65535) (1-65535) (1-30)]",
+      NO_STR
+      BGP_STR
+      "TCP keepalive parameters\n"
+      "TCP keepalive idle time (seconds)\n"
+      "TCP keepalive interval (seconds)\n"
+      "TCP keepalive maximum probes\n")
+{
+       VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+       bgp_tcp_keepalive_unset(bgp);
+
+       return CMD_SUCCESS;
+}
+
 DEFUN (bgp_client_to_client_reflection,
        bgp_client_to_client_reflection_cmd,
        "bgp client-to-client reflection",
@@ -9645,11 +9675,7 @@ DEFPY (show_bgp_srv6,
        struct listnode *node;
        struct srv6_locator_chunk *chunk;
        struct bgp_srv6_function *func;
-       struct in6_addr *tovpn4_sid;
-       struct in6_addr *tovpn6_sid;
        char buf[256];
-       char buf_tovpn4_sid[256];
-       char buf_tovpn6_sid[256];
 
        bgp = bgp_get_default();
        if (!bgp)
@@ -9672,19 +9698,10 @@ DEFPY (show_bgp_srv6,
                vty_out(vty, "- name: %s\n",
                        bgp->name ? bgp->name : "default");
 
-               tovpn4_sid = bgp->vpn_policy[AFI_IP].tovpn_sid;
-               tovpn6_sid = bgp->vpn_policy[AFI_IP6].tovpn_sid;
-               if (tovpn4_sid)
-                       inet_ntop(AF_INET6, tovpn4_sid, buf_tovpn4_sid,
-                                 sizeof(buf_tovpn4_sid));
-               if (tovpn6_sid)
-                       inet_ntop(AF_INET6, tovpn6_sid, buf_tovpn6_sid,
-                                 sizeof(buf_tovpn6_sid));
-
-               vty_out(vty, "  vpn_policy[AFI_IP].tovpn_sid: %s\n",
-                       tovpn4_sid ? buf_tovpn4_sid : "none");
-               vty_out(vty, "  vpn_policy[AFI_IP6].tovpn_sid: %s\n",
-                       tovpn6_sid ? buf_tovpn6_sid : "none");
+               vty_out(vty, "  vpn_policy[AFI_IP].tovpn_sid: %pI6\n",
+                       bgp->vpn_policy[AFI_IP].tovpn_sid);
+               vty_out(vty, "  vpn_policy[AFI_IP6].tovpn_sid: %pI6\n",
+                       bgp->vpn_policy[AFI_IP6].tovpn_sid);
        }
 
        return CMD_SUCCESS;
@@ -14743,7 +14760,7 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
 
 
 /* "show [ip] bgp neighbors graceful-restart" commands.  */
-DEFUN (show_ip_bgp_neighbors_gracrful_restart,
+DEFUN (show_ip_bgp_neighbors_graceful_restart,
        show_ip_bgp_neighbors_graceful_restart_cmd,
        "show bgp [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] graceful-restart [json]",
        SHOW_STR
@@ -15001,7 +15018,6 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
        struct bgp *bgp;
        struct listnode *node;
        char *vname;
-       char buf1[INET6_ADDRSTRLEN];
        char *ecom_str;
        enum vpn_policy_direction dir;
 
@@ -15066,9 +15082,9 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
                                                json_object_new_string(vname));
                        json_object_object_add(json, "exportToVrfs",
                                               json_export_vrfs);
-                       json_object_string_add(json, "routeDistinguisher",
-                                  prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd,
-                                                buf1, RD_ADDRSTRLEN));
+                       json_object_string_addf(json, "routeDistinguisher",
+                                               "%pRD",
+                                               &bgp->vpn_policy[afi].tovpn_rd);
 
                        dir = BGP_VPN_POLICY_DIR_TOVPN;
                        if (bgp->vpn_policy[afi].rtlist[dir]) {
@@ -15137,9 +15153,8 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
                                                node, vname))
                                vty_out(vty, "  %s\n", vname);
 
-                       vty_out(vty, "RD: %s\n",
-                               prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd,
-                                             buf1, RD_ADDRSTRLEN));
+                       vty_out(vty, "RD: %pRD\n",
+                               &bgp->vpn_policy[afi].tovpn_rd);
 
                        dir = BGP_VPN_POLICY_DIR_TOVPN;
                        if (bgp->vpn_policy[afi].rtlist[dir]) {
@@ -16629,13 +16644,10 @@ static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
                        tovpn_sid_index);
        }
 
-       if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
-                      BGP_VPN_POLICY_TOVPN_RD_SET)) {
-               char buf[RD_ADDRSTRLEN];
-               vty_out(vty, "%*srd vpn export %s\n", indent, "",
-                       prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
-                                     sizeof(buf)));
-       }
+       if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET))
+               vty_out(vty, "%*srd vpn export %pRD\n", indent, "",
+                       &bgp->vpn_policy[afi].tovpn_rd);
+
        if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
                       BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
 
@@ -17730,6 +17742,9 @@ int bgp_config_write(struct vty *vty)
                        vty_out(vty,
                                " bgp graceful-restart preserve-fw-state\n");
 
+               /* BGP TCP keepalive */
+               bgp_config_tcp_keepalive(vty, bgp);
+
                /* Stale timer for RIB */
                if (bgp->rib_stale_time != BGP_DEFAULT_RIB_STALE_TIME)
                        vty_out(vty,
@@ -19609,6 +19624,10 @@ void bgp_vty_init(void)
        install_element(BGP_NODE, &neighbor_ttl_security_cmd);
        install_element(BGP_NODE, &no_neighbor_ttl_security_cmd);
 
+       /* "bgp tcp-keepalive" commands */
+       install_element(BGP_NODE, &bgp_tcp_keepalive_cmd);
+       install_element(BGP_NODE, &no_bgp_tcp_keepalive_cmd);
+
        /* "show [ip] bgp memory" commands. */
        install_element(VIEW_NODE, &show_bgp_memory_cmd);
 
index 68dc3fe2986cff9fc3080f2770efd46be75afa8e..209fe1ace41ade57068a154bca52671ecd2fc286 100644 (file)
@@ -307,6 +307,11 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS)
 {
        struct connected *ifc;
        struct bgp *bgp;
+       struct peer *peer;
+       struct prefix *addr;
+       struct listnode *node, *nnode;
+       afi_t afi;
+       safi_t safi;
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
 
@@ -332,6 +337,48 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS)
                if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6)
                    && !list_isempty(ifc->ifp->nbr_connected))
                        bgp_start_interface_nbrs(bgp, ifc->ifp);
+               else {
+                       addr = ifc->address;
+
+                       for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+                               if (addr->family == AF_INET)
+                                       continue;
+
+                               /*
+                                * If the Peer's interface name matches the
+                                * interface name for which BGP received the
+                                * update and if the received interface address
+                                * is a globalV6 and if the peer is currently
+                                * using a v4-mapped-v6 addr or a link local
+                                * address, then copy the Rxed global v6 addr
+                                * into peer's v6_global and send updates out
+                                * with new nexthop addr.
+                                */
+                               if ((peer->conf_if &&
+                                    (strcmp(peer->conf_if, ifc->ifp->name) ==
+                                     0)) &&
+                                   !IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6) &&
+                                   ((IS_MAPPED_IPV6(
+                                            &peer->nexthop.v6_global)) ||
+                                    IN6_IS_ADDR_LINKLOCAL(
+                                            &peer->nexthop.v6_global))) {
+
+                                       if (bgp_debug_zebra(ifc->address)) {
+                                               zlog_debug(
+                                                       "Update peer %pBP's current intf addr %pI6 and send updates",
+                                                       peer,
+                                                       &peer->nexthop
+                                                                .v6_global);
+                                       }
+                                       memcpy(&peer->nexthop.v6_global,
+                                              &addr->u.prefix6,
+                                              IPV6_MAX_BYTELEN);
+                                       FOREACH_AFI_SAFI (afi, safi)
+                                               bgp_announce_route(peer, afi,
+                                                                  safi, true);
+                               }
+                       }
+               }
        }
 
        return 0;
index 4c151b2d374398862e00ee88758dabfe40b943fd..1bcd714407985b03616ae00e20e9ece57a793ef5 100644 (file)
@@ -551,6 +551,21 @@ void bgp_timers_unset(struct bgp *bgp)
        bgp->default_delayopen = BGP_DEFAULT_DELAYOPEN;
 }
 
+void bgp_tcp_keepalive_set(struct bgp *bgp, uint16_t keepalive_idle,
+                          uint16_t keepalive_intvl, uint16_t keepalive_probes)
+{
+       bgp->tcp_keepalive_idle = keepalive_idle;
+       bgp->tcp_keepalive_intvl = keepalive_intvl;
+       bgp->tcp_keepalive_probes = keepalive_probes;
+}
+
+void bgp_tcp_keepalive_unset(struct bgp *bgp)
+{
+       bgp->tcp_keepalive_idle = 0;
+       bgp->tcp_keepalive_intvl = 0;
+       bgp->tcp_keepalive_probes = 0;
+}
+
 /* BGP confederation configuration.  */
 void bgp_confederation_id_set(struct bgp *bgp, as_t as)
 {
@@ -997,9 +1012,15 @@ void peer_af_flag_inherit(struct peer *peer, afi_t afi, safi_t safi,
 static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
 {
        struct bgp *bgp;
+       as_t local_as;
 
        bgp = peer->bgp;
 
+       if (peer->change_local_as)
+               local_as = peer->change_local_as;
+       else
+               local_as = peer->local_as;
+
        /* Peer-group */
        if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
                if (peer->as_type == AS_INTERNAL)
@@ -1010,8 +1031,8 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
 
                else if (peer->as_type == AS_SPECIFIED && peer->as) {
                        assert(bgp);
-                       return (bgp->as == peer->as ? BGP_PEER_IBGP
-                                                   : BGP_PEER_EBGP);
+                       return (local_as == peer->as ? BGP_PEER_IBGP
+                                                    : BGP_PEER_EBGP);
                }
 
                else {
@@ -1028,17 +1049,17 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
 
        /* Normal peer */
        if (bgp && CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
-               if (peer->local_as == 0)
+               if (local_as == 0)
                        return BGP_PEER_INTERNAL;
 
-               if (peer->local_as == peer->as) {
+               if (local_as == peer->as) {
                        if (bgp->as == bgp->confed_id) {
-                               if (peer->local_as == bgp->as)
+                               if (local_as == bgp->as)
                                        return BGP_PEER_IBGP;
                                else
                                        return BGP_PEER_EBGP;
                        } else {
-                               if (peer->local_as == bgp->confed_id)
+                               if (local_as == bgp->confed_id)
                                        return BGP_PEER_EBGP;
                                else
                                        return BGP_PEER_IBGP;
@@ -1056,8 +1077,7 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
                            && (peer->group->conf->as_type != AS_UNSPECIFIED)) {
                                if (peer->group->conf->as_type
                                    == AS_SPECIFIED) {
-                                       if (peer->local_as
-                                           == peer->group->conf->as)
+                                       if (local_as == peer->group->conf->as)
                                                return BGP_PEER_IBGP;
                                        else
                                                return BGP_PEER_EBGP;
@@ -1073,9 +1093,8 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
                        return (peer->as_type == AS_INTERNAL ? BGP_PEER_IBGP
                                                             : BGP_PEER_EBGP);
 
-               return (peer->local_as == 0
-                               ? BGP_PEER_INTERNAL
-                               : peer->local_as == peer->as ? BGP_PEER_IBGP
+               return (local_as == 0 ? BGP_PEER_INTERNAL
+                                     : local_as == peer->as ? BGP_PEER_IBGP
                                                             : BGP_PEER_EBGP);
        }
 }
@@ -1885,14 +1904,6 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
                UNSET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
                           PEER_FLAG_REFLECTOR_CLIENT);
        }
-
-       /* local-as reset */
-       if (newtype != BGP_PEER_EBGP) {
-               peer->change_local_as = 0;
-               peer_flag_unset(peer, PEER_FLAG_LOCAL_AS);
-               peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
-               peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
-       }
 }
 
 /* If peer does not exist, create new one.  If peer already exists,
@@ -2374,8 +2385,10 @@ void peer_nsf_stop(struct peer *peer)
        UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
        UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
 
-       FOREACH_AFI_SAFI_NSF (afi, safi)
+       FOREACH_AFI_SAFI_NSF (afi, safi) {
                peer->nsf[afi][safi] = 0;
+               THREAD_OFF(peer->t_llgr_stale[afi][safi]);
+       }
 
        if (peer->t_gr_restart) {
                THREAD_OFF(peer->t_gr_restart);
@@ -2758,6 +2771,21 @@ void peer_notify_unconfig(struct peer *peer)
                                BGP_NOTIFY_CEASE_PEER_UNCONFIG);
 }
 
+static void peer_notify_shutdown(struct peer *peer)
+{
+       if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
+               if (bgp_debug_neighbor_events(peer))
+                       zlog_debug(
+                               "%pBP configured Graceful-Restart, skipping shutdown notification",
+                               peer);
+               return;
+       }
+
+       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
+               bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+                               BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
+}
+
 void peer_group_notify_unconfig(struct peer_group *group)
 {
        struct peer *peer, *other;
@@ -3016,17 +3044,6 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
                        /* ebgp-multihop reset */
                        if (gtype == BGP_PEER_IBGP)
                                group->conf->ttl = MAXTTL;
-
-                       /* local-as reset */
-                       if (gtype != BGP_PEER_EBGP) {
-                               group->conf->change_local_as = 0;
-                               peer_flag_unset(group->conf,
-                                               PEER_FLAG_LOCAL_AS);
-                               peer_flag_unset(group->conf,
-                                               PEER_FLAG_LOCAL_AS_NO_PREPEND);
-                               peer_flag_unset(group->conf,
-                                               PEER_FLAG_LOCAL_AS_REPLACE_AS);
-                       }
                }
 
                SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
@@ -3180,6 +3197,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
        bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
        bgp->default_subgroup_pkt_queue_max =
                BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
+       bgp_tcp_keepalive_unset(bgp);
        bgp_timers_unset(bgp);
        bgp->default_min_holdtime = 0;
        bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
@@ -3615,6 +3633,7 @@ int bgp_delete(struct bgp *bgp)
 
        hook_call(bgp_inst_delete, bgp);
 
+       THREAD_OFF(bgp->t_condition_check);
        THREAD_OFF(bgp->t_startup);
        THREAD_OFF(bgp->t_maxmed_onstartup);
        THREAD_OFF(bgp->t_update_delay);
@@ -3630,7 +3649,12 @@ int bgp_delete(struct bgp *bgp)
                gr_info = &bgp->gr_info[afi][safi];
                if (!gr_info)
                        continue;
+               t = gr_info->t_select_deferral;
+               if (t) {
+                       void *info = THREAD_ARG(t);
 
+                       XFREE(MTYPE_TMP, info);
+               }
                THREAD_OFF(gr_info->t_select_deferral);
 
                t = gr_info->t_route_select;
@@ -3668,11 +3692,8 @@ int bgp_delete(struct bgp *bgp)
        }
 
        /* Inform peers we're going down. */
-       for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
-               if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
-                       bgp_notify_send(peer, BGP_NOTIFY_CEASE,
-                                       BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
-       }
+       for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer))
+               peer_notify_shutdown(peer);
 
        /* Delete static routes (networks). */
        bgp_static_delete(bgp);
@@ -3713,6 +3734,17 @@ int bgp_delete(struct bgp *bgp)
                bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
        }
 
+       /* Free any memory allocated to holding routemap references */
+       for (afi = 0; afi < AFI_MAX; ++afi) {
+               for (enum vpn_policy_direction dir = 0;
+                    dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
+                       if (bgp->vpn_policy[afi].rmap_name[dir])
+                               XFREE(MTYPE_ROUTE_MAP_NAME,
+                                     bgp->vpn_policy[afi].rmap_name[dir]);
+                       bgp->vpn_policy[afi].rmap[dir] = NULL;
+               }
+       }
+
        /* Deregister from Zebra, if needed */
        if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
                if (BGP_DEBUG(zebra, ZEBRA))
@@ -5457,8 +5489,8 @@ void peer_tcp_mss_unset(struct peer *peer)
  * being used by a peer has changed (AF specific). Automatically
  * initiates inbound or outbound processing as needed.
  */
-static void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
-                                 int outbound)
+void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
+                          int outbound)
 {
        if (outbound) {
                update_group_adjust_peer(peer_af_find(peer, afi, safi));
@@ -6090,17 +6122,10 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
        struct bgp *bgp = peer->bgp;
        struct peer *member;
        struct listnode *node, *nnode;
-       enum bgp_peer_sort ptype = peer_sort(peer);
-
-       if (ptype != BGP_PEER_EBGP && ptype != BGP_PEER_INTERNAL)
-               return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
 
        if (bgp->as == as)
                return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
 
-       if (peer->as == as)
-               return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
-
        /* Save previous flag states. */
        old_no_prepend =
                !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
@@ -6116,6 +6141,7 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
            && old_replace_as == replace_as)
                return 0;
        peer->change_local_as = as;
+       (void)peer_sort(peer);
 
        /* Check if handling a regular peer. */
        if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
@@ -7200,166 +7226,6 @@ int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
        return 0;
 }
 
-static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi,
-                                            safi_t safi, const char *amap_name,
-                                            struct route_map *amap,
-                                            const char *cmap_name,
-                                            struct route_map *cmap,
-                                            bool condition, bool set)
-{
-       struct bgp_filter *filter;
-       bool filter_exists = false;
-
-       filter = &peer->filter[afi][safi];
-
-       /* advertise-map is already configured. */
-       if (filter->advmap.aname) {
-               filter_exists = true;
-               XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname);
-               XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname);
-       }
-
-       route_map_counter_decrement(filter->advmap.amap);
-
-       /* Removed advertise-map configuration */
-       if (!set) {
-               memset(&filter->advmap, 0, sizeof(filter->advmap));
-
-               /* decrement condition_filter_count delete timer if
-                * this is the last advertise-map to be removed.
-                */
-               if (filter_exists)
-                       bgp_conditional_adv_disable(peer, afi, safi);
-
-               return;
-       }
-
-       /* Update filter data with newly configured values. */
-       filter->advmap.aname = XSTRDUP(MTYPE_BGP_FILTER_NAME, amap_name);
-       filter->advmap.cname = XSTRDUP(MTYPE_BGP_FILTER_NAME, cmap_name);
-       filter->advmap.amap = amap;
-       filter->advmap.cmap = cmap;
-       filter->advmap.condition = condition;
-       route_map_counter_increment(filter->advmap.amap);
-       peer->advmap_config_change[afi][safi] = true;
-
-       /* Increment condition_filter_count and/or create timer. */
-       if (!filter_exists) {
-               filter->advmap.update_type = UPDATE_TYPE_ADVERTISE;
-               bgp_conditional_adv_enable(peer, afi, safi);
-       }
-
-       /* Process peer route updates. */
-       peer_on_policy_change(peer, afi, safi, 1);
-}
-
-/* Set advertise-map to the peer. */
-int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
-                          const char *advertise_name,
-                          struct route_map *advertise_map,
-                          const char *condition_name,
-                          struct route_map *condition_map, bool condition)
-{
-       struct peer *member;
-       struct listnode *node, *nnode;
-
-       /* Set configuration on peer. */
-       peer_advertise_map_filter_update(peer, afi, safi, advertise_name,
-                                        advertise_map, condition_name,
-                                        condition_map, condition, true);
-
-       /* Check if handling a regular peer & Skip peer-group mechanics. */
-       if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
-               /* Set override-flag and process peer route updates. */
-               SET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
-                        PEER_FT_ADVERTISE_MAP);
-               return 0;
-       }
-
-       /*
-        * Set configuration on all peer-group members, unless they are
-        * explicitly overriding peer-group configuration.
-        */
-       for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
-               /* Skip peers with overridden configuration. */
-               if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
-                              PEER_FT_ADVERTISE_MAP))
-                       continue;
-
-               /* Set configuration on peer-group member. */
-               peer_advertise_map_filter_update(
-                       member, afi, safi, advertise_name, advertise_map,
-                       condition_name, condition_map, condition, true);
-       }
-
-       return 0;
-}
-
-/* Unset advertise-map from the peer. */
-int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
-                            const char *advertise_name,
-                            struct route_map *advertise_map,
-                            const char *condition_name,
-                            struct route_map *condition_map, bool condition)
-{
-       struct peer *member;
-       struct listnode *node, *nnode;
-
-       /* advertise-map is not configured */
-       if (!peer->filter[afi][safi].advmap.aname)
-               return 0;
-
-       /* Unset override-flag unconditionally. */
-       UNSET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
-                  PEER_FT_ADVERTISE_MAP);
-
-       /* Inherit configuration from peer-group if peer is member. */
-       if (peer_group_active(peer)) {
-               PEER_STR_ATTR_INHERIT(peer, peer->group,
-                                     filter[afi][safi].advmap.aname,
-                                     MTYPE_BGP_FILTER_NAME);
-               PEER_ATTR_INHERIT(peer, peer->group,
-                                 filter[afi][safi].advmap.amap);
-       } else
-               peer_advertise_map_filter_update(
-                       peer, afi, safi, advertise_name, advertise_map,
-                       condition_name, condition_map, condition, false);
-
-       /* Check if handling a regular peer and skip peer-group mechanics. */
-       if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
-               /* Process peer route updates. */
-               if (BGP_DEBUG(update, UPDATE_OUT))
-                       zlog_debug("%s: Send normal update to %s for %s",
-                                  __func__, peer->host,
-                                  get_afi_safi_str(afi, safi, false));
-
-               return 0;
-       }
-
-       /*
-        * Remove configuration on all peer-group members, unless they are
-        * explicitly overriding peer-group configuration.
-        */
-       for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
-               /* Skip peers with overridden configuration. */
-               if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
-                              PEER_FT_ADVERTISE_MAP))
-                       continue;
-               /* Remove configuration on peer-group member. */
-               peer_advertise_map_filter_update(
-                       member, afi, safi, advertise_name, advertise_map,
-                       condition_name, condition_map, condition, false);
-
-               /* Process peer route updates. */
-               if (BGP_DEBUG(update, UPDATE_OUT))
-                       zlog_debug("%s: Send normal update to %s for %s ",
-                                  __func__, member->host,
-                                  get_afi_safi_str(afi, safi, false));
-       }
-
-       return 0;
-}
-
 static bool peer_maximum_prefix_clear_overflow(struct peer *peer)
 {
        if (!CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
@@ -8229,11 +8095,18 @@ void bgp_terminate(void)
        /* reverse bgp_master_init */
        for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
                bgp_close_vrf_socket(bgp);
-               for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
-                       if (peer_established(peer) || peer->status == OpenSent
-                           || peer->status == OpenConfirm)
+               for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+                       if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
+                               if (bgp_debug_neighbor_events(peer))
+                                       zlog_debug(
+                                               "%pBP configured Graceful-Restart, skipping unconfig notification",
+                                               peer);
+                               continue;
+                       }
+                       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
                                bgp_notify_send(peer, BGP_NOTIFY_CEASE,
                                                BGP_NOTIFY_CEASE_PEER_UNCONFIG);
+               }
        }
 
        if (bm->listen_sockets)
diff --git a/bgpd/bgpd.conf.sample2 b/bgpd/bgpd.conf.sample2
deleted file mode 100644 (file)
index d376ad2..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-!
-! Zebra configuration saved from vty
-!   2002/07/01 03:16:33
-!
-hostname bgpd
-password zebra
-log file bgpd.log
-log stdout
-!
-router bgp 7675
- no bgp default ipv4-unicast
- neighbor 3ffe:506:1000::2 remote-as 7675
- neighbor fe80::200:c0ff:fe30:9be3 remote-as 9377
- neighbor fe80::200:c0ff:fe30:9be3 interface sit3
- neighbor fe80::210:5aff:fe6b:3cee remote-as 7675
- neighbor fe80::210:5aff:fe6b:3cee interface eth0
- neighbor fe80::290:27ff:fe51:84c7 remote-as 4691
- neighbor fe80::290:27ff:fe51:84c7 description DTI 
- neighbor fe80::290:27ff:fe51:84c7 interface sit7
- neighbor fe80::2a0:c9ff:fec8:82ec remote-as 7530
- neighbor fe80::2a0:c9ff:fec8:82ec description IRI 
- neighbor fe80::2a0:c9ff:fec8:82ec interface sit8
- neighbor fe80::2e0:18ff:fe98:2725 remote-as 2500
- neighbor fe80::2e0:18ff:fe98:2725 description WIDE 
- neighbor fe80::2e0:18ff:fe98:2725 interface sit5
- neighbor fe80::2e0:18ff:fea8:bf5 remote-as 65000
- neighbor fe80::2e0:18ff:fea8:bf5 interface sit6
-!
- address-family ipv6
- network 3ffe:506::/33
- network 3ffe:1800:e800::/40
- aggregate-address 3ffe:506::/32
- redistribute connected
- neighbor 3ffe:506:1000::2 activate
- neighbor fe80::200:c0ff:fe30:9be3 activate
- neighbor fe80::200:c0ff:fe30:9be3 route-map set-nexthop out
- neighbor fe80::210:5aff:fe6b:3cee activate
- neighbor fe80::290:27ff:fe51:84c7 activate
- neighbor fe80::290:27ff:fe51:84c7 route-map set-nexthop out
- neighbor fe80::2a0:c9ff:fec8:82ec activate
- neighbor fe80::2a0:c9ff:fec8:82ec route-map set-nexthop out
- neighbor fe80::2e0:18ff:fe98:2725 activate
- neighbor fe80::2e0:18ff:fe98:2725 distribute-list nla1 out
- neighbor fe80::2e0:18ff:fe98:2725 route-map set-nexthop out
- neighbor fe80::2e0:18ff:fea8:bf5 activate
- neighbor fe80::2e0:18ff:fea8:bf5 route-map set-nexthop out
- exit-address-family
-!
-ipv6 access-list all permit any
-ipv6 access-list nla1 deny 3ffe:506::/33
-ipv6 access-list nla1 permit 3ffe:506::/32
-ipv6 access-list nla1 deny any
-ipv6 access-list ntt-nla1 permit 3ffe:1800:0:ffff::c/127
-ipv6 access-list ntt-nla1 deny 3ffe:1800:e800::/41
-ipv6 access-list ntt-nla1 permit 3ffe:1800:e800::/40
-ipv6 access-list ntt-nla1 deny any
-!
-ipv6 prefix-list 6bone-filter seq 5 permit 3ffe::/17 ge 24 le 24
-ipv6 prefix-list 6bone-filter seq 10 permit 3ffe:8000::/17 ge 28 le 28
-ipv6 prefix-list 6bone-filter seq 12 deny 3ffe::/16
-ipv6 prefix-list 6bone-filter seq 15 permit 2000::/3 ge 16 le 16
-ipv6 prefix-list 6bone-filter seq 20 permit 2001::/16 ge 35 le 35
-!
-route-map set-nexthop permit 10
- match ipv6 address all
- set ipv6 next-hop global 3ffe:506::1
- set ipv6 next-hop local fe80::cbb5:591a
- set ip next-hop 203.181.89.26
- set community 7675:0
-!
-route-map set-link-local permit 10
- match ipv6 address all
- set ipv6 next-hop local fe80::cbb5:591a
- set ipv6 next-hop global 3ffe:1800:0:ffff::d
-!
-line vty
-!
index 9c54676899fbd2b66b9febcc93cc5185c1f9dd02..7fc9c5c1ce619370cccf3f34719927a0efbb2b52 100644 (file)
@@ -132,6 +132,7 @@ struct bgp_master {
 
        /* Various BGP global configuration.  */
        uint8_t options;
+
 #define BGP_OPT_NO_FIB                   (1 << 0)
 #define BGP_OPT_NO_LISTEN                (1 << 1)
 #define BGP_OPT_NO_ZEBRA                 (1 << 2)
@@ -768,6 +769,10 @@ struct bgp {
        char srv6_locator_name[SRV6_LOCNAME_SIZE];
        struct list *srv6_locator_chunks;
        struct list *srv6_functions;
+       /* TCP keepalive parameters for BGP connection */
+       uint16_t tcp_keepalive_idle;
+       uint16_t tcp_keepalive_intvl;
+       uint16_t tcp_keepalive_probes;
 
        struct timeval ebgprequirespolicywarning;
 #define FIFTEENMINUTE2USEC (int64_t)15 * 60 * 1000000
@@ -1456,6 +1461,7 @@ struct peer {
 #define PEER_STATUS_EORR_RECEIVED (1U << 10) /* EoRR received from peer */
 /* LLGR aware peer */
 #define PEER_STATUS_LLGR_WAIT (1U << 11)
+#define PEER_STATUS_REFRESH_PENDING (1U << 12) /* refresh request from peer */
 
        /* Configured timer values. */
        _Atomic uint32_t holdtime;
@@ -2003,13 +2009,11 @@ enum bgp_create_error_code {
        BGP_ERR_AF_UNCONFIGURED = -15,
        BGP_ERR_SOFT_RECONFIG_UNCONFIGURED = -16,
        BGP_ERR_INSTANCE_MISMATCH = -17,
-       BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP = -18,
        BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS = -19,
        BGP_ERR_TCPSIG_FAILED = -20,
        BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK = -21,
        BGP_ERR_NO_IBGP_WITH_TTLHACK = -22,
        BGP_ERR_NO_INTERFACE_CONFIG = -23,
-       BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS = -24,
        BGP_ERR_AS_OVERRIDE = -25,
        BGP_ERR_INVALID_DYNAMIC_NEIGHBORS_LIMIT = -26,
        BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_EXISTS = -27,
@@ -2214,6 +2218,9 @@ extern int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
                                      const char *rmap,
                                      struct route_map *route_map);
 extern int peer_default_originate_unset(struct peer *, afi_t, safi_t);
+extern void bgp_tcp_keepalive_set(struct bgp *bgp, uint16_t idle,
+                                 uint16_t interval, uint16_t probes);
+extern void bgp_tcp_keepalive_unset(struct bgp *bgp);
 
 extern void peer_port_set(struct peer *, uint16_t);
 extern void peer_port_unset(struct peer *);
@@ -2575,7 +2582,8 @@ void peer_tcp_mss_unset(struct peer *peer);
 
 extern void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi,
                                               safi_t safi);
-
+extern void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
+                                 int outbound);
 #ifdef _FRR_ATTRIBUTE_PRINTFRR
 /* clang-format off */
 #pragma FRR printfrr_ext "%pBP" (struct peer *)
index 831f92996ad4eedc4e0b7c9cf0b1aea3c381821c..eae9859ba188caa2d1f4560d7c5fd099fe863097 100644 (file)
@@ -3913,8 +3913,6 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
                        }
 
                        if (rfg->rd.prefixlen) {
-                               char buf[RD_ADDRSTRLEN];
-
                                if (AF_UNIX == rfg->rd.family) {
 
                                        uint16_t value = 0;
@@ -3927,9 +3925,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
                                                value);
 
                                } else
-                                       vty_out(vty, "  rd %s\n",
-                                               prefix_rd2str(&rfg->rd, buf,
-                                                             sizeof(buf)));
+                                       vty_out(vty, "  rd %pRD\n", &rfg->rd);
                        }
 
                        if (rfg->rt_import_list && rfg->rt_export_list
@@ -4137,8 +4133,6 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
                        vty_out(vty, " vnc defaults\n");
 
                        if (hc->default_rd.prefixlen) {
-                               char buf[RD_ADDRSTRLEN];
-
                                if (AF_UNIX == hc->default_rd.family) {
                                        uint16_t value = 0;
 
@@ -4151,10 +4145,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
                                                value);
 
                                } else
-                                       vty_out(vty, "  rd %s\n",
-                                               prefix_rd2str(&hc->default_rd,
-                                                             buf,
-                                                             sizeof(buf)));
+                                       vty_out(vty, "  rd %pRD\n",
+                                               &hc->default_rd);
                        }
                        if (hc->default_response_lifetime
                            != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT) {
@@ -4219,8 +4211,6 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
 
 
                                if (rfg->rd.prefixlen) {
-                                       char buf[RD_ADDRSTRLEN];
-
                                        if (AF_UNIX == rfg->rd.family) {
 
                                                uint16_t value = 0;
@@ -4235,10 +4225,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
                                                        value);
 
                                        } else
-                                               vty_out(vty, "  rd %s\n",
-                                                       prefix_rd2str(
-                                                               &rfg->rd, buf,
-                                                               sizeof(buf)));
+                                               vty_out(vty, "  rd %pRD\n",
+                                                       &rfg->rd);
                                }
                                if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) {
                                        vty_out(vty, "  response-lifetime ");
index a34c10d84280c80ff733b6eacae9ce932a0e4611..ed0714ce2d929ff41677a2cb1d036befdd43da87 100644 (file)
@@ -362,7 +362,6 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
        afi_t afi; /* of the VN address */
        struct bgp_dest *bn;
        struct bgp_path_info *bpi;
-       char buf2[RD_ADDRSTRLEN];
        struct prefix_rd prd0;
 
        afi = family2afi(p->family);
@@ -377,9 +376,9 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
        bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
 
        vnc_zlog_debug_verbose(
-               "%s: peer=%p, prefix=%pFX, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p",
-               __func__, peer, p, prefix_rd2str(prd, buf2, sizeof(buf2)), afi,
-               safi, bn, (bn ? bgp_dest_get_bgp_path_info(bn) : NULL));
+               "%s: peer=%p, prefix=%pFX, prd=%pRD afi=%d, safi=%d bn=%p, bn->info=%p",
+               __func__, peer, p, prd, afi, safi, bn,
+               (bn ? bgp_dest_get_bgp_path_info(bn) : NULL));
 
        for (bpi = (bn ? bgp_dest_get_bgp_path_info(bn) : NULL); bpi;
             bpi = bpi->next) {
@@ -577,7 +576,6 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
 
        struct bgp_attr_encap_subtlv *encaptlv;
        char buf[PREFIX_STRLEN];
-       char buf2[RD_ADDRSTRLEN];
 
        struct rfapi_nexthop *lnh = NULL; /* local nexthop */
        struct rfapi_vn_option *vo;
@@ -616,8 +614,6 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
        else
                label_val = MPLS_LABEL_IMPLICIT_NULL;
 
-       prefix_rd2str(prd, buf2, sizeof(buf2));
-
        afi = family2afi(p->family);
        assert(afi == AFI_IP || afi == AFI_IP6);
 
@@ -1070,8 +1066,8 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
        bgp_process(bgp, bn, afi, safi);
 
        vnc_zlog_debug_any(
-               "%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%s)",
-               __func__, safi2str(safi), buf, bn, buf2);
+               "%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%pRD)",
+               __func__, safi2str(safi), buf, bn, prd);
 
 done:
        /* Loop back to import tables */
@@ -3724,12 +3720,7 @@ int rfapi_set_autord_from_vn(struct prefix_rd *rd, struct rfapi_ip_addr *vn)
                memcpy(rd->val + 2, &vn->addr.v6.s6_addr32[3],
                       4); /* low order 4 bytes */
        }
-       {
-               char buf[RD_ADDRSTRLEN];
-
-               vnc_zlog_debug_verbose("%s: auto-RD is set to %s", __func__,
-                                      prefix_rd2str(rd, buf, sizeof(buf)));
-       }
+       vnc_zlog_debug_verbose("%s: auto-RD is set to %pRD", __func__, rd);
        return 0;
 }
 
index be64153cef8fa074a023c20ad5c090a3636ac6ba..1dd623d3f3f21abb8d10bd08d4a6069c2f27b89b 100644 (file)
@@ -2091,14 +2091,8 @@ static void rfapiItBiIndexAdd(struct agg_node *rn, /* Import table VPN node */
        assert(bpi);
        assert(bpi->extra);
 
-       {
-               char buf[RD_ADDRSTRLEN];
-
-               vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %s", __func__,
-                                      bpi, bpi->peer,
-                                      prefix_rd2str(&bpi->extra->vnc.import.rd,
-                                                    buf, sizeof(buf)));
-       }
+       vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRD", __func__, bpi,
+                              bpi->peer, &bpi->extra->vnc.import.rd);
 
        sl = RFAPI_RDINDEX_W_ALLOC(rn);
        if (!sl) {
@@ -2164,7 +2158,6 @@ static struct bgp_path_info *rfapiItBiIndexSearch(
 
 #ifdef DEBUG_BI_SEARCH
        {
-               char buf[RD_ADDRSTRLEN];
                char buf_aux_pfx[PREFIX_STRLEN];
 
                if (aux_prefix) {
@@ -2173,10 +2166,9 @@ static struct bgp_path_info *rfapiItBiIndexSearch(
                } else
                        strlcpy(buf_aux_pfx, "(nil)", sizeof(buf_aux_pfx));
 
-               vnc_zlog_debug_verbose("%s want prd=%s, peer=%p, aux_prefix=%s",
-                                      __func__,
-                                      prefix_rd2str(prd, buf, sizeof(buf)),
-                                      peer, buf_aux_pfx);
+               vnc_zlog_debug_verbose(
+                       "%s want prd=%pRD, peer=%p, aux_prefix=%s", __func__,
+                       prd, peer, buf_aux_pfx);
                rfapiItBiIndexDump(rn);
        }
 #endif
@@ -2190,16 +2182,10 @@ static struct bgp_path_info *rfapiItBiIndexSearch(
                for (bpi_result = rn->info; bpi_result;
                     bpi_result = bpi_result->next) {
 #ifdef DEBUG_BI_SEARCH
-                       {
-                               char buf[RD_ADDRSTRLEN];
-
-                               vnc_zlog_debug_verbose(
-                                       "%s: bpi has prd=%s, peer=%p", __func__,
-                                       prefix_rd2str(&bpi_result->extra->vnc
-                                                              .import.rd,
-                                                     buf, sizeof(buf)),
-                                       bpi_result->peer);
-                       }
+                       vnc_zlog_debug_verbose(
+                               "%s: bpi has prd=%pRD, peer=%p", __func__,
+                               &bpi_result->extra->vnc.import.rd,
+                               bpi_result->peer);
 #endif
                        if (peer == bpi_result->peer
                            && !prefix_cmp((struct prefix *)&bpi_result->extra
@@ -2261,14 +2247,8 @@ static void rfapiItBiIndexDel(struct agg_node *rn, /* Import table VPN node */
        struct skiplist *sl;
        int rc;
 
-       {
-               char buf[RD_ADDRSTRLEN];
-
-               vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %s", __func__,
-                                      bpi, bpi->peer,
-                                      prefix_rd2str(&bpi->extra->vnc.import.rd,
-                                                    buf, sizeof(buf)));
-       }
+       vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRD", __func__, bpi,
+                              bpi->peer, &bpi->extra->vnc.import.rd);
 
        sl = RFAPI_RDINDEX(rn);
        assert(sl);
index 9e13c481340c3163ee0071044aea3b4ef57153dd..50a10c3b1d9e3f2fc3b60c271a0d9403c3216c56 100644 (file)
@@ -1104,9 +1104,6 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
                                        __func__, ri);
 
                        } else {
-
-                               char buf_rd[RD_ADDRSTRLEN];
-
                                /* not found: add new route to RIB */
                                ori = rfapi_info_new();
                                ori->rk = ri->rk;
@@ -1129,16 +1126,9 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
                                }
                                skiplist_insert(slRibPt, &ori->rk, ori);
 
-#if DEBUG_RIB_SL_RD
-                               prefix_rd2str(&ori->rk.rd, buf_rd,
-                                             sizeof(buf_rd));
-#else
-                               buf_rd[0] = 0;
-#endif
-
                                vnc_zlog_debug_verbose(
-                                       "%s:   nomatch lPendCost item %p in slRibPt, added (rd=%s)",
-                                       __func__, ri, buf_rd);
+                                       "%s:   nomatch lPendCost item %p in slRibPt, added (rd=%pRD)",
+                                       __func__, ri, &ori->rk.rd);
                        }
 
                        /*
@@ -1378,17 +1368,9 @@ callback:
                                                0, delete_list->count);
                                        ri->last_sent_time = monotime(NULL);
 #if DEBUG_RIB_SL_RD
-                                       {
-                                               char buf_rd[RD_ADDRSTRLEN];
-
-                                               vnc_zlog_debug_verbose(
-                                                       "%s: move route to recently deleted list, rd=%s",
-                                                       __func__,
-                                                       prefix_rd2str(
-                                                               &ri->rk.rd,
-                                                               buf_rd,
-                                                               sizeof(buf_rd)));
-                                       }
+                                       vnc_zlog_debug_verbose(
+                                               "%s: move route to recently deleted list, rd=%pRD",
+                                               __func__, &ri->rk.rd);
 #endif
 
                                } else {
@@ -2256,7 +2238,6 @@ static int print_rib_sl(int (*fp)(void *, const char *, ...), struct vty *vty,
                char str_lifetime[BUFSIZ];
                char str_age[BUFSIZ];
                char *p;
-               char str_rd[RD_ADDRSTRLEN];
 
                ++routes_displayed;
 
@@ -2284,14 +2265,9 @@ static int print_rib_sl(int (*fp)(void *, const char *, ...), struct vty *vty,
                }
 #endif
 
-               str_rd[0] = 0; /* start empty */
-#if DEBUG_RIB_SL_RD
-               prefix_rd2str(&ri->rk.rd, str_rd, sizeof(str_rd));
-#endif
-
-               fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s %s\n",
+               fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s %pRD\n",
                   deleted ? 'r' : ' ', *printedprefix ? "" : str_pfx, str_vn,
-                  str_un, ri->cost, str_lifetime, str_age, str_rd);
+                  str_un, ri->cost, str_lifetime, str_age, &ri->rk.rd);
 
                if (!*printedprefix)
                        *printedprefix = 1;
index a8ab618417e68161198c9c716baa498ef52d0131..23f43fa7d3e66271010b3bd7146b362cc454b6f3 100644 (file)
@@ -1537,14 +1537,6 @@ void rfapiPrintRfapiIpPrefix(void *stream, struct rfapi_ip_prefix *p)
                fp(out, "?/?:?");
 }
 
-void rfapiPrintRd(struct vty *vty, struct prefix_rd *prd)
-{
-       char buf[RD_ADDRSTRLEN];
-
-       prefix_rd2str(prd, buf, sizeof(buf));
-       vty_out(vty, "%s", buf);
-}
-
 void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd,
                              safi_t safi, struct prefix *p)
 {
@@ -1615,7 +1607,7 @@ void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd)
        vty_out(vty, " ");
        rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr);
        vty_out(vty, " %p %p ", rfd->response_cb, rfd->cookie);
-       rfapiPrintRd(vty, &rfd->rd);
+       vty_out(vty, "%pRD", &rfd->rd);
        vty_out(vty, " %d", rfd->response_lifetime);
        vty_out(vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>"));
        vty_out(vty, "%s", HVTYNL);
index b5e1c38b0dd70a0a2a2fdbca0c4db48dc6ddb908..09e1b3c4c4931f080f036e933e63b331f184eb51 100644 (file)
@@ -93,8 +93,6 @@ extern void rfapiPrintRfapiIpAddr(void *stream, struct rfapi_ip_addr *a);
 
 extern void rfapiPrintRfapiIpPrefix(void *stream, struct rfapi_ip_prefix *p);
 
-void rfapiPrintRd(struct vty *vty, struct prefix_rd *prd);
-
 extern void rfapiPrintAdvertisedInfo(struct vty *vty,
                                     struct rfapi_descriptor *rfd, safi_t safi,
                                     struct prefix *p);
index 8c1fab0eabedf8f643edd6b99f75ec54027fbb45..4e1080045e7890e50ac3b300fcdf6ba8b40a2834 100644 (file)
@@ -7,7 +7,7 @@
 ##
 AC_PREREQ([2.69])
 
-AC_INIT([frr], [8.4-dev], [https://github.com/frrouting/frr/issues])
+AC_INIT([frr], [8.5-dev], [https://github.com/frrouting/frr/issues])
 PACKAGE_URL="https://frrouting.org/"
 AC_SUBST([PACKAGE_URL])
 PACKAGE_FULLNAME="FRRouting"
index 9c14270b664d72f2f5dd2b3e868fd2617147e81c..ad43f13e3356a8d000804c0269580e0d5db7968a 100644 (file)
@@ -1,3 +1,9 @@
+frr (8.5~dev-1) UNRELEASED; urgency=medium
+
+  * FRR Dev 8.5
+
+ -- Donatas Abraitis <donatas@opensourcerouting.org>  Tue, 04 Oct 2022 16:00:00 +0500
+
 frr (8.4~dev-1) UNRELEASED; urgency=medium
 
   * FRR Dev 8.4
index bd5767beba6c2b5f21f219d2bad3977a10a49890..25d1cbfb6b978492f412db0d0f549f89210f175f 100644 (file)
@@ -1775,12 +1775,28 @@ Configuring Peers
    default, the DelayOpenTimer is disabled. The timer interval may be set to a
    duration of 1 to 240 seconds.
 
+.. clicmd:: neighbor PEER extended-optional-parameters
+
+   Force the extended optional parameters format for OPEN messages. By default,
+   optional parameters length is 255 octets. With more and more BGP capabilities
+   implemented on top of BGP, this is needed to extend this value.
+
+   This is turned off by default, but it's automatically enabled when this limit
+   is hit. You can force this new encoding to be enabled with this command.
+
 .. clicmd:: bgp minimum-holdtime (1-65535)
 
    This command allows user to prevent session establishment with BGP peers
    with lower holdtime less than configured minimum holdtime.
    When this command is not set, minimum holdtime does not work.
 
+.. clicmd:: bgp tcp-keepalive (1-65535) (1-65535) (1-30)
+
+   This command allows user to configure TCP keepalive with new BGP peers.
+   Each parameter respectively stands for TCP keepalive idle timer (seconds),
+   interval (seconds), and maximum probes. By default, TCP keepalive is
+   disabled.
+
 Displaying Information about Peers
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -3488,6 +3504,10 @@ Debugging
    library messages and BGP BFD integration messages that are mostly state
    transitions and validation problems.
 
+.. clicmd:: debug bgp conditional-advertisement
+
+   Enable or disable debugging of BGP conditional advertisement.
+
 .. clicmd:: debug bgp neighbor-events
 
    Enable or disable debugging for neighbor events. This provides general
index 26810bd8830de88566c785bf3651b2e4376f8d2c..3bb018548ea0202f427c107e51978b562820ea3c 100644 (file)
@@ -1060,78 +1060,83 @@ TI-LFA requires a proper Segment Routing configuration.
 Debugging OSPF
 ==============
 
-.. clicmd:: debug ospf bfd
+.. clicmd:: debug ospf [(1-65535)] bfd
 
    Enable or disable debugging for BFD events. This will show BFD integration
    library messages and OSPF BFD integration messages that are mostly state
    transitions and validation problems.
 
-.. clicmd:: debug ospf client-api
+.. clicmd:: debug ospf [(1-65535)] client-api
 
    Show debug information for the OSPF opaque data client API.
 
-.. clicmd:: debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail]
+.. clicmd:: debug ospf [(1-65535)] default-information
 
+   Show debug information of default information
 
-   Dump Packet for debugging
+.. clicmd:: debug ospf [(1-65535)] packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail]
 
-.. clicmd:: debug ospf ism
 
-.. clicmd:: debug ospf ism (status|events|timers)
+   Dump Packet for debugging
 
+.. clicmd:: debug ospf [(1-65535)] ism [status|events|timers]
 
 
-   Show debug information of Interface State Machine
 
-.. clicmd:: debug ospf nsm
+   Show debug information of Interface State Machine
 
-.. clicmd:: debug ospf nsm (status|events|timers)
+.. clicmd:: debug ospf [(1-65535)] nsm [status|events|timers]
 
 
 
    Show debug information of Network State Machine
 
-.. clicmd:: debug ospf event
+.. clicmd:: debug ospf [(1-65535)] event
 
 
    Show debug information of OSPF event
 
-.. clicmd:: debug ospf nssa
+.. clicmd:: debug ospf [(1-65535)] nssa
 
 
    Show debug information about Not So Stub Area
 
-.. clicmd:: debug ospf lsa
+.. clicmd:: debug ospf [(1-65535)] ldp-sync
+
+   Show debug information about LDP-Sync
 
-.. clicmd:: debug ospf lsa (generate|flooding|refresh)
+.. clicmd:: debug ospf [(1-65535)] lsa [aggregate|flooding|generate|install|refresh]
 
 
 
    Show debug detail of Link State messages
 
-.. clicmd:: debug ospf te
+.. clicmd:: debug ospf [(1-65535)] sr
+
+   Show debug information about Segment Routing
+
+.. clicmd:: debug ospf [(1-65535)] te
 
 
    Show debug information about Traffic Engineering LSA
 
-.. clicmd:: debug ospf zebra
+.. clicmd:: debug ospf [(1-65535)] ti-lfa
 
-.. clicmd:: debug ospf zebra (interface|redistribute)
+   Show debug information about SR TI-LFA
+
+.. clicmd:: debug ospf [(1-65535)] zebra [interface|redistribute]
 
 
 
    Show debug information of ZEBRA API
 
-.. clicmd:: debug ospf graceful-restart helper
+.. clicmd:: debug ospf [(1-65535)] graceful-restart
 
 
    Enable/disable debug information for OSPF Graceful Restart Helper
 
 .. clicmd:: show debugging ospf
 
-.. clicmd:: debug ospf lsa aggregate
-
-   Debug commnd to enable/disable external route summarisation specific debugs.
 
 
 Sample Configuration
index 70bfee283502c3f625c73779f8725a36178a7171..4a24fa52be565e59a15252c344582ac5108fab94 100644 (file)
@@ -310,41 +310,64 @@ BGP
   :t:`Autonomous System Confederations for BGP. P. Traina. June 1996.`
 - :rfc:`1997`
   :t:`BGP Communities Attribute. R. Chandra, P. Traina & T. Li. August 1996.`
+- :rfc:`1998`
+  :t:`An Application of the BGP Community Attribute in Multi-home Routing. E. Chen, T. Bates. August 1996.`
+- :rfc:`2385`
+  :t:`Protection of BGP Sessions via the TCP MD5 Signature Option. A. Heffernan. August 1998.`
 - :rfc:`2439`
   :t:`BGP Route Flap Damping. C. Villamizar, R. Chandra, R. Govindan. November 1998.`
 - :rfc:`2545`
-  :t:`Use of BGP-4 Multiprotocol Extensions for IPv6 Inter-Domain Routing. P.
-  Marques, F. Dupont. March 1999.`
+  :t:`Use of BGP-4 Multiprotocol Extensions for IPv6 Inter-Domain Routing. P. Marques, F. Dupont. March 1999.`
 - :rfc:`2796`
   :t:`BGP Route Reflection An alternative to full mesh IBGP. T. Bates & R. Chandrasekeran. June 1996.`
 - :rfc:`2842`
   :t:`Capabilities Advertisement with BGP-4. R. Chandra, J. Scudder. May 2000.`
 - :rfc:`2858`
-  :t:`Multiprotocol Extensions for BGP-4. T. Bates, Y. Rekhter, R. Chandra, D.`
+  :t:`Multiprotocol Extensions for BGP-4. T. Bates, Y. Rekhter, R. Chandra, D. Katz. June 2000.`
+- :rfc:`2918`
+  :t:`Route Refresh Capability for BGP-4. E. Chen, September 2000.`
 - :rfc:`3107`
   :t:`Carrying Label Information in BGP-4. Y. Rekhter & E. Rosen. May 2001.`
 - :rfc:`3765`
-  :t:`NOPEER Community for Border Gateway Protocol (BGP) Route Scope Control. G.Huston, April 2001.`
+  :t:`NOPEER Community for Border Gateway Protocol (BGP) Route Scope Control. G.Huston. April 2001.`
 - :rfc:`4271`
   :t:`A Border Gateway Protocol 4 (BGP-4). Updates RFC1771. Y. Rekhter, T. Li & S. Hares. January 2006.`
+- :rfc:`4360`
+  :t:`BGP Extended Communities Attribute. S. Sangli, D. Tappan, Y. Rekhter. February 2006.`
 - :rfc:`4364`
-  :t:`BGP/MPLS IP Virtual Private Networks (VPNs). Y. Rekhter. Feb 2006.`
+  :t:`BGP/MPLS IP Virtual Private Networks (VPNs). Y. Rekhter. February 2006.`
+- :rfc:`4456`
+  :t:`BGP Route Reflection An alternative to full mesh IBGP. T. Bates, E. Chen, R. Chandra. April 2006.`
 - :rfc:`4486`
   :t:`Subcodes for BGP Cease Notification Message. E. Chen, V. Gillet. April 2006.`
 - :rfc:`4659`
   :t:`BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN. J. De Clercq, D. Ooms, M. Carugi, F. Le Faucheur. September 2006.`
+- :rfc:`4724`
+  :t:`Graceful Restart Mechanism for BGP. S. Sangli, E. Chen, R. Fernando, J. Scudder, Y. Rekhter. January 2007.`
+- :rfc:`4760`
+  :t:`Multiprotocol Extensions for BGP-4. T. Bates, R. Chandra, D. Katz, Y. Rekhter. January 2007.`
 - :rfc:`4893`
   :t:`BGP Support for Four-octet AS Number Space. Q. Vohra, E. Chen May 2007.`
 - :rfc:`5004`
   :t:`Avoid BGP Best Path Transitions from One External to Another. E. Chen & S. Sangli. September 2007 (Partial support).`
+- :rfc:`5065`
+  :t:`Autonomous System Confederations for BGP. P. Traina, D. McPherson, J. Scudder. August 2007.`
 - :rfc:`5082`
   :t:`The Generalized TTL Security Mechanism (GTSM). V. Gill, J. Heasley, D. Meyer, P. Savola, C. Pingnataro. October 2007.`
+- :rfc:`5291`
+  :t:`Outbound Route Filtering Capability. E. Chen, Y. Rekhter. August 2008.`
+- :rfc:`5292`
+  :t:`Address-Prefix-Based Outbound Route Filter for BGP-4. E. Chen, S. Sangli. August 2008.`
+- :rfc:`5492`
+  :t:`Capabilities Advertisement with BGP-4. J. Scudder, R. Chandra. February 2009.`
 - :rfc:`5575`
-  :t:`Dissemination of Flow Specification Rules. P. Marques, N. Sheth, R. Raszuk, B. Greene, J. Mauch, D. McPherson. August 2009`
+  :t:`Dissemination of Flow Specification Rules. P. Marques, N. Sheth, R. Raszuk, B. Greene, J. Mauch, D. McPherson. August 2009.`
 - :rfc:`5668`
-  :t:`4-Octet AS Specific BGP Extended Community. Y. Rekhter, S. Sangli, D. Tappan October 2009`
+  :t:`4-Octet AS Specific BGP Extended Community. Y. Rekhter, S. Sangli, D. Tappan October 2009.`
 - :rfc:`6286`
-  :t:`Autonomous-System-Wide Unique BGP Identifier for BGP-4. E. Chen, J. Yuan, June 2011.`
+  :t:`Autonomous-System-Wide Unique BGP Identifier for BGP-4. E. Chen, J. Yuan. June 2011.`
+- :rfc:`6472`
+  :t:`Recommendation for Not Using AS_SET and AS_CONFED_SET in BGP. W. Kumari, K. Sriram. December 2011.`
 - :rfc:`6608`
   :t:`Subcodes for BGP Finite State Machine Error. J. Dong, M. Chen, Huawei Technologies, A. Suryanarayana, Cisco Systems. May 2012.`
 - :rfc:`6810`
@@ -353,6 +376,8 @@ BGP
   :t:`BGP Prefix Origin Validation. P. Mohapatra, J. Scudder, D. Ward, R. Bush, R. Austein. January 2013.`
 - :rfc:`6938`
   :t:`Deprecation of BGP Path Attributes: DPA, ADVERTISER, and RCID_PATH / CLUSTER_ID. J. Scudder. May 2013.`
+- :rfc:`6996`
+  :t:`Autonomous System (AS) Reservation for Private Use. J. Mitchell. July 2013.`
 - :rfc:`7196`
   :t:`Making Route Flap Damping Usable. C. Pelsser, R. Bush, K. Patel, P. Mohapatra, O. Maennel. May 2014.`
 - :rfc:`7300`
@@ -365,30 +390,40 @@ BGP
   :t:`Codification of AS 0 Processing. W. Kumari, R. Bush, H. Schiller, K. Patel. August 2015.`
 - :rfc:`7611`
   :t:`BGP ACCEPT_OWN Community Attribute. J. Uttaro, P. Mohapatra, D. Smith, R. Raszuk, J. Scudder. August 2015.`
+- :rfc:`7911`
+  :t:`Advertisement of Multiple Paths in BGP. D. Walton, A. Retana, E. Chen, J. Scudder. July 2016.`
+- :rfc:`7947`
+  :t:`Internet Exchange BGP Route Server. E. Jasinska, N. Hilliard, R. Raszuk, N. Bakker. September 2016.`
 - :rfc:`7999`
-  :t:`BLACKHOLE Community. T. King, C. Dietzel, J. Snijders, G. Doering, G. Hankins. Oct 2016.`
+  :t:`BLACKHOLE Community. T. King, C. Dietzel, J. Snijders, G. Doering, G. Hankins. October 2016.`
+- :rfc:`8050`
+  :t:`Multi-Threaded Routing Toolkit (MRT) Routing Information Export Format with BGP Additional Path Extensions. C. Petrie, T. King. May 2017.`
 - :rfc:`8092`
-  :t:`BGP Large Communities Attribute. J. Heitz, Ed., J. Snijders, Ed, K. Patel, I. Bagdonas, N. Hilliard. February 2017`
+  :t:`BGP Large Communities Attribute. J. Heitz, Ed., J. Snijders, Ed, K. Patel, I. Bagdonas, N. Hilliard. February 2017.`
+- :rfc:`8093`
+  :t:`Deprecation of BGP Path Attribute Values 30, 31, 129, 241, 242, and 243. J. Snijders. February 2017.`
 - :rfc:`8097`
-  :t:`BGP Prefix Origin Validation State Extended Community. P. Mohapatra, K. Patel, J. Scudder, D. Ward, R. Bush. March 2017`
+  :t:`BGP Prefix Origin Validation State Extended Community. P. Mohapatra, K. Patel, J. Scudder, D. Ward, R. Bush. March 2017.`
 - :rfc:`8195`
-  :t:`Use of BGP Large Communities. J. Snijders, J. Heasley, M. Schmidt, June 2017`
+  :t:`Use of BGP Large Communities. J. Snijders, J. Heasley, M. Schmidt. June 2017.`
 - :rfc:`8203`
   :t:`BGP Administrative Shutdown Communication. J. Snijders, J. Heitz, J. Scudder. July 2017.`
 - :rfc:`8212`
-  :t:`Default External BGP (EBGP) Route Propagation Behavior without Policies. J. Mauch, J. Snijders, G. Hankins. July 2017`
+  :t:`Default External BGP (EBGP) Route Propagation Behavior without Policies. J. Mauch, J. Snijders, G. Hankins. July 2017.`
 - :rfc:`8277`
-  :t:`Using BGP to Bind MPLS Labels to Address Prefixes. E. Rosen. October 2017`
+  :t:`Using BGP to Bind MPLS Labels to Address Prefixes. E. Rosen. October 2017.`
 - :rfc:`8538`
-  :t:`Notification Message Support for BGP Graceful Restart. K. Patel, R. Fernando, J. Scudder, J. Haas. March 2019`
+  :t:`Notification Message Support for BGP Graceful Restart. K. Patel, R. Fernando, J. Scudder, J. Haas. March 2019.`
 - :rfc:`8654`
-  :t:`Extended Message Support for BGP. R. Bush, K. Patel, D. Ward.  October 2019`
+  :t:`Extended Message Support for BGP. R. Bush, K. Patel, D. Ward. October 2019.`
 - :rfc:`9003`
-  :t:`Extended BGP Administrative Shutdown Communication. J. Snijders, J. Heitz, J. Scudder, A. Azimov. January 2021`
+  :t:`Extended BGP Administrative Shutdown Communication. J. Snijders, J. Heitz, J. Scudder, A. Azimov. January 2021.`
+- :rfc:`9012`
+  :t:`The BGP Tunnel Encapsulation Attribute. K. Patel, G. Van de Velde, S. Sangli, J. Scudder. April 2021.`
 - :rfc:`9072`
-  :t:`Extended Optional Parameters Length for BGP OPEN Message. E. Chen, J. Scudder. July 2021`
+  :t:`Extended Optional Parameters Length for BGP OPEN Message. E. Chen, J. Scudder. July 2021.`
 - :rfc:`9234`
-  :t:`Route Leak Prevention and Detection Using Roles in UPDATE and OPEN Messages. A. Azimov, E. Bogomazov, R. Bush, K. Patel, K. Sriram. May 2022`
+  :t:`Route Leak Prevention and Detection Using Roles in UPDATE and OPEN Messages. A. Azimov, E. Bogomazov, R. Bush, K. Patel, K. Sriram. May 2022.`
 
 OSPF
 ----
index 843734e217193e90d3c5bcb7c74124ea41c5e3cb..b242f4fe17395ac30554c7d1eb8caaf67b87af8e 100644 (file)
@@ -416,6 +416,10 @@ configure CLI mode. If you specify debug commands in the configuration cli
 mode, the debug commands can be persistent across restarts of the FRR pim6d if
 the config was written out.
 
+.. clicmd:: debug mld
+
+   This turns on debugging for MLD protocol activity.
+
 .. clicmd:: debug pimv6 events
 
    This turns on debugging for PIMv6 system events. Especially timers.
@@ -456,3 +460,15 @@ the config was written out.
 .. clicmd:: debug mroute6 detail
 
    This turns on detailed debugging for PIMv6 interaction with kernel MFC cache.
+
+.. clicmd:: debug mld events
+
+   This turns on debugging for MLD system events.
+
+.. clicmd:: debug mld packets
+
+   This turns on information about MLD protocol packets handling.
+
+.. clicmd:: debug mld trace [detail]
+
+   This traces mld code and how it is running. 
index 25934df9cbe2d8c985d15b3b58a126813980bb0e..dcc7607e4841418faa816c62c1fdeaf38c03f115 100644 (file)
@@ -111,7 +111,7 @@ reasons touched on in the VTYSH documentation and should generally be enabled.
 This allows the operator to control the number of open file descriptors
 each daemon is allowed to start with.  The current assumed value on
 most operating systems is 1024.  If the operator plans to run bgp with
-several thousands of peers than this is where we would modify FRR to
+several thousands of peers then this is where we would modify FRR to
 allow this to happen.
 
 ::
index 97b3863ef574f5be88ad4a4b0c74bfd307b6d6cd..1ab54f09ab9c1419bd207beed93bd10f0322168d 100644 (file)
@@ -177,11 +177,7 @@ Writing the configuration can be triggered directly by invoking *vtysh -w*.
 This may be useful for scripting. Note this command should be run as either the
 superuser or the FRR user.
 
-We recommend you do not mix the use of the two types of files. Further, it is
-better not to use the integrated :file:`frr.conf` file, as any syntax error in
-it can lead to /all/ of your daemons being unable to start up. Per daemon files
-are more robust as impact of errors in configuration are limited to the daemon
-in whose file the error is made.
+We recommend you do not mix the use of the two types of files.
 
 .. clicmd:: service integrated-vtysh-config
 
index 187b5285244695f0d35250293d3784ecee6ebe7f..b9278dbb880e58f64e2360be3ae5e70defd3c0fe 100644 (file)
@@ -12,16 +12,6 @@ RUN apk add \
        && echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
 RUN adduser -D -G abuild builder && su builder -c 'abuild-keygen -a -n'
 
-# This stage builds a libyang APK from source
-FROM alpine-builder as libyang-builder
-RUN mkdir -p /libyang && chown -R builder /pkgs /libyang
-# -- Not currently needed - libyang currently available in Alpine upstream
-# COPY docker/alpine/libyang/ /libyang
-# USER builder
-# RUN cd /libyang \
-#      && abuild checksum \
-#      && abuild -r -P /pkgs/apk
-
 # This stage builds a dist tarball from the source
 FROM alpine:3.15 as source-builder
 
@@ -36,14 +26,7 @@ RUN source /src/alpine/APKBUILD.in \
                py-pip \
                rtrlib \
        && pip install pytest
-
 RUN mkdir -p /pkgs/apk
-# -- Not needed while libyang is not built
-# COPY --from=libyang-builder /pkgs/apk/ /pkgs/apk/
-# RUN apk add \
-#              --no-cache \
-#              --allow-untrusted /pkgs/apk/*/*.apk \
-
 COPY . /src
 ARG PKGVER
 RUN cd /src \
@@ -54,12 +37,7 @@ RUN cd /src \
        && make dist
 
 # This stage builds an APK from the dist tarball
-FROM alpine-builder as frr-apk-builder
-# -- Not needed while libyang is not built
-# COPY --from=libyang-builder /pkgs/apk/ /pkgs/apk/
-# RUN apk add \
-#              --no-cache \
-#              --allow-untrusted /pkgs/apk/*/*.apk
+FROM alpine-builder as alpine-apk-builder
 COPY --from=source-builder /src/frr-*.tar.gz /src/alpine/* /dist/
 RUN find /pkgs/apk -type f -name APKINDEX.tar.gz -delete
 RUN chown -R builder /dist /pkgs
@@ -72,7 +50,7 @@ RUN cd /dist \
 # This stage installs frr from the apk
 FROM alpine:3.15
 RUN mkdir -p /pkgs/apk
-COPY --from=frr-apk-builder /pkgs/apk/ /pkgs/apk/
+COPY --from=alpine-apk-builder /pkgs/apk/ /pkgs/apk/
 RUN apk add \
                --no-cache \
                --update-cache \
index 3132feb9f1e5ebee5bc761b3744f1589bb471092..80ee81c821bb780e953ffb37edd654340968835b 100755 (executable)
@@ -25,7 +25,16 @@ docker build \
        --target=alpine-builder \
        .
 
-CONTAINER_ID="$(docker create "frr:alpine-builder-$GITREV")"
+# Keep .apk files for debugging purposes, docker image as well.
+docker build \
+       --pull \
+       --file=docker/alpine/Dockerfile \
+       --build-arg="PKGVER=$PKGVER" \
+       --tag="frr:alpine-apk-builder-$GITREV" \
+       --target=alpine-apk-builder \
+       .
+
+CONTAINER_ID="$(docker create "frr:alpine-apk-builder-$GITREV")"
 docker cp "${CONTAINER_ID}:/pkgs/" docker/alpine
 docker rm "${CONTAINER_ID}"
 
@@ -36,3 +45,4 @@ docker build \
        .
 
 docker rmi "frr:alpine-builder-$GITREV"
+docker rmi "frr:alpine-apk-builder-$GITREV"
index e1ad51a9dbb1f7d4350accd2788e75a4310e8601..b0d34f55e619ccf2c917edef02a16df6ac0aa706 100644 (file)
@@ -322,6 +322,7 @@ DEFUN_NOSH (show_debugging_eigrp,
                }
        }
 
+       cmd_show_lib_debugs(vty);
        return CMD_SUCCESS;
 }
 
index b15b72a262d2c1a5ce8fc4c3735780ebfd24096b..71ad7bf69e1064e83ee73ba9b358cf4582181c80 100644 (file)
@@ -188,12 +188,12 @@ enum {
         RTM_SETHWFLAGS = 119,
 #define RTM_SETHWFLAGS RTM_SETHWFLAGS
 
-        RTM_NEWTUNNEL = 120,
-#define RTM_NEWTUNNEL  RTM_NEWTUNNEL
-        RTM_DELTUNNEL,
-#define RTM_DELTUNNEL  RTM_DELTUNNEL
-        RTM_GETTUNNEL,
-#define RTM_GETTUNNEL  RTM_GETTUNNEL
+       RTM_NEWTUNNEL = 120,
+#define RTM_NEWTUNNEL  RTM_NEWTUNNEL
+       RTM_DELTUNNEL,
+#define RTM_DELTUNNEL  RTM_DELTUNNEL
+       RTM_GETTUNNEL,
+#define RTM_GETTUNNEL  RTM_GETTUNNEL
 
        __RTM_MAX,
 #define RTM_MAX                (((__RTM_MAX + 3) & ~3) - 1)
index a37cda1ce136c9e99b11ca3781fba87cfa24890a..be035b623d6330702bba6bfc2bb3757230f32bd1 100644 (file)
@@ -254,8 +254,10 @@ static void fabricd_initial_sync_timeout(struct thread *thread)
 {
        struct fabricd *f = THREAD_ARG(thread);
 
-       zlog_info("OpenFabric: Initial synchronization on %s timed out!",
-                 f->initial_sync_circuit->interface->name);
+       if (IS_DEBUG_ADJ_PACKETS)
+               zlog_debug(
+                       "OpenFabric: Initial synchronization on %s timed out!",
+                       f->initial_sync_circuit->interface->name);
        f->initial_sync_state = FABRICD_SYNC_PENDING;
        f->initial_sync_circuit = NULL;
 }
@@ -282,9 +284,11 @@ void fabricd_initial_sync_hello(struct isis_circuit *circuit)
                         timeout, &f->initial_sync_timeout);
        f->initial_sync_start = monotime(NULL);
 
-       zlog_info("OpenFabric: Started initial synchronization with %s on %s",
-                 sysid_print(circuit->u.p2p.neighbor->sysid),
-                 circuit->interface->name);
+       if (IS_DEBUG_ADJ_PACKETS)
+               zlog_debug(
+                       "OpenFabric: Started initial synchronization with %s on %s",
+                       sysid_print(circuit->u.p2p.neighbor->sysid),
+                       circuit->interface->name);
 }
 
 bool fabricd_initial_sync_is_in_progress(struct isis_area *area)
index dbe4a017bc91d7d5ce9f894821d9a8b4ce93ad1c..e0decf48f2447157517f1b2473fed38b47a4a03c 100644 (file)
@@ -54,8 +54,6 @@
 #include "isisd/isis_dr.h"
 #include "isisd/isis_zebra.h"
 
-DEFINE_MTYPE_STATIC(ISISD, ISIS_PLIST_NAME, "ISIS prefix-list name");
-
 /*
  * XPath: /frr-isisd:isis/instance
  */
index bce3dbb77b4673e7612e767611c7c776d834fcbf..0ff31df0f8649eeeba8704e369f57653fc52828b 100644 (file)
@@ -90,6 +90,7 @@ DEFINE_MTYPE_STATIC(ISISD, ISIS_NAME, "ISIS process name");
 DEFINE_MTYPE_STATIC(ISISD, ISIS_AREA, "ISIS area");
 DEFINE_MTYPE(ISISD, ISIS_AREA_ADDR,   "ISIS area address");
 DEFINE_MTYPE(ISISD, ISIS_ACL_NAME,    "ISIS access-list name");
+DEFINE_MTYPE(ISISD, ISIS_PLIST_NAME, "ISIS prefix-list name");
 
 DEFINE_QOBJ_TYPE(isis_area);
 
@@ -565,6 +566,11 @@ void isis_area_destroy(struct isis_area *area)
 
        area_mt_finish(area);
 
+       if (area->rlfa_plist_name[0])
+               XFREE(MTYPE_ISIS_PLIST_NAME, area->rlfa_plist_name[0]);
+       if (area->rlfa_plist_name[1])
+               XFREE(MTYPE_ISIS_PLIST_NAME, area->rlfa_plist_name[1]);
+
        XFREE(MTYPE_ISIS_AREA, area);
 
 }
@@ -1694,6 +1700,8 @@ DEFUN_NOSH (show_debugging,
        if (IS_DEBUG_LFA)
                print_debug(vty, DEBUG_LFA, 1);
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index c313fd9ef786a7eb18922ba0200dbcec3f158fc2..4951e5809b79027a124d630a3ebcdfccb3bd7381 100644 (file)
@@ -251,6 +251,7 @@ DECLARE_QOBJ_TYPE(isis_area);
 
 DECLARE_MTYPE(ISIS_ACL_NAME);  /* isis_area->spf_prefix_prioritites */
 DECLARE_MTYPE(ISIS_AREA_ADDR); /* isis_area->area_addrs */
+DECLARE_MTYPE(ISIS_PLIST_NAME);
 
 DECLARE_HOOK(isis_area_overload_bit_update, (struct isis_area * area), (area));
 
index 11d6930f06a30d65d49c52031062270796300303..3795cdaf387a1bd1c0ec8dfa327bef3b2c7dce0a 100644 (file)
@@ -774,7 +774,11 @@ DEFPY_NOSH (ldp_show_debugging_mpls_ldp,
            "MPLS information\n"
            "Label Distribution Protocol\n")
 {
-       return (ldp_vty_show_debugging(vty));
+       ldp_vty_show_debugging(vty);
+
+       cmd_show_lib_debugs(vty);
+
+       return CMD_SUCCESS;
 }
 
 static void
index a23afb1e43863e15ff36c50a1d866ff1e69ca0f5..7e171cb309157f2960668040f077071dd8776298 100644 (file)
@@ -48,6 +48,7 @@
 #include "lib_errors.h"
 #include "northbound_cli.h"
 #include "network.h"
+#include "routemap.h"
 
 #include "frrscript.h"
 
@@ -2446,6 +2447,11 @@ const char *host_config_get(void)
        return host.config;
 }
 
+void cmd_show_lib_debugs(struct vty *vty)
+{
+       route_map_show_debug(vty);
+}
+
 void install_default(enum node_type node)
 {
        _install_element(node, &config_exit_cmd);
index 70e52708a741ee0ac5def20e7d8d94af64fe1f12..ca49efd262a740a7e6af46adea971f28491b9d62 100644 (file)
@@ -649,6 +649,12 @@ extern char *cmd_variable_comp2str(vector comps, unsigned short cols);
 
 extern void command_setup_early_logging(const char *dest, const char *level);
 
+/*
+ * Allow a mechanism for `debug XXX` commands that live
+ * under the lib directory to output their debug status
+ */
+extern void cmd_show_lib_debugs(struct vty *vty);
+
 #ifdef __cplusplus
 }
 #endif
index d8ef9dcbd5d154ca068009eca40859c1d62293e8..ff2a59ba2dfd3e2489c9c8308e66d8487574bde1 100644 (file)
@@ -1570,7 +1570,6 @@ static void prefix_list_reset_afi(afi_t afi, int orf)
 
        while ((plist = plist_first(&master->str))) {
                prefix_list_delete(plist);
-               plist_pop(&master->str);
        }
 
        master->recent = NULL;
index 7b2f889874982d744b921e1a114d762c8c1dce16..b9043115395f1b2484ccf4b7dde680e3e7c1aea7 100644 (file)
@@ -674,6 +674,7 @@ static inline bool ipv4_mcast_ssm(const struct in_addr *addr)
 #pragma FRR printfrr_ext "%pFX"  (struct prefix_eth *)
 #pragma FRR printfrr_ext "%pFX"  (struct prefix_evpn *)
 #pragma FRR printfrr_ext "%pFX"  (struct prefix_fs *)
+#pragma FRR printfrr_ext "%pRD"  (struct prefix_rd *)
 
 #pragma FRR printfrr_ext "%pPSG4" (struct prefix_sg *)
 #endif
index e6310465e333484752ef7970347cdcc8fdfbef3a..3a927999915923a0a073489f661fdd2f5d7bc449 100644 (file)
@@ -1059,7 +1059,6 @@ static int vty_show_route_map(struct vty *vty, const char *name, bool use_json)
 
                if (map) {
                        vty_show_route_map_entry(vty, map, json_proto);
-                       return CMD_SUCCESS;
                } else if (!use_json) {
                        vty_out(vty, "%s: 'route-map %s' not found\n",
                                frr_protonameinst, name);
@@ -3175,6 +3174,12 @@ static struct cmd_node rmap_debug_node = {
        .config_write = rmap_config_write_debug,
 };
 
+void route_map_show_debug(struct vty *vty)
+{
+       if (rmap_debug)
+               vty_out(vty, "debug route-map\n");
+}
+
 /* Configuration write function. */
 static int rmap_config_write_debug(struct vty *vty)
 {
index a3659258545f2886c1929316b73ea89d164b333a..c2e9de6cfbb2bf106b07bfdcb5f8c7d461e8d027 100644 (file)
@@ -1015,6 +1015,8 @@ extern void route_map_optimization_disabled_show(struct vty *vty,
                                                 bool show_defaults);
 extern void route_map_cli_init(void);
 
+extern void route_map_show_debug(struct vty *vty);
+
 #ifdef __cplusplus
 }
 #endif
index 7a2b8a1c835e1bd8331e6e98d7987a32b9702a40..de11a9eab36bfb43ea6c4414857f74e734dc43d6 100644 (file)
@@ -693,3 +693,52 @@ int sockopt_tcp_mss_get(int sock)
 
        return tcp_maxseg;
 }
+
+int setsockopt_tcp_keepalive(int sock, uint16_t keepalive_idle,
+                            uint16_t keepalive_intvl,
+                            uint16_t keepalive_probes)
+{
+       int val = 1;
+
+       if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) < 0) {
+               flog_err_sys(EC_LIB_SYSTEM_CALL,
+                            "%s failed: setsockopt SO_KEEPALIVE (%d): %s",
+                            __func__, sock, safe_strerror(errno));
+               return -1;
+       }
+
+#if defined __OpenBSD__
+       return 0;
+#else
+       /* Send first probe after keepalive_idle seconds */
+       val = keepalive_idle;
+       if (setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) <
+           0) {
+               flog_err_sys(EC_LIB_SYSTEM_CALL,
+                            "%s failed: setsockopt TCP_KEEPIDLE (%d): %s",
+                            __func__, sock, safe_strerror(errno));
+               return -1;
+       }
+
+       /* Set interval between two probes */
+       val = keepalive_intvl;
+       if (setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) <
+           0) {
+               flog_err_sys(EC_LIB_SYSTEM_CALL,
+                            "%s failed: setsockopt TCP_KEEPINTVL (%d): %s",
+                            __func__, sock, safe_strerror(errno));
+               return -1;
+       }
+
+       /* Set maximum probes */
+       val = keepalive_probes;
+       if (setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
+               flog_err_sys(EC_LIB_SYSTEM_CALL,
+                            "%s failed: setsockopt TCP_KEEPCNT (%d): %s",
+                            __func__, sock, safe_strerror(errno));
+               return -1;
+       }
+
+       return 0;
+#endif
+}
index 6c80841e3c2b904ec20a8b1766bae21ef11e01e9..694edf7638aad6b39500dd57af8bb6680f005968 100644 (file)
@@ -153,6 +153,28 @@ extern int sockopt_tcp_mss_set(int sock, int tcp_maxseg);
  *    Socket to get max segement size.
  */
 extern int sockopt_tcp_mss_get(int sock);
+
+/*
+ * Configure TCP keepalive for a given socket
+ *
+ * sock
+ *   Socket to enable keepalive option on.
+ *
+ * keepalive_idle
+ *   number of seconds a connection needs to be idle
+ *   before sending out keep-alive proves
+ *
+ * keepalive_intvl
+ *   number of seconds between TCP keep-alive probes
+ *
+ * keepalive_probes
+ *   max number of probers to send before giving up
+ *   and killing tcp connection
+ */
+extern int setsockopt_tcp_keepalive(int sock, uint16_t keepalive_idle,
+                                   uint16_t keepalive_intvl,
+                                   uint16_t keepalive_probes);
+
 #ifdef __cplusplus
 }
 #endif
index 50c410ad24242944d7d669bcfa6795e178682fcb..8aeabb34e61399d67ff5f690fb6ccbf03120c1f7 100644 (file)
@@ -850,9 +850,12 @@ macro_inline type *prefix ## _add(struct prefix##_head *h, type *item)         \
        struct thash_item **np = &h->hh.entries[hbits];                        \
        while (*np && (*np)->hashval < hval)                                   \
                np = &(*np)->next;                                             \
-       if (*np && cmpfn(container_of(*np, type, field.hi), item) == 0) {      \
-               h->hh.count--;                                                 \
-               return container_of(*np, type, field.hi);                      \
+       while (*np && (*np)->hashval == hval) {                                \
+               if (cmpfn(container_of(*np, type, field.hi), item) == 0) {     \
+                       h->hh.count--;                                         \
+                       return container_of(*np, type, field.hi);              \
+               }                                                              \
+               np = &(*np)->next;                                             \
        }                                                                      \
        item->field.hi.next = *np;                                             \
        *np = &item->field.hi;                                                 \
index 3a8baa2342ddd1a75e75c81e3db13737f4315dcf..53ba9eb12f3b0d449edd47291f6db72873c38d52 100644 (file)
@@ -126,6 +126,8 @@ DEFUN_NOSH(show_debugging_nhrp, show_debugging_nhrp_cmd,
                        debug_flags_desc[i].str);
        }
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index a16f4f73eb6ae4a25e0b6236aebb93baa57b3234..fe742b912fb0ebb6386416e72c85270010e0a713 100644 (file)
@@ -115,6 +115,8 @@ DEFUN_NOSH (show_debugging_ospf6,
 
        config_write_ospf6_debug(vty);
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index 258a93fb16fc92943488af27f0f7c7692cd4b119..9f6adf322685c67346d0e06b00df6f889a630871 100644 (file)
@@ -54,13 +54,13 @@ unsigned long conf_debug_ospf_nsm = 0;
 unsigned long conf_debug_ospf_lsa = 0;
 unsigned long conf_debug_ospf_zebra = 0;
 unsigned long conf_debug_ospf_nssa = 0;
-unsigned long conf_debug_ospf_te = 0;
+unsigned long conf_debug_ospf_te;
 unsigned long conf_debug_ospf_ext = 0;
-unsigned long conf_debug_ospf_sr = 0;
-unsigned long conf_debug_ospf_ti_lfa = 0;
-unsigned long conf_debug_ospf_defaultinfo = 0;
-unsigned long conf_debug_ospf_ldp_sync = 0;
-unsigned long conf_debug_ospf_gr = 0;
+unsigned long conf_debug_ospf_sr;
+unsigned long conf_debug_ospf_ti_lfa;
+unsigned long conf_debug_ospf_defaultinfo;
+unsigned long conf_debug_ospf_ldp_sync;
+unsigned long conf_debug_ospf_gr;
 unsigned long conf_debug_ospf_bfd;
 unsigned long conf_debug_ospf_client_api;
 
@@ -72,13 +72,13 @@ unsigned long term_debug_ospf_nsm = 0;
 unsigned long term_debug_ospf_lsa = 0;
 unsigned long term_debug_ospf_zebra = 0;
 unsigned long term_debug_ospf_nssa = 0;
-unsigned long term_debug_ospf_te = 0;
+unsigned long term_debug_ospf_te;
 unsigned long term_debug_ospf_ext = 0;
-unsigned long term_debug_ospf_sr = 0;
-unsigned long term_debug_ospf_ti_lfa = 0;
+unsigned long term_debug_ospf_sr;
+unsigned long term_debug_ospf_ti_lfa;
 unsigned long term_debug_ospf_defaultinfo;
 unsigned long term_debug_ospf_ldp_sync;
-unsigned long term_debug_ospf_gr = 0;
+unsigned long term_debug_ospf_gr;
 unsigned long term_debug_ospf_bfd;
 unsigned long term_debug_ospf_client_api;
 
@@ -628,84 +628,9 @@ void ospf_packet_dump(struct stream *s)
        stream_set_getp(s, gp);
 }
 
-DEFUN (debug_ospf_packet,
+DEFPY (debug_ospf_packet,
        debug_ospf_packet_cmd,
-       "debug ospf [(1-65535)] packet <hello|dd|ls-request|ls-update|ls-ack|all> [<send [detail]|recv [detail]|detail>]",
-       DEBUG_STR
-       OSPF_STR
-       "Instance ID\n"
-       "OSPF packets\n"
-       "OSPF Hello\n"
-       "OSPF Database Description\n"
-       "OSPF Link State Request\n"
-       "OSPF Link State Update\n"
-       "OSPF Link State Acknowledgment\n"
-       "OSPF all packets\n"
-       "Packet sent\n"
-       "Detail Information\n"
-       "Packet received\n"
-       "Detail Information\n"
-       "Detail Information\n")
-{
-       int inst = (argv[2]->type == RANGE_TKN) ? 1 : 0;
-       int detail = strmatch(argv[argc - 1]->text, "detail");
-       int send = strmatch(argv[argc - (1 + detail)]->text, "send");
-       int recv = strmatch(argv[argc - (1 + detail)]->text, "recv");
-       char *packet = argv[3 + inst]->text;
-
-       if (inst) // user passed instance ID
-       {
-               if (inst != ospf_instance)
-                       return CMD_NOT_MY_INSTANCE;
-       }
-
-       int type = 0;
-       int flag = 0;
-       int i;
-
-       /* Check packet type. */
-       if (strmatch(packet, "hello"))
-               type = OSPF_DEBUG_HELLO;
-       else if (strmatch(packet, "dd"))
-               type = OSPF_DEBUG_DB_DESC;
-       else if (strmatch(packet, "ls-request"))
-               type = OSPF_DEBUG_LS_REQ;
-       else if (strmatch(packet, "ls-update"))
-               type = OSPF_DEBUG_LS_UPD;
-       else if (strmatch(packet, "ls-ack"))
-               type = OSPF_DEBUG_LS_ACK;
-       else if (strmatch(packet, "all"))
-               type = OSPF_DEBUG_ALL;
-
-       /* Cases:
-        * (none)      = send + recv
-        * detail      = send + recv + detail
-        * recv        = recv
-        * send        = send
-        * recv detail = recv + detail
-        * send detail = send + detail
-        */
-       if (!send && !recv)
-               send = recv = 1;
-
-       flag |= (send) ? OSPF_DEBUG_SEND : 0;
-       flag |= (recv) ? OSPF_DEBUG_RECV : 0;
-       flag |= (detail) ? OSPF_DEBUG_DETAIL : 0;
-
-       for (i = 0; i < 5; i++)
-               if (type & (0x01 << i)) {
-                       if (vty->node == CONFIG_NODE)
-                               DEBUG_PACKET_ON(i, flag);
-                       else
-                               TERM_DEBUG_PACKET_ON(i, flag);
-               }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_ospf_packet,
-       no_debug_ospf_packet_cmd,
-       "no debug ospf [(1-65535)] packet <hello|dd|ls-request|ls-update|ls-ack|all> [<send [detail]|recv [detail]|detail>]",
+       "[no$no] debug ospf [(1-65535)$inst] packet <hello|dd|ls-request|ls-update|ls-ack|all>$packet [<send$send [detail$detail]|recv$recv [detail$detail]|detail$detail>]",
        NO_STR
        DEBUG_STR
        OSPF_STR
@@ -723,22 +648,13 @@ DEFUN (no_debug_ospf_packet,
        "Detail Information\n"
        "Detail Information\n")
 {
-       int inst = (argv[3]->type == RANGE_TKN) ? 1 : 0;
-       int detail = strmatch(argv[argc - 1]->text, "detail");
-       int send = strmatch(argv[argc - (1 + detail)]->text, "send");
-       int recv = strmatch(argv[argc - (1 + detail)]->text, "recv");
-       char *packet = argv[4 + inst]->text;
-
-       if (inst) // user passed instance ID
-       {
-               if (inst != ospf_instance)
-                       return CMD_NOT_MY_INSTANCE;
-       }
-
        int type = 0;
        int flag = 0;
        int i;
 
+       if (inst && inst != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+
        /* Check packet type. */
        if (strmatch(packet, "hello"))
                type = OSPF_DEBUG_HELLO;
@@ -761,8 +677,10 @@ DEFUN (no_debug_ospf_packet,
         * recv detail = recv + detail
         * send detail = send + detail
         */
-       if (!send && !recv)
-               send = recv = 1;
+       if (!send && !recv) {
+               flag |= OSPF_DEBUG_SEND;
+               flag |= OSPF_DEBUG_RECV;
+       }
 
        flag |= (send) ? OSPF_DEBUG_SEND : 0;
        flag |= (recv) ? OSPF_DEBUG_RECV : 0;
@@ -770,10 +688,17 @@ DEFUN (no_debug_ospf_packet,
 
        for (i = 0; i < 5; i++)
                if (type & (0x01 << i)) {
-                       if (vty->node == CONFIG_NODE)
-                               DEBUG_PACKET_OFF(i, flag);
-                       else
-                               TERM_DEBUG_PACKET_OFF(i, flag);
+                       if (vty->node == CONFIG_NODE) {
+                               if (no)
+                                       DEBUG_PACKET_OFF(i, flag);
+                               else
+                                       DEBUG_PACKET_ON(i, flag);
+                       } else {
+                               if (no)
+                                       TERM_DEBUG_PACKET_OFF(i, flag);
+                               else
+                                       TERM_DEBUG_PACKET_ON(i, flag);
+                       }
                }
 
 #ifdef DEBUG
@@ -1457,194 +1382,221 @@ DEFUN (no_debug_ospf_instance_nssa,
        return CMD_SUCCESS;
 }
 
-DEFUN (debug_ospf_te,
+DEFPY (debug_ospf_te,
        debug_ospf_te_cmd,
-       "debug ospf te",
-       DEBUG_STR
-       OSPF_STR
-       "OSPF-TE information\n")
-{
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(te, TE);
-       TERM_DEBUG_ON(te, TE);
-       return CMD_SUCCESS;
-}
-
-DEFUN (no_debug_ospf_te,
-       no_debug_ospf_te_cmd,
-       "no debug ospf te",
+       "[no$no] debug ospf [(1-65535)$instance] te",
        NO_STR
        DEBUG_STR
        OSPF_STR
+       "Instance ID\n"
        "OSPF-TE information\n")
 {
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_OFF(te, TE);
-       TERM_DEBUG_OFF(te, TE);
+       if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+
+       if (vty->node == CONFIG_NODE) {
+               if (no)
+                       DEBUG_OFF(te, TE);
+               else
+                       DEBUG_ON(te, TE);
+       } else {
+               if (no)
+                       TERM_DEBUG_OFF(te, TE);
+               else
+                       TERM_DEBUG_ON(te, TE);
+       }
+
        return CMD_SUCCESS;
 }
 
-DEFUN (debug_ospf_sr,
+DEFPY (debug_ospf_sr,
        debug_ospf_sr_cmd,
-       "debug ospf sr",
+       "[no$no] debug ospf [(1-65535)$instance] sr",
+       NO_STR
        DEBUG_STR
        OSPF_STR
+       "Instance ID\n"
        "OSPF-SR information\n")
 {
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(sr, SR);
-       TERM_DEBUG_ON(sr, SR);
+       if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+
+       if (vty->node == CONFIG_NODE) {
+               if (no)
+                       DEBUG_OFF(sr, SR);
+               else
+                       DEBUG_ON(sr, SR);
+       } else {
+               if (no)
+                       TERM_DEBUG_OFF(sr, SR);
+               else
+                       TERM_DEBUG_ON(sr, SR);
+       }
+
        return CMD_SUCCESS;
 }
 
-DEFUN (no_debug_ospf_sr,
-       no_debug_ospf_sr_cmd,
-       "no debug ospf sr",
+DEFPY (debug_ospf_ti_lfa,
+       debug_ospf_ti_lfa_cmd,
+       "[no$no] debug ospf [(1-65535)$instance] ti-lfa",
        NO_STR
        DEBUG_STR
        OSPF_STR
-       "OSPF-SR information\n")
+       "Instance ID\n"
+       "OSPF-SR TI-LFA information\n")
 {
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_OFF(sr, SR);
-       TERM_DEBUG_OFF(sr, SR);
-       return CMD_SUCCESS;
-}
+       if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
 
-DEFUN(debug_ospf_ti_lfa, debug_ospf_ti_lfa_cmd, "debug ospf ti-lfa",
-      DEBUG_STR OSPF_STR "OSPF-SR TI-LFA information\n")
-{
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(ti_lfa, TI_LFA);
-       TERM_DEBUG_ON(ti_lfa, TI_LFA);
-       return CMD_SUCCESS;
-}
+       if (vty->node == CONFIG_NODE) {
+               if (no)
+                       DEBUG_OFF(ti_lfa, TI_LFA);
+               else
+                       DEBUG_ON(ti_lfa, TI_LFA);
+       } else {
+               if (no)
+                       TERM_DEBUG_OFF(ti_lfa, TI_LFA);
+               else
+                       TERM_DEBUG_ON(ti_lfa, TI_LFA);
+       }
 
-DEFUN(no_debug_ospf_ti_lfa, no_debug_ospf_ti_lfa_cmd, "no debug ospf ti-lfa",
-      NO_STR DEBUG_STR OSPF_STR "OSPF-SR TI-LFA information\n")
-{
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_OFF(ti_lfa, TI_LFA);
-       TERM_DEBUG_OFF(ti_lfa, TI_LFA);
        return CMD_SUCCESS;
 }
 
-DEFUN (debug_ospf_default_info,
+DEFPY (debug_ospf_default_info,
        debug_ospf_default_info_cmd,
-       "debug ospf default-information",
+       "[no$no] debug ospf [(1-65535)$instance] default-information",
+       NO_STR
        DEBUG_STR
        OSPF_STR
+       "Instance ID\n"
        "OSPF default information\n")
 {
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(defaultinfo, DEFAULTINFO);
-       TERM_DEBUG_ON(defaultinfo, DEFAULTINFO);
+       if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+
+       if (vty->node == CONFIG_NODE) {
+               if (no)
+                       DEBUG_OFF(defaultinfo, DEFAULTINFO);
+               else
+                       DEBUG_ON(defaultinfo, DEFAULTINFO);
+       } else {
+               if (no)
+                       TERM_DEBUG_OFF(defaultinfo, DEFAULTINFO);
+               else
+                       TERM_DEBUG_ON(defaultinfo, DEFAULTINFO);
+       }
+
        return CMD_SUCCESS;
 }
 
-DEFUN (no_debug_ospf_default_info,
-       no_debug_ospf_default_info_cmd,
-       "no debug ospf default-information",
+DEFPY (debug_ospf_ldp_sync,
+       debug_ospf_ldp_sync_cmd,
+       "[no$no] debug ospf [(1-65535)$instance] ldp-sync",
        NO_STR
        DEBUG_STR
        OSPF_STR
-       "OSPF default information\n")
-{
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_OFF(defaultinfo, DEFAULTINFO);
-       TERM_DEBUG_OFF(defaultinfo, DEFAULTINFO);
-       return CMD_SUCCESS;
-}
-
-DEFUN(debug_ospf_ldp_sync,
-      debug_ospf_ldp_sync_cmd,
-      "debug ospf ldp-sync",
-      DEBUG_STR OSPF_STR
-      "OSPF LDP-Sync information\n")
+       "Instance ID\n"
+       "OSPF LDP-Sync information\n")
 {
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(ldp_sync, LDP_SYNC);
-       TERM_DEBUG_ON(ldp_sync, LDP_SYNC);
-       return CMD_SUCCESS;
-}
+       if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
 
-DEFUN(no_debug_ospf_ldp_sync,
-      no_debug_ospf_ldp_sync_cmd,
-      "no debug ospf ldp-sync",
-      NO_STR
-      DEBUG_STR
-      OSPF_STR
-      "OSPF LDP-Sync information\n")
-{
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_OFF(ldp_sync, LDP_SYNC);
-       TERM_DEBUG_OFF(ldp_sync, LDP_SYNC);
+       if (vty->node == CONFIG_NODE) {
+               if (no)
+                       DEBUG_OFF(ldp_sync, LDP_SYNC);
+               else
+                       DEBUG_ON(ldp_sync, LDP_SYNC);
+       } else {
+               if (no)
+                       TERM_DEBUG_OFF(ldp_sync, LDP_SYNC);
+               else
+                       TERM_DEBUG_ON(ldp_sync, LDP_SYNC);
+       }
 
        return CMD_SUCCESS;
 }
 
-DEFPY(debug_ospf_gr, debug_ospf_gr_cmd, "[no$no] debug ospf graceful-restart",
-      NO_STR DEBUG_STR OSPF_STR "OSPF Graceful Restart\n")
+DEFPY (debug_ospf_gr,
+       debug_ospf_gr_cmd,
+       "[no$no] debug ospf [(1-65535)$instance] graceful-restart",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF Graceful Restart\n")
 {
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(gr, GR);
+       if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
 
-       if (!no)
-               TERM_DEBUG_ON(gr, GR);
-       else
+       if (vty->node == CONFIG_NODE) {
+               if (no)
+                       CONF_DEBUG_OFF(gr, GR);
+               else
+                       CONF_DEBUG_ON(gr, GR);
+       }
+
+       if (no)
                TERM_DEBUG_OFF(gr, GR);
+       else
+               TERM_DEBUG_ON(gr, GR);
 
        return CMD_SUCCESS;
 }
 
-DEFPY(debug_ospf_bfd, debug_ospf_bfd_cmd,
-      "[no] debug ospf bfd",
-      NO_STR
-      DEBUG_STR
-      OSPF_STR
-      "Bidirection Forwarding Detection\n")
+DEFPY (debug_ospf_bfd,
+       debug_ospf_bfd_cmd,
+       "[no] debug ospf [(1-65535)$instance] bfd",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "Bidirection Forwarding Detection\n")
 {
+       if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+
        if (vty->node == CONFIG_NODE) {
                if (no) {
                        bfd_protocol_integration_set_debug(false);
-                       CONF_DEBUG_OFF(bfd, BFD_LIB);
+                       DEBUG_OFF(bfd, BFD_LIB);
                } else {
                        bfd_protocol_integration_set_debug(true);
-                       CONF_DEBUG_ON(bfd, BFD_LIB);
+                       DEBUG_ON(bfd, BFD_LIB);
                }
+       } else {
+               if (no)
+                       TERM_DEBUG_OFF(bfd, BFD_LIB);
+               else
+                       TERM_DEBUG_ON(bfd, BFD_LIB);
        }
 
-       if (no)
-               TERM_DEBUG_OFF(bfd, BFD_LIB);
-       else
-               TERM_DEBUG_ON(bfd, BFD_LIB);
-
        return CMD_SUCCESS;
 }
 
-DEFUN(debug_ospf_client_api,
-      debug_ospf_client_api_cmd,
-      "debug ospf client-api",
-      DEBUG_STR OSPF_STR
-      "OSPF client API information\n")
+DEFPY (debug_ospf_client_api,
+       debug_ospf_client_api_cmd,
+       "[no$no] debug ospf [(1-65535)$instance] client-api",
+       NO_STR
+       DEBUG_STR
+       OSPF_STR
+       "Instance ID\n"
+       "OSPF client API information\n")
 {
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(client_api, CLIENT_API);
-       TERM_DEBUG_ON(client_api, CLIENT_API);
-       return CMD_SUCCESS;
-}
+       if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
 
-DEFUN(no_debug_ospf_client_api,
-      no_debug_ospf_client_api_cmd,
-      "no debug ospf client-api",
-      NO_STR
-      DEBUG_STR
-      OSPF_STR
-      "OSPF client API information\n")
-{
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_OFF(client_api, CLIENT_API);
-       TERM_DEBUG_OFF(client_api, CLIENT_API);
+       if (vty->node == CONFIG_NODE) {
+               if (no)
+                       DEBUG_OFF(client_api, CLIENT_API);
+               else
+                       DEBUG_ON(client_api, CLIENT_API);
+       } else {
+               if (no)
+                       TERM_DEBUG_OFF(client_api, CLIENT_API);
+               else
+                       TERM_DEBUG_ON(client_api, CLIENT_API);
+       }
 
        return CMD_SUCCESS;
 }
@@ -1816,7 +1768,7 @@ static int show_debugging_ospf_common(struct vty *vty)
        }
 
        if (IS_DEBUG_OSPF(defaultinfo, DEFAULTINFO) == OSPF_DEBUG_DEFAULTINFO)
-               vty_out(vty, "OSPF default information is on\n");
+               vty_out(vty, "  OSPF default information is on\n");
 
        /* Show debug status for NSSA. */
        if (IS_DEBUG_OSPF(nssa, NSSA) == OSPF_DEBUG_NSSA)
@@ -1860,7 +1812,11 @@ DEFUN_NOSH (show_debugging_ospf,
            DEBUG_STR
            OSPF_STR)
 {
-       return show_debugging_ospf_common(vty);
+       show_debugging_ospf_common(vty);
+
+       cmd_show_lib_debugs(vty);
+
+       return CMD_SUCCESS;
 }
 
 DEFUN_NOSH (show_debugging_ospf_instance,
@@ -1878,7 +1834,11 @@ DEFUN_NOSH (show_debugging_ospf_instance,
        if (instance != ospf_instance)
                return CMD_NOT_MY_INSTANCE;
 
-       return show_debugging_ospf_common(vty);
+       show_debugging_ospf_common(vty);
+
+       cmd_show_lib_debugs(vty);
+
+       return CMD_SUCCESS;
 }
 
 static int config_write_debug(struct vty *vty);
@@ -1978,7 +1938,7 @@ static int config_write_debug(struct vty *vty)
                     & (OSPF_DEBUG_SEND_RECV | OSPF_DEBUG_DETAIL);
        if (r == (OSPF_DEBUG_SEND_RECV | OSPF_DEBUG_DETAIL)) {
                vty_out(vty, "debug ospf%s packet all detail\n", str);
-               return 1;
+               write = 1;
        }
 
        /* debug ospf packet all. */
@@ -1991,7 +1951,7 @@ static int config_write_debug(struct vty *vty)
                        if (conf_debug_ospf_packet[i] & OSPF_DEBUG_DETAIL)
                                vty_out(vty, "debug ospf%s packet %s detail\n",
                                        str, type_str[i]);
-               return 1;
+               write = 1;
        }
 
        /* debug ospf packet (hello|dd|ls-request|ls-update|ls-ack)
@@ -2047,6 +2007,13 @@ static int config_write_debug(struct vty *vty)
                write = 1;
        }
 
+       /* debug ospf default-information */
+       if (IS_CONF_DEBUG_OSPF(defaultinfo, DEFAULTINFO) ==
+           OSPF_DEBUG_DEFAULTINFO) {
+               vty_out(vty, "debug ospf%s default-information\n", str);
+               write = 1;
+       }
+
        return write;
 }
 
@@ -2074,18 +2041,11 @@ void ospf_debug_init(void)
        install_element(ENABLE_NODE, &no_debug_ospf_zebra_cmd);
        install_element(ENABLE_NODE, &no_debug_ospf_event_cmd);
        install_element(ENABLE_NODE, &no_debug_ospf_nssa_cmd);
-       install_element(ENABLE_NODE, &no_debug_ospf_te_cmd);
-       install_element(ENABLE_NODE, &no_debug_ospf_sr_cmd);
-       install_element(ENABLE_NODE, &no_debug_ospf_ti_lfa_cmd);
-       install_element(ENABLE_NODE, &no_debug_ospf_default_info_cmd);
-       install_element(ENABLE_NODE, &no_debug_ospf_ldp_sync_cmd);
-       install_element(ENABLE_NODE, &no_debug_ospf_client_api_cmd);
        install_element(ENABLE_NODE, &debug_ospf_gr_cmd);
        install_element(ENABLE_NODE, &debug_ospf_bfd_cmd);
 
        install_element(ENABLE_NODE, &show_debugging_ospf_instance_cmd);
        install_element(ENABLE_NODE, &debug_ospf_packet_cmd);
-       install_element(ENABLE_NODE, &no_debug_ospf_packet_cmd);
 
        install_element(ENABLE_NODE, &debug_ospf_instance_nsm_cmd);
        install_element(ENABLE_NODE, &debug_ospf_instance_lsa_cmd);
@@ -2100,7 +2060,6 @@ void ospf_debug_init(void)
        install_element(ENABLE_NODE, &no_debug_ospf_cmd);
 
        install_element(CONFIG_NODE, &debug_ospf_packet_cmd);
-       install_element(CONFIG_NODE, &no_debug_ospf_packet_cmd);
        install_element(CONFIG_NODE, &debug_ospf_ism_cmd);
        install_element(CONFIG_NODE, &no_debug_ospf_ism_cmd);
 
@@ -2120,12 +2079,6 @@ void ospf_debug_init(void)
        install_element(CONFIG_NODE, &no_debug_ospf_zebra_cmd);
        install_element(CONFIG_NODE, &no_debug_ospf_event_cmd);
        install_element(CONFIG_NODE, &no_debug_ospf_nssa_cmd);
-       install_element(CONFIG_NODE, &no_debug_ospf_te_cmd);
-       install_element(CONFIG_NODE, &no_debug_ospf_sr_cmd);
-       install_element(CONFIG_NODE, &no_debug_ospf_ti_lfa_cmd);
-       install_element(CONFIG_NODE, &no_debug_ospf_default_info_cmd);
-       install_element(CONFIG_NODE, &no_debug_ospf_ldp_sync_cmd);
-       install_element(CONFIG_NODE, &no_debug_ospf_client_api_cmd);
        install_element(CONFIG_NODE, &debug_ospf_gr_cmd);
        install_element(CONFIG_NODE, &debug_ospf_bfd_cmd);
 
index 2a0016ea1957ee9b41d24ca7e0deff2581df2a68..c957c8c014e0757e89b9b396b2a9ed35590270a7 100644 (file)
@@ -9892,49 +9892,6 @@ DEFPY(no_ospf_gr_helper_enable,
        return CMD_SUCCESS;
 }
 
-#if CONFDATE > 20220921
-CPP_NOTICE(
-       "Time to remove the deprecated \"[no] graceful-restart helper-only\" commands")
-#endif
-
-DEFPY_HIDDEN(ospf_gr_helper_only, ospf_gr_helper_only_cmd,
-      "graceful-restart helper-only [A.B.C.D]",
-      "OSPF Graceful Restart\n"
-      "Enable Helper support\n"
-      "Advertising router id\n")
-{
-       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-       struct in_addr addr;
-       int ret;
-
-       vty_out(vty,
-               "%% This command is deprecated. Please, use `graceful-restart helper enable` instead.\n");
-
-       if (argc == 3) {
-               ret = inet_aton(argv[2]->arg, &addr);
-               if (!ret) {
-                       vty_out(vty,
-                               "Please specify the valid routerid address.\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-
-               ospf_gr_helper_support_set_per_routerid(ospf, &addr, OSPF_GR_TRUE);
-               return CMD_SUCCESS;
-       }
-
-       ospf_gr_helper_support_set(ospf, OSPF_GR_TRUE);
-
-       return CMD_SUCCESS;
-}
-
-ALIAS_HIDDEN(no_ospf_gr_helper_enable,
-      no_ospf_gr_helper_only_cmd,
-      "no graceful-restart helper-only [A.B.C.D]",
-      NO_STR
-      "OSPF Graceful Restart\n"
-      "Disable Helper support\n"
-      "Advertising router id\n")
-
 DEFPY(ospf_gr_helper_enable_lsacheck,
       ospf_gr_helper_enable_lsacheck_cmd,
       "graceful-restart helper strict-lsa-checking",
@@ -12862,8 +12819,6 @@ static void ospf_vty_zebra_init(void)
        /*Ospf garcefull restart helper configurations */
        install_element(OSPF_NODE, &ospf_gr_helper_enable_cmd);
        install_element(OSPF_NODE, &no_ospf_gr_helper_enable_cmd);
-       install_element(OSPF_NODE, &ospf_gr_helper_only_cmd);
-       install_element(OSPF_NODE, &no_ospf_gr_helper_only_cmd);
        install_element(OSPF_NODE, &ospf_gr_helper_enable_lsacheck_cmd);
        install_element(OSPF_NODE, &no_ospf_gr_helper_enable_lsacheck_cmd);
        install_element(OSPF_NODE, &ospf_gr_helper_supported_grace_time_cmd);
index 4775aa36fbda8a6af70f12d98c61b12596ed30f2..13e52ac86bf7604d20b81b266de777b35414a6bd 100644 (file)
@@ -1092,6 +1092,8 @@ DEFPY_NOSH(show_debugging_pathd, show_debugging_pathd_cmd,
           "State of each debugging option\n"
           "pathd module debugging\n")
 {
+
+       cmd_show_lib_debugs(vty);
        /* nothing to do here */
        return CMD_SUCCESS;
 }
index 270c664dafb4ad86b3d2ab72d29dd08d79057df9..316255a97ee236fd63cb76423b9723dcfd13be39 100644 (file)
@@ -243,16 +243,16 @@ uint32_t path_ted_query_type_f(struct ipaddr *local, struct ipaddr *remote)
                }
                break;
        case IPADDR_V6:
-               key = (uint64_t)(local->ip._v6_addr.s6_addr32[0] & 0xffffffff)
-                     | ((uint64_t)local->ip._v6_addr.s6_addr32[1] << 32);
+               key = (uint64_t)ntohl(local->ip._v6_addr.s6_addr32[2]) << 32 |
+                     (uint64_t)ntohl(local->ip._v6_addr.s6_addr32[3]);
                edge = ls_find_edge_by_key(ted_state_g.ted, key);
                if (edge) {
-                       if ((memcmp(&edge->attributes->standard.remote6,
-                                   &remote->ip._v6_addr,
-                                   sizeof(remote->ip._v6_addr))
-                            && CHECK_FLAG(edge->attributes->flags,
-                                          LS_ATTR_ADJ_SID))) {
-                               sid = edge->attributes->adj_sid[0]
+                       if ((0 == memcmp(&edge->attributes->standard.remote6,
+                                        &remote->ip._v6_addr,
+                                        sizeof(remote->ip._v6_addr)) &&
+                            CHECK_FLAG(edge->attributes->flags,
+                                       LS_ATTR_ADJ_SID6))) {
+                               sid = edge->attributes->adj_sid[ADJ_PRI_IPV6]
                                              .sid; /* from primary */
                                break;
                        }
@@ -385,7 +385,7 @@ DEFUN (no_path_ted,
        "Disable the TE Database functionality\n")
 /* clang-format on */
 {
-       if (ted_state_g.enabled) {
+       if (!ted_state_g.enabled) {
                PATH_TED_DEBUG("%s: PATHD-TED: OFF -> OFF", __func__);
                return CMD_SUCCESS;
        }
@@ -462,7 +462,7 @@ DEFPY (show_pathd_ted_db,
        json_object *json = NULL;
 
        if (!ted_state_g.enabled) {
-               vty_out(vty, "PATHD TED database is not enabled\n");
+               vty_out(vty, "Traffic Engineering database is not enabled\n");
                return CMD_WARNING;
        }
        if (strcmp(ver_json, "json") == 0) {
index a2b3431b94fcc346e8f8130a5bb58199cc2d9801..6f53adb334da8e37a326425e5dc585acacd63e55 100644 (file)
@@ -1243,6 +1243,8 @@ DEFUN_NOSH(show_debugging_pbr,
 
        pbr_debug_config_write_helper(vty, false);
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index dc84de6bfd6377da01857d8b7dfa751fa83d5d33..f6b370cee32b0a6d369876ebef9e374b507baa26 100644 (file)
@@ -1558,6 +1558,93 @@ DEFUN_NOSH (show_debugging_pimv6,
 
        pim_debug_config_write(vty);
 
+       cmd_show_lib_debugs(vty);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (debug_mld,
+       debug_mld_cmd,
+       "[no] debug mld",
+       NO_STR
+       DEBUG_STR
+       DEBUG_MLD_STR)
+{
+       if (!no) {
+               PIM_DO_DEBUG_GM_EVENTS;
+               PIM_DO_DEBUG_GM_PACKETS;
+               PIM_DO_DEBUG_GM_TRACE;
+       } else {
+               PIM_DONT_DEBUG_GM_EVENTS;
+               PIM_DONT_DEBUG_GM_PACKETS;
+               PIM_DONT_DEBUG_GM_TRACE;
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (debug_mld_events,
+       debug_mld_events_cmd,
+       "[no] debug mld events",
+       NO_STR
+       DEBUG_STR
+       DEBUG_MLD_STR
+       DEBUG_MLD_EVENTS_STR)
+{
+       if (!no)
+               PIM_DO_DEBUG_GM_EVENTS;
+       else
+               PIM_DONT_DEBUG_GM_EVENTS;
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (debug_mld_packets,
+       debug_mld_packets_cmd,
+       "[no] debug mld packets",
+       NO_STR
+       DEBUG_STR
+       DEBUG_MLD_STR
+       DEBUG_MLD_PACKETS_STR)
+{
+       if (!no)
+               PIM_DO_DEBUG_GM_PACKETS;
+       else
+               PIM_DONT_DEBUG_GM_PACKETS;
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (debug_mld_trace,
+       debug_mld_trace_cmd,
+       "[no] debug mld trace",
+       NO_STR
+       DEBUG_STR
+       DEBUG_MLD_STR
+       DEBUG_MLD_TRACE_STR)
+{
+       if (!no)
+               PIM_DO_DEBUG_GM_TRACE;
+       else
+               PIM_DONT_DEBUG_GM_TRACE;
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (debug_mld_trace_detail,
+       debug_mld_trace_detail_cmd,
+       "[no] debug mld trace detail",
+       NO_STR
+       DEBUG_STR
+       DEBUG_MLD_STR
+       DEBUG_MLD_TRACE_STR
+       "detailed\n")
+{
+       if (!no)
+               PIM_DO_DEBUG_GM_TRACE_DETAIL;
+       else
+               PIM_DONT_DEBUG_GM_TRACE_DETAIL;
+
        return CMD_SUCCESS;
 }
 
@@ -1693,6 +1780,11 @@ void pim_cmd_init(void)
        install_element(ENABLE_NODE, &debug_pimv6_zebra_cmd);
        install_element(ENABLE_NODE, &debug_mroute6_cmd);
        install_element(ENABLE_NODE, &debug_mroute6_detail_cmd);
+       install_element(ENABLE_NODE, &debug_mld_cmd);
+       install_element(ENABLE_NODE, &debug_mld_events_cmd);
+       install_element(ENABLE_NODE, &debug_mld_packets_cmd);
+       install_element(ENABLE_NODE, &debug_mld_trace_cmd);
+       install_element(ENABLE_NODE, &debug_mld_trace_detail_cmd);
 
        install_element(CONFIG_NODE, &debug_pimv6_cmd);
        install_element(CONFIG_NODE, &debug_pimv6_nht_cmd);
@@ -1706,4 +1798,9 @@ void pim_cmd_init(void)
        install_element(CONFIG_NODE, &debug_pimv6_zebra_cmd);
        install_element(CONFIG_NODE, &debug_mroute6_cmd);
        install_element(CONFIG_NODE, &debug_mroute6_detail_cmd);
+       install_element(CONFIG_NODE, &debug_mld_cmd);
+       install_element(CONFIG_NODE, &debug_mld_events_cmd);
+       install_element(CONFIG_NODE, &debug_mld_packets_cmd);
+       install_element(CONFIG_NODE, &debug_mld_trace_cmd);
+       install_element(CONFIG_NODE, &debug_mld_trace_detail_cmd);
 }
index e0b5a87e059a7c2c35057bc1cc7619648ab611a3..7ac22fd02524bcf5f9b125a43b5ae9e3c72180bb 100644 (file)
@@ -119,9 +119,7 @@ static const struct frr_yang_module_info *const pim6d_yang_modules[] = {
 
 /* clang-format off */
 FRR_DAEMON_INFO(pim6d, PIM6,
-       .vty_port = 0,
-       .flags = FRR_NO_SPLIT_CONFIG,
-
+       .vty_port = PIM6D_VTY_PORT,
        .proghelp = "Protocol Independent Multicast (RFC7761) for IPv6",
 
        .signals = pim6d_signals,
index b9c3aec30c4c03f2c5424d900629ecca12e1e34f..23042ef14e6094a13eccab7ddf7f0f840bc5f9fd 100644 (file)
@@ -1609,7 +1609,7 @@ static void gm_t_recv(struct thread *t)
        char rxbuf[2048];
        struct msghdr mh[1] = {};
        struct iovec iov[1];
-       struct sockaddr_in6 pkt_src[1];
+       struct sockaddr_in6 pkt_src[1] = {};
        ssize_t nread;
        size_t pktlen;
 
@@ -2122,15 +2122,47 @@ static void gm_start(struct interface *ifp)
        }
 }
 
-void gm_ifp_teardown(struct interface *ifp)
+void gm_group_delete(struct gm_if *gm_ifp)
 {
-       struct pim_interface *pim_ifp = ifp->info;
-       struct gm_if *gm_ifp;
+       struct gm_sg *sg;
        struct gm_packet_state *pkt;
        struct gm_grp_pending *pend_grp;
        struct gm_gsq_pending *pend_gsq;
        struct gm_subscriber *subscriber;
-       struct gm_sg *sg;
+
+       while ((pkt = gm_packet_expires_first(gm_ifp->expires)))
+               gm_packet_drop(pkt, false);
+
+       while ((pend_grp = gm_grp_pends_pop(gm_ifp->grp_pends))) {
+               THREAD_OFF(pend_grp->t_expire);
+               XFREE(MTYPE_GM_GRP_PENDING, pend_grp);
+       }
+
+       while ((pend_gsq = gm_gsq_pends_pop(gm_ifp->gsq_pends))) {
+               THREAD_OFF(pend_gsq->t_send);
+               XFREE(MTYPE_GM_GSQ_PENDING, pend_gsq);
+       }
+
+       while ((sg = gm_sgs_pop(gm_ifp->sgs))) {
+               THREAD_OFF(sg->t_sg_expire);
+               assertf(!gm_packet_sg_subs_count(sg->subs_negative), "%pSG",
+                       &sg->sgaddr);
+               assertf(!gm_packet_sg_subs_count(sg->subs_positive), "%pSG",
+                       &sg->sgaddr);
+
+               gm_sg_free(sg);
+       }
+       while ((subscriber = gm_subscribers_pop(gm_ifp->subscribers))) {
+               assertf(!gm_packets_count(subscriber->packets), "%pPA",
+                       &subscriber->addr);
+               XFREE(MTYPE_GM_SUBSCRIBER, subscriber);
+       }
+}
+
+void gm_ifp_teardown(struct interface *ifp)
+{
+       struct pim_interface *pim_ifp = ifp->info;
+       struct gm_if *gm_ifp;
 
        if (!pim_ifp || !pim_ifp->mld)
                return;
@@ -2161,34 +2193,7 @@ void gm_ifp_teardown(struct interface *ifp)
 
        gm_vrf_socket_decref(gm_ifp->pim);
 
-       while ((pkt = gm_packet_expires_first(gm_ifp->expires)))
-               gm_packet_drop(pkt, false);
-
-       while ((pend_grp = gm_grp_pends_pop(gm_ifp->grp_pends))) {
-               THREAD_OFF(pend_grp->t_expire);
-               XFREE(MTYPE_GM_GRP_PENDING, pend_grp);
-       }
-
-       while ((pend_gsq = gm_gsq_pends_pop(gm_ifp->gsq_pends))) {
-               THREAD_OFF(pend_gsq->t_send);
-               XFREE(MTYPE_GM_GSQ_PENDING, pend_gsq);
-       }
-
-       while ((sg = gm_sgs_pop(gm_ifp->sgs))) {
-               THREAD_OFF(sg->t_sg_expire);
-               assertf(!gm_packet_sg_subs_count(sg->subs_negative), "%pSG",
-                       &sg->sgaddr);
-               assertf(!gm_packet_sg_subs_count(sg->subs_positive), "%pSG",
-                       &sg->sgaddr);
-
-               gm_sg_free(sg);
-       }
-
-       while ((subscriber = gm_subscribers_pop(gm_ifp->subscribers))) {
-               assertf(!gm_packets_count(subscriber->packets), "%pPA",
-                       &subscriber->addr);
-               XFREE(MTYPE_GM_SUBSCRIBER, subscriber);
-       }
+       gm_group_delete(gm_ifp);
 
        gm_grp_pends_fini(gm_ifp->grp_pends);
        gm_packet_expires_fini(gm_ifp->expires);
@@ -2308,22 +2313,6 @@ void gm_ifp_update(struct interface *ifp)
        }
 }
 
-void gm_group_delete(struct gm_if *gm_ifp)
-{
-       struct gm_sg *sg, *sg_start;
-
-       sg_start = gm_sgs_first(gm_ifp->sgs);
-
-       /* clean up all mld groups */
-       frr_each_from (gm_sgs, gm_ifp->sgs, sg, sg_start) {
-               THREAD_OFF(sg->t_sg_expire);
-               if (sg->oil)
-                       pim_channel_oil_del(sg->oil, __func__);
-               gm_sgs_del(gm_ifp->sgs, sg);
-               gm_sg_free(sg);
-       }
-}
-
 /*
  * CLI (show commands only)
  */
@@ -2441,6 +2430,8 @@ static void gm_show_if_one(struct vty *vty, struct interface *ifp,
                                                gm_ifp->t_other_querier);
                json_object_int_add(js_if, "timerRobustnessValue",
                                    gm_ifp->cur_qrv);
+               json_object_int_add(js_if, "lastMemberQueryCount",
+                                   gm_ifp->cur_lmqc);
                json_object_int_add(js_if, "timerQueryIntervalMsec",
                                    gm_ifp->cur_query_intv);
                json_object_int_add(js_if, "timerQueryResponseTimerMsec",
@@ -2504,13 +2495,13 @@ static void gm_show_if(struct vty *vty, struct vrf *vrf, const char *ifname,
 
 DEFPY(gm_show_interface,
       gm_show_interface_cmd,
-      "show ipv6 mld [vrf <VRF|all>$vrf_str] interface [IFNAME] [detail$detail|json$json]",
-      DEBUG_STR
+      "show ipv6 mld [vrf <VRF|all>$vrf_str] interface [IFNAME | detail$detail] [json$json]",
       SHOW_STR
       IPV6_STR
       MLD_STR
       VRF_FULL_CMD_HELP_STR
       "MLD interface information\n"
+      "Interface name\n"
       "Detailed output\n"
       JSON_STR)
 {
index 7852d1788a7758a7c9edc76868361ce6d42c76cf..d15e978855560f147c6c862c58ff012fcb5b1a90 100644 (file)
@@ -37,6 +37,7 @@ typedef struct in_addr pim_addr;
 #define PIM_MAX_BITLEN IPV4_MAX_BITLEN
 #define PIM_AF_NAME     "ip"
 #define PIM_AF_DBG     "pim"
+#define GM_AF_DBG      "igmp"
 #define PIM_MROUTE_DBG  "mroute"
 #define PIMREG          "pimreg"
 #define GM              "IGMP"
@@ -65,6 +66,7 @@ typedef struct in6_addr pim_addr;
 #define PIM_MAX_BITLEN IPV6_MAX_BITLEN
 #define PIM_AF_NAME     "ipv6"
 #define PIM_AF_DBG     "pimv6"
+#define GM_AF_DBG      "mld"
 #define PIM_MROUTE_DBG  "mroute6"
 #define PIMREG          "pim6reg"
 #define GM              "MLD"
index c2f7396c180e75fa392616cc26ca17918d414bf3..1ac22f38a3b52f54d8f9177098c5140dc680a76b 100644 (file)
@@ -963,7 +963,7 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
 
                                bsm_rpinfo = (struct bsmmsg_rpinfo *)buf;
                                /* unaligned, again */
-                               memcpy(&rp_addr, &bsm_rpinfo->rpaddr,
+                               memcpy(&rp_addr, &bsm_rpinfo->rpaddr.addr,
                                       sizeof(rp_addr));
 
                                buf += sizeof(struct bsmmsg_rpinfo);
@@ -4906,6 +4906,7 @@ DEFUN_NOSH (show_debugging_pim,
 
        pim_debug_config_write(vty);
 
+       cmd_show_lib_debugs(vty);
        return CMD_SUCCESS;
 }
 
index 70c1544717e3550594e7eae76f583c5c5012eda7..9283016d0814744d39dae496c6987fced134c129 100644 (file)
@@ -1027,6 +1027,11 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
                    json_object *json)
 {
        struct channel_oil *c_oil;
+#if PIM_IPV != 4
+       struct ttable *tt = NULL;
+       char *table = NULL;
+#endif
+       char flag[50];
        json_object *json_group = NULL;
        json_object *json_ifp_in = NULL;
        json_object *json_ifp_out = NULL;
@@ -1038,9 +1043,18 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
 
        if (!json) {
                vty_out(vty,
-                       "Codes: J -> Pim Join, I -> " GM " Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted");
+                       "Codes: J -> Pim Join, I -> " GM " Report, S -> Source, * -> Inherited from (*,G), V -> VxLAN, M -> Muted\n");
+#if PIM_IPV == 4
                vty_out(vty,
-                       "\nActive Source           Group            RPT  IIF               OIL\n");
+                       "Active Source           Group            RPT  IIF               OIL\n");
+#else
+               /* Prepare table. */
+               tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+               ttable_add_row(tt, "Active|Source|Group|RPT|IIF|OIL");
+               tt->style.cell.rpad = 2;
+               tt->style.corner = '+';
+               ttable_restyle(tt);
+#endif
        }
 
        frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
@@ -1153,11 +1167,14 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
                                                    "wrongInterface",
                                                    c_oil->cc.wrong_if);
                        }
-               } else
+               }
+#if PIM_IPV == 4
+               else
                        vty_out(vty, "%-6d %-15pPAs  %-15pPAs  %-3s  %-16s  ",
                                c_oil->installed, oil_origin(c_oil),
                                oil_mcastgrp(c_oil), isRpt ? "y" : "n",
                                in_ifname);
+#endif
 
                for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
                     ++oif_vif_index) {
@@ -1199,72 +1216,72 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
                                json_object_object_add(json_ifp_in, out_ifname,
                                                       json_ifp_out);
                        } else {
+                               flag[0] = '\0';
+                               snprintf(flag, sizeof(flag), "(%c%c%c%c%c)",
+                                        (c_oil->oif_flags[oif_vif_index] &
+                                         PIM_OIF_FLAG_PROTO_GM)
+                                                ? 'I'
+                                                : ' ',
+                                        (c_oil->oif_flags[oif_vif_index] &
+                                         PIM_OIF_FLAG_PROTO_PIM)
+                                                ? 'J'
+                                                : ' ',
+                                        (c_oil->oif_flags[oif_vif_index] &
+                                         PIM_OIF_FLAG_PROTO_VXLAN)
+                                                ? 'V'
+                                                : ' ',
+                                        (c_oil->oif_flags[oif_vif_index] &
+                                         PIM_OIF_FLAG_PROTO_STAR)
+                                                ? '*'
+                                                : ' ',
+                                        (c_oil->oif_flags[oif_vif_index] &
+                                         PIM_OIF_FLAG_MUTE)
+                                                ? 'M'
+                                                : ' ');
+
                                if (first_oif) {
                                        first_oif = 0;
-                                       vty_out(vty, "%s(%c%c%c%c%c)",
-                                               out_ifname,
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_PROTO_GM)
-                                                       ? 'I'
-                                                       : ' ',
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_PROTO_PIM)
-                                                       ? 'J'
-                                                       : ' ',
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_PROTO_VXLAN)
-                                                       ? 'V'
-                                                       : ' ',
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_PROTO_STAR)
-                                                       ? '*'
-                                                       : ' ',
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_MUTE)
-                                                       ? 'M'
-                                                       : ' ');
-                               } else
-                                       vty_out(vty, ", %s(%c%c%c%c%c)",
-                                               out_ifname,
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_PROTO_GM)
-                                                       ? 'I'
-                                                       : ' ',
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_PROTO_PIM)
-                                                       ? 'J'
-                                                       : ' ',
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_PROTO_VXLAN)
-                                                       ? 'V'
-                                                       : ' ',
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_PROTO_STAR)
-                                                       ? '*'
-                                                       : ' ',
-                                               (c_oil->oif_flags
-                                                        [oif_vif_index] &
-                                                PIM_OIF_FLAG_MUTE)
-                                                       ? 'M'
-                                                       : ' ');
+#if PIM_IPV == 4
+                                       vty_out(vty, "%s%s", out_ifname, flag);
+#else
+                                       ttable_add_row(
+                                               tt, "%d|%pPAs|%pPAs|%s|%s|%s%s",
+                                               c_oil->installed,
+                                               oil_origin(c_oil),
+                                               oil_mcastgrp(c_oil),
+                                               isRpt ? "y" : "n", in_ifname,
+                                               out_ifname, flag);
+#endif
+                               } else {
+#if PIM_IPV == 4
+                                       vty_out(vty, ", %s%s", out_ifname,
+                                               flag);
+#else
+                                       ttable_add_row(tt,
+                                                      "%c|%c|%c|%c|%c|%s%s",
+                                                      ' ', ' ', ' ', ' ', ' ',
+                                                      out_ifname, flag);
+#endif
+                               }
                        }
                }
-
+#if PIM_IPV == 4
                if (!json)
                        vty_out(vty, "\n");
+#endif
        }
 
-       if (!json)
+       /* Dump the generated table. */
+       if (!json) {
+#if PIM_IPV == 4
                vty_out(vty, "\n");
+#else
+               table = ttable_dump(tt, "\n");
+               vty_out(vty, "%s\n", table);
+               XFREE(MTYPE_TMP, table);
+               ttable_del(tt);
+#endif
+       }
 }
 
 /* pim statistics - just adding only bsm related now.
@@ -1655,9 +1672,9 @@ void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
        }
 }
 
-static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
+static void pim_show_join_helper(struct pim_interface *pim_ifp,
                                 struct pim_ifchannel *ch, json_object *json,
-                                time_t now)
+                                time_t now, struct ttable *tt)
 {
        json_object *json_iface = NULL;
        json_object *json_row = NULL;
@@ -1724,8 +1741,8 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
                        json_object_object_addf(json_grp, json_row, "%pPAs",
                                                &ch->sg.src);
        } else {
-               vty_out(vty,
-                       "%-16s %-15pPAs %-15pPAs %-15pPAs %-10s %8s %-6s %5s\n",
+               ttable_add_row(
+                       tt, "%s|%pPAs|%pPAs|%pPAs|%s|%s|%s|%s",
                        ch->interface->name, &ifaddr, &ch->sg.src, &ch->sg.grp,
                        pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
                        uptime, expire, prune);
@@ -1806,12 +1823,21 @@ void pim_show_join(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
        struct pim_ifchannel *ch;
        struct interface *ifp;
        time_t now;
+       struct ttable *tt = NULL;
+       char *table = NULL;
 
        now = pim_time_monotonic_sec();
 
-       if (!json)
-               vty_out(vty,
-                       "Interface        Address         Source          Group           State      Uptime   Expire Prune\n");
+       if (!json) {
+               /* Prepare table. */
+               tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+               ttable_add_row(
+                       tt,
+                       "Interface|Address|Source|Group|State|Uptime|Expire|Prune");
+               tt->style.cell.rpad = 2;
+               tt->style.corner = '+';
+               ttable_restyle(tt);
+       }
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
                pim_ifp = ifp->info;
@@ -1822,9 +1848,16 @@ void pim_show_join(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
                        if (!pim_sgaddr_match(ch->sg, *sg))
                                continue;
 
-                       pim_show_join_helper(vty, pim_ifp, ch, json, now);
+                       pim_show_join_helper(pim_ifp, ch, json, now, tt);
                } /* scan interface channels */
        }
+       /* Dump the generated table. */
+       if (!json) {
+               table = ttable_dump(tt, "\n");
+               vty_out(vty, "%s\n", table);
+               XFREE(MTYPE_TMP, table);
+               ttable_del(tt);
+       }
 }
 
 static void pim_show_jp_agg_helper(struct interface *ifp,
@@ -1953,6 +1986,8 @@ void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj)
        enum json_type type;
        json_object *json = NULL;
        json_object *json_tmp = NULL;
+       struct ttable *tt = NULL;
+       char *table = NULL;
 
        json = json_object_new_object();
 
@@ -1969,8 +2004,12 @@ void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj)
        if (uj) {
                vty_json(vty, json);
        } else {
-               vty_out(vty,
-                       "Interface         Address          Source           Group            Membership\n");
+               /* Prepare table. */
+               tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+               ttable_add_row(tt, "Interface|Address|Source|Group|Membership");
+               tt->style.cell.rpad = 2;
+               tt->style.corner = '+';
+               ttable_restyle(tt);
 
                /*
                 * Example of the json data we are traversing
@@ -2007,34 +2046,40 @@ void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj)
                                type = json_object_get_type(if_field_val);
 
                                if (type == json_type_object) {
-                                       vty_out(vty, "%-16s  ", key);
+                                       const char *address, *source,
+                                               *localMembership;
 
                                        json_object_object_get_ex(
                                                val, "address", &json_tmp);
-                                       vty_out(vty, "%-15s  ",
-                                               json_object_get_string(
-                                                       json_tmp));
+                                       address = json_object_get_string(
+                                               json_tmp);
 
                                        json_object_object_get_ex(if_field_val,
                                                                  "source",
                                                                  &json_tmp);
-                                       vty_out(vty, "%-15s  ",
-                                               json_object_get_string(
-                                                       json_tmp));
-
-                                       /* Group */
-                                       vty_out(vty, "%-15s  ", if_field_key);
+                                       source = json_object_get_string(
+                                               json_tmp);
 
                                        json_object_object_get_ex(
                                                if_field_val, "localMembership",
                                                &json_tmp);
-                                       vty_out(vty, "%-10s\n",
+                                       localMembership =
                                                json_object_get_string(
-                                                       json_tmp));
+                                                       json_tmp);
+
+                                       ttable_add_row(tt, "%s|%s|%s|%s|%s",
+                                                      key, address, source,
+                                                      if_field_key,
+                                                      localMembership);
                                }
                        }
                }
                json_object_free(json);
+               /* Dump the generated table. */
+               table = ttable_dump(tt, "\n");
+               vty_out(vty, "%s\n", table);
+               XFREE(MTYPE_TMP, table);
+               ttable_del(tt);
        }
 }
 
@@ -3179,6 +3224,8 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
        struct interface *ifp;
        struct pim_interface *pim_ifp;
        struct pim_neighbor *neigh;
+       struct ttable *tt = NULL;
+       char *table = NULL;
        time_t now;
        char uptime[10];
        char expire[10];
@@ -3189,8 +3236,12 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
        now = pim_time_monotonic_sec();
 
        if (!json) {
-               vty_out(vty,
-                       "Interface                Neighbor    Uptime  Holdtime  DR Pri\n");
+               /* Prepare table. */
+               tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+               ttable_add_row(tt, "Interface|Neighbor|Uptime|Holdtime|DR Pri");
+               tt->style.cell.rpad = 2;
+               tt->style.corner = '+';
+               ttable_restyle(tt);
        }
 
        FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -3232,9 +3283,10 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
                                                       neigh_src_str, json_row);
 
                        } else {
-                               vty_out(vty, "%-16s  %15s  %8s  %8s  %6d\n",
-                                       ifp->name, neigh_src_str, uptime,
-                                       expire, neigh->dr_priority);
+                               ttable_add_row(tt, "%s|%pPAs|%s|%s|%d",
+                                              ifp->name, &neigh->source_addr,
+                                              uptime, expire,
+                                              neigh->dr_priority);
                        }
                }
 
@@ -3243,6 +3295,13 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
                        json_ifp_rows = NULL;
                }
        }
+       /* Dump the generated table. */
+       if (!json) {
+               table = ttable_dump(tt, "\n");
+               vty_out(vty, "%s\n", table);
+               XFREE(MTYPE_TMP, table);
+               ttable_del(tt);
+       }
 }
 
 int gm_process_query_max_response_time_cmd(struct vty *vty,
index 833103c27fc305e5bda46f3edd1ce7879f01c6f8..03ce8687e5f279e49182291e2a6ee6159bb6d03c 100644 (file)
@@ -389,8 +389,10 @@ int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf,
        uint8_t *curr = tlv_buf;
        uint8_t *pastend = tlv_buf + tlv_buf_size;
        uint8_t *tmp;
+#if PIM_IPV == 4
        struct pim_interface *pim_ifp = ifp->info;
        struct pim_instance *pim = pim_ifp->pim;
+#endif
 
        /*
         * Append options
@@ -452,19 +454,20 @@ int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf,
 
        /* Secondary Address List */
        if (ifp->connected->count) {
-               curr = pim_tlv_append_addrlist_ucast(curr, pastend,
-                                                    ifp->connected, AF_INET);
+               curr = pim_tlv_append_addrlist_ucast(curr, pastend, ifp,
+                                                    PIM_AF);
                if (!curr) {
                        if (PIM_DEBUG_PIM_HELLO) {
                                zlog_debug(
-                                       "%s: could not set PIM hello v4 Secondary Address List option for interface %s",
-                                       __func__, ifp->name);
+                                       "%s: could not set PIM hello %s Secondary Address List option for interface %s",
+                                       __func__, PIM_AF_NAME, ifp->name);
                        }
                        return -4;
                }
+#if PIM_IPV == 4
                if (pim->send_v6_secondary) {
-                       curr = pim_tlv_append_addrlist_ucast(
-                               curr, pastend, ifp->connected, AF_INET6);
+                       curr = pim_tlv_append_addrlist_ucast(curr, pastend, ifp,
+                                                            AF_INET6);
                        if (!curr) {
                                if (PIM_DEBUG_PIM_HELLO) {
                                        zlog_debug(
@@ -474,6 +477,7 @@ int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf,
                                return -4;
                        }
                }
+#endif
        }
 
        return curr - tlv_buf;
index 40c4c2306d29b78955fdda863371ae9951c97419..6f272f008519ec911a7d95192aecf0aa8c14d0aa 100644 (file)
@@ -131,13 +131,13 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool gm, bool pim,
        pim_ifp->igmp_version = IGMP_DEFAULT_VERSION;
        pim_ifp->mld_version = MLD_DEFAULT_VERSION;
        pim_ifp->gm_default_robustness_variable =
-               IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
-       pim_ifp->gm_default_query_interval = IGMP_GENERAL_QUERY_INTERVAL;
+               GM_DEFAULT_ROBUSTNESS_VARIABLE;
+       pim_ifp->gm_default_query_interval = GM_GENERAL_QUERY_INTERVAL;
        pim_ifp->gm_query_max_response_time_dsec =
-               IGMP_QUERY_MAX_RESPONSE_TIME_DSEC;
+               GM_QUERY_MAX_RESPONSE_TIME_DSEC;
        pim_ifp->gm_specific_query_max_response_time_dsec =
-               IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
-       pim_ifp->gm_last_member_query_count = IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
+               GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC;
+       pim_ifp->gm_last_member_query_count = GM_DEFAULT_ROBUSTNESS_VARIABLE;
 
        /* BSM config on interface: true by default */
        pim_ifp->bsm_enable = true;
@@ -222,6 +222,9 @@ void pim_if_delete(struct interface *ifp)
        list_delete(&pim_ifp->upstream_switch_list);
        list_delete(&pim_ifp->sec_addr_list);
 
+       if (pim_ifp->bfd_config.profile)
+               XFREE(MTYPE_TMP, pim_ifp->bfd_config.profile);
+
        XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
        XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
 
@@ -880,7 +883,7 @@ pim_addr pim_find_primary_addr(struct interface *ifp)
                return pim_ifp->update_source;
 
 #if PIM_IPV == 6
-       if (pim_ifp)
+       if (pim_ifp && !pim_addr_is_any(pim_ifp->ll_highest))
                return pim_ifp->ll_highest;
 
        pim_addr best_addr = PIMADDR_ANY;
index 57ae15079b7b23be7c564c3f03a250043dd12359..308cba0697f1624e19ac14088666acae6d217998 100644 (file)
@@ -610,10 +610,17 @@ static int igmp_recv_query(struct gm_sock *igmp, int query_version,
                                ntohl(igmp->ifaddr.s_addr), from_str,
                                ntohl(from.s_addr));
                }
-               if (ntohl(from.s_addr) < ntohl(igmp->querier_addr.s_addr))
+               /* Reset the other querier timer only if query is received from
+                * the previously elected querier or a better new querier
+                * This will make sure that non-querier elects the new querier
+                * whose ip address is higher than the old querier
+                * in case the old querier goes down via other querier present
+                * timer expiry
+                */
+               if (ntohl(from.s_addr) <= ntohl(igmp->querier_addr.s_addr)) {
                        igmp->querier_addr.s_addr = from.s_addr;
-
-               pim_igmp_other_querier_timer_on(igmp);
+                       pim_igmp_other_querier_timer_on(igmp);
+               }
        }
 
        /* IGMP version 3 is the only one where we process the RXed query */
index a642469f273286f5cb084157bcbd88adce6248a5..9ce3a2a17fa8679444016d7cee84c04463a87475 100644 (file)
 #define IGMP_V3_GROUP_RECORD_SOURCE_OFFSET     (8)
 #define IGMP_CHECKSUM_OFFSET                   (2)
 
-/* RFC 3376: 8.1. Robustness Variable - Default: 2 */
-#define IGMP_DEFAULT_ROBUSTNESS_VARIABLE           (2)
-
-/* RFC 3376: 8.2. Query Interval - Default: 125 seconds */
-#define IGMP_GENERAL_QUERY_INTERVAL                (125)
-
-/* RFC 3376: 8.3. Query Response Interval - Default: 100 deciseconds */
-#define IGMP_QUERY_MAX_RESPONSE_TIME_DSEC          (100)
-
-/* RFC 3376: 8.8. Last Member Query Interval - Default: 10 deciseconds */
-#define IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC (10)
-
 #define IGMP_DEFAULT_VERSION (3)
 
 #define IGMP_GET_INT16(ptr, output)                                            \
index 5c81f9b8143bcb89735e0f502a7184763c7e997a..12f8ffedfe28b344c4e2d27f6f2226312c7e530c 100644 (file)
@@ -2844,6 +2844,9 @@ int lib_interface_gmp_address_family_last_member_query_interval_modify(
                        yang_dnode_get_uint16(args->dnode, NULL);
                pim_ifp->gm_specific_query_max_response_time_dsec =
                        last_member_query_interval;
+#if PIM_IPV == 6
+               gm_ifp_update(ifp);
+#endif
 
                break;
        }
@@ -2872,7 +2875,9 @@ int lib_interface_gmp_address_family_robustness_variable_modify(
                last_member_query_count =
                        yang_dnode_get_uint8(args->dnode, NULL);
                pim_ifp->gm_last_member_query_count = last_member_query_count;
-
+#if PIM_IPV == 6
+               gm_ifp_update(ifp);
+#endif
                break;
        }
 
index 65975ce14640bca825fc723a93374315ac92c497..c9caf0016ee7aaf77ba82be6a9750b4f3c530039 100644 (file)
@@ -29,6 +29,8 @@
 #include "pim_tlv.h"
 #include "pim_str.h"
 #include "pim_msg.h"
+#include "pim_iface.h"
+#include "pim_addr.h"
 
 #if PIM_IPV == 4
 #define PIM_MSG_ADDRESS_FAMILY PIM_MSG_ADDRESS_FAMILY_IPV4
@@ -226,12 +228,15 @@ int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope,
 }
 
 uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
-                                      struct list *ifconnected, int family)
+                                      struct interface *ifp, int family)
 {
        struct listnode *node;
        uint16_t option_len = 0;
        uint8_t *curr;
        size_t uel;
+       struct list *ifconnected = ifp->connected;
+       struct pim_interface *pim_ifp = ifp->info;
+       pim_addr addr;
 
        node = listhead(ifconnected);
 
@@ -252,7 +257,10 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
                struct prefix *p = ifc->address;
                int l_encode;
 
-               if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
+               addr = pim_addr_from_prefix(p);
+               if (!pim_addr_cmp(pim_ifp->primary_address, addr))
+                       /* don't add the primary address
+                        * into the secondary address list */
                        continue;
 
                if ((curr + uel) > buf_pastend)
index 64b3a0b6ba7206052c5324a506f7f0a7c4fc387d..63bd2c41f69f5e31b6083408141f89e902e859c2 100644 (file)
@@ -82,7 +82,7 @@ uint8_t *pim_tlv_append_2uint16(uint8_t *buf, const uint8_t *buf_pastend,
 uint8_t *pim_tlv_append_uint32(uint8_t *buf, const uint8_t *buf_pastend,
                               uint16_t option_type, uint32_t option_value);
 uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
-                                      struct list *ifconnected, int family);
+                                      struct interface *ifp, int family);
 
 int pim_tlv_parse_holdtime(const char *ifname, pim_addr src_addr,
                           pim_hello_options *hello_options,
index d01cb0c87372fa48c440aa22e9dad887e6c0ecc4..9021f1e12f560c7bc6a343eb3fd80f6f1e60ba5d 100644 (file)
@@ -59,20 +59,20 @@ int pim_debug_config_write(struct vty *vty)
                ++writes;
        }
        if (PIM_DEBUG_GM_EVENTS) {
-               vty_out(vty, "debug igmp events\n");
+               vty_out(vty, "debug " GM_AF_DBG " events\n");
                ++writes;
        }
        if (PIM_DEBUG_GM_PACKETS) {
-               vty_out(vty, "debug igmp packets\n");
+               vty_out(vty, "debug " GM_AF_DBG " packets\n");
                ++writes;
        }
        /* PIM_DEBUG_GM_TRACE catches _DETAIL too */
        if (router->debugs & PIM_MASK_GM_TRACE) {
-               vty_out(vty, "debug igmp trace\n");
+               vty_out(vty, "debug " GM_AF_DBG " trace\n");
                ++writes;
        }
        if (PIM_DEBUG_GM_TRACE_DETAIL) {
-               vty_out(vty, "debug igmp trace detail\n");
+               vty_out(vty, "debug " GM_AF_DBG " trace detail\n");
                ++writes;
        }
 
@@ -314,14 +314,14 @@ static int gm_config_write(struct vty *vty, int writes,
 
        /* IF ip igmp query-max-response-time */
        if (pim_ifp->gm_query_max_response_time_dsec !=
-           IGMP_QUERY_MAX_RESPONSE_TIME_DSEC) {
+           GM_QUERY_MAX_RESPONSE_TIME_DSEC) {
                vty_out(vty, " ip igmp query-max-response-time %d\n",
                        pim_ifp->gm_query_max_response_time_dsec);
                ++writes;
        }
 
        /* IF ip igmp query-interval */
-       if (pim_ifp->gm_default_query_interval != IGMP_GENERAL_QUERY_INTERVAL) {
+       if (pim_ifp->gm_default_query_interval != GM_GENERAL_QUERY_INTERVAL) {
                vty_out(vty, " ip igmp query-interval %d\n",
                        pim_ifp->gm_default_query_interval);
                ++writes;
@@ -329,7 +329,7 @@ static int gm_config_write(struct vty *vty, int writes,
 
        /* IF ip igmp last-member_query-count */
        if (pim_ifp->gm_last_member_query_count !=
-           IGMP_DEFAULT_ROBUSTNESS_VARIABLE) {
+           GM_DEFAULT_ROBUSTNESS_VARIABLE) {
                vty_out(vty, " ip igmp last-member-query-count %d\n",
                        pim_ifp->gm_last_member_query_count);
                ++writes;
@@ -337,7 +337,7 @@ static int gm_config_write(struct vty *vty, int writes,
 
        /* IF ip igmp last-member_query-interval */
        if (pim_ifp->gm_specific_query_max_response_time_dsec !=
-           IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC) {
+           GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC) {
                vty_out(vty, " ip igmp last-member-query-interval %d\n",
                        pim_ifp->gm_specific_query_max_response_time_dsec);
                ++writes;
@@ -381,23 +381,23 @@ static int gm_config_write(struct vty *vty, int writes,
 
        /* IF ipv6 mld query-max-response-time */
        if (pim_ifp->gm_query_max_response_time_dsec !=
-           IGMP_QUERY_MAX_RESPONSE_TIME_DSEC)
+           GM_QUERY_MAX_RESPONSE_TIME_DSEC)
                vty_out(vty, " ipv6 mld query-max-response-time %d\n",
                        pim_ifp->gm_query_max_response_time_dsec);
 
-       if (pim_ifp->gm_default_query_interval != IGMP_GENERAL_QUERY_INTERVAL)
+       if (pim_ifp->gm_default_query_interval != GM_GENERAL_QUERY_INTERVAL)
                vty_out(vty, " ipv6 mld query-interval %d\n",
                        pim_ifp->gm_default_query_interval);
 
        /* IF ipv6 mld last-member_query-count */
        if (pim_ifp->gm_last_member_query_count !=
-           IGMP_DEFAULT_ROBUSTNESS_VARIABLE)
+           GM_DEFAULT_ROBUSTNESS_VARIABLE)
                vty_out(vty, " ipv6 mld last-member-query-count %d\n",
                        pim_ifp->gm_last_member_query_count);
 
        /* IF ipv6 mld last-member_query-interval */
        if (pim_ifp->gm_specific_query_max_response_time_dsec !=
-           IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC)
+           GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC)
                vty_out(vty, " ipv6 mld last-member-query-interval %d\n",
                        pim_ifp->gm_specific_query_max_response_time_dsec);
 
index 06fcec2b6e618f769a5e815c5b6606909102f640..3a80c24f7c75daf82c946be312465350f03d5548 100644 (file)
@@ -32,9 +32,8 @@
 #include "pim_memory.h"
 #include "pim_assert.h"
 
-#define PIMD_PROGNAME       "pimd"
-#define PIMD_DEFAULT_CONFIG "pimd.conf"
 #define PIMD_VTY_PORT       2611
+#define PIM6D_VTY_PORT      2622
 
 #define PIM_IP_PROTO_IGMP             (2)
 #define PIM_IP_PROTO_PIM              (103)
@@ -261,6 +260,24 @@ extern uint8_t qpim_ecmp_rebalance_enable;
 #define PIM_DONT_DEBUG_VXLAN (router->debugs &= ~PIM_MASK_VXLAN)
 #define PIM_DONT_DEBUG_BSM (router->debugs &= ~PIM_MASK_BSM_PROC)
 
+/* RFC 3376: 8.1. Robustness Variable - Default: 2 for IGMP */
+/* RFC 2710: 7.1. Robustness Variable - Default: 2 for MLD */
+#define GM_DEFAULT_ROBUSTNESS_VARIABLE 2
+
+/* RFC 3376: 8.2. Query Interval - Default: 125 seconds for IGMP */
+/* RFC 2710: 7.2. Query Interval - Default: 125 seconds for MLD */
+#define GM_GENERAL_QUERY_INTERVAL 125
+
+/* RFC 3376: 8.3. Query Response Interval - Default: 100 deciseconds for IGMP */
+/* RFC 2710: 7.3. Query Response Interval - Default: 100 deciseconds for MLD */
+#define GM_QUERY_MAX_RESPONSE_TIME_DSEC 100
+
+/* RFC 3376: 8.8. Last Member Query Interval - Default: 10 deciseconds for IGMP
+ */
+/* RFC 2710: 7.8. Last Listener Query Interval - Default: 10 deciseconds for MLD
+ */
+#define GM_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC 10
+
 void pim_router_init(void);
 void pim_router_terminate(void);
 
index 962541405f9f57e12b64cfa4e0a55a413f4b5fb2..8f469d2a07ac3929fa84e5bc8d721036debc22ad 100644 (file)
@@ -795,6 +795,8 @@ sed -i 's/ -M rpki//' %{_sysconfdir}/frr/daemons
 
 * Wed Jul 20 2022 Martin Winter <mwinter@opensourcerouting.org> - %{version}
 
+* Tue Oct 04 2022 Donatas Abraitis <donatas@opensourcerouting.org> - 8.4
+
 * Wed Jul 13 2022 Jafar Al-Gharaibeh <jafar@atcorp.com> - 8.3
 - General:
 -    Add camelcase json keys in addition to pascalcase (Wrong JSON keys will be depracated)
index 871ee8e87ef4e0e3b3b3fc84e8f1139e501147de..ded62812a756764ab8253d877dd357d987ab9d6a 100644 (file)
@@ -55,6 +55,8 @@ DEFUN_NOSH (show_debugging_rip,
        if (IS_RIP_DEBUG_ZEBRA)
                vty_out(vty, "  RIP zebra debugging is on\n");
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index 539c01b3ecda67121de09e6307440e780e4ab2dc..d36327cb7680f567dc01248606677019445ece58 100644 (file)
@@ -56,6 +56,8 @@ DEFUN_NOSH (show_debugging_ripng,
        if (IS_RIPNG_DEBUG_ZEBRA)
                vty_out(vty, "  RIPng zebra debugging is on\n");
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index 3853df7cb08a1b4d754cd29bc183c5140e794645..9b900fccd23298642afc685b8ed4030fd4f4be8a 100644 (file)
@@ -615,6 +615,8 @@ DEFUN_NOSH (show_debugging_sharpd,
 {
        vty_out(vty, "Sharp debugging status:\n");
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index c0ace0e2588ca9d1f65c8595ea6585ba4685357a..c0638f4bc4b436ed8fc9868ee4b18db85ceba4f8 100644 (file)
@@ -1301,6 +1301,8 @@ DEFUN_NOSH (show_debugging_static,
 
        static_debug_status_write(vty);
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index e3579c67a24d92081c0d269459fcfa0279f06085..feb42909a8cc8705f694c66e991fe3a7e3b6c407 100644 (file)
@@ -74,7 +74,7 @@ static uint32_t list_hash(const struct item *a)
 {
 #ifdef SHITTY_HASH
        /* crappy hash to get some hash collisions */
-       return a->val ^ (a->val << 29) ^ 0x55AA0000U;
+       return (a->val & 0xFF) ^ (a->val << 29) ^ 0x55AA0000U;
 #else
        return jhash_1word(a->val, 0xdeadbeef);
 #endif
index b18e32f6bd4beae6fcf0fe52427008e6f7d1162f..42b9b8adb9ed673fc1c7d6a65562e187b8dd0480 100644 (file)
@@ -121,7 +121,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.15")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.15")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -1148,9 +1148,9 @@ def test_bgp_with_loopback_with_same_subnet_p1(request):
             tgen, addr_type, dut, input_dict_r1, expected=False
         )  # pylint: disable=E1123
         assert result is not True, (
-            "Testcase {} : Failed \n".format(tc_name)
-            + "Expected behavior: routes should not present in fib \n"
-            + "Error: {}".format(result)
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     step("Verify Ipv4 and Ipv6 network installed in r3 RIB but not in FIB")
@@ -1169,9 +1169,9 @@ def test_bgp_with_loopback_with_same_subnet_p1(request):
             tgen, addr_type, dut, input_dict_r1, expected=False
         )  # pylint: disable=E1123
         assert result is not True, (
-            "Testcase {} : Failed \n".format(tc_name)
-            + "Expected behavior: routes should not present in fib \n"
-            + "Error: {}".format(result)
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     write_test_footer(tc_name)
index e4c25ff5cb1a60e366aa908c70f231ca1eab9e9e..1c1a5cdfe49234a0344ba2f3133e241551f9690b 100644 (file)
@@ -83,7 +83,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.15")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >= 4.15")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -317,17 +317,18 @@ def test_bgp_no_advertise_community_p0(request):
         )
 
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
-        assert result is not True, "Testcase {} : Failed \n ".format(
-            tc_name
-        ) + " Routes still present in R3 router. Error: {}".format(result)
+        assert result is not True, (
+            "Testcase {} : Failed \n Expected: "
+            "Routes still present in {} router. Found: {}".format(tc_name, dut, result)
+        )
 
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
         assert (
             result is not True
-        ), "Testcase {} : Failed \n  Routes still present in R3 router. Error: {}".format(
-            tc_name, result
+        ), "Testcase {} : Failed \n  Expected: Routes still present in {} router. Found: {}".format(
+            tc_name, dut, result
         )
 
         step("Remove and Add no advertise community")
index f6ee9ea79597c2667cc5649b494d65ce8c504abf..a93061740f87eaaad877fb998347424a59aed2fe 100644 (file)
@@ -87,7 +87,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.14")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >= 4.14")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -305,8 +305,10 @@ def test_bgp_no_export_local_as_and_internet_communities_p0(request):
                     ],
                     expected=False,
                 )
-                assert result is not True, "Testcase {} : Failed \n Error: {}".format(
-                    tc_name, result
+                assert result is not True, (
+                    "Testcase {} : Failed \n "
+                    "Expected: Routes are still present in rib of r3 \n "
+                    "Found: {}".format(tc_name, result)
                 )
 
         step("Remove route-map from redistribute static on R1")
index 1097be3d709c62de523796c1a39a41d78439cf2f..0e16b97e4a8def32c8f9c5646e659bf6f6853e7c 100644 (file)
@@ -43,10 +43,15 @@ TC21: exist-map routes present in R2's BGP table.
       advertise-map routes present in R2's BGP table are advertised to R3.
 TC22: exist-map routes not present in R2's BGP table
       advertise-map routes present in R2's BGP table are withdrawn from R3.
+TC23: advertise-map with exist-map configuration is removed from a peer
+      send normal BGP update to advertise previously withdrawn routes if any.
+
 TC31: non-exist-map routes not present in R2's BGP table
       advertise-map routes present in R2's BGP table are advertised to R3.
 TC32: non-exist-map routes present in R2's BGP table
       advertise-map routes present in R2's BGP table are withdrawn from R3.
+TC33: advertise-map with non-exist-map configuration is removed from a peer
+      send normal BGP update to advertisepreviously withdrawn routes if any.
 
 TC41: non-exist-map route-map configuration removed in R2.
       advertise-map routes present in R2's BGP table are advertised to R3.
@@ -221,6 +226,18 @@ def all_routes_withdrawn(router):
     return topotest.json_cmp(output, expected)
 
 
+def default_route_withdrawn(router):
+    output = json.loads(router.vtysh_cmd("show ip route json"))
+    expected = {
+        "0.0.0.0/0": None,
+        "192.0.2.1/32": [{"protocol": "bgp"}],
+        "192.0.2.5/32": [{"protocol": "bgp"}],
+        "10.139.224.0/20": [{"protocol": "bgp"}],
+        "203.0.113.1/32": [{"protocol": "bgp"}],
+    }
+    return topotest.json_cmp(output, expected)
+
+
 # BGP conditional advertisement with route-maps
 # EXIST-MAP, ADV-MAP-1 and RMAP-1
 def exist_map_routes_present(router):
@@ -252,15 +269,7 @@ def non_exist_map_routes_present(router):
 
 
 def non_exist_map_routes_not_present(router):
-    output = json.loads(router.vtysh_cmd("show ip route json"))
-    expected = {
-        "0.0.0.0/0": None,
-        "192.0.2.1/32": [{"protocol": "bgp"}],
-        "192.0.2.5/32": [{"protocol": "bgp"}],
-        "10.139.224.0/20": [{"protocol": "bgp"}],
-        "203.0.113.1/32": [{"protocol": "bgp"}],
-    }
-    return topotest.json_cmp(output, expected)
+    return default_route_withdrawn(router)
 
 
 def exist_map_no_condition_route_map(router):
@@ -389,7 +398,7 @@ passed = "PASSED!!!"
 failed = "FAILED!!!"
 
 
-def test_bgp_conditional_advertisement_step1():
+def test_bgp_conditional_advertisement_tc_1_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -409,7 +418,7 @@ def test_bgp_conditional_advertisement_step1():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step2():
+def test_bgp_conditional_advertisement_tc_2_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -438,7 +447,7 @@ def test_bgp_conditional_advertisement_step2():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step3():
+def test_bgp_conditional_advertisement_tc_2_2():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -467,7 +476,36 @@ def test_bgp_conditional_advertisement_step3():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step4():
+def test_bgp_conditional_advertisement_tc_2_3():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    router1 = tgen.gears["r1"]
+    router2 = tgen.gears["r2"]
+    router3 = tgen.gears["r3"]
+
+    # TC23: advertise-map with exist-map configuration is removed from a peer
+    # send normal BGP update to advertise previously withdrawn routes if any.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(default_route_withdrawn, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC23: advertise-map with exist-map configuration is removed from peer - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+
+def test_bgp_conditional_advertisement_tc_3_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -496,7 +534,7 @@ def test_bgp_conditional_advertisement_step4():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step5():
+def test_bgp_conditional_advertisement_tc_3_2():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -525,7 +563,38 @@ def test_bgp_conditional_advertisement_step5():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step6():
+def test_bgp_conditional_advertisement_tc_3_3():
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    router1 = tgen.gears["r1"]
+    router2 = tgen.gears["r2"]
+    router3 = tgen.gears["r3"]
+
+    # TC33: advertise-map with non-exist-map configuration is removed from a peer
+    # send normal BGP update to advertisepreviously withdrawn routes if any.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(all_routes_advertised, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = (
+        "TC33: advertise-map with non-exist-map configuration is removed from a peer - "
+    )
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+
+def test_bgp_conditional_advertisement_tc_4_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -539,6 +608,9 @@ def test_bgp_conditional_advertisement_step6():
     router2.vtysh_cmd(
         """
           configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP
            no route-map EXIST-MAP permit 10
         """
     )
@@ -552,7 +624,7 @@ def test_bgp_conditional_advertisement_step6():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step7():
+def test_bgp_conditional_advertisement_tc_4_2():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -581,7 +653,7 @@ def test_bgp_conditional_advertisement_step7():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step8():
+def test_bgp_conditional_advertisement_tc_5_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -614,7 +686,7 @@ def test_bgp_conditional_advertisement_step8():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step9():
+def test_bgp_conditional_advertisement_tc_5_2():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -643,7 +715,7 @@ def test_bgp_conditional_advertisement_step9():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step10():
+def test_bgp_conditional_advertisement_tc_5_3():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -673,7 +745,7 @@ def test_bgp_conditional_advertisement_step10():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step11():
+def test_bgp_conditional_advertisement_tc_5_4():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -702,7 +774,7 @@ def test_bgp_conditional_advertisement_step11():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step12():
+def test_bgp_conditional_advertisement_tc_6_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -740,7 +812,7 @@ def test_bgp_conditional_advertisement_step12():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step13():
+def test_bgp_conditional_advertisement_tc_6_2():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -769,7 +841,7 @@ def test_bgp_conditional_advertisement_step13():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step14():
+def test_bgp_conditional_advertisement_tc_6_3():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -799,7 +871,7 @@ def test_bgp_conditional_advertisement_step14():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step15():
+def test_bgp_conditional_advertisement_tc_6_4():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -830,7 +902,7 @@ def test_bgp_conditional_advertisement_step15():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step16():
+def test_bgp_conditional_advertisement_tc_7_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -868,7 +940,7 @@ def test_bgp_conditional_advertisement_step16():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step17():
+def test_bgp_conditional_advertisement_tc_7_2():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -897,7 +969,7 @@ def test_bgp_conditional_advertisement_step17():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step18():
+def test_bgp_conditional_advertisement_tc_7_3():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -927,7 +999,7 @@ def test_bgp_conditional_advertisement_step18():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step19():
+def test_bgp_conditional_advertisement_tc_7_4():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -956,7 +1028,7 @@ def test_bgp_conditional_advertisement_step19():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step20():
+def test_bgp_conditional_advertisement_tc_8_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -994,7 +1066,7 @@ def test_bgp_conditional_advertisement_step20():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step21():
+def test_bgp_conditional_advertisement_tc_8_2():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -1023,7 +1095,7 @@ def test_bgp_conditional_advertisement_step21():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step22():
+def test_bgp_conditional_advertisement_tc_8_3():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -1055,7 +1127,7 @@ def test_bgp_conditional_advertisement_step22():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step23():
+def test_bgp_conditional_advertisement_tc_8_4():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -1086,7 +1158,7 @@ def test_bgp_conditional_advertisement_step23():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step24():
+def test_bgp_conditional_advertisement_tc_9_1():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -1124,7 +1196,7 @@ def test_bgp_conditional_advertisement_step24():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step25():
+def test_bgp_conditional_advertisement_tc_9_2():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -1153,7 +1225,7 @@ def test_bgp_conditional_advertisement_step25():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step26():
+def test_bgp_conditional_advertisement_tc_9_3():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
@@ -1193,7 +1265,7 @@ def test_bgp_conditional_advertisement_step26():
     logger.info(msg + passed)
 
 
-def test_bgp_conditional_advertisement_step27():
+def test_bgp_conditional_advertisement_tc_9_4():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
index 2784e956fa389d1a2a818fc2f99d5e84c3b4095b..8fd0120dd82172a9061d3625bcdd5a2d625e6127 100644 (file)
@@ -90,7 +90,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.15")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.15")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -436,7 +436,9 @@ def test_ecmp_remove_redistribute_static(request):
         )
         assert (
             result is not True
-        ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
+        ), "Testcase {} : Failed \n Expected: Routes still present in {} RIB. Found: {}".format(
+            tc_name, dut, result
+        )
 
     logger.info("Enable redistribute static")
     input_dict_2 = {
@@ -621,7 +623,9 @@ def test_ecmp_remove_static_route(request):
         )
         assert (
             result is not True
-        ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
+        ), "Testcase {} : Failed \n  Expected: Routes still present in {} RIB. Found: {}".format(
+            tc_name, dut, result
+        )
 
     for addr_type in ADDR_TYPES:
         # Enable static routes
@@ -727,7 +731,9 @@ def test_ecmp_remove_nw_advertise(request):
         )
         assert (
             result is not True
-        ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
+        ), "Testcase {} : Failed \n  Expected: Routes still present in {} RIB. Found: {}".format(
+            tc_name, dut, result
+        )
 
     static_or_nw(tgen, topo, tc_name, "advertise_nw", "r2")
     for addr_type in ADDR_TYPES:
index 704e8fdf04a63c46ffef1b7f3df3f225a6fcf215..185a086838683cd04f3d0839e3ae14a38c8d192c 100644 (file)
@@ -90,7 +90,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.15")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.15")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -437,7 +437,9 @@ def test_ecmp_remove_redistribute_static(request):
         )
         assert (
             result is not True
-        ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
+        ), "Testcase {} : Failed \n  Expected: Routes still present in {} RIB. Found: {}".format(
+            tc_name, dut, result
+        )
 
     logger.info("Enable redistribute static")
     input_dict_2 = {
@@ -622,7 +624,9 @@ def test_ecmp_remove_static_route(request):
         )
         assert (
             result is not True
-        ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
+        ), "Testcase {} : Failed \n  Expected: Routes still present in {} RIB. Found: {}".format(
+            tc_name, dut, result
+        )
 
     for addr_type in ADDR_TYPES:
         # Enable static routes
@@ -730,7 +734,9 @@ def test_ecmp_remove_nw_advertise(request):
         )
         assert (
             result is not True
-        ), "Testcase {} : Failed \n Routes still" " present in RIB".format(tc_name)
+        ), "Testcase {} : Failed \n  Expected: Routes still present in {} RIB. Found: {}".format(
+            tc_name, dut, result
+        )
 
     static_or_nw(tgen, topo, tc_name, "advertise_nw", "r2")
     for addr_type in ADDR_TYPES:
index 2a51dc83ef429045de2b9ae5ec9f4644e7041292..9b6480c0d3f884d3a14e1bfbb32349fb75b01950 100644 (file)
@@ -240,17 +240,18 @@ def test_ecmp_fast_convergence(request, test_type, tgen, topo):
     logger.info("Ensure BGP has processed the cli")
     r2 = tgen.gears["r2"]
     output = r2.vtysh_cmd("show run")
-    verify = re.search(r"fast-convergence", output )
-    assert verify is not None, (
-        "r2 does not have the fast convergence command yet")
+    verify = re.search(r"fast-convergence", output)
+    assert verify is not None, "r2 does not have the fast convergence command yet"
 
     logger.info("Shutdown one link b/w r2 and r3")
     shutdown_bringup_interface(tgen, "r2", intf1, False)
 
     logger.info("Verify bgp neighbors goes down immediately")
     result = verify_bgp_convergence(tgen, topo, dut="r2", expected=False)
-    assert result is not True, "Testcase {} : Failed \n Error: {}".format(
-        tc_name, result
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: BGP should not be converged for {} \n "
+        "Found: {}".format(tc_name, "r2", result)
     )
 
     logger.info("Shutdown second link b/w r2 and r3")
@@ -258,8 +259,10 @@ def test_ecmp_fast_convergence(request, test_type, tgen, topo):
 
     logger.info("Verify bgp neighbors goes down immediately")
     result = verify_bgp_convergence(tgen, topo, dut="r2", expected=False)
-    assert result is not True, "Testcase {} : Failed \n Error: {}".format(
-        tc_name, result
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: BGP should not be converged for {} \n "
+        "Found: {}".format(tc_name, "r2", result)
     )
 
     write_test_footer(tc_name)
index f155325502b31ef78299fdaa022232f8cf7afbf2..deca4bcfd7d690d4f1e7abab45fd1bcc800c3a1a 100644 (file)
@@ -160,7 +160,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -1033,11 +1033,9 @@ def test_BGP_GR_TC_4_p0(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes
         result = verify_rib(
@@ -1045,9 +1043,9 @@ def test_BGP_GR_TC_4_p0(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     logger.info("[Phase 5] : R2 is about to come up now  ")
     start_router_daemons(tgen, "r2", ["bgpd"])
@@ -1506,10 +1504,10 @@ def test_BGP_GR_TC_6_1_2_p1(request):
         result = verify_r_bit(
             tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r2: R-bit is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: R-bit should not be set to True in r2\n"
+            "Found: {}".format(tc_name, result)
         )
 
     logger.info("Restart BGPd on R2 ")
@@ -1528,10 +1526,10 @@ def test_BGP_GR_TC_6_1_2_p1(request):
         result = verify_r_bit(
             tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r2: R-bit is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: R-bit should not be set to True in r2\n"
+            "Found: {}".format(tc_name, result)
         )
 
     write_test_footer(tc_name)
index dda3bd4b30758ef3b0ff54d892213e5fec4eb72c..a92fde2d0dca81d4a226bec428f90b2efc3bd728 100644 (file)
@@ -160,7 +160,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
index e4b533b295afc84548c3aa894ff27681bc026329..b0166033df6a39df643003f11cc579ecfccca951 100644 (file)
@@ -160,7 +160,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -829,11 +829,9 @@ def test_BGP_GR_TC_20_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes
         result = verify_rib(
@@ -841,9 +839,9 @@ def test_BGP_GR_TC_20_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     logger.info("[Phase 5] : R2 is about to come up now  ")
 
@@ -1117,7 +1115,8 @@ def test_BGP_GR_TC_31_1_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     logger.info("[Phase 4] : R1 is about to come up now  ")
@@ -1599,11 +1598,9 @@ def test_BGP_GR_TC_9_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes
         protocol = "bgp"
@@ -1612,9 +1609,9 @@ def test_BGP_GR_TC_9_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     logger.info("[Phase 5] : R2 is about to come up now  ")
     start_router_daemons(tgen, "r2", ["bgpd"])
@@ -1643,10 +1640,10 @@ def test_BGP_GR_TC_9_p1(request):
         result = verify_f_bit(
             tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r1: F-bit is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: F-bit should not be set to True in r1\n"
+            "Found: {}".format(tc_name, result)
         )
 
     write_test_footer(tc_name)
@@ -1781,11 +1778,9 @@ def test_BGP_GR_TC_17_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes
         protocol = "bgp"
@@ -1794,9 +1789,9 @@ def test_BGP_GR_TC_17_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     logger.info("[Phase 5] : R2 is about to come up now  ")
     start_router_daemons(tgen, "r2", ["bgpd"])
@@ -1817,10 +1812,10 @@ def test_BGP_GR_TC_17_p1(request):
         result = verify_r_bit(
             tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r1: R-bit is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: R-bit should not be set to True in r1\n"
+            "Found: {}".format(tc_name, result)
         )
 
         # Verifying BGP RIB routes
@@ -2026,10 +2021,10 @@ def test_BGP_GR_TC_43_p1(request):
         result = verify_rib(
             tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
         dut = "r2"
@@ -2043,18 +2038,18 @@ def test_BGP_GR_TC_43_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r2: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
+
         protocol = "bgp"
         result = verify_rib(
             tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     step(
@@ -2353,17 +2348,17 @@ def test_BGP_GR_TC_44_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
+
         result = verify_rib(
             tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} :Failed \n Routes are still present \n Error {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     step("Bring up BGPd on R2 and remove GR related config from R1 in global level")
index 835ef41de1696585ecf6e10dd98f64890967e3e5..f408ff4854833cf2deab45c8b0f0049702aa622f 100644 (file)
@@ -160,7 +160,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
@@ -1157,7 +1157,8 @@ def test_BGP_GR_TC_48_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
         dut = "r2"
@@ -1171,16 +1172,17 @@ def test_BGP_GR_TC_48_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r2: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
+
         result = verify_rib(
             tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r2: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     step("Bring up BGP on R1 and remove Peer-level GR config from R1")
@@ -1542,16 +1544,17 @@ def BGP_GR_TC_52_p1(request):
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
+
         result = verify_rib(
             tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     step("Bring up BGP on R2 and remove Peer-level GR config from R1")
index 3afe38857ba0bd1a5ef1b4478171b02f26debd7b..293f3042eb692abe82239c6bfd0ce5cec3341aa9 100644 (file)
@@ -155,7 +155,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     global ADDR_TYPES
 
@@ -528,10 +528,10 @@ def test_BGP_GR_TC_3_p0(request):
     result = verify_eor(
         tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n " "r2: EOR is set to True\n Error: {}".format(
-        tc_name, result
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: EOR should not be set to True in r2\n"
+        "Found: {}".format(tc_name, result)
     )
 
     logger.info(
@@ -675,10 +675,10 @@ def test_BGP_GR_TC_11_p0(request):
         result = verify_eor(
             tgen, topo, addr_type, input_dict, dut="r1", peer="r3", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: EOR should not be set to True in r1\n"
+            "Found: {}".format(tc_name, result)
         )
 
     logger.info(
@@ -706,10 +706,10 @@ def test_BGP_GR_TC_11_p0(request):
         result = verify_eor(
             tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: EOR should not be set to True in r3\n"
+            "Found: {}".format(tc_name, result)
         )
 
     write_test_footer(tc_name)
@@ -1474,38 +1474,33 @@ def test_BGP_GR_18_p1(request):
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r6: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes before shutting down BGPd daemon
         result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r6: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying BGP RIB routes
         dut = "r2"
-        result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r2: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes before shutting down BGPd daemon
         result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r6: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     write_test_footer(tc_name)
 
index 535f272ef4096cc4ce15c9f6d16efe893cb13885..fe885372d5af66422529a399b47577622569c5c9 100644 (file)
@@ -155,7 +155,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     global ADDR_TYPES
 
@@ -726,19 +726,17 @@ def test_BGP_GR_chaos_29_p1(request):
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes before shutting down BGPd daemon
         result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     logger.info("[Step 4] : Start BGPd daemon on R1..")
 
@@ -981,11 +979,9 @@ def test_BGP_GR_chaos_33_p1(request):
             )
             assert result is not True, (
                 "Testcase {} : Failed \n "
-                "r3: routes are still present in BGP RIB\n Error: {}".format(
-                    tc_name, result
-                )
+                "Expected: Routes should not be present in {} FIB \n "
+                "Found: {}".format(tc_name, dut, result)
             )
-            logger.info(" Expected behavior: {}".format(result))
 
         if addr_type == "ipv6":
             if "link_local" in PREFERRED_NEXT_HOP:
@@ -998,11 +994,9 @@ def test_BGP_GR_chaos_33_p1(request):
             )
             assert result is not True, (
                 "Testcase {} : Failed \n "
-                "r3: routes are still present in ZEBRA\n Error: {}".format(
-                    tc_name, result
-                )
+                "Expected: Routes should not be present in {} FIB \n "
+                "Found: {}".format(tc_name, dut, result)
             )
-            logger.info(" Expected behavior: {}".format(result))
 
     logger.info("[Step 4] : Start BGPd daemon on R1 and R4..")
 
@@ -1182,31 +1176,28 @@ def test_BGP_GR_chaos_34_2_p1(request):
         result = verify_f_bit(
             tgen, topo, addr_type, input_dict, "r3", "r1", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: F-bit should not be set to True in r3\n"
+            "Found: {}".format(tc_name, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying BGP RIB routes after starting BGPd daemon
         input_dict_1 = {key: topo["routers"][key] for key in ["r1"]}
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes
         result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     write_test_footer(tc_name)
 
index e60552ed101cfe500bc523da5928d05f920b97b0..4ff62a97858ea63c044805800c701c93e1ff3644 100644 (file)
@@ -155,7 +155,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     global ADDR_TYPES
 
@@ -380,12 +380,11 @@ def test_BGP_GR_chaos_34_1_p1(request):
         result = verify_f_bit(
             tgen, topo, addr_type, input_dict_2, "r3", "r1", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: F-bit should not be set to True in r3\n"
+            "Found: {}".format(tc_name, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     logger.info("[Step 3] : Kill BGPd daemon on R1..")
 
@@ -402,19 +401,17 @@ def test_BGP_GR_chaos_34_1_p1(request):
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes
         result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     # Start BGPd daemon on R1
     start_router_daemons(tgen, "r1", ["bgpd"])
@@ -587,31 +584,28 @@ def test_BGP_GR_chaos_32_p1(request):
         result = verify_eor(
             tgen, topo, addr_type, input_dict_3, dut="r5", peer="r1", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r5: EOR is set to TRUE\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: EOR should not be set to True in r5\n"
+            "Found: {}".format(tc_name, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying BGP RIB routes after starting BGPd daemon
         input_dict_1 = {key: topo["routers"][key] for key in ["r5"]}
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes
         result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -716,12 +710,11 @@ def test_BGP_GR_chaos_37_p1(request):
         result = verify_eor(
             tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: EOR should not be set to True in r3\n"
+            "Found: {}".format(tc_name, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying BGP RIB routes after starting BGPd daemon
         dut = "r1"
@@ -783,10 +776,10 @@ def test_BGP_GR_chaos_37_p1(request):
         result = verify_eor(
             tgen, topo, addr_type, input_dict_3, dut="r1", peer="r3", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: EOR should not be set to True in r1\n"
+            "Found: {}".format(tc_name, result)
         )
 
     write_test_footer(tc_name)
@@ -941,19 +934,17 @@ def test_BGP_GR_chaos_30_p1(request):
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes before shutting down BGPd daemon
         result = verify_rib(tgen, addr_type, dut, input_dict, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -1356,7 +1347,8 @@ def BGP_GR_TC_7_p1(request):
         result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     write_test_footer(tc_name)
index 1df77ebeb2089602f0e493ab11dd4072cbbf6a08..fd1ef097c4420389d0bab7b96d4f6ed3c1f00b0f 100644 (file)
@@ -157,7 +157,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     global ADDR_TYPES
 
@@ -420,10 +420,10 @@ def test_BGP_GR_TC_23_p1(request):
         result = verify_eor(
             tgen, topo, addr_type, input_dict, dut="r1", peer="r2", expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: EOR should not be set to True in r2\n"
+            "Found: {}".format(tc_name, result)
         )
 
         # Verifying BGP RIB routes received from router R1
@@ -547,19 +547,17 @@ def test_BGP_GR_20_p1(request):
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in BGP RIB\n Error: {}".format(
-                tc_name, result
-            )
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
         # Verifying RIB routes before shutting down BGPd daemon
         result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n "
-            "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result)
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info(" Expected behavior: {}".format(result))
 
     # Start BGPd daemon on R1
     start_router_daemons(tgen, "r1", ["bgpd"])
index 6bf8b963098324514a4125a88286bacbe4a9996a..76522206a419d5bf761821452548bbbffb962d0e 100644 (file)
@@ -56,15 +56,20 @@ from lib.bgp import (
     verify_graceful_restart_timers,
     verify_bgp_convergence_from_running_config,
 )
+
 # Import common_config to use commomnly used APIs
-from lib.common_config import (create_common_configuration,
-                               InvalidCLIError, retry,
-                               generate_ips, FRRCFG_FILE,
-                               find_interface_with_greater_ip,
-                               check_address_types,
-                               validate_ip_address,
-                               run_frr_cmd,
-                               get_frr_ipv6_linklocal)
+from lib.common_config import (
+    create_common_configuration,
+    InvalidCLIError,
+    retry,
+    generate_ips,
+    FRRCFG_FILE,
+    find_interface_with_greater_ip,
+    check_address_types,
+    validate_ip_address,
+    run_frr_cmd,
+    get_frr_ipv6_linklocal,
+)
 
 from lib.common_config import (
     write_test_header,
@@ -108,8 +113,7 @@ NEXT_HOP_IP = {"ipv4": "Null0", "ipv6": "Null0"}
 PREFERRED_NEXT_HOP = "link_local"
 
 
-def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name,
-                                   dut, peer):
+def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
     """
     result = configure_gr_followed_by_clear(tgen, topo, dut)
     assert result is True, \
@@ -118,8 +122,7 @@ def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name,
     """
 
     result = create_router_bgp(tgen, topo, input_dict)
-    assert result is True, "Testcase {} : Failed \n Error: {}".format(
-        tc_name, result)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
     for addr_type in ADDR_TYPES:
         clear_bgp(tgen, addr_type, dut)
 
@@ -131,6 +134,7 @@ def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name,
 
     return True
 
+
 def verify_stale_routes_list(tgen, addr_type, dut, input_dict):
     """
     This API is use verify Stale routes on refering the network with next hop value
@@ -175,8 +179,8 @@ def verify_stale_routes_list(tgen, addr_type, dut, input_dict):
             command = "show bgp"
             # Static routes
             sleep(2)
-            logger.info('Checking router {} BGP RIB:'.format(dut))
-            if 'static_routes' in input_dict[routerInput]:
+            logger.info("Checking router {} BGP RIB:".format(dut))
+            if "static_routes" in input_dict[routerInput]:
                 static_routes = input_dict[routerInput]["static_routes"]
                 for static_route in static_routes:
                     found_routes = []
@@ -185,30 +189,27 @@ def verify_stale_routes_list(tgen, addr_type, dut, input_dict):
                     nh_found = False
                     vrf = static_route.setdefault("vrf", None)
                     community = static_route.setdefault("community", None)
-                    largeCommunity = \
-                        static_route.setdefault("largeCommunity", None)
+                    largeCommunity = static_route.setdefault("largeCommunity", None)
                     if vrf:
-                        cmd = "{} vrf {} {}".\
-                            format(command, vrf, addr_type)
+                        cmd = "{} vrf {} {}".format(command, vrf, addr_type)
                         if community:
-                            cmd = "{} community {}".\
-                                format(cmd, community)
+                            cmd = "{} community {}".format(cmd, community)
                         if largeCommunity:
-                            cmd = "{} large-community {}".\
-                                format(cmd, largeCommunity)
+                            cmd = "{} large-community {}".format(cmd, largeCommunity)
                     else:
-                        cmd = "{} {}".\
-                            format(command, addr_type)
+                        cmd = "{} {}".format(command, addr_type)
                     cmd = "{} json".format(cmd)
                     rib_routes_json = run_frr_cmd(rnode, cmd, isjson=True)
                     # Verifying output dictionary rib_routes_json is not empty
                     if bool(rib_routes_json) == False:
-                        errormsg = "[DUT: {}]: No route found in rib of router". \
-                            format(router)
+                        errormsg = "[DUT: {}]: No route found in rib of router".format(
+                            router
+                        )
                         return errormsg
                     elif "warning" in rib_routes_json:
-                        errormsg = "[DUT: {}]: {}". \
-                            format(router, rib_routes_json["warning"])
+                        errormsg = "[DUT: {}]: {}".format(
+                            router, rib_routes_json["warning"]
+                        )
                         return errormsg
                     network = static_route["network"]
                     if "no_of_ip" in static_route:
@@ -227,15 +228,18 @@ def verify_stale_routes_list(tgen, addr_type, dut, input_dict):
                             st_found = True
 
                             found_routes.append(st_rt)
-                            for mnh in range(0, len(rib_routes_json[
-                                'routes'][st_rt])):
-                                found_hops.append([rib_r[
-                                        "ip"] for rib_r in rib_routes_json[
-                                            'routes'][st_rt][
-                                                mnh]["nexthops"]])
+                            for mnh in range(0, len(rib_routes_json["routes"][st_rt])):
+                                found_hops.append(
+                                    [
+                                        rib_r["ip"]
+                                        for rib_r in rib_routes_json["routes"][st_rt][
+                                            mnh
+                                        ]["nexthops"]
+                                    ]
+                                )
                             return found_hops
                         else:
-                            return 'error  msg - no hops found'
+                            return "error  msg - no hops found"
 
 
 def setup_module(mod):
@@ -248,7 +252,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     global ADDR_TYPES
 
@@ -302,6 +306,8 @@ def teardown_module(mod):
         "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
     )
     logger.info("=" * 40)
+
+
 ################################################################################
 #
 #                       TEST CASES
@@ -318,175 +324,160 @@ def test_bgp_gr_stale_routes(request):
 
     step("Creating 5 static Routes in Router R3 with NULL0 as Next hop")
     for addr_type in ADDR_TYPES:
-            input_dict_1 = {
-                "r3": {
-                    "static_routes": [{
-                    "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
-                    "next_hop": NEXT_HOP_IP[addr_type]
-                },
-                {
-                    "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
-                    "next_hop": NEXT_HOP_IP[addr_type]
-                },
-                {
-                    "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
-                    "next_hop": NEXT_HOP_IP[addr_type]
-                },
-                {
-                    "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
-                    "next_hop": NEXT_HOP_IP[addr_type]
-                },
-                {
-                    "network": [NETWORK5_1[addr_type]] + [NETWORK5_2[addr_type]],
-                    "next_hop": NEXT_HOP_IP[addr_type]
-                }]
-            }
+        input_dict_1 = {
+            "r3": {
+                "static_routes": [
+                    {
+                        "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
+                        "next_hop": NEXT_HOP_IP[addr_type],
+                    },
+                    {
+                        "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
+                        "next_hop": NEXT_HOP_IP[addr_type],
+                    },
+                    {
+                        "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
+                        "next_hop": NEXT_HOP_IP[addr_type],
+                    },
+                    {
+                        "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
+                        "next_hop": NEXT_HOP_IP[addr_type],
+                    },
+                    {
+                        "network": [NETWORK5_1[addr_type]] + [NETWORK5_2[addr_type]],
+                        "next_hop": NEXT_HOP_IP[addr_type],
+                    },
+                ]
             }
-            result = create_static_routes(tgen, input_dict_1)
-            assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        }
+        result = create_static_routes(tgen, input_dict_1)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
     step("verifying Created  Route  at R3 in VRF default")
     for addr_type in ADDR_TYPES:
-        dut = 'r3'
-        input_dict_1= {'r3': topo['routers']['r3']}
+        dut = "r3"
+        input_dict_1 = {"r3": topo["routers"]["r3"]}
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
-        assert result is True, \
-            "Testcase {} :Failed \n Error {}". \
-                format(tc_name, result)
-    #done
+        assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+    # done
     step("verifying Created  Route  at R2 in VRF default")
     for addr_type in ADDR_TYPES:
-        dut = 'r2'
-        input_dict_1= {'r2': topo['routers']['r2']}
+        dut = "r2"
+        input_dict_1 = {"r2": topo["routers"]["r2"]}
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
-        assert result is True, \
-            "Testcase {} :Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
     step("importing vrf RED on R2 under Address Family")
     for addr_type in ADDR_TYPES:
-        input_import_vrf={
+        input_import_vrf = {
             "r2": {
                 "bgp": [
                     {
                         "local_as": 200,
                         "vrf": "RED",
-                        "address_family": {addr_type: {"unicast": {"import": {"vrf": "default"}}}},
+                        "address_family": {
+                            addr_type: {"unicast": {"import": {"vrf": "default"}}}
+                        },
                     }
                 ]
             }
         }
-        result = create_router_bgp(tgen, topo,input_import_vrf)
-        assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
-    #done
+        result = create_router_bgp(tgen, topo, input_import_vrf)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+    # done
     step("verifying static  Routes  at R2 in VRF RED")
     for addr_type in ADDR_TYPES:
-        dut = 'r2'
-        input_dict_1= {'r2': topo['routers']['r2']}
+        dut = "r2"
+        input_dict_1 = {"r2": topo["routers"]["r2"]}
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
-        assert result is True, \
-            "Testcase {} :Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
 
     step("verifying static  Routes  at R1 in VRF RED")
     for addr_type in ADDR_TYPES:
-        dut = 'r1'
-        input_dict_1= {'r1': topo['routers']['r1']}
+        dut = "r1"
+        input_dict_1 = {"r1": topo["routers"]["r1"]}
         result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
-        assert result is True, \
-            "Testcase {} :Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
 
     step("Configuring Graceful restart at R2 and R3 ")
     input_dict = {
         "r2": {
-
             "bgp": {
                 "local_as": "200",
                 "graceful-restart": {
                     "graceful-restart": True,
-                }
+                },
             }
         },
         "r3": {
-            "bgp": {
-                "local_as": "300",
-                "graceful-restart": {
-                    "graceful-restart": True
-                }
-            }
-        }
+            "bgp": {"local_as": "300", "graceful-restart": {"graceful-restart": True}}
+        },
     }
 
-    configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name,dut='r2', peer='r3')
-
-
+    configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r2", peer="r3")
 
     step("verify Graceful restart at R2")
     for addr_type in ADDR_TYPES:
-        result = verify_graceful_restart(tgen, topo, addr_type, input_dict,
-                                         dut='r2', peer='r3')
-        assert result is True, \
-            "Testcase {} :Failed \n Error {}". \
-                format(tc_name, result)
+        result = verify_graceful_restart(
+            tgen, topo, addr_type, input_dict, dut="r2", peer="r3"
+        )
+        assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
 
     step("verify Graceful restart at R3")
     for addr_type in ADDR_TYPES:
-        result = verify_graceful_restart(tgen, topo, addr_type, input_dict,
-                                         dut='r3', peer='r2')
-        assert result is True, \
-            "Testcase {} :Failed \n Error {}". \
-                format(tc_name, result)
+        result = verify_graceful_restart(
+            tgen, topo, addr_type, input_dict, dut="r3", peer="r2"
+        )
+        assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
 
     step("Configuring Graceful-restart-disable at R3")
     input_dict = {
         "r2": {
-
             "bgp": {
                 "local_as": "200",
                 "graceful-restart": {
                     "graceful-restart": False,
-                }
+                },
             }
         },
         "r3": {
-            "bgp": {
-                "local_as": "300",
-                "graceful-restart": {
-                    "graceful-restart": False
-                }
-            }
-        }
+            "bgp": {"local_as": "300", "graceful-restart": {"graceful-restart": False}}
+        },
     }
-    configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name,dut='r3', peer='r2')
+    configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r3", peer="r2")
 
     step("Verify Graceful-restart-disable at R3")
     for addr_type in ADDR_TYPES:
-        result = verify_graceful_restart(tgen, topo, addr_type, input_dict,
-                                         dut='r3', peer='r2')
-        assert result is True, \
-            "Testcase {} :Failed \n Error {}". \
-                format(tc_name, result)
+        result = verify_graceful_restart(
+            tgen, topo, addr_type, input_dict, dut="r3", peer="r2"
+        )
+        assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
 
     for iteration in range(5):
         step("graceful-restart-disable:True  at R3")
         input_dict = {
-        "r3": {
-            "bgp": {
-                "graceful-restart": {
-                    "graceful-restart-disable": True,
+            "r3": {
+                "bgp": {
+                    "graceful-restart": {
+                        "graceful-restart-disable": True,
+                    }
                 }
             }
-            }
         }
-        configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name,
-                                   dut='r3', peer='r2')
+        configure_gr_followed_by_clear(
+            tgen, topo, input_dict, tc_name, dut="r3", peer="r2"
+        )
 
         step("Verifying  Routes at R2 on enabling GRD")
-        dut = 'r2'
+        dut = "r2"
         for addr_type in ADDR_TYPES:
-            input_dict_1= {'r2': topo['routers']['r2']}
+            input_dict_1 = {"r2": topo["routers"]["r2"]}
             result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
-            assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+            assert result is True, "Testcase {} :Failed \n Error {}".format(
+                tc_name, result
+            )
 
         step("Verify stale Routes in Router R2 enabling GRD")
         for addr_type in ADDR_TYPES:
@@ -495,39 +486,45 @@ def test_bgp_gr_stale_routes(request):
             verify_nh_for_static_rtes = {
                 "r3": {
                     "static_routes": [
-
                         {
                             "network": [NETWORK1_1[addr_type]],
                             "no_of_ip": 2,
-                            "vrf": "RED"
+                            "vrf": "RED",
                         }
                     ]
                 }
             }
             bgp_rib_next_hops = verify_stale_routes_list(
-            tgen, addr_type, dut, verify_nh_for_static_rtes)
-            assert (len(bgp_rib_next_hops)== 1) is True, "Testcase {} : Failed \n Error: {}".format(
-             tc_name, bgp_rib_next_hops,expected=True)
+                tgen, addr_type, dut, verify_nh_for_static_rtes
+            )
+            assert (
+                len(bgp_rib_next_hops) == 1
+            ) is True, "Testcase {} : Failed \n Error: {}".format(
+                tc_name, bgp_rib_next_hops, expected=True
+            )
 
         step("graceful-restart-disable:False at R3")
         input_dict = {
-        "r3": {
-            "bgp": {
-                "graceful-restart": {
-                    "graceful-restart-disable": False,
+            "r3": {
+                "bgp": {
+                    "graceful-restart": {
+                        "graceful-restart-disable": False,
+                    }
                 }
             }
-            }
         }
-        configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name,
-                                   dut='r3', peer='r2')
+        configure_gr_followed_by_clear(
+            tgen, topo, input_dict, tc_name, dut="r3", peer="r2"
+        )
 
         step("Verifying  Routes at R2 on disabling GRD")
-        dut = 'r2'
+        dut = "r2"
         for addr_type in ADDR_TYPES:
-            input_dict_1= {'r2': topo['routers']['r2']}
+            input_dict_1 = {"r2": topo["routers"]["r2"]}
             result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
-            assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
+            assert result is True, "Testcase {} :Failed \n Error {}".format(
+                tc_name, result
+            )
 
         step("Verify stale Routes in Router R2 on disabling GRD")
         for addr_type in ADDR_TYPES:
@@ -536,19 +533,22 @@ def test_bgp_gr_stale_routes(request):
             verify_nh_for_static_rtes = {
                 "r3": {
                     "static_routes": [
-
                         {
                             "network": [NETWORK1_1[addr_type]],
                             "no_of_ip": 2,
-                            "vrf": "RED"
+                            "vrf": "RED",
                         }
                     ]
                 }
             }
-            bgp_rib_next_hops = verify_stale_routes_list(tgen, addr_type, dut, verify_nh_for_static_rtes)
-
-            stale_route_status=len(bgp_rib_next_hops)== 1
-            assert stale_route_status is True, "Testcase {} : Failed \n Error: {}".format(
-             tc_name, stale_route_status,expected=True)
+            bgp_rib_next_hops = verify_stale_routes_list(
+                tgen, addr_type, dut, verify_nh_for_static_rtes
+            )
+
+            stale_route_status = len(bgp_rib_next_hops) == 1
+            assert (
+                stale_route_status is True
+            ), "Testcase {} : Failed \n Error: {}".format(
+                tc_name, stale_route_status, expected=True
+            )
     write_test_footer(tc_name)
-
diff --git a/tests/topotests/bgp_gr_restart_retain_routes/__init__.py b/tests/topotests/bgp_gr_restart_retain_routes/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_gr_restart_retain_routes/r1/bgpd.conf b/tests/topotests/bgp_gr_restart_retain_routes/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..50d1583
--- /dev/null
@@ -0,0 +1,11 @@
+router bgp 65001
+ no bgp ebgp-requires-policy
+ bgp graceful-restart
+ bgp graceful-restart preserve-fw-state
+ neighbor 192.168.255.2 remote-as external
+ neighbor 192.168.255.2 timers 1 3
+ neighbor 192.168.255.2 timers connect 1
+ address-family ipv4
+  redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_gr_restart_retain_routes/r1/zebra.conf b/tests/topotests/bgp_gr_restart_retain_routes/r1/zebra.conf
new file mode 100644 (file)
index 0000000..e65bfb2
--- /dev/null
@@ -0,0 +1,7 @@
+!
+interface lo
+ ip address 172.16.255.1/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
diff --git a/tests/topotests/bgp_gr_restart_retain_routes/r2/bgpd.conf b/tests/topotests/bgp_gr_restart_retain_routes/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..97418ca
--- /dev/null
@@ -0,0 +1,8 @@
+router bgp 65002
+ no bgp ebgp-requires-policy
+ bgp graceful-restart
+ bgp graceful-restart preserve-fw-state
+ neighbor 192.168.255.1 remote-as external
+ neighbor 192.168.255.1 timers 1 3
+ neighbor 192.168.255.1 timers connect 1
+!
diff --git a/tests/topotests/bgp_gr_restart_retain_routes/r2/zebra.conf b/tests/topotests/bgp_gr_restart_retain_routes/r2/zebra.conf
new file mode 100644 (file)
index 0000000..758d797
--- /dev/null
@@ -0,0 +1,5 @@
+no zebra nexthop kernel enable
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
diff --git a/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_restart_retain_routes.py b/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_restart_retain_routes.py
new file mode 100644 (file)
index 0000000..52ce0d5
--- /dev/null
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2022 by
+# Donatas Abraitis <donatas@opensourcerouting.org>
+#
+# 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 routes are retained during BGP restarts.
+"""
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+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.common_config import step, stop_router
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+    for routern in range(1, 3):
+        tgen.add_router("r{}".format(routern))
+
+    switch = tgen.add_switch("s1")
+    switch.add_link(tgen.gears["r1"])
+    switch.add_link(tgen.gears["r2"])
+
+
+def setup_module(mod):
+    tgen = Topogen(build_topo, 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_gr_restart_retain_routes():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    r1 = tgen.gears["r1"]
+    r2 = tgen.gears["r2"]
+
+    def _bgp_converge():
+        output = json.loads(r2.vtysh_cmd("show bgp ipv4 neighbors 192.168.255.1 json"))
+        expected = {
+            "192.168.255.1": {
+                "bgpState": "Established",
+                "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}},
+            }
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _bgp_check_bgp_retained_routes():
+        output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast 172.16.255.1/32 json"))
+        expected = {"paths": [{"stale": True}]}
+        return topotest.json_cmp(output, expected)
+
+    def _bgp_check_kernel_retained_routes():
+        output = (
+            r2.cmd("ip route show 172.16.255.1/32 proto bgp dev r2-eth0")
+            .replace("\n", "")
+            .rstrip()
+        )
+        expected = "172.16.255.1 via 192.168.255.1 metric 20"
+        diff = topotest.get_textdiff(
+            output, expected, "Actual IP Routing Table", "Expected IP RoutingTable"
+        )
+        if diff:
+            return False
+        return True
+
+    step("Initial BGP converge")
+    test_func = functools.partial(_bgp_converge)
+    _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+    assert result is None, "Failed to see BGP convergence on R2"
+
+    step("Restart R1")
+    stop_router(tgen, "r1")
+
+    step("Check if routes (BGP) are retained at R2")
+    test_func = functools.partial(_bgp_check_bgp_retained_routes)
+    _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+    assert result is None, "Failed to see BGP retained routes on R2"
+
+    step("Check if routes (Kernel) are retained at R2")
+    assert _bgp_check_kernel_retained_routes() == True
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
index 58133c44a97068fb39a55cf7dff5c9042b173c94..684d2fcb57925551fa1c03b1dfb39a071da31ed9 100644 (file)
@@ -92,7 +92,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
index a79ce0e3a0e91ea9325d380a786fd7229a7406d1..16572a7967e6cecee302800a093f6ea209cb2fd1 100644 (file)
@@ -87,7 +87,7 @@ def setup_module(mod):
     # Required linux kernel version for this suite to run.
     result = required_linux_kernel_version("4.16")
     if result is not True:
-        pytest.skip("Kernel requirements are not met")
+        pytest.skip("Kernel requirements are not met, kernel version should be >=4.16")
 
     testsuite_run_time = time.asctime(time.localtime(time.time()))
     logger.info("Testsuite start time: {}".format(testsuite_run_time))
index 4105c3fe63eb6de27e0be757bc04906322301ccc..c0709043538b7fb908ee804b4f3875b6e263bed6 100644 (file)
@@ -26,13 +26,17 @@ import os
 import sys
 import time
 import pytest
+import functools
+import json
 
 # Save the Current Working Directory to find configuration files.
 CWD = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.join(CWD, "../"))
 sys.path.append(os.path.join(CWD, "../../"))
 
-from lib.topogen import Topogen, get_topogen
+
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
 
 from lib.common_config import (
     write_test_header,
@@ -288,7 +292,6 @@ def test_unnumbered_loopback_ebgp_nbr_p0(request):
         " received on R2 BGP and routing table , "
         "verify using show ip bgp, show ip route for IPv4 routes ."
     )
-
     llip = get_llip("r1", "r2-link0")
     assert llip is not None, "Testcase {} : Failed \n Error: {}".format(tc_name, llip)
 
@@ -582,6 +585,195 @@ def test_restart_frr_p2(request):
     write_test_footer(tc_name)
 
 
+def test_configure_gua_on_unnumbered_intf(request):
+    """
+    Configure a global V6 address on an unnumbered interface on R1
+
+    """
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+    reset_config_on_routers(tgen)
+
+    step("Configure IPv6 EBGP Unnumbered session between R1 and R2")
+    step("Enable capability extended-nexthop on both the IPv6 BGP peers")
+    step("Activate same IPv6 nbr from IPv4 unicast family")
+    step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
+    step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
+    bgp_convergence = verify_bgp_convergence(tgen, topo)
+    assert bgp_convergence is True, "Testcase {} :Failed \n Error: {}".format(
+        tc_name, bgp_convergence
+    )
+
+    step(" Configure 5 IPv4 static" " routes on R1, Nexthop as different links of R0")
+    for rte in range(0, NO_OF_RTES):
+        # Create Static routes
+        input_dict = {
+            "r1": {
+                "static_routes": [
+                    {
+                        "network": NETWORK["ipv4"][rte],
+                        "no_of_ip": 1,
+                        "next_hop": NEXT_HOP["ipv4"][rte],
+                    }
+                ]
+            }
+        }
+        result = create_static_routes(tgen, input_dict)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+
+    step(
+        "Advertise static routes from IPv4 unicast family and IPv6 "
+        "unicast family respectively from R1 using red static cmd "
+        "Advertise loopback from IPv4 unicast family using network command "
+        "from R1"
+    )
+
+    configure_bgp_on_r1 = {
+        "r1": {
+            "bgp": {
+                "address_family": {
+                    "ipv4": {
+                        "unicast": {
+                            "redistribute": [{"redist_type": "static"}],
+                            "advertise_networks": [
+                                {"network": NETWORK_CMD_IP, "no_of_network": 1}
+                            ],
+                        }
+                    },
+                    "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+                }
+            }
+        }
+    }
+    result = create_router_bgp(tgen, topo, configure_bgp_on_r1)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+    r2 = tgen.gears["r2"]
+
+    def bgp_prefix_received_gua_nh(router):
+        output = json.loads(router.vtysh_cmd("show bgp ipv4 unicast 11.0.20.1/32 json"))
+        expected = {
+            "prefix": "11.0.20.1/32",
+            "paths": [
+                {
+                    "nexthops": [
+                        {
+                            "ip": "5001:dead:beef::1",
+                            "hostname": "r1",
+                            "afi": "ipv6",
+                            "scope": "global",
+                        }
+                    ]
+                }
+            ],
+        }
+        return topotest.json_cmp(output, expected)
+
+    def bgp_prefix_received_v4_mapped_v6_nh(router):
+        output = json.loads(router.vtysh_cmd("show bgp ipv4 unicast 11.0.20.1/32 json"))
+        expected = {
+            "prefix": "11.0.20.1/32",
+            "paths": [
+                {
+                    "nexthops": [
+                        {
+                            "ip": "::ffff:a00:501",
+                            "hostname": "r1",
+                            "afi": "ipv6",
+                            "scope": "global",
+                        }
+                    ]
+                }
+            ],
+        }
+        return topotest.json_cmp(output, expected)
+
+    step("Configure a global V6 address on an unnumbered interface on R1")
+    output = tgen.gears["r1"].vtysh_cmd(
+        """
+        configure terminal
+        interface r1-r2-eth5
+        ipv6 address 5001:dead:beef::1/126
+        !
+        """
+    )
+
+    # verify that r2 has received prefix with GUA as nexthop
+    test_func = functools.partial(bgp_prefix_received_gua_nh, r2)
+    _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+    assert (
+        result is None
+    ), "Testcase {} : Failed \n Error: Nexthop for prefix 11.0.20.1 \
+    is not 5001:dead:beef::1".format(
+        tc_name
+    )
+
+    step("Configure a secondary global V6 address on an unnumbered interface on R1")
+    output = tgen.gears["r1"].vtysh_cmd(
+        """
+        configure terminal
+        interface r1-r2-eth5
+        ipv6 address 7771:dead:beef::1/126
+        !
+        """
+    )
+    # verify that r1 did not readvertise the prefix with secondary V6 address as the nexthop
+    test_func = functools.partial(bgp_prefix_received_gua_nh, r2)
+    _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+    assert (
+        result is None
+    ), "Testcase {} : Failed \n Error: Nexthop for prefix 11.0.20.1 \
+    is not 5001:dead:beef::1".format(
+        tc_name
+    )
+
+    step("Unconfigure the secondary global V6 address from unnumbered interface on R1")
+    output = tgen.gears["r1"].vtysh_cmd(
+        """
+        configure terminal
+        interface r1-r2-eth5
+        no ipv6 address 7771:dead:beef::1/126
+        !
+        """
+    )
+    # verify that r1 still has the prefix with primary GUA as the nexthop
+    test_func = functools.partial(bgp_prefix_received_gua_nh, r2)
+    _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+    assert (
+        result is None
+    ), "Testcase {} : Failed \n Error: Nexthop for prefix 11.0.20.1 \
+    is not 5001:dead:beef::1".format(
+        tc_name
+    )
+
+    step("Unconfigure the primary global V6 address from unnumbered interface on R1")
+    output = tgen.gears["r1"].vtysh_cmd(
+        """
+        configure terminal
+        interface r1-r2-eth5
+        no ipv6 address 5001:dead:beef::1/126
+        !
+        """
+    )
+    # verify that r1 has rcvd the prefix with v4-mapped-v6 address as the nexthop
+    test_func = functools.partial(bgp_prefix_received_v4_mapped_v6_nh, r2)
+    _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+    assert (
+        result is None
+    ), "Testcase {} : Failed \n Error: Nexthop for prefix 11.0.20.1 \
+    is not ::ffff:a00:501".format(
+        tc_name
+    )
+
+    write_test_footer(tc_name)
+
+
 if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_local_as/__init__.py b/tests/topotests/bgp_local_as/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_local_as/r1/bgpd.conf b/tests/topotests/bgp_local_as/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..fa147d8
--- /dev/null
@@ -0,0 +1,14 @@
+router bgp 65001
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.2 remote-as 65002
+ neighbor 192.168.1.2 local-as 65002
+ neighbor 192.168.1.2 timers 1 3
+ neighbor 192.168.1.2 timers connect 1
+ neighbor PG peer-group
+ neighbor PG remote-as 65003
+ neighbor PG local-as 65003
+ neighbor 192.168.2.2 peer-group PG
+ address-family ipv4
+  redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_local_as/r1/zebra.conf b/tests/topotests/bgp_local_as/r1/zebra.conf
new file mode 100644 (file)
index 0000000..5b32fae
--- /dev/null
@@ -0,0 +1,10 @@
+!
+interface lo
+ ip address 172.16.255.1/32
+!
+interface r1-eth0
+ ip address 192.168.1.1/24
+!
+interface r1-eth1
+ ip address 192.168.2.1/24
+!
diff --git a/tests/topotests/bgp_local_as/r2/bgpd.conf b/tests/topotests/bgp_local_as/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..9c25bdf
--- /dev/null
@@ -0,0 +1,6 @@
+router bgp 65002
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.1 remote-as internal
+ neighbor 192.168.1.1 timers 1 3
+ neighbor 192.168.1.1 timers connect 1
+!
diff --git a/tests/topotests/bgp_local_as/r2/zebra.conf b/tests/topotests/bgp_local_as/r2/zebra.conf
new file mode 100644 (file)
index 0000000..0c95656
--- /dev/null
@@ -0,0 +1,4 @@
+!
+interface r2-eth0
+ ip address 192.168.1.2/24
+!
diff --git a/tests/topotests/bgp_local_as/r3/bgpd.conf b/tests/topotests/bgp_local_as/r3/bgpd.conf
new file mode 100644 (file)
index 0000000..54ccd90
--- /dev/null
@@ -0,0 +1,6 @@
+router bgp 65003
+ no bgp ebgp-requires-policy
+ neighbor 192.168.2.1 remote-as internal
+ neighbor 192.168.2.1 timers 1 3
+ neighbor 192.168.2.1 timers connect 1
+!
diff --git a/tests/topotests/bgp_local_as/r3/zebra.conf b/tests/topotests/bgp_local_as/r3/zebra.conf
new file mode 100644 (file)
index 0000000..d28dedd
--- /dev/null
@@ -0,0 +1,4 @@
+!
+interface r3-eth0
+ ip address 192.168.2.2/24
+!
diff --git a/tests/topotests/bgp_local_as/test_bgp_local_as.py b/tests/topotests/bgp_local_as/test_bgp_local_as.py
new file mode 100644 (file)
index 0000000..525d442
--- /dev/null
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2022 by
+# Donatas Abraitis <donatas@opensourcerouting.org>
+#
+# 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.
+#
+
+"""
+
+"""
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+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.common_config import step
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+    for routern in range(1, 4):
+        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"])
+
+
+def setup_module(mod):
+    tgen = Topogen(build_topo, 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_local_as_same_remote_as():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    def _bgp_check_local_as_same_remote_as():
+        output = json.loads(
+            tgen.gears["r2"].vtysh_cmd("show bgp ipv4 unicast 172.16.255.1/32 json")
+        )
+        expected = {
+            "paths": [
+                {
+                    "valid": True,
+                    "aspath": {"string": "Local"},
+                    "nexthops": [{"ip": "192.168.1.1", "hostname": "r1"}],
+                }
+            ]
+        }
+        return topotest.json_cmp(output, expected)
+
+    step("Check if iBGP works when local-as == remote-as")
+    test_func = functools.partial(_bgp_check_local_as_same_remote_as)
+    _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+    assert result is None, "Failed to see BGP prefixes on R2"
+
+
+def test_bgp_peer_group_local_as_same_remote_as():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    def _bgp_check_local_as_same_remote_as():
+        output = json.loads(
+            tgen.gears["r3"].vtysh_cmd("show bgp ipv4 unicast 172.16.255.1/32 json")
+        )
+        expected = {
+            "paths": [
+                {
+                    "valid": True,
+                    "aspath": {"string": "Local"},
+                    "nexthops": [{"ip": "192.168.2.1", "hostname": "r1"}],
+                }
+            ]
+        }
+        return topotest.json_cmp(output, expected)
+
+    step("Initial BGP converge")
+    test_func = functools.partial(_bgp_check_local_as_same_remote_as)
+    _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+    assert result is None, "Failed to see BGP prefixes on R3"
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
index 2dc95cee21a82dfe06da20c2dedb800c3087dd4f..5131a89ce832512903b57e124b0842887fc78f71 100644 (file)
@@ -346,9 +346,12 @@ def test_ip_prefix_lists_out_permit(request):
     result = verify_rib(
         tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: Routes still" " present in RIB".format(tc_name)
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: Routes should not be present in {} FIB \n "
+        "Found: {}".format(tc_name, dut, result)
+    )
+
     write_test_footer(tc_name)
 
 
@@ -444,9 +447,11 @@ def test_ip_prefix_lists_in_deny_and_permit_any(request):
     result = verify_rib(
         tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: Routes still" " present in RIB".format(tc_name)
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: Routes should not be present in {} BGP RIB \n "
+        "Found: {}".format(tc_name, dut, result)
+    )
 
     write_test_footer(tc_name)
 
@@ -644,9 +649,12 @@ def test_ip_prefix_lists_out_deny_and_permit_any(request):
     result = verify_rib(
         tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: Routes still" " present in RIB".format(tc_name)
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: Routes should not be present in {} BGP RIB \n "
+        "Found: {}".format(tc_name, dut, result)
+    )
+
     write_test_footer(tc_name)
 
 
@@ -778,9 +786,11 @@ def test_modify_prefix_lists_in_permit_to_deny(request):
     result = verify_rib(
         tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: Routes still" " present in RIB".format(tc_name)
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: Routes should not be present in {} BGP RIB \n "
+        "Found: {}".format(tc_name, dut, result)
+    )
 
     write_test_footer(tc_name)
 
@@ -882,9 +892,11 @@ def test_modify_prefix_lists_in_deny_to_permit(request):
     result = verify_rib(
         tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: Routes still" " present in RIB".format(tc_name)
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: Routes should not be present in {} BGP RIB \n "
+        "Found: {}".format(tc_name, dut, result)
+    )
 
     # Modify  ip prefix list
     input_dict_1 = {
@@ -1051,9 +1063,11 @@ def test_modify_prefix_lists_out_permit_to_deny(request):
     result = verify_rib(
         tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: Routes still" " present in RIB".format(tc_name)
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: Routes should not be present in {} BGP RIB \n "
+        "Found: {}".format(tc_name, dut, result)
+    )
 
     write_test_footer(tc_name)
 
@@ -1157,9 +1171,11 @@ def test_modify_prefix_lists_out_deny_to_permit(request):
     result = verify_rib(
         tgen, "ipv4", dut, input_dict, protocol=protocol, expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: Routes still" " present in RIB".format(tc_name)
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: Routes should not be present in {} BGP RIB \n "
+        "Found: {}".format(tc_name, dut, result)
+    )
 
     # Modify ip prefix list
     input_dict_1 = {
@@ -1324,9 +1340,11 @@ def test_ip_prefix_lists_implicit_deny(request):
     result = verify_rib(
         tgen, "ipv4", dut, input_dict_1, protocol=protocol, expected=False
     )
-    assert (
-        result is not True
-    ), "Testcase {} : Failed \n Error: Routes still" " present in RIB".format(tc_name)
+    assert result is not True, (
+        "Testcase {} : Failed \n "
+        "Expected: Routes should not be present in {} BGP RIB \n "
+        "Found: {}".format(tc_name, dut, result)
+    )
 
     write_test_footer(tc_name)
 
index 655a3dc8991e84a36562c2cb55d47164e71a140a..77bddbe3372491e5abcc8df38a52397b37dde672 100644 (file)
@@ -444,12 +444,11 @@ def test_route_map_inbound_outbound_same_neighbor_p0(request):
         result = verify_rib(
             tgen, adt, dut, input_dict_2, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are not present in rib \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} BGP RIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
         # Verifying RIB routes
         dut = "r4"
@@ -467,12 +466,11 @@ def test_route_map_inbound_outbound_same_neighbor_p0(request):
         result = verify_rib(
             tgen, adt, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are not present in rib \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -666,12 +664,11 @@ def test_route_map_with_action_values_combination_of_prefix_action_p0(
             result = verify_rib(
                 tgen, adt, dut, input_dict_2, protocol=protocol, expected=False
             )
-            assert (
-                result is not True
-            ), "Testcase {} : Failed \nRoutes are still present \n Error: {}".format(
-                tc_name, result
+            assert result is not True, (
+                "Testcase {} : Failed \n "
+                "Expected: Routes should not be present in {} FIB \n "
+                "Found: {}".format(tc_name, dut, result)
             )
-            logger.info("Expected behaviour: {}".format(result))
         else:
             result = verify_rib(tgen, adt, dut, input_dict_2, protocol=protocol)
             assert result is True, "Testcase {} : Failed \n Error: {}".format(
index 4da7eeb2ff2b87de314fdd8c167154788198a673..589482d6a594ca17650598dc2466c04d6297715d 100644 (file)
@@ -1022,12 +1022,11 @@ def test_modify_prefix_list_referenced_by_rmap_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are not present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     # Verifying RIB routes
     dut = "r4"
@@ -1036,10 +1035,10 @@ def test_modify_prefix_list_referenced_by_rmap_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nExpected behaviour: routes are not present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
 
     write_test_footer(tc_name)
@@ -1293,12 +1292,11 @@ def test_remove_prefix_list_referenced_by_rmap_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are not present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     # Verifying RIB routes
     dut = "r4"
@@ -1307,12 +1305,11 @@ def test_remove_prefix_list_referenced_by_rmap_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are not present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -2139,12 +2136,11 @@ def test_add_remove_rmap_to_specific_neighbor_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \n Error Routes are still present: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     # Remove applied rmap from neighbor
     input_dict_4 = {
@@ -2553,12 +2549,11 @@ def test_rmap_without_match_and_set_clause_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are not present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     write_test_footer(tc_name)
     # Uncomment next line for debugging
@@ -2801,12 +2796,11 @@ def test_set_localpref_weight_to_ebgp_and_med_to_ibgp_peers_p0():
             input_dict_3_addr_type[addr_type],
             expected=False,
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nAttributes are not set \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: BGP attributes should not be set in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     # Verifying RIB routes
     dut = "r5"
@@ -2835,12 +2829,11 @@ def test_set_localpref_weight_to_ebgp_and_med_to_ibgp_peers_p0():
             input_dict_3_addr_type[addr_type],
             expected=False,
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nAttributes are not set \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: BGP attributes should not be set in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -3644,12 +3637,11 @@ def test_create_rmap_match_prefix_list_to_deny_in_and_outbound_prefixes_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are not present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     # Verifying RIB routes
     dut = "r4"
@@ -3658,12 +3650,11 @@ def test_create_rmap_match_prefix_list_to_deny_in_and_outbound_prefixes_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are not present \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     write_test_footer(tc_name)
 
@@ -3963,12 +3954,11 @@ def test_create_rmap_to_match_tag_deny_outbound_prefixes_p0():
         result = verify_rib(
             tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
         )
-        assert (
-            result is not True
-        ), "Testcase {} : Failed \nroutes are denied \n Error: {}".format(
-            tc_name, result
+        assert result is not True, (
+            "Testcase {} : Failed \n "
+            "Expected: Routes should not be present in {} FIB \n "
+            "Found: {}".format(tc_name, dut, result)
         )
-        logger.info("Expected behaviour: {}".format(result))
 
     write_test_footer(tc_name)
 
diff --git a/tools/coccinelle/route_map_apply.cocci b/tools/coccinelle/route_map_apply.cocci
new file mode 100644 (file)
index 0000000..ccca619
--- /dev/null
@@ -0,0 +1,15 @@
+@rmap@
+identifier ret;
+position p;
+@@
+
+int ret@p;
+...
+* ret = route_map_apply(...);
+
+@script:python@
+p << rmap.p;
+@@
+
+msg = "ERROR: Invalid type of return value variable for route_map_apply_ext()"
+coccilib.report.print_report(p[0], msg)
index 32f9a7884197ef5710afbfd34bbe956a18d84220..7c5d91d4dc5471a722eee8a0ec77cac75a3f24d8 100755 (executable)
@@ -890,7 +890,7 @@ def bgp_remove_neighbor_cfg(lines_to_del, del_nbr_dict):
         ):
             if ctx_keys[0] in del_nbr_dict:
                 for nbr in del_nbr_dict[ctx_keys[0]]:
-                    re_nbr_pg = re.search('neighbor (\S+) .*peer-group (\S+)', line)
+                    re_nbr_pg = re.search("neighbor (\S+) .*peer-group (\S+)", line)
                     nb_exp = "neighbor %s .*" % nbr
                     if not re_nbr_pg:
                         re_nb = re.search(nb_exp, line)
@@ -997,7 +997,7 @@ def delete_move_lines(lines_to_add, lines_to_del):
             # 'no neighbor peer [interface] peer-group <>' is in lines_to_del
             # copy the neighbor and look for all config removal lines associated
             # to neighbor and delete them from the lines_to_del
-            re_nbr_pg = re.search('neighbor (\S+) .*peer-group (\S+)', line)
+            re_nbr_pg = re.search("neighbor (\S+) .*peer-group (\S+)", line)
             if re_nbr_pg:
                 if ctx_keys[0] not in del_nbr_dict:
                     del_nbr_dict[ctx_keys[0]] = list()
@@ -1376,6 +1376,37 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                 lines_to_add.append((add_cmd, None))
                 lines_to_del_to_del.append((ctx_keys, None))
 
+        # bgp community-list, large-community-list, extcommunity-list can be
+        # specified without a seq number. However, the running config always
+        # adds `seq X` (sequence number). So, ignore such lines as well.
+        # Examples:
+        #      bgp community-list standard clist seq 5 permit 222:213
+        #      bgp large-community-list standard llist seq 5 permit 65001:65001:1
+        #      bgp extcommunity-list standard elist seq 5 permit soo 123:123
+        re_bgp_lists = re.search(
+            "^(bgp )(community-list|large-community-list|extcommunity-list)(\s+\S+\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$",
+            ctx_keys[0],
+        )
+        if re_bgp_lists:
+            found = False
+            tmpline = (
+                re_bgp_lists.group(1)
+                + re_bgp_lists.group(2)
+                + re_bgp_lists.group(3)
+                + re_bgp_lists.group(4)
+                + re_bgp_lists.group(6)
+                + re_bgp_lists.group(7)
+            )
+            for ctx in lines_to_add:
+                if ctx[0][0] == tmpline:
+                    lines_to_del_to_del.append((ctx_keys, None))
+                    lines_to_add_to_del.append(((tmpline,), None))
+                    found = True
+            if found is False:
+                add_cmd = ("no " + ctx_keys[0],)
+                lines_to_add.append((add_cmd, None))
+                lines_to_del_to_del.append((ctx_keys, None))
+
         if (
             len(ctx_keys) == 3
             and ctx_keys[0].startswith("router bgp")
index df1e4f3b081e0f47be669949cf2e7dedb4f2446b..1e958dd93e3d0c7bec4ad809c4822289bf10bab2 100644 (file)
@@ -15,7 +15,7 @@ StartLimitBurst=3
 TimeoutSec=@TIMEOUT_MIN@m
 WatchdogSec=60s
 RestartSec=5
-Restart=on-abnormal
+Restart=always
 LimitNOFILE=1024
 PIDFile=@CFG_STATE@/watchfrr.pid
 ExecStart=@CFG_SBIN@/frrinit.sh start
index 1cbef1b18c042573ce88c7261eecd52300745dda..85408a0cc7ea99b26b9024246fdb1686faa3d3a0 100644 (file)
@@ -15,7 +15,7 @@ StartLimitBurst=3
 TimeoutSec=@TIMEOUT_MIN@m
 WatchdogSec=60s
 RestartSec=5
-Restart=on-abnormal
+Restart=always
 LimitNOFILE=1024
 PIDFile=@CFG_STATE@/%I/watchfrr.pid
 ExecStart=@CFG_SBIN@/frrinit.sh start %I
index 634a55dbc37fd3390b6375df0d67a579311a3496..d2f25f2d405da7728b9fd0d37d98e47186b9a4f5 100644 (file)
@@ -710,6 +710,8 @@ DEFUN_NOSH (show_debugging_vrrp,
 
        vrrp_debug_status_write(vty);
 
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index a7ec2a93c2d56f3ad9636157044ce81d08d7107f..d98f83dbf6d6f32482a1ca2b0caf2de9d661087b 100644 (file)
@@ -483,13 +483,21 @@ void vtysh_config_parse_line(void *arg, const char *line)
                                    0 ||
                            strncmp(line, "domainname", strlen("domainname")) ==
                                    0 ||
+                           strncmp(line, "allow-reserved-ranges",
+                                   strlen("allow-reserved-ranges")) == 0 ||
                            strncmp(line, "frr", strlen("frr")) == 0 ||
                            strncmp(line, "agentx", strlen("agentx")) == 0 ||
                            strncmp(line, "no log", strlen("no log")) == 0 ||
                            strncmp(line, "no ip prefix-list",
                                    strlen("no ip prefix-list")) == 0 ||
                            strncmp(line, "no ipv6 prefix-list",
-                                   strlen("no ipv6 prefix-list")) == 0)
+                                   strlen("no ipv6 prefix-list")) == 0 ||
+                           strncmp(line, "service cputime-stats",
+                                   strlen("service cputime-stats")) == 0 ||
+                           strncmp(line, "no service cputime-stats",
+                                   strlen("no service cputime-stats")) == 0 ||
+                           strncmp(line, "service cputime-warning",
+                                   strlen("service cputime-warning")) == 0)
                                config_add_line_uniq(config_top, line);
                        else
                                config_add_line(config_top, line);
index 1492ee37b600073b443cf3d2aea8eba5e39657a2..e5cc43754243786d2e435ad7833497c651241335 100644 (file)
@@ -125,6 +125,8 @@ DEFUN_NOSH (show_debugging_watchfrr,
             DEBUG_STR
             WATCHFRR_STR)
 {
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index 69aaed33acb5a88ed5640c804334e4e6ab2b204f..25102145d757e81d34b3bbfeaf6677ced07d01ff 100644 (file)
@@ -137,6 +137,9 @@ DEFUN_NOSH (show_debugging_zebra,
                vty_out(vty, "  Zebra PBR debugging is on\n");
 
        hook_call(zebra_debug_show_debugging, vty);
+
+       cmd_show_lib_debugs(vty);
+
        return CMD_SUCCESS;
 }
 
index 2c83a7ed4ce5f2914a020958476a1d64796685c5..e02f3d5624a8ff059a2c2f6ed0bd23980cc9d16a 100644 (file)
@@ -199,7 +199,7 @@ static int if_getaddrs(void)
                ifp = if_lookup_by_name(ifap->ifa_name, VRF_DEFAULT);
                if (ifp == NULL) {
                        flog_err(EC_LIB_INTERFACE,
-                                "if_getaddrs(): Can't lookup interface %s",
+                                "%s: Can't lookup interface %s", __func__,
                                 ifap->ifa_name);
                        continue;
                }
@@ -290,7 +290,7 @@ static void interface_info_ioctl()
 void interface_list(struct zebra_ns *zns)
 {
 
-       zlog_info("interface_list: NS %u", zns->ns_id);
+       zlog_info("%s: NS %u", __func__, zns->ns_id);
 
 /* Linux can do both proc & ioctl, ioctl is the only way to get
    interface aliases in 2.2 series kernels. */
index c7e7443a1b7a18862f65848ebf05a0c0819c7e93..b28c468a969dcb268f7a206895ba1fe7866a5adb 100644 (file)
@@ -1182,13 +1182,19 @@ int interface_lookup_netlink(struct zebra_ns *zns)
        if (ret < 0)
                return ret;
 
+       /*
+        * So netlink_tunneldump_read will initiate a request
+        * per tunnel to get data.  If we are on a kernel that
+        * does not support this then we will get X error messages
+        * (one per tunnel request )back which netlink_parse_info will
+        * stop after the first one.  So we need to read equivalent
+        * error messages per tunnel then we can continue.
+        * if we do not gather all the read failures then
+        * later requests will not work right.
+        */
        ret = netlink_tunneldump_read(zns);
        if (ret < 0)
                return ret;
-       ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0,
-                                true);
-       if (ret < 0)
-               return ret;
 
        /* fixup linkages */
        zebra_if_update_all_links(zns);
@@ -1443,7 +1449,7 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
        {
                char buf[BUFSIZ];
-               zlog_debug("netlink_interface_addr %s %s flags 0x%x:",
+               zlog_debug("%s %s %s flags 0x%x:", __func__,
                           nl_msg_type_to_str(h->nlmsg_type), ifp->name,
                           kernel_flags);
                if (tb[IFA_LOCAL])
@@ -1818,7 +1824,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        /* assume if not default zns, then new VRF */
        if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) {
                /* If this is not link add/delete message so print warning. */
-               zlog_debug("netlink_link_change: wrong kernel message %s",
+               zlog_debug("%s: wrong kernel message %s", __func__,
                           nl_msg_type_to_str(h->nlmsg_type));
                return 0;
        }
@@ -2322,6 +2328,7 @@ int netlink_tunneldump_read(struct zebra_ns *zns)
        struct route_node *rn;
        struct interface *tmp_if = NULL;
        struct zebra_if *zif;
+       struct nlsock *netlink_cmd = &zns->netlink_cmd;
 
        zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
 
@@ -2337,7 +2344,14 @@ int netlink_tunneldump_read(struct zebra_ns *zns)
                                                 tmp_if->ifindex);
                if (ret < 0)
                        return ret;
+
+               ret = netlink_parse_info(netlink_interface, netlink_cmd,
+                                        &dp_info, 0, true);
+
+               if (ret < 0)
+                       return ret;
        }
+
        return 0;
 }
 #endif /* GNU_LINUX */
index 38729c8d38e4a9896d857bae105ee78b0ea8f1f8..70d11646c34488916fc4d9513cc377a90a443992 100644 (file)
@@ -97,7 +97,7 @@ void interface_list(struct zebra_ns *zns)
                NET_RT_IFLIST, 0};
 
        if (zns->ns_id != NS_DEFAULT) {
-               zlog_debug("interface_list: ignore NS %u", zns->ns_id);
+               zlog_debug("%s: ignore NS %u", __func__, zns->ns_id);
                return;
        }
 
@@ -132,7 +132,7 @@ void interface_list(struct zebra_ns *zns)
                        ifam_read((struct ifa_msghdr *)ifm);
                        break;
                default:
-                       zlog_info("interfaces_list(): unexpected message type");
+                       zlog_info("%s: unexpected message type", __func__);
                        XFREE(MTYPE_TMP, ref);
                        return;
                        break;
index 4c089ee19479a981b1043670e75e2a24e1c567fa..e76d8c0cc4a65bcd0b334d1e178dd841a62f0227 100644 (file)
@@ -534,7 +534,7 @@ int ifm_read(struct if_msghdr *ifm)
        /* paranoia: sanity check structure */
        if (ifm->ifm_msglen < sizeof(struct if_msghdr)) {
                flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
-                        "ifm_read: ifm->ifm_msglen %d too short",
+                        "%s: ifm->ifm_msglen %d too short", __func__,
                         ifm->ifm_msglen);
                return -1;
        }
@@ -1388,9 +1388,8 @@ static void kernel_read(struct thread *thread)
         * can assume they have the whole message.
         */
        if (rtm->rtm_msglen != nbytes) {
-               zlog_debug(
-                       "kernel_read: rtm->rtm_msglen %d, nbytes %d, type %d",
-                       rtm->rtm_msglen, nbytes, rtm->rtm_type);
+               zlog_debug("%s: rtm->rtm_msglen %d, nbytes %d, type %d",
+                          __func__, rtm->rtm_msglen, nbytes, rtm->rtm_type);
                return;
        }
 
index dec5b2b8d6d62ca1fd64731e2b04ac927f1c4d8a..99f52bcd4e434070c3ea20ddad4a1a39645df2c7 100644 (file)
@@ -585,6 +585,7 @@ static inline void rib_tables_iter_cleanup(rib_tables_iter_t *iter)
 
 DECLARE_HOOK(rib_update, (struct route_node * rn, const char *reason),
             (rn, reason));
+DECLARE_HOOK(rib_shutdown, (struct route_node * rn), (rn));
 
 /*
  * Access installed/fib nexthops, which may be a subset of the
index bf959980be85c4327841b56a1f948526453a885d..127888d6554796f2ee5674784a21c11a0f67ab22 100644 (file)
@@ -227,8 +227,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp,
                adata = calloc(1, CMSG_SPACE(sizeof(struct in6_pktinfo)));
 
                if (adata == NULL) {
-                       zlog_debug(
-                               "rtadv_send_packet: can't malloc control data");
+                       zlog_debug("%s: can't malloc control data", __func__);
                        exit(-1);
                }
        }
@@ -665,8 +664,9 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,
             zif->rtadv.lastadvcurhoplimit.tv_sec == 0)) {
                flog_warn(
                        EC_ZEBRA_RA_PARAM_MISMATCH,
-                       "%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
-                       ifp->name, ifp->ifindex, addr_str);
+                       "%s(%u): Rx RA - our AdvCurHopLimit (%u) doesn't agree with %s (%u)",
+                       ifp->name, ifp->ifindex, zif->rtadv.AdvCurHopLimit,
+                       addr_str, radvert->nd_ra_curhoplimit);
                monotime(&zif->rtadv.lastadvcurhoplimit);
        }
 
@@ -677,8 +677,11 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,
             zif->rtadv.lastadvmanagedflag.tv_sec == 0)) {
                flog_warn(
                        EC_ZEBRA_RA_PARAM_MISMATCH,
-                       "%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
-                       ifp->name, ifp->ifindex, addr_str);
+                       "%s(%u): Rx RA - our AdvManagedFlag (%u) doesn't agree with %s (%u)",
+                       ifp->name, ifp->ifindex, zif->rtadv.AdvManagedFlag,
+                       addr_str,
+                       !!CHECK_FLAG(radvert->nd_ra_flags_reserved,
+                                    ND_RA_FLAG_MANAGED));
                monotime(&zif->rtadv.lastadvmanagedflag);
        }
 
@@ -689,8 +692,11 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,
             zif->rtadv.lastadvotherconfigflag.tv_sec == 0)) {
                flog_warn(
                        EC_ZEBRA_RA_PARAM_MISMATCH,
-                       "%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
-                       ifp->name, ifp->ifindex, addr_str);
+                       "%s(%u): Rx RA - our AdvOtherConfigFlag (%u) doesn't agree with %s (%u)",
+                       ifp->name, ifp->ifindex, zif->rtadv.AdvOtherConfigFlag,
+                       addr_str,
+                       !!CHECK_FLAG(radvert->nd_ra_flags_reserved,
+                                    ND_RA_FLAG_OTHER));
                monotime(&zif->rtadv.lastadvotherconfigflag);
        }
 
@@ -701,20 +707,23 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,
             zif->rtadv.lastadvreachabletime.tv_sec == 0)) {
                flog_warn(
                        EC_ZEBRA_RA_PARAM_MISMATCH,
-                       "%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
-                       ifp->name, ifp->ifindex, addr_str);
+                       "%s(%u): Rx RA - our AdvReachableTime (%u) doesn't agree with %s (%u)",
+                       ifp->name, ifp->ifindex, zif->rtadv.AdvReachableTime,
+                       addr_str, ntohl(radvert->nd_ra_reachable));
                monotime(&zif->rtadv.lastadvreachabletime);
        }
 
-       if ((ntohl(radvert->nd_ra_retransmit) !=
+       if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) &&
+           (ntohl(radvert->nd_ra_retransmit) !=
             (unsigned int)zif->rtadv.AdvRetransTimer) &&
            (monotime_since(&zif->rtadv.lastadvretranstimer, NULL) >
                     SIXHOUR2USEC ||
             zif->rtadv.lastadvretranstimer.tv_sec == 0)) {
                flog_warn(
                        EC_ZEBRA_RA_PARAM_MISMATCH,
-                       "%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
-                       ifp->name, ifp->ifindex, addr_str);
+                       "%s(%u): Rx RA - our AdvRetransTimer (%u) doesn't agree with %s (%u)",
+                       ifp->name, ifp->ifindex, zif->rtadv.AdvRetransTimer,
+                       addr_str, ntohl(radvert->nd_ra_retransmit));
                monotime(&zif->rtadv.lastadvretranstimer);
        }
 
index 21acaa823c6231908035600ab2d37894acbb8805..1b2753377b1dac792aa4c4a3e6f30c490a630a0f 100644 (file)
@@ -1477,6 +1477,32 @@ static int zfpm_trigger_update(struct route_node *rn, const char *reason)
        return 0;
 }
 
+/*
+ * zfpm_trigger_remove
+ *
+ * The zebra code invokes this function to indicate that we should
+ * send an remove to the FPM about the given route_node.
+ */
+
+static int zfpm_trigger_remove(struct route_node *rn)
+{
+       rib_dest_t *dest;
+
+       if (!zfpm_conn_is_up())
+               return 0;
+
+       dest = rib_dest_from_rnode(rn);
+       if (!CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_FPM))
+               return 0;
+
+       zfpm_debug("%pRN Removing from update queue shutting down", rn);
+
+       UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_FPM);
+       TAILQ_REMOVE(&zfpm_g->dest_q, dest, fpm_q_entries);
+
+       return 0;
+}
+
 /*
  * Generate Key for FPM MAC info hash entry
  */
@@ -2036,6 +2062,7 @@ static int zfpm_fini(void)
 static int zebra_fpm_module_init(void)
 {
        hook_register(rib_update, zfpm_trigger_update);
+       hook_register(rib_shutdown, zfpm_trigger_remove);
        hook_register(zebra_rmac_update, zfpm_trigger_rmac_update);
        hook_register(frr_late_init, zfpm_init);
        hook_register(frr_early_fini, zfpm_fini);
index bd7e8bbbd0938d5fae79331d2b04d77bf002b7e7..fceaaaa9f02633a1dd24433841dc22bdb962a1e0 100644 (file)
@@ -76,6 +76,8 @@ static struct dplane_ctx_q rib_dplane_q;
 
 DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
            (rn, reason));
+DEFINE_HOOK(rib_shutdown, (struct route_node * rn), (rn));
+
 
 /* Meta Q's specific names */
 enum meta_queue_indexes {
@@ -944,6 +946,9 @@ void zebra_rtable_node_cleanup(struct route_table *table,
        if (node->info) {
                rib_dest_t *dest = node->info;
 
+               /* Remove from update queue of FPM module */
+               hook_call(rib_shutdown, node);
+
                rnh_list_fini(&dest->nht);
                XFREE(MTYPE_RIB_DEST, node->info);
        }