Mailing List Archive

[PATCH 5/6] bgpd: new vty neighbor default-originate rd subcommand
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.courtat@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