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