This patch set introduces the support for BGP table version.
BGP table version is generally used to denote the instability in the network.
Table versions are incremented when any changes in the best path
happens. The initial version of table version is set to one by default.

I have tested the changes in my local setup against three Cisco boxes
connected in GNS3 setup in few scenarios and fairly works.

Comments/Suggestions most welcome.

Signed-off-by: Balaji Gurudoss <balaji...@gmail.com>
---
 bgpd/bgp_advertise.c |  2 ++
 bgpd/bgp_fsm.c       |  2 ++
 bgpd/bgp_mplsvpn.c   |  8 ++++----
 bgpd/bgp_route.c     | 24 +++++++++++++++++-------
 bgpd/bgp_vty.c       |  6 +++++-
 bgpd/bgpd.c          |  1 +
 bgpd/bgpd.h          |  4 ++++
 7 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index be9b480..38f5029 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -264,6 +264,7 @@ bgp_adj_out_set (struct bgp_node *rn, struct peer *peer, 
struct prefix *p,
   bgp_advertise_add (adv->baa, adv);
 
   FIFO_ADD (&peer->sync[afi][safi]->update, &adv->fifo);
+  peer->table_version++;
 }
 
 void
@@ -299,6 +300,7 @@ bgp_adj_out_unset (struct bgp_node *rn, struct peer *peer, 
struct prefix *p,
       /* Add to synchronization entry for withdraw announcement.  */
       FIFO_ADD (&peer->sync[afi][safi]->withdraw, &adv->fifo);
 
+      peer->table_version++;
       /* Schedule packet write. */
       BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
     }
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 9ac3335..93752de 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -578,6 +578,7 @@ bgp_stop (struct peer *peer)
     }
 
   peer->update_time = 0;
+  peer->table_version = 0;
 
   /* Until we are sure that there is no problem about prefix count
      this should be commented out.*/
@@ -830,6 +831,7 @@ bgp_establish (struct peer *peer)
 
   /* Increment established count. */
   peer->established++;
+  peer->table_version++;
   bgp_fsm_change_status (peer, Established);
 
   /* bgp log-neighbor-changes of neighbor Up */
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 8a1ed70..05b7745 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -343,8 +343,8 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, 
struct prefix_rd *prd)
               {
                 if (header)
                   {
-                    vty_out (vty, "BGP table version is 0, local router ID is 
%s%s",
-                             inet_ntoa (bgp->router_id), VTY_NEWLINE);
+                    vty_out (vty, "BGP table version is %d, local router ID is 
%s%s",
+                             bgp->table_version, inet_ntoa (bgp->router_id), 
VTY_NEWLINE);
                     vty_out (vty, "Status codes: s suppressed, d damped, h 
history, * valid, > best, i - internal%s",
                              VTY_NEWLINE);
                     vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - 
incomplete%s%s",
@@ -449,8 +449,8 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, 
enum bgp_show_type ty
                      vty_out (vty, v4_header_tag, VTY_NEWLINE);
                    else
                      {
-                       vty_out (vty, "BGP table version is 0, local router ID 
is %s%s",
-                                inet_ntoa (bgp->router_id), VTY_NEWLINE);
+                       vty_out (vty, "BGP table version is %d, local router ID 
is %s%s",
+                               bgp->table_version, inet_ntoa (bgp->router_id), 
VTY_NEWLINE);
                        vty_out (vty, "Status codes: s suppressed, d damped, h 
history, * valid, > best, i - internal%s",
                                 VTY_NEWLINE);
                        vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - 
incomplete%s%s",
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 316fa5a..8753c02 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1515,7 +1515,6 @@ bgp_process_announce_selected (struct peer *peer, struct 
bgp_info *selected,
          bgp_adj_out_unset (rn, peer, p, afi, safi);
         break;
     }
-
   return 0;
 }
 
@@ -1625,7 +1624,11 @@ bgp_process_main (struct work_queue *wq, void *data)
     }
 
   if (old_select)
-    bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
+    {
+      bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
+      bgp->table_version++;
+      old_select->peer->table_version++;
+    }
   if (new_select)
     {
       bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
@@ -1633,6 +1636,11 @@ bgp_process_main (struct work_queue *wq, void *data)
       UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
     }
 
+  if (new_select && CHECK_FLAG (new_select->flags, BGP_INFO_SELECTED))
+    {
+      bgp->table_version++;
+      new_select->peer->table_version++;
+    }
 
   /* Check each BGP peer. */
   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
@@ -2503,7 +2511,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, struct 
attr *attr,
       break;
 
   /* Withdraw specified route from routing table. */
-  if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
+  if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) 
     bgp_rib_withdraw (rn, ri, peer, afi, safi);
   else if (BGP_DEBUG (update, UPDATE_IN))
     zlog (peer->log, LOG_DEBUG, 
@@ -6204,10 +6212,12 @@ bgp_show_table (struct vty *vty, struct bgp_table 
*table, struct in_addr *router
   int header = 1;
   int display;
   unsigned long output_count;
+  struct bgp *bgp;
 
   /* This is first entry point, so reset total line. */
   output_count = 0;
 
+  bgp = bgp_get_default();
   /* Start processing of routes. */
   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) 
     if (rn->info != NULL)
@@ -6362,7 +6372,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, 
struct in_addr *router
 
            if (header)
              {
-               vty_out (vty, "BGP table version is 0, local router ID is 
%s%s", inet_ntoa (*router_id), VTY_NEWLINE);
+               vty_out (vty, "BGP table version is %d, local router ID is 
%s%s", bgp->table_version, inet_ntoa (*router_id), VTY_NEWLINE);
                vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
                vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
                if (type == bgp_show_type_dampend_paths
@@ -9950,7 +9960,7 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t 
afi, safi_t safi,
   if (! in && CHECK_FLAG (peer->af_sflags[afi][safi],
                          PEER_STATUS_DEFAULT_ORIGINATE))
     {
-      vty_out (vty, "BGP table version is 0, local router ID is %s%s", 
inet_ntoa (bgp->router_id), VTY_NEWLINE);
+      vty_out (vty, "BGP table version is %d, local router ID is %s%s", 
bgp->table_version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
       vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
       vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
 
@@ -9967,7 +9977,7 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t 
afi, safi_t safi,
            {
              if (header1)
                {
-                 vty_out (vty, "BGP table version is 0, local router ID is 
%s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
+                 vty_out (vty, "BGP table version is %d, local router ID is 
%s%s", bgp->table_version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
                  vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, 
VTY_NEWLINE);
                  vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, 
VTY_NEWLINE);
                  header1 = 0;
@@ -9991,7 +10001,7 @@ show_adj_route (struct vty *vty, struct peer *peer, 
afi_t afi, safi_t safi,
            {
              if (header1)
                {
-                 vty_out (vty, "BGP table version is 0, local router ID is 
%s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
+                 vty_out (vty, "BGP table version is %d, local router ID is 
%s%s", bgp->table_version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
                  vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, 
VTY_NEWLINE);
                  vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, 
VTY_NEWLINE);
                  header1 = 0;
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 4fd255f..2b043ad 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -6963,6 +6963,10 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int 
afi, int safi)
                        "BGP router identifier %s, local AS number %u%s",
                        inet_ntoa (bgp->router_id), bgp->as, VTY_NEWLINE);
 
+              vty_out (vty,
+                       "BGP table version is %d%s",
+                       bgp->table_version, VTY_NEWLINE);
+
               ents = bgp_table_count (bgp->rib[afi][safi]);
               vty_out (vty, "RIB entries %ld, using %s of memory%s", ents,
                        mtype_memstr (memstrbuf, sizeof (memstrbuf),
@@ -7014,7 +7018,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int 
afi, int safi)
                   peer->open_out + peer->update_out + peer->keepalive_out
                   + peer->notify_out + peer->refresh_out
                   + peer->dynamic_cap_out,
-                  0, 0, (unsigned long) peer->obuf->count);
+                  peer->table_version, 0, (unsigned long) peer->obuf->count);
 
          vty_out (vty, "%8s", 
                   peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN));
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 0068037..8affbfd 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1972,6 +1972,7 @@ bgp_create (as_t *as, const char *name)
   bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
   bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
   bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
+  bgp->table_version = 1;
 
   bgp->as = *as;
 
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 7ae0acb..65d84b9 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -167,6 +167,9 @@ struct bgp
   u_int32_t restart_time;
   u_int32_t stalepath_time;
 
+  /* BGP table version */
+  u_int32_t table_version;
+
   /* Maximum-paths configuration */
   struct bgp_maxpaths_cfg {
     u_int16_t maxpaths_ebgp;
@@ -505,6 +508,7 @@ struct peer
   /* BGP state count */
   u_int32_t established;       /* Established */
   u_int32_t dropped;           /* Dropped */
+  u_int32_t table_version;      /* Table Version */
 
   /* Syncronization list and time.  */
   struct bgp_synchronize *sync[AFI_MAX][SAFI_MAX];
-- 
1.9.1


_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to