]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #4204 from dslicenc/frr-reload-bfd-timers
authorRuss White <russ@riw.us>
Thu, 25 Apr 2019 22:55:42 +0000 (18:55 -0400)
committerGitHub <noreply@github.com>
Thu, 25 Apr 2019 22:55:42 +0000 (18:55 -0400)
tools: frr-reload.py stop bouncing peers on bfd timer change

22 files changed:
bfdd/bfd.h
bfdd/bfdd_vty.c
bfdd/ptm_adapter.c
bgpd/bgp_bfd.c
bgpd/bgp_evpn.c
bgpd/bgp_flowspec.c
bgpd/bgp_fsm.c
bgpd/bgp_fsm.h
bgpd/bgp_label.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_nht.c
bgpd/bgp_packet.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_vty.c
tests/topotests/bgp_maximum_prefix_invalid_update/__init__.py [new file with mode: 0644]
tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_maximum_prefix_invalid_update/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_maximum_prefix_invalid_update/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_maximum_prefix_invalid_update/test_bgp_maximum_prefix_invalid_update.py [new file with mode: 0644]
zebra/zebra_vxlan.c

index a69ff9a1a7b9a33b7756d6ef6305a125904220d2..e08a1ff724e8bec4ec5bafde7a3dd4b432b0a39f 100644 (file)
@@ -166,6 +166,7 @@ enum bfd_session_flags {
                                                 * expires
                                                 */
        BFD_SESS_FLAG_SHUTDOWN = 1 << 7,        /* disable BGP peer function */
+       BFD_SESS_FLAG_CONFIG = 1 << 8,  /* Session configured with bfd NB API */
 };
 
 #define BFD_SET_FLAG(field, flag) (field |= flag)
@@ -308,8 +309,8 @@ TAILQ_HEAD(obslist, bfd_session_observer);
 #define BFD_PKT_INFO_VAL 1
 #define BFD_IPV6_PKT_INFO_VAL 1
 #define BFD_IPV6_ONLY_VAL 1
-#define BFD_SRCPORTINIT 49142
-#define BFD_SRCPORTMAX 65536
+#define BFD_SRCPORTINIT 49152
+#define BFD_SRCPORTMAX 65535
 #define BFD_DEFDESTPORT 3784
 #define BFD_DEF_ECHO_PORT 3785
 #define BFD_DEF_MHOP_DEST_PORT 4784
index c13949207642fe1e81673269291b48a957afda2f..4efdd817c1c78a44a22844d84cb9b907fd9f6379 100644 (file)
@@ -158,6 +158,12 @@ DEFUN_NOSH(
                }
        }
 
+       if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG)) {
+               if (bs->refcount)
+                       vty_out(vty, "%% session peer is now configurable via bfd daemon.\n");
+               BFD_SET_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG);
+       }
+
        VTY_PUSH_CONTEXT(BFD_PEER_NODE, bs);
 
        return CMD_SUCCESS;
@@ -984,6 +990,9 @@ static void _bfdd_peer_write_config_iter(struct hash_bucket *hb, void *arg)
        struct vty *vty = arg;
        struct bfd_session *bs = hb->data;
 
+       if (!BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG))
+               return;
+
        _bfdd_peer_write_config(vty, bs);
 }
 
index 8d80b9468db5374af1dbdeda8af84b00b05f9ff2..e92500cd80990722b60620f4068b95dbaa0d8e2a 100644 (file)
@@ -431,6 +431,10 @@ static void bfdd_dest_deregister(struct stream *msg)
        /* Unregister client peer notification. */
        pcn = pcn_lookup(pc, bs);
        pcn_free(pcn);
