]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Creating Loopback Interface Flaps BGPd (#2865)
authorroot <root@dev.vmware.com>
Mon, 19 Nov 2018 12:35:32 +0000 (04:35 -0800)
committerroot <root@dev.vmware.com>
Mon, 19 Nov 2018 12:35:32 +0000 (04:35 -0800)
* The function bgp_router_id_zebra_bump() will check for active bgp
  peers before chenging the router ID.
  If there are established peers, router ID is not modified
  which prevents the flapping of established peer connection

* Added field in bgp structure to store the count of established peers

Signed-off-by: kssoman <somanks@vmware.com>
bgpd/bgp_fsm.c
bgpd/bgpd.c
bgpd/bgpd.h

index 1f0cfd6e257e92ce815f9bf14ceccce8430fdfa6..b70c8bbd631cb88b2cf55b12838185ade095d858 100644 (file)
@@ -935,9 +935,29 @@ static void bgp_update_delay_process_status_change(struct peer *peer)
    read/write and timer thread. */
 void bgp_fsm_change_status(struct peer *peer, int status)
 {
+       struct bgp *bgp;
+       uint32_t peer_count;
 
        bgp_dump_state(peer, peer->status, status);
 
+       bgp = peer->bgp;
+       peer_count = bgp->established_peers;
+
+       if (status == Established)
+               bgp->established_peers++;
+       else if ((peer->status == Established) && (status != Established))
+               bgp->established_peers--;
+
+       if (BGP_DEBUG(neighbor_events, NEIGHBOR_EVENTS))
+               zlog_debug("%s : vrf %u, established_peers %u", __func__,
+                               bgp->vrf_id, bgp->established_peers);
+       /* Set to router ID to the value provided by RIB if there are no peers
+        * in the established state and peer count did not change
+        */
+       if ((peer_count != bgp->established_peers) &&
+           (bgp->established_peers == 0))
+               bgp_router_id_zebra_bump(bgp->vrf_id, NULL);
+
        /* Transition into Clearing or Deleted must /always/ clear all routes..
         * (and must do so before actually changing into Deleted..
         */
index a078c4f58743b8c7065f241556709a109941cc7e..48a3b1bb0902a9bfe27cd62bb3ffaf1e3d416cde 100644 (file)
@@ -274,6 +274,10 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
+       struct in_addr *addr = NULL;
+
+       if (router_id != NULL)
+               addr = (struct in_addr *)&(router_id->u.prefix4);
 
        if (vrf_id == VRF_DEFAULT) {
                /* Router-id change for default VRF has to also update all
@@ -282,17 +286,43 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id)
                        if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
                                continue;
 
-                       bgp->router_id_zebra = router_id->u.prefix4;
-                       if (!bgp->router_id_static.s_addr)
-                               bgp_router_id_set(bgp, &router_id->u.prefix4);
+                       if (addr)
+                               bgp->router_id_zebra = *addr;
+                       else
+                               addr = &bgp->router_id_zebra;
+
+                       if (!bgp->router_id_static.s_addr) {
+                               /* Router ID is updated if there are no active
+                                * peer sessions
+                                */
+                               if (bgp->established_peers == 0) {
+                                       if (BGP_DEBUG(zebra, ZEBRA))
+                                               zlog_debug("RID change : vrf %u, RTR ID %s",
+                                       bgp->vrf_id, inet_ntoa(*addr));
+                                       bgp_router_id_set(bgp, addr);
+                               }
+                       }
                }
        } else {
                bgp = bgp_lookup_by_vrf_id(vrf_id);
                if (bgp) {
-                       bgp->router_id_zebra = router_id->u.prefix4;
+                       if (addr)
+                               bgp->router_id_zebra = *addr;
+                       else
+                               addr = &bgp->router_id_zebra;
+
+                       if (!bgp->router_id_static.s_addr) {
+                               /* Router ID is updated if there are no active
+                                * peer sessions
+                                */
+                               if (bgp->established_peers == 0) {
+                                       if (BGP_DEBUG(zebra, ZEBRA))
+                                               zlog_debug("RID change : vrf %u, RTR ID %s",
+                                       bgp->vrf_id, inet_ntoa(*addr));
+                                       bgp_router_id_set(bgp, addr);
+                               }
+                       }
 
-                       if (!bgp->router_id_static.s_addr)
-                               bgp_router_id_set(bgp, &router_id->u.prefix4);
                }
        }
 }
index 70193104b41b30dc85aaa273d1a1ac2acf1e17a1..383fbc1c92b11124f7697633b1c20a624bce7f4b 100644 (file)
@@ -542,6 +542,9 @@ struct bgp {
        /* local esi hash table */
        struct hash *esihash;
 
+       /* Count of peers in established state */
+       uint32_t established_peers;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(bgp)
@@ -1886,5 +1889,4 @@ extern void bgp_update_redist_vrf_bitmaps(struct bgp *, vrf_id_t);
 
 /* For benefit of rfapi */
 extern struct peer *peer_new(struct bgp *bgp);
-
 #endif /* _QUAGGA_BGPD_H */