]> git.proxmox.com Git - mirror_frr.git/commitdiff
If the default route is removed from the BGP table we must re-evaluate "neighbor...
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:29:19 +0000 (18:29 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:29:19 +0000 (18:29 -0700)
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_updgrp.h
bgpd/bgp_updgrp_adv.c

index a0fc60f95bade86eac49ef8301baa0c517353c83..7ffb35c1b1ad59dec325832761eba64d86ca9481 100644 (file)
@@ -64,7 +64,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 extern const char *bgp_origin_str[];
 extern const char *bgp_origin_long_str[];
 
-static struct bgp_node *
+struct bgp_node *
 bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix *p,
                  struct prefix_rd *prd)
 {
@@ -1220,6 +1220,18 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
       return 0;
     }
 
+  /* Do not send the default route in the BGP table if the neighbor is
+   * configured for default-originate */
+  if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
+    {
+      if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
+        return 0;
+#ifdef HAVE_IPV6
+      else if (p->family == AF_INET6 && p->prefixlen == 0)
+        return 0;
+#endif /* HAVE_IPV6 */
+    }
+
   /* Transparency check. */
   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
       && CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
@@ -1902,7 +1914,7 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp,
        if (selected && subgroup_announce_check(selected, subgrp, p, &attr))
          bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
         else
-         bgp_adj_out_unset_subgroup(rn, subgrp);
+         bgp_adj_out_unset_subgroup(rn, subgrp, 1);
 
         break;
       case BGP_TABLE_RSCLIENT:
@@ -1912,7 +1924,7 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp,
             subgroup_announce_check_rsclient (selected, subgrp, p, &attr))
           bgp_adj_out_set_subgroup (rn, subgrp, &attr, selected);
         else
-         bgp_adj_out_unset_subgroup(rn, subgrp);
+         bgp_adj_out_unset_subgroup(rn, subgrp, 1);
         break;
     }
 
index c15b824061193b705b3c6364a094955dffaefa80..b6c5a2511a902fbf427598d3c1165696fd0dba05 100644 (file)
@@ -230,6 +230,9 @@ extern void bgp_clear_route_all (struct peer *);
 extern void bgp_clear_adj_in (struct peer *, afi_t, safi_t);
 extern void bgp_clear_stale_route (struct peer *, afi_t, safi_t);
 
+extern struct bgp_node *bgp_afi_node_get (struct bgp_table *table, afi_t afi,
+                                          safi_t safi, struct prefix *p,
+                                          struct prefix_rd *prd);
 extern struct bgp_info *bgp_info_lock (struct bgp_info *);
 extern struct bgp_info *bgp_info_unlock (struct bgp_info *);
 extern void bgp_info_add (struct bgp_node *rn, struct bgp_info *ri);
index 6d411282273c184ee5861e0dad3aa80a75a98869..7a980f0612e6239ce23f845424635a1655d4afa4 100644 (file)
@@ -459,7 +459,8 @@ bgp_adj_out_set_subgroup (struct bgp_node *rn,
                          struct attr *attr, struct bgp_info *binfo);
 extern void
 bgp_adj_out_unset_subgroup (struct bgp_node *rn,
-                           struct update_subgroup *subgrp);
+                           struct update_subgroup *subgrp,
+                            char withdraw);
 void
 subgroup_announce_table (struct update_subgroup *subgrp,
                         struct bgp_table *table, int rsclient);
index 712e9eb06a90af6b84a10d8c03888ab729c0c531..4eeca365fbc096a6feea45ea92ac4df374ed7111 100644 (file)
@@ -382,12 +382,18 @@ bgp_adj_out_set_subgroup (struct bgp_node *rn,
   subgrp->version = max (subgrp->version, rn->version);
 }
 
+/* The only time 'withdraw' will be false is if we are sending
+ * the "neighbor x.x.x.x default-originate" default and need to clear
+ * bgp_adj_out for the 0.0.0.0/0 route in the BGP table.
+ */
 void
 bgp_adj_out_unset_subgroup (struct bgp_node *rn,
-                           struct update_subgroup *subgrp)
+                           struct update_subgroup *subgrp,
+                            char withdraw)
 {
   struct bgp_adj_out *adj;
   struct bgp_advertise *adv;
+  char trigger_write;
 
   if (DISABLE_BGP_ANNOUNCE)
     return;
@@ -398,11 +404,11 @@ bgp_adj_out_unset_subgroup (struct bgp_node *rn,
   if (!adj)
     goto done;
 
-  /* Clearn up previous advertisement.  */
+  /* Clean up previous advertisement.  */
   if (adj->adv)
     bgp_advertise_clean_subgroup (subgrp, adj);
 
-  if (adj->attr)
+  if (adj->attr && withdraw)
     {
       /* We need advertisement structure.  */
       adj->adv = bgp_advertise_new ();
@@ -410,12 +416,18 @@ bgp_adj_out_unset_subgroup (struct bgp_node *rn,
       adv->rn = rn;
       adv->adj = adj;
 
-      /* Schedule packet write, if FIFO is getting its first entry. */
+      /* Note if we need to trigger a packet write */
       if (BGP_ADV_FIFO_EMPTY (&subgrp->sync->withdraw))
-        subgroup_trigger_write(subgrp);
+        trigger_write = 1;
+      else
+        trigger_write = 0;
 
       /* Add to synchronization entry for withdraw announcement.  */
       BGP_ADV_FIFO_ADD (&subgrp->sync->withdraw, &adv->fifo);
+
+      /* Schedule packet write, if FIFO is getting its first entry. */
+      if (trigger_write)
+        subgroup_trigger_write(subgrp);
     }
   else
     {
@@ -510,7 +522,7 @@ subgroup_announce_table (struct update_subgroup *subgrp,
              && subgroup_announce_check (ri, subgrp, &rn->p, &attr))
            bgp_adj_out_set_subgroup (rn, subgrp, &attr, ri);
          else
-           bgp_adj_out_unset_subgroup (rn, subgrp);
+           bgp_adj_out_unset_subgroup (rn, subgrp, 1);
        }
 
   /*
@@ -680,6 +692,20 @@ subgroup_default_originate (struct update_subgroup *subgrp, int withdraw)
        {
          SET_FLAG (subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE);
          subgroup_default_update_packet (subgrp, &attr, from);
+
+          /* The 'neighbor x.x.x.x default-originate' default will act as an
+           * implicit withdraw for any previous UPDATEs sent for 0.0.0.0/0 so
+           * clear adj_out for the 0.0.0.0/0 prefix in the BGP table.
+           */
+          if (afi == AFI_IP)
+            str2prefix ("0.0.0.0/0", &p);
+#ifdef HAVE_IPV6
+          else
+            str2prefix ("::/0", &p);
+#endif /* HAVE_IPV6 */
+
+          rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, &p, NULL);
+          bgp_adj_out_unset_subgroup (rn, subgrp, 0);
        }
     }