+       if (bs->refcount ||
+           BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG))
+               return;
+       ptm_bfd_ses_del(&bpc);
 }
 
 /*
index 663bc4894a842aae8e262a7c4f7e3b5e60902d07..dadf124eec195a2136ad3528b3530db5709af5ca 100644 (file)
@@ -280,6 +280,13 @@ static void bgp_bfd_peer_status_update(struct peer *peer, int status)
                peer->last_reset = PEER_DOWN_BFD_DOWN;
                BGP_EVENT_ADD(peer, BGP_Stop);
        }
+       if ((status == BFD_STATUS_UP) && (old_status == BFD_STATUS_DOWN)
+           && peer->status != Established) {
+               if (!BGP_PEER_START_SUPPRESSED(peer)) {
+                       bgp_fsm_event_update(peer, 1);
+                       BGP_EVENT_ADD(peer, BGP_Start);
+               }
+       }
 }
 
 /*
index 5d191a787ccf1d6f353daff3518d0c290efa5ad1..52aa923959a91cc9870799f2dfec29694b773d4c 100644 (file)
@@ -4921,7 +4921,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
                if (addpath_encoded) {
                        /* When packet overflow occurs return immediately. */
                        if (pnt + BGP_ADDPATH_ID_LEN > lim)
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
 
                        addpath_id = ntohl(*((uint32_t *)pnt));
                        pnt += BGP_ADDPATH_ID_LEN;
@@ -4929,14 +4929,14 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
 
                /* All EVPN NLRI types start with type and length. */
                if (pnt + 2 > lim)
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_EVPN_MISSING_TYPE;
 
                rtype = *pnt++;
                psize = *pnt++;
 
                /* When packet overflow occur return immediately. */
                if (pnt + psize > lim)
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
 
                switch (rtype) {
                case BGP_EVPN_MAC_IP_ROUTE:
@@ -4947,7 +4947,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
                                        EC_BGP_EVPN_FAIL,
                                        "%u:%s - Error in processing EVPN type-2 NLRI size %d",
                                        peer->bgp->vrf_id, peer->host, psize);
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_EVPN_TYPE2_SIZE;
                        }
                        break;
 
@@ -4959,7 +4959,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
                                        EC_BGP_PKT_PROCESS,
                                        "%u:%s - Error in processing EVPN type-3 NLRI size %d",
                                        peer->bgp->vrf_id, peer->host, psize);
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_EVPN_TYPE3_SIZE;
                        }
                        break;
 
@@ -4971,7 +4971,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
                                        EC_BGP_PKT_PROCESS,
                                        "%u:%s - Error in processing EVPN type-4 NLRI size %d",
                                        peer->bgp->vrf_id, peer->host, psize);
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_EVPN_TYPE4_SIZE;
                        }
                        break;
 
@@ -4983,7 +4983,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
                                        EC_BGP_PKT_PROCESS,
                                        "%u:%s - Error in processing EVPN type-5 NLRI size %d",
                                        peer->bgp->vrf_id, peer->host, psize);
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_EVPN_TYPE5_SIZE;
                        }
                        break;
 
@@ -4994,9 +4994,9 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
 
        /* Packet length consistency check. */
        if (pnt != lim)
-               return -1;
+               return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
 
-       return 0;
+       return BGP_NLRI_PARSE_OK;
 }
 
 /*
index ab8bfcb770c708268db3dcb21a91e1dbd85a433f..9554638735f163f68ec77a537806259d400c517a 100644 (file)
@@ -105,14 +105,14 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
 
        if (afi == AFI_IP6) {
                flog_err(EC_LIB_DEVELOPMENT, "BGP flowspec IPv6 not supported");
-               return -1;
+               return BGP_NLRI_PARSE_ERROR_FLOWSPEC_IPV6_NOT_SUPPORTED;
        }
 
        if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT) {
                flog_err(EC_BGP_FLOWSPEC_PACKET,
                         "BGP flowspec nlri length maximum reached (%u)",
                         packet->length);
-               return -1;
+               return BGP_NLRI_PARSE_ERROR_FLOWSPEC_NLRI_SIZELIMIT;
        }
 
        for (; pnt < lim; pnt += psize) {
@@ -121,7 +121,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
 
                /* All FlowSpec NLRI begin with length. */
                if (pnt + 1 > lim)
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
 
                psize = *pnt++;
 
@@ -131,13 +131,13 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
                                EC_BGP_FLOWSPEC_PACKET,
                                "Flowspec NLRI length inconsistent ( size %u seen)",
                                psize);
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
                }
                if (bgp_fs_nlri_validate(pnt, psize) < 0) {
                        flog_err(
                                EC_BGP_FLOWSPEC_PACKET,
                                "Bad flowspec format or NLRI options not supported");
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_FLOWSPEC_BAD_FORMAT;
                }
                p.family = AF_FLOWSPEC;
                p.prefixlen = 0;
@@ -192,8 +192,8 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
                        flog_err(EC_BGP_FLOWSPEC_INSTALLATION,
                                 "Flowspec NLRI failed to be %s.",
                                 attr ? "added" : "withdrawn");
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR;
                }
        }
-       return 0;
+       return BGP_NLRI_PARSE_OK;
 }
index 447d8da613722bd17eb00d61694b61707f6c7fb3..9e37a6018859b9df31e43bc26fd7564db4c0018e 100644 (file)
@@ -1754,7 +1754,7 @@ static int bgp_fsm_exeption(struct peer *peer)
        return (bgp_stop(peer));
 }
 
-void bgp_fsm_nht_update(struct peer *peer, int valid)
+void bgp_fsm_event_update(struct peer *peer, int valid)
 {
        if (!peer)
                return;
@@ -1788,7 +1788,6 @@ void bgp_fsm_nht_update(struct peer *peer, int valid)
        }
 }
 
-
 /* Finite State Machine structure */
 static const struct {
        int (*func)(struct peer *);
index d021c9884a55acd011696c522b4282ab80f0930d..3476a3c3a9816c2d7208b05264c9fb02e6cb2792 100644 (file)
@@ -57,7 +57,7 @@
 #define FSM_PEER_TRANSITIONED   3
 
 /* Prototypes. */
-extern void bgp_fsm_nht_update(struct peer *, int valid);
+extern void bgp_fsm_event_update(struct peer *peer, int valid);
 extern int bgp_event(struct thread *);
 extern int bgp_event_update(struct peer *, int event);
 extern int bgp_stop(struct peer *peer);
index a219c407dabd861f71b68aae00dc0cab95bce357..95116508427776323934dbc191d9f97de548bf2b 100644 (file)
@@ -355,7 +355,7 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
 
                        /* When packet overflow occurs return immediately. */
                        if (pnt + BGP_ADDPATH_ID_LEN > lim)
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
 
                        addpath_id = ntohl(*((uint32_t *)pnt));
                        pnt += BGP_ADDPATH_ID_LEN;
@@ -372,7 +372,7 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error / L-U (prefix length %d exceeds packet size %u)",
                                peer->host, prefixlen, (uint)(lim - pnt));
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
                }
 
                /* Fill in the labels */
@@ -387,12 +387,12 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
                                 peer->host, prefixlen);
                        bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
                                        BGP_NOTIFY_UPDATE_INVAL_NETWORK);
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_LABEL_LENGTH;
                }
 
                if ((afi == AFI_IP && p.prefixlen > 32)
                    || (afi == AFI_IP6 && p.prefixlen > 128))
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
 
                /* Fetch prefix from NLRI packet */
                memcpy(&p.u.prefix, pnt + llen, psize - llen);
@@ -463,8 +463,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
                        EC_BGP_UPDATE_RCV,
                        "%s [Error] Update packet error / L-U (%zu data remaining after parsing)",
                        peer->host, lim - pnt);
-               return -1;
+               return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
        }
 
-       return 0;
+       return BGP_NLRI_PARSE_OK;
 }
index 4c4659ad543959f989200bedb8c757b68c99d140..d7cb84c32358d204edd93a1d62a11f9f6fee62bf 100644 (file)
@@ -140,7 +140,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
 
                        /* When packet overflow occurs return immediately. */
                        if (pnt + BGP_ADDPATH_ID_LEN > lim)
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
 
                        addpath_id = ntohl(*((uint32_t *)pnt));
                        pnt += BGP_ADDPATH_ID_LEN;
@@ -156,7 +156,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error / VPN (prefix length %d less than VPN min length)",
                                peer->host, prefixlen);
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
                }
 
                /* sanity check against packet data */
@@ -165,7 +165,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error / VPN (prefix length %d exceeds packet size %u)",
                                peer->host, prefixlen, (uint)(lim - pnt));
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
                }
 
                /* sanity check against storage for the IP address portion */
@@ -176,7 +176,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
                                peer->host,
                                prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
                                sizeof(p.u));
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
                }
 
                /* Sanity check against max bitlen of the address family */
@@ -187,7 +187,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
                                peer->host,
                                prefixlen - VPN_PREFIXLEN_MIN_BYTES * 8,
                                p.family, prefix_blen(&p));
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
                }
 
                /* Copy label to prefix. */
@@ -245,7 +245,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
                        EC_BGP_UPDATE_RCV,
                        "%s [Error] Update packet error / VPN (%zu data remaining after parsing)",
                        peer->host, lim - pnt);
-               return -1;
+               return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
        }
 
        return 0;
index 6e85abc8dfc8f260f1883b14bba0ecaede288940..7e721db49dbaf9b6a64711e824ab92e63d5a5b67 100644 (file)
@@ -793,7 +793,7 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
                if (BGP_DEBUG(nht, NHT))
                        zlog_debug("%s: Updating peer (%s) status with NHT",
                                   __FUNCTION__, peer->host);
-               bgp_fsm_nht_update(peer, bgp_isvalid_nexthop(bnc));
+               bgp_fsm_event_update(peer, bgp_isvalid_nexthop(bnc));
                SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
        }
 
index 7b76d7e83e881d1a7fd098bb9e23448cfb3179eb..130e06a6cf1ba887531db13fee05b445dc501391 100644 (file)
@@ -308,7 +308,7 @@ int bgp_nlri_parse(struct peer *peer, struct attr *attr,
        case SAFI_FLOWSPEC:
                return bgp_nlri_parse_flowspec(peer, attr, packet, mp_withdraw);
        }
-       return -1;
+       return BGP_NLRI_PARSE_ERROR;
 }
 
 /*
@@ -1568,10 +1568,11 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
                        nlri_ret = bgp_nlri_parse(peer, &attr, &nlris[i], 1);
                        break;
                default:
-                       nlri_ret = -1;
+                       nlri_ret = BGP_NLRI_PARSE_ERROR;
                }
 
-               if (nlri_ret < 0) {
+               if (nlri_ret < BGP_NLRI_PARSE_OK
+                   && nlri_ret != BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW) {
                        flog_err(EC_BGP_UPDATE_RCV,
                                 "%s [Error] Error parsing NLRI", peer->host);
                        if (peer->status == Established)
index 36d1369eb086e31d014b5b74093947d9c7f9514c..063cc24dc1bd69918e6397b14c9ba8d97a4161c7 100644 (file)
@@ -4340,7 +4340,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
 
                        /* When packet overflow occurs return immediately. */
                        if (pnt + BGP_ADDPATH_ID_LEN > lim)
-                               return -1;
+                               return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
 
                        addpath_id = ntohl(*((uint32_t *)pnt));
                        pnt += BGP_ADDPATH_ID_LEN;
@@ -4358,7 +4358,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
                                peer->host, p.prefixlen, packet->afi);
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
                }
 
                /* Packet size overflow check. */
@@ -4370,7 +4370,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (prefix length %d overflows packet)",
                                peer->host, p.prefixlen);
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
                }
 
                /* Defensive coding, double-check the psize fits in a struct
@@ -4380,7 +4380,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
                                peer->host, p.prefixlen, sizeof(p.u));
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
                }
 
                /* Fetch prefix from NLRI packet. */
@@ -4445,10 +4445,14 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                           BGP_ROUTE_NORMAL, NULL, NULL, 0,
                                           NULL);
 
-               /* Address family configuration mismatch or maximum-prefix count
-                  overflow. */
+               /* Do not send BGP notification twice when maximum-prefix count
+                * overflow. */
+               if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
+                       return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
+
+               /* Address family configuration mismatch. */
                if (ret < 0)
-                       return -1;
+                       return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
        }
 
        /* Packet length consistency check. */
@@ -4457,10 +4461,10 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                        EC_BGP_UPDATE_RCV,
                        "%s [Error] Update packet error (prefix length mismatch with total length)",
                        peer->host);
-               return -1;
+               return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
        }
 
-       return 0;
+       return BGP_NLRI_PARSE_OK;
 }
 
 static struct bgp_static *bgp_static_new(void)
index a559a6b58cb4390acd6045f7d5c0adf8de509190..7bbc14b46f2b11444d2a7ce32600ea02f24f40d9 100644 (file)
@@ -73,6 +73,24 @@ enum bgp_show_adj_route_type {
  */
 #define BGP_MAX_LABELS 2
 
+/* Error codes for handling NLRI */
+#define BGP_NLRI_PARSE_OK 0
+#define BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW -1
+#define BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW -2
+#define BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH -3
+#define BGP_NLRI_PARSE_ERROR_PACKET_LENGTH -4
+#define BGP_NLRI_PARSE_ERROR_LABEL_LENGTH -5
+#define BGP_NLRI_PARSE_ERROR_EVPN_MISSING_TYPE -6
+#define BGP_NLRI_PARSE_ERROR_EVPN_TYPE2_SIZE -7
+#define BGP_NLRI_PARSE_ERROR_EVPN_TYPE3_SIZE -8
+#define BGP_NLRI_PARSE_ERROR_EVPN_TYPE4_SIZE -9
+#define BGP_NLRI_PARSE_ERROR_EVPN_TYPE5_SIZE -10
+#define BGP_NLRI_PARSE_ERROR_FLOWSPEC_IPV6_NOT_SUPPORTED -11
+#define BGP_NLRI_PARSE_ERROR_FLOWSPEC_NLRI_SIZELIMIT -12
+#define BGP_NLRI_PARSE_ERROR_FLOWSPEC_BAD_FORMAT -13
+#define BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY -14
+#define BGP_NLRI_PARSE_ERROR -32
+
 /* Ancillary information to struct bgp_path_info,
  * used for uncommonly used data (aggregation, MPLS, etc.)
  * and lazily allocated to save memory.
index 9004926dee5edb5dcf9cdd821365b9999cd16fd5..01144f5c78ae94346297540e51ed5a1972b89a87 100644 (file)
@@ -3943,6 +3943,13 @@ ALIAS_HIDDEN(neighbor_nexthop_self_force,
             "Disable the next hop calculation for this neighbor\n"
             "Set the next hop to self for reflected routes\n")
 
+ALIAS_HIDDEN(neighbor_nexthop_self_force,
+            neighbor_nexthop_self_all_hidden_cmd,
+            "neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self all",
+            NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Disable the next hop calculation for this neighbor\n"
+            "Set the next hop to self for reflected routes\n")
+
 DEFUN (no_neighbor_nexthop_self,
        no_neighbor_nexthop_self_cmd,
        "no neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self",
@@ -3984,6 +3991,13 @@ ALIAS_HIDDEN(no_neighbor_nexthop_self_force,
             "Disable the next hop calculation for this neighbor\n"
             "Set the next hop to self for reflected routes\n")
 
+ALIAS_HIDDEN(no_neighbor_nexthop_self_force,
+            no_neighbor_nexthop_self_all_hidden_cmd,
+            "no neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self all",
+            NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Disable the next hop calculation for this neighbor\n"
+            "Set the next hop to self for reflected routes\n")
+
 /* neighbor as-override */
 DEFUN (neighbor_as_override,
        neighbor_as_override_cmd,
@@ -13234,6 +13248,8 @@ void bgp_vty_init(void)
        /* "neighbor next-hop-self force" commands. */
        install_element(BGP_NODE, &neighbor_nexthop_self_force_hidden_cmd);
        install_element(BGP_NODE, &no_neighbor_nexthop_self_force_hidden_cmd);
+       install_element(BGP_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_NODE, &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_IPV4_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_IPV4_NODE, &no_neighbor_nexthop_self_force_cmd);
        install_element(BGP_IPV4M_NODE, &neighbor_nexthop_self_force_cmd);
diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/__init__.py b/tests/topotests/bgp_maximum_prefix_invalid_update/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf b/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..235b42b
--- /dev/null
@@ -0,0 +1,4 @@
+router bgp 65000
+  neighbor 192.168.255.2 remote-as 65001
+  address-family ipv4 unicast
+    redistribute connected
diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/r1/zebra.conf b/tests/topotests/bgp_maximum_prefix_invalid_update/r1/zebra.conf
new file mode 100644 (file)
index 0000000..0a283c0
--- /dev/null
@@ -0,0 +1,9 @@
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf b/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..e016284
--- /dev/null
@@ -0,0 +1,4 @@
+router bgp 65001
+  neighbor 192.168.255.1 remote-as 65000
+  address-family ipv4
+    neighbor 192.168.255.1 maximum-prefix 1
diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/r2/zebra.conf b/tests/topotests/bgp_maximum_prefix_invalid_update/r2/zebra.conf
new file mode 100644 (file)
index 0000000..606c17b
--- /dev/null
@@ -0,0 +1,6 @@
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/test_bgp_maximum_prefix_invalid_update.py b/tests/topotests/bgp_maximum_prefix_invalid_update/test_bgp_maximum_prefix_invalid_update.py
new file mode 100644 (file)
index 0000000..69b8c7c
--- /dev/null
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+
+#
+# bgp_local_as_private_remove.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2019 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+bgp_maximum_prefix_invalid_update.py:
+Test if unnecesarry UPDATE message like below:
+
+[Error] Error parsing NLRI
+%NOTIFICATION: sent to neighbor X.X.X.X 3/10 (UPDATE Message Error/Invalid Network Field) 0 bytes
+
+is not sent if maximum-prefix count is overflow.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../'))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+class TemplateTopo(Topo):
+    def build(self, *_args, **_opts):
+        tgen = get_topogen(self)
+
+        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(TemplateTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    for i, (rname, router) in enumerate(router_list.iteritems(), 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_maximum_prefix_invalid():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    def _bgp_converge(router):
+        while True:
+            output = json.loads(tgen.gears[router].vtysh_cmd("show ip bgp neighbor 192.168.255.1 json"))
+            if output['192.168.255.1']['connectionsEstablished'] > 3:
+                return True
+            time.sleep(1)
+
+    def _bgp_parsing_nlri(router):
+        cmd_max_exceeded = 'grep "%MAXPFXEXCEED: No. of IPv4 Unicast prefix received" bgpd.log'
+        cmdt_error_parsing_nlri = 'grep "Error parsing NLRI" bgpd.log'
+        output_max_exceeded = tgen.gears[router].run(cmd_max_exceeded)
+        output_error_parsing_nlri = tgen.gears[router].run(cmdt_error_parsing_nlri)
+
+        if len(output_max_exceeded) > 0:
+            if len(output_error_parsing_nlri) > 0:
+                return False
+        return True
+
+
+    if _bgp_converge('r2'):
+        assert _bgp_parsing_nlri('r2') == True
+
+if __name__ == '__main__':
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
index 22c489e6073fc573ff1494a7a7560b6ba25088fc..4f6e4e85974de0e84df7a74abbf5afe1b61e9ee7 100644 (file)
@@ -8779,6 +8779,13 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni,
                        return -1;
                }
 
+               if (zvrf->l3vni != vni) {
+                       snprintf(err, err_str_sz,
+                                       "VNI %d doesn't exist in VRF: %s",
+                                       vni, zvrf->vrf->name);
+                       return -1;
+               }
+
                if (filter && !CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)) {
                        snprintf(err, ERR_STR_SZ,
                                 "prefix-routes-only is not set for the vni");