A new vty command is supported to configure default route for VPNv4
address family. This command is also visible into show running
config.

[no] neighbor IP-neighbor default-originate rd RD [IP-NH] [LABEL]

example:
neighbor 10.125.0.2 default-originate rd 64603:3333 [10.12.11.1] [200]
no neighbor 10.125.0.2 default-originate rd 64603:3333

Signed-off-by: Julien Courtat <julien.cour...@6wind.com>
---
 bgpd/bgp_vty.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 bgpd/bgpd.c    |  51 ++++++++++++++++++++++---
 bgpd/bgpd.h    |   5 +++
 3 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9242db2..d593a02 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -3320,6 +3320,123 @@ ALIAS (no_neighbor_default_originate,
        "Route-map to specify criteria to originate default\n"
        "route-map name\n")
 
+static int
+peer_default_originate_set_rd_vty (struct vty *vty, const char *peer_str,
+                                   afi_t afi, safi_t safi,
+                                   const char *rd, const char *nh,
+                                   const char *labels, int set)
+{
+  int ret = CMD_WARNING;
+  struct peer *peer;
+
+  peer = peer_and_group_lookup_vty (vty, peer_str);
+  if (! peer)
+    return CMD_WARNING;
+
+  if (safi == SAFI_MPLS_VPN)
+    {
+      struct prefix_rd prd;
+
+      if (!str2prefix_rd(rd, &prd))
+        {
+          vty_out (vty, "%% Malformed Route Distinguisher%s%s", rd, 
VTY_NEWLINE);
+          return CMD_WARNING;
+        }
+
+      if (set)
+        {
+          struct bgp_nexthop bnh;
+          uint32_t l[1];
+          size_t nlabels = 1;
+
+          if (nh)
+            {
+              if (!inet_aton(nh, &bnh.v4))
+                {
+                  vty_out (vty, "%% Malformed Next Hop address %s%s", nh, 
VTY_NEWLINE);
+                  return CMD_WARNING;
+                }
+            }
+          else
+            bnh.v4 = peer->bgp->router_id;
+
+          if (labels)
+            if (!str2labels(labels, l, &nlabels))
+              {
+                vty_out (vty, "%% Malformed Label%s%s", labels, VTY_NEWLINE);
+                return CMD_WARNING;
+              }
+
+          ret = peer_default_originate_set_rd(peer, &prd, afi, &bnh,
+                                              labels? nlabels: 0,
+                                              labels? l: NULL);
+          if (ret)
+            vty_out (vty, "%% rd %s not configured%s", rd, VTY_NEWLINE);
+          ret = CMD_WARNING;
+        }
+      else
+        {
+          ret = peer_default_originate_unset_rd(peer, afi, &prd);
+          if (ret)
+            vty_out (vty, "%% rd %s not configured%s", rd, VTY_NEWLINE);
+          ret = CMD_WARNING;
+        }
+    }
+
+  return bgp_vty_return (vty, ret);
+}
+
+DEFUN (neighbor_default_originate_rd,
+       neighbor_default_originate_rd_cmd,
+       NEIGHBOR_CMD2 "default-originate rd ASN:nn [A.B.C.D] [0-1048575]",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Originate default route to this route distinguisher\n"
+       "route distinguisher\n"
+       "route distinguisher value\n"
+       "Optional next hop\n"
+       "Optional label\n")
+{
+  const char *argv1 = NULL, *argv2 = NULL, *argv3 = NULL;
+
+  switch (argc)
+  {
+  case 2:
+    argv1 = argv[1];
+    break;
+  case 3:
+    argv1 = argv[1];
+    argv2 = argv[2];
+    break;
+  case 4:
+    argv1 = argv[1];
+    argv2 = argv[2];
+    argv3 = argv[3];
+    break;
+  }
+
+  return peer_default_originate_set_rd_vty (vty, argv[0],
+                                            bgp_node_afi (vty),
+                                            bgp_node_safi (vty),
+                                            argv1, argv2, argv3, 1);
+}
+
+DEFUN (no_neighbor_default_originate_rd,
+       no_neighbor_default_originate_rd_cmd,
+       NO_NEIGHBOR_CMD2 "default-originate rd ASN:nn",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Originate default route to this route distinguisher\n"
+       "route distinguisher\n"
+       "route distinguisher value\n")
+{
+  return peer_default_originate_set_rd_vty (vty, argv[0],
+                                            bgp_node_afi (vty),
+                                            bgp_node_safi (vty),
+                                            argv[1], NULL, NULL, 0);
+}
+
 /* Set neighbor's BGP port.  */
 static int
 peer_port_vty (struct vty *vty, const char *ip_str, int afi, 
@@ -10791,6 +10908,8 @@ bgp_vty_init (void)
   install_element (BGP_IPV6M_NODE, &neighbor_default_originate_rmap_cmd);
   install_element (BGP_IPV6M_NODE, &no_neighbor_default_originate_cmd);
   install_element (BGP_IPV6M_NODE, &no_neighbor_default_originate_rmap_cmd);
+  install_element (BGP_VPNV4_NODE, &neighbor_default_originate_rd_cmd);
+  install_element (BGP_VPNV4_NODE, &no_neighbor_default_originate_rd_cmd);
 
   /* "neighbor port" commands. */
   install_element (BGP_NODE, &neighbor_port_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 64edefc..c2bd6e3 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -3520,13 +3520,17 @@ peer_default_originate_set_rd (struct peer *peer, 
struct prefix_rd *rd, afi_t af
 
   labels2str(labelstr, RD_ADDRSTRLEN, labels, nlabels);
   zlog_info("%s: rd=%s, afi=%d, nh=%s, nlabels=%zu, labels=%s", __func__,
-            rdstr, afi, inet_ntoa(nh->v4), nlabels, nlabels? labelstr:"");
+            rdstr, afi, nh?inet_ntoa(nh->v4):"null", nlabels, nlabels? 
labelstr:"");
 
   /* add this VRF in peer list of VPNv4 default route if not already present */
   d = (struct prefix_rd*) listnode_lookup(peer->def_route_rd, found);
   if (!d)
     {
-      memcpy (&found->nh, nh, sizeof(*nh));
+      if (nh)
+        memcpy (&found->nh, nh, sizeof(*nh));
+      if (labels)
+        memcpy (&found->labels, labels, sizeof(*labels));
+      found->nlabels = nlabels;
       listnode_add(peer->def_route_rd, found);
     }
 
@@ -3557,7 +3561,7 @@ peer_default_originate_unset_rd (struct peer *peer, afi_t 
afi, struct prefix_rd
     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 
   /* Check RD has been recorded for the peer */
-  for (ALL_LIST_ELEMENTS_RO(peer->bgp->vrfs, node, vrf))
+  for (ALL_LIST_ELEMENTS_RO(peer->def_route_rd, node, vrf))
     {
       if (!prefix_rd_cmp(rd, &vrf->outbound_rd))
         found = vrf;
@@ -3566,6 +3570,11 @@ peer_default_originate_unset_rd (struct peer *peer, 
afi_t afi, struct prefix_rd
   if (!found)
     return 1;
 
+  /* reset data related to default route in struct bgp_vrf found */
+  found->nlabels = 0;
+  memset(&found->nh, 0, sizeof(found->nh));
+  memset(&found->labels, 0, sizeof(found->labels));
+
   /* remove this RD in peer list of VPNv4 default route */
   listnode_delete(peer->def_route_rd, found);
   empty = (NULL == listnode_head(peer->def_route_rd));
@@ -5558,10 +5567,40 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
       && ! peer->af_group[afi][safi])
     {
-      vty_out (vty, " neighbor %s default-originate", addr);
+      if (safi != SAFI_MPLS_VPN)
+        vty_out (vty, " neighbor %s default-originate%s", addr, VTY_NEWLINE);
+      else
+        {
+          struct listnode *node;
+          struct bgp_vrf *vrf;
+          char rdstr[RD_ADDRSTRLEN];
+          char labelstr[RD_ADDRSTRLEN];
+
+          for (ALL_LIST_ELEMENTS_RO(peer->def_route_rd, node, vrf))
+            {
+              prefix_rd2str(&vrf->outbound_rd, rdstr, RD_ADDRSTRLEN);
+              if (!vrf->nh.v4.s_addr)
+                vty_out (vty, " neighbor %s default-originate rd %s%s", addr,
+                         rdstr, VTY_NEWLINE);
+              else
+                {
+                  if (vrf->nlabels)
+                    {
+                      labels2str(labelstr, RD_ADDRSTRLEN, vrf->labels, 
vrf->nlabels);
+                      vty_out (vty, " neighbor %s default-originate rd %s %s 
%s%s", addr,
+                               rdstr, inet_ntoa(vrf->nh.v4), labelstr, 
VTY_NEWLINE);
+                    }
+                  else
+                    vty_out (vty, " neighbor %s default-originate rd %s %s%s", 
addr,
+                             rdstr, inet_ntoa(vrf->nh.v4), VTY_NEWLINE);
+                }
+            }
+        }
       if (peer->default_rmap[afi][safi].name)
-       vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
-      vty_out (vty, "%s", VTY_NEWLINE);
+        {
+          vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
+          vty_out (vty, "%s", VTY_NEWLINE);
+        }
     }
 
   /* Soft reconfiguration inbound. */
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 1a7ea7a..98f5451 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -37,6 +37,7 @@ struct bgp_node;
 
 /* BGP router distinguisher value.  */
 #define BGP_RD_SIZE                8
+#define BGP_MAX_LABELS 6
 
 struct bgp_rd
 {
@@ -237,6 +238,10 @@ struct bgp_vrf
   /* default route */
   struct bgp_nexthop nh;
 
+  /* labels of Route Distinguishers */
+  uint32_t labels[BGP_MAX_LABELS];
+  size_t nlabels;
+
 };
 
 struct bgp_api_route
-- 
2.1.4


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

Reply via email to