On 1/6/2016 11:30 AM, Donald Sharp wrote: > I see HAVE_IPV6 introduced, these should be removed. > will do
> I see #if 0, dead code should be removed. > ack. Lou > donald > > On Thu, Dec 24, 2015 at 1:10 PM, Lou Berger <[email protected] > <mailto:[email protected]>> wrote: > > This is part of the core VPN and Encap SAFI changes. > > Adds RFC5512 and a (per DL) non-compliant version of Encapsulation > Attribute. > > Signed-off-by: Lou Berger <[email protected] <mailto:[email protected]>> > Reviewed-by: David Lamparter <[email protected] > <mailto:[email protected]>> > --- > bgpd/Makefile.am | 4 +- > bgpd/bgp_attr.c | 57 ++++ > bgpd/bgp_encap.c | 991 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > bgpd/bgp_encap.h | 34 ++ > bgpd/bgp_open.c | 32 +- > bgpd/bgp_packet.c | 49 +++ > bgpd/bgp_route.c | 235 ++++++++----- > bgpd/bgp_route.h | 3 + > bgpd/bgp_vty.c | 222 ++++++++++++ > bgpd/bgpd.c | 19 +- > 10 files changed, 1561 insertions(+), 85 deletions(-) > create mode 100644 bgpd/bgp_encap.c > create mode 100644 bgpd/bgp_encap.h > > diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am > index 82c69ea..7da4dd8 100644 > --- a/bgpd/Makefile.am > +++ b/bgpd/Makefile.am > @@ -16,7 +16,7 @@ libbgp_a_SOURCES = \ > bgp_packet.c bgp_network.c bgp_filter.c bgp_regex.c > bgp_clist.c \ > bgp_dump.c bgp_snmp.c bgp_ecommunity.c bgp_mplsvpn.c > bgp_nexthop.c \ > bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \ > - bgp_encap_tlv.c > + bgp_encap.c bgp_encap_tlv.c > > noinst_HEADERS = \ > bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h > bgp_fsm.h \ > @@ -24,7 +24,7 @@ noinst_HEADERS = \ > bgpd.h bgp_filter.h bgp_clist.h bgp_dump.h bgp_zebra.h \ > bgp_ecommunity.h bgp_mplsvpn.h bgp_nexthop.h bgp_damp.h > bgp_table.h \ > bgp_advertise.h bgp_snmp.h bgp_vty.h bgp_mpath.h \ > - bgp_encap_tlv.h bgp_encap_types.h > + bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h > > bgpd_SOURCES = bgp_main.c > bgpd_LDADD = libbgp.a ../lib/libzebra.la <http://libzebra.la> > @LIBCAP@ @LIBM@ > diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c > index a5f5ea1..3909669 100644 > --- a/bgpd/bgp_attr.c > +++ b/bgpd/bgp_attr.c > @@ -2426,6 +2426,10 @@ bgp_packet_mpattr_start (struct stream *s, > afi_t afi, safi_t safi, > stream_putl (s, 0); > stream_put (s, &attr->extra->mp_nexthop_global_in, 4); > break; > + case SAFI_ENCAP: > + stream_putc (s, 4); > + stream_put (s, &attr->extra->mp_nexthop_global_in, 4); > + break; > default: > break; > } > @@ -2467,6 +2471,11 @@ bgp_packet_mpattr_start (struct stream *s, > afi_t afi, safi_t safi, > } > } > break; > + case SAFI_ENCAP: > + assert (attr->extra); > + stream_putc (s, 16); > + stream_put (s, &attr->extra->mp_nexthop_global, 16); > + break; > default: > break; > } > @@ -2948,6 +2957,54 @@ bgp_packet_attribute (struct bgp *bgp, > struct peer *peer, > stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr); > } > > + if ((p->family == AF_INET > +#ifdef HAVE_IPV6 > + || p->family == AF_INET6 > +#endif > + ) && > + ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN))) > + { > + struct bgp_attr_encap_subtlv *pEncap; > + unsigned int attrlenfield = 0; > + /* Tunnel Encap attribute */ > + bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP); > + > + /* compute attr length */ > + if (attr && attr->extra && attr->extra->encap_subtlvs) { > + for (pEncap = attr->extra->encap_subtlvs; pEncap; pEncap = > pEncap->next) { > + attrlenfield += (4 + pEncap->length); > + } > + } > + > + if (attrlenfield) { /* only make attr if subtlvs exist */ > + if (attrlenfield > 0xffff) { > + zlog (peer->log, LOG_ERR, > + "Tunnel Encap attribute is too long (length=%d), > can't send it", > + attrlenfield); > + } else { > + if (attrlenfield > 0xff) { > + /* 2-octet length field */ > + stream_putc (s, > + > BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_EXTLEN); > + stream_putc (s, BGP_ATTR_ENCAP); > + stream_putw (s, attrlenfield & 0xffff); > + } else { > + /* 1-octet length field */ > + stream_putc (s, > BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL); > + stream_putc (s, BGP_ATTR_ENCAP); > + stream_putc (s, attrlenfield & 0xff); > + } > + > + /* write each sub-tlv */ > + for (pEncap = attr->extra->encap_subtlvs; pEncap; > pEncap = pEncap->next) { > + stream_putw (s, pEncap->type); > + stream_putw (s, pEncap->length); > + stream_put (s, pEncap->value, pEncap->length); > + } > + } > + } > + } > + > /* Unknown transit attribute. */ > if (attr->extra && attr->extra->transit) > stream_put (s, attr->extra->transit->val, > attr->extra->transit->length); > diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c > new file mode 100644 > index 0000000..235492d > --- /dev/null > +++ b/bgpd/bgp_encap.c > @@ -0,0 +1,991 @@ > + > +/* > + * This file created by LabN Consulting, L.L.C. > + * > + * > + * This file is based on bgp_mplsvpn.c which is Copyright (C) 2000 > + * Kunihiro Ishiguro <[email protected] <mailto:[email protected]>> > + * > + */ > + > +/* > + > +This file is part of GNU Zebra. > + > +GNU Zebra is free software; you can redistribute it and/or modify it > +under the terms of the GNU General Public License as published by the > +Free Software Foundation; either version 2, or (at your option) any > +later version. > + > +GNU Zebra is distributed in the hope that it will be useful, but > +WITHOUT ANY WARRANTY; without even the implied warranty of > +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > +General Public License for more details. > + > +You should have received a copy of the GNU General Public License > +along with GNU Zebra; see the file COPYING. If not, write to the > Free > +Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > +02111-1307, USA. */ > + > +#include <zebra.h> > + > +#include "command.h" > +#include "prefix.h" > +#include "log.h" > +#include "memory.h" > +#include "stream.h" > + > +#include "bgpd/bgpd.h" > +#include "bgpd/bgp_table.h" > +#include "bgpd/bgp_route.h" > +#include "bgpd/bgp_attr.h" > +#include "bgpd/bgp_ecommunity.h" > +#include "bgpd/bgp_mplsvpn.h" > +#include "bgpd/bgp_vty.h" > +#include "bgpd/bgp_encap.h" > + > +static u_int16_t > +decode_rd_type (u_char *pnt) > +{ > + u_int16_t v; > + > + v = ((u_int16_t) *pnt++ << 8); > + v |= (u_int16_t) *pnt; > + return v; > +} > + > + > +static void > +decode_rd_as (u_char *pnt, struct rd_as *rd_as) > +{ > + rd_as->as = (u_int16_t) *pnt++ << 8; > + rd_as->as |= (u_int16_t) *pnt++; > + > + rd_as->val = ((u_int32_t) *pnt++) << 24; > + rd_as->val |= ((u_int32_t) *pnt++) << 16; > + rd_as->val |= ((u_int32_t) *pnt++) << 8; > + rd_as->val |= (u_int32_t) *pnt; > +} > + > +static void > +decode_rd_as4 (u_char *pnt, struct rd_as *rd_as) > +{ > + rd_as->as = (u_int32_t) *pnt++ << 24; > + rd_as->as |= (u_int32_t) *pnt++ << 16; > + rd_as->as |= (u_int32_t) *pnt++ << 8; > + rd_as->as |= (u_int32_t) *pnt++; > + > + rd_as->val = ((u_int32_t) *pnt++ << 8); > + rd_as->val |= (u_int32_t) *pnt; > +} > + > +static void > +decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip) > +{ > + memcpy (&rd_ip->ip, pnt, 4); > + pnt += 4; > + > + rd_ip->val = ((u_int16_t) *pnt++ << 8); > + rd_ip->val |= (u_int16_t) *pnt; > +} > + > +static void > +ecom2prd(struct ecommunity *ecom, struct prefix_rd *prd) > +{ > + int i; > + > + memset(prd, 0, sizeof(struct prefix_rd)); > + prd->family = AF_UNSPEC; > + prd->prefixlen = 64; > + > + if (!ecom) > + return; > + > + for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += > ECOMMUNITY_SIZE) { > + > + uint8_t *ep; > + > + ep = ecom->val + i; > + > + switch (ep[0]) { > + default: > + continue; > + > + case 0x80: > + case 0x81: > + case 0x82: > + if (ep[1] == 0x0) { > + prd->val[1] = ep[0] & 0x03; > + memcpy(prd->val + 2, ep + 2, 6); > + return; > + } > + } > + } > +} > + > +int > +bgp_nlri_parse_encap( > + afi_t afi, > + struct peer *peer, > + struct attr *attr, /* Need even for > withdraw */ > + struct bgp_nlri *packet, > + int withdraw) /* 0=update, !0 = > withdraw */ > +{ > + u_char *pnt; > + u_char *lim; > + struct prefix p; > + int psize = 0; > + int prefixlen; > + struct rd_as rd_as; > + struct rd_ip rd_ip; > + struct prefix_rd prd; > + struct ecommunity *pEcom = NULL; > + u_int16_t rdtype = 0xffff; > + char buf[BUFSIZ]; > + > + /* Check peer status. */ > + if (peer->status != Established) > + return 0; > + > + /* Make prefix_rd */ > + if (attr && attr->extra && attr->extra->ecommunity) > + pEcom = attr->extra->ecommunity; > + > + ecom2prd(pEcom, &prd); > + memset(&rd_as, 0, sizeof(rd_as)); > + memset(&rd_ip, 0, sizeof(rd_ip)); > + > + if (pEcom) { > + > + rdtype = (prd.val[0] << 8) | prd.val[1]; > + > + /* Decode RD value. */ > + if (rdtype == RD_TYPE_AS) > + decode_rd_as (prd.val + 2, &rd_as); > + else if (rdtype == RD_TYPE_IP) > + decode_rd_ip (prd.val + 2, &rd_ip); > + else if (rdtype == RD_TYPE_AS4) > + decode_rd_as4 (prd.val + 2, &rd_as); > + else > + { > + zlog_err ("Invalid RD type %d", rdtype); > + } > + > + } > + > + /* > + * NB: this code was based on the MPLS VPN code, which > supported RDs. > + * For the moment we are retaining the underlying RIB structure > that > + * keeps a per-RD radix tree, but since the RDs are not carried > over > + * the wire, we set the RD internally to 0. > + */ > + prd.family = AF_UNSPEC; > + prd.prefixlen = 64; > + memset(prd.val, 0, sizeof(prd.val)); > + > + pnt = packet->nlri; > + lim = pnt + packet->length; > + > + for (; pnt < lim; pnt += psize) > + { > + /* Clear prefix structure. */ > + memset (&p, 0, sizeof (struct prefix)); > + > + /* Fetch prefix length. */ > + prefixlen = *pnt++; > + p.family = afi2family(afi); > + if (p.family == 0) { > + /* bad afi, shouldn't happen */ > + zlog_warn("%s: bad afi %d, dropping incoming route", > __func__, afi); > + continue; > + } > + psize = PSIZE (prefixlen); > + > + p.prefixlen = prefixlen; > + memcpy (&p.u.prefix, pnt, psize); > + > + if (pnt + psize > lim) > + return -1; > + > + > + if (rdtype == RD_TYPE_AS) > + zlog_info ("rd-as %u:%u prefix %s/%d", rd_as.as > <http://rd_as.as>, rd_as.val, > + inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ), > + p.prefixlen); > + else if (rdtype == RD_TYPE_IP) > + zlog_info ("rd-ip %s:%u prefix %s/%d", inet_ntoa (rd_ip.ip), > + rd_ip.val, > + inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ), > + p.prefixlen); > + else if (rdtype == RD_TYPE_AS4) > + zlog_info ("rd-as4 %u:%u prefix %s/%d", rd_as.as > <http://rd_as.as>, rd_as.val, > + inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ), > + p.prefixlen); > + else > + zlog_info ("rd unknown, default to 0:0 prefix %s/%d", > + inet_ntop (p.family, &p.u.prefix, buf, BUFSIZ), > + p.prefixlen); > + > + if (!withdraw) { > + bgp_update (peer, &p, attr, afi, SAFI_ENCAP, > + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0); > + } else { > + bgp_withdraw (peer, &p, attr, afi, SAFI_ENCAP, > + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL); > + } > + } > + > + /* Packet length consistency check. */ > + if (pnt != lim) > + return -1; > + > + return 0; > +} > + > + > +/* TBD: these routes should probably all be host routes */ > + > +/* For testing purpose, static route of ENCAP. */ > +DEFUN (encap_network, > + encap_network_cmd, > + "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD", > + "Specify a network to announce via BGP\n" > + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n > <http://35.0.0.0/8%5Cn>" > + "Specify Route Distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "BGP tag\n" > + "tag value\n") > +{ > + return bgp_static_set_safi (SAFI_ENCAP, vty, argv[0], argv[1], > argv[2], NULL); > +} > + > +/* For testing purpose, static route of ENCAP. */ > +DEFUN (no_encap_network, > + no_encap_network_cmd, > + "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD", > + NO_STR > + "Specify a network to announce via BGP\n" > + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n > <http://35.0.0.0/8%5Cn>" > + "Specify Route Distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "BGP tag\n" > + "tag value\n") > +{ > + return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[0], > argv[1], argv[2]); > +} > + > +static int > +show_adj_route_encap (struct vty *vty, struct peer *peer, struct > prefix_rd *prd) > +{ > + struct bgp *bgp; > + struct bgp_table *table; > + struct bgp_node *rn; > + struct bgp_node *rm; > + struct attr *attr; > + int rd_header; > + int header = 1; > + char v4_header[] = " Network Next Hop > Metric LocPrf Weight Path%s"; > + > + bgp = bgp_get_default (); > + if (bgp == NULL) > + { > + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_ENCAP]); rn; > + rn = bgp_route_next (rn)) > + { > + if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) > + continue; > + > + if ((table = rn->info) != NULL) > + { > + rd_header = 1; > + > + for (rm = bgp_table_top (table); rm; rm = > bgp_route_next (rm)) > + if ((attr = rm->info) != NULL) > + { > + 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, "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", > + VTY_NEWLINE, VTY_NEWLINE); > + vty_out (vty, v4_header, VTY_NEWLINE); > + header = 0; > + } > + > + if (rd_header) > + { > + u_int16_t type; > + struct rd_as rd_as; > + struct rd_ip rd_ip; > + u_char *pnt; > + > + pnt = rn->p.u.val; > + > + vty_out (vty, "Route Distinguisher: "); > + > + /* Decode RD type. */ > + type = decode_rd_type (pnt); > + > + switch (type) { > + > + case RD_TYPE_AS: > + decode_rd_as (pnt + 2, &rd_as); > + vty_out (vty, "%u:%d", rd_as.as > <http://rd_as.as>, rd_as.val); > + break; > + > + case RD_TYPE_IP: > + decode_rd_ip (pnt + 2, &rd_ip); > + vty_out (vty, "%s:%d", inet_ntoa > (rd_ip.ip), rd_ip.val); > + break; > + > + default: > + vty_out (vty, "unknown RD type"); > + } > + > + > + vty_out (vty, "%s", VTY_NEWLINE); > + rd_header = 0; > + } > + route_vty_out_tmp (vty, &rm->p, attr, SAFI_ENCAP); > + } > + } > + } > + return CMD_SUCCESS; > +} > + > +enum bgp_show_type > +{ > + bgp_show_type_normal, > + bgp_show_type_regexp, > + bgp_show_type_prefix_list, > + bgp_show_type_filter_list, > + bgp_show_type_neighbor, > + bgp_show_type_cidr_only, > + bgp_show_type_prefix_longer, > + bgp_show_type_community_all, > + bgp_show_type_community, > + bgp_show_type_community_exact, > + bgp_show_type_community_list, > + bgp_show_type_community_list_exact > +}; > + > +static int > +bgp_show_encap ( > + struct vty *vty, > + afi_t afi, > + struct prefix_rd *prd, > + enum bgp_show_type type, > + void *output_arg, > + int tags) > +{ > + struct bgp *bgp; > + struct bgp_table *table; > + struct bgp_node *rn; > + struct bgp_node *rm; > + struct bgp_info *ri; > + int rd_header; > + int header = 1; > + char v4_header[] = " Network Next Hop > Metric LocPrf Weight Path%s"; > + char v4_header_tag[] = " Network Next Hop In > tag/Out tag%s"; > + > + unsigned long output_count = 0; > + unsigned long total_count = 0; > + > + bgp = bgp_get_default (); > + if (bgp == NULL) > + { > + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + if ((afi != AFI_IP) && (afi != AFI_IP6)) { > + vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + for (rn = bgp_table_top (bgp->rib[afi][SAFI_ENCAP]); rn; rn = > bgp_route_next (rn)) > + { > + if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) > + continue; > + > + if ((table = rn->info) != NULL) > + { > + rd_header = 1; > + > + for (rm = bgp_table_top (table); rm; rm = bgp_route_next > (rm)) > + for (ri = rm->info; ri; ri = ri->next) > + { > + total_count++; > + if (type == bgp_show_type_neighbor) > + { > + union sockunion *su = output_arg; > + > + if (ri->peer->su_remote == NULL || ! > sockunion_same(ri->peer->su_remote, su)) > + continue; > + } > + if (header) > + { > + if (tags) > + 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, "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", > + VTY_NEWLINE, VTY_NEWLINE); > + vty_out (vty, v4_header, VTY_NEWLINE); > + } > + header = 0; > + } > + > + if (rd_header) > + { > + u_int16_t type; > + struct rd_as rd_as; > + struct rd_ip rd_ip; > + u_char *pnt; > + > + pnt = rn->p.u.val; > + > + /* Decode RD type. */ > + type = decode_rd_type (pnt); > + > + vty_out (vty, "Route Distinguisher: "); > + > + switch (type) { > + > + case RD_TYPE_AS: > + decode_rd_as (pnt + 2, &rd_as); > + vty_out (vty, "%u:%d", rd_as.as > <http://rd_as.as>, rd_as.val); > + break; > + > + case RD_TYPE_IP: > + decode_rd_ip (pnt + 2, &rd_ip); > + vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), > rd_ip.val); > + break; > + > + default: > + vty_out (vty, "Unknown RD type"); > + break; > + } > + > + vty_out (vty, "%s", VTY_NEWLINE); > + rd_header = 0; > + } > + if (tags) > + route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_ENCAP); > + else > + route_vty_out (vty, &rm->p, ri, 0, SAFI_ENCAP, 0); > + output_count++; > + } > + } > + } > + > + if (output_count == 0) > + { > + vty_out (vty, "No prefixes displayed, %ld exist%s", > total_count, VTY_NEWLINE); > + } > + else > + vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s", > + VTY_NEWLINE, output_count, total_count, VTY_NEWLINE); > + > + return CMD_SUCCESS; > +} > + > +DEFUN (show_bgp_ipv4_encap, > + show_bgp_ipv4_encap_cmd, > + "show bgp ipv4 encap", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n") > +{ > + return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, > NULL, 0); > +} > +#ifdef HAVE_IPV6 > +DEFUN (show_bgp_ipv6_encap, > + show_bgp_ipv6_encap_cmd, > + "show bgp ipv6 encap", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n") > +{ > + return bgp_show_encap (vty, AFI_IP6, NULL, > bgp_show_type_normal, NULL, 0); > +} > +#endif > + > +DEFUN (show_bgp_ipv4_encap_rd, > + show_bgp_ipv4_encap_rd_cmd, > + "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display information for a route distinguisher\n" > + "ENCAP Route Distinguisher\n") > +{ > + int ret; > + struct prefix_rd prd; > + > + ret = str2prefix_rd (argv[0], &prd); > + if (! ret) > + { > + vty_out (vty, "%% Malformed Route Distinguisher%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, > NULL, 0); > +} > +#ifdef HAVE_IPV6 > +DEFUN (show_bgp_ipv6_encap_rd, > + show_bgp_ipv6_encap_rd_cmd, > + "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display information for a route distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "Display BGP tags for prefixes\n") > +{ > + int ret; > + struct prefix_rd prd; > + > + ret = str2prefix_rd (argv[0], &prd); > + if (! ret) > + { > + vty_out (vty, "%% Malformed Route Distinguisher%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + return bgp_show_encap (vty, AFI_IP6, &prd, > bgp_show_type_normal, NULL, 0); > +} > +#endif > + > +DEFUN (show_bgp_ipv4_encap_tags, > + show_bgp_ipv4_encap_tags_cmd, > + "show bgp ipv4 encap tags", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display BGP tags for prefixes\n") > +{ > + return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_normal, > NULL, 1); > +} > +#ifdef HAVE_IPV6 > +DEFUN (show_bgp_ipv6_encap_tags, > + show_bgp_ipv6_encap_tags_cmd, > + "show bgp ipv6 encap tags", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display BGP tags for prefixes\n") > +{ > + return bgp_show_encap (vty, AFI_IP6, NULL, > bgp_show_type_normal, NULL, 1); > +} > +#endif > + > +DEFUN (show_bgp_ipv4_encap_rd_tags, > + show_bgp_ipv4_encap_rd_tags_cmd, > + "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn tags", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display information for a route distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "Display BGP tags for prefixes\n") > +{ > + int ret; > + struct prefix_rd prd; > + > + ret = str2prefix_rd (argv[0], &prd); > + if (! ret) > + { > + vty_out (vty, "%% Malformed Route Distinguisher%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_normal, > NULL, 1); > +} > +#ifdef HAVE_IPV6 > +DEFUN (show_bgp_ipv6_encap_rd_tags, > + show_bgp_ipv6_encap_rd_tags_cmd, > + "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn tags", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display information for a route distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "Display BGP tags for prefixes\n") > +{ > + int ret; > + struct prefix_rd prd; > + > + ret = str2prefix_rd (argv[0], &prd); > + if (! ret) > + { > + vty_out (vty, "%% Malformed Route Distinguisher%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + return bgp_show_encap (vty, AFI_IP6, &prd, > bgp_show_type_normal, NULL, 1); > +} > +#endif > + > +DEFUN (show_bgp_ipv4_encap_neighbor_routes, > + show_bgp_ipv4_encap_neighbor_routes_cmd, > + "show bgp ipv4 encap neighbors A.B.C.D routes", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Detailed information on TCP and BGP neighbor connections\n" > + "Neighbor to display information about\n" > + "Display routes learned from neighbor\n") > +{ > + union sockunion *su; > + struct peer *peer; > + > + su = sockunion_str2su (argv[0]); > + if (su == NULL) > + { > + vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + peer = peer_lookup (NULL, su); > + if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) > + { > + vty_out (vty, "%% No such neighbor or address family%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + return bgp_show_encap (vty, AFI_IP, NULL, > bgp_show_type_neighbor, su, 0); > +} > +#ifdef HAVE_IPV6 > +DEFUN (show_bgp_ipv6_encap_neighbor_routes, > + show_bgp_ipv6_encap_neighbor_routes_cmd, > + "show bgp ipv6 encap neighbors A.B.C.D routes", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Detailed information on TCP and BGP neighbor connections\n" > + "Neighbor to display information about\n" > + "Display routes learned from neighbor\n") > +{ > + union sockunion *su; > + struct peer *peer; > + > + su = sockunion_str2su (argv[0]); > + if (su == NULL) > + { > + vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + peer = peer_lookup (NULL, su); > + if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) > + { > + vty_out (vty, "%% No such neighbor or address family%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + return bgp_show_encap (vty, AFI_IP6, NULL, > bgp_show_type_neighbor, su, 0); > +} > +#endif > + > +DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes, > + show_bgp_ipv4_encap_rd_neighbor_routes_cmd, > + "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors > (A.B.C.D|X:X::X:X) routes", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display information for a route distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "Detailed information on TCP and BGP neighbor connections\n" > + "Neighbor to display information about\n" > + "Neighbor to display information about\n" > + "Display routes learned from neighbor\n") > +{ > + int ret; > + union sockunion *su; > + struct peer *peer; > + struct prefix_rd prd; > + > + ret = str2prefix_rd (argv[0], &prd); > + if (! ret) > + { > + vty_out (vty, "%% Malformed Route Distinguisher%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + su = sockunion_str2su (argv[1]); > + if (su == NULL) > + { > + vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + peer = peer_lookup (NULL, su); > + if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) > + { > + vty_out (vty, "%% No such neighbor or address family%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + return bgp_show_encap (vty, AFI_IP, &prd, > bgp_show_type_neighbor, su, 0); > +} > +#ifdef HAVE_IPV6 > +DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes, > + show_bgp_ipv6_encap_rd_neighbor_routes_cmd, > + "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors > (A.B.C.D|X:X::X:X) routes", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display information for a route distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "Detailed information on TCP and BGP neighbor connections\n" > + "Neighbor to display information about\n" > + "Neighbor to display information about\n" > + "Display routes learned from neighbor\n") > +{ > + int ret; > + union sockunion *su; > + struct peer *peer; > + struct prefix_rd prd; > + > + ret = str2prefix_rd (argv[0], &prd); > + if (! ret) > + { > + vty_out (vty, "%% Malformed Route Distinguisher%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + su = sockunion_str2su (argv[1]); > + if (su == NULL) > + { > + vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + peer = peer_lookup (NULL, su); > + if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) > + { > + vty_out (vty, "%% No such neighbor or address family%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + return bgp_show_encap (vty, AFI_IP6, &prd, > bgp_show_type_neighbor, su, 0); > +} > +#endif > + > +DEFUN (show_bgp_ipv4_encap_neighbor_advertised_routes, > + show_bgp_ipv4_encap_neighbor_advertised_routes_cmd, > + "show bgp ipv4 encap neighbors A.B.C.D advertised-routes", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Detailed information on TCP and BGP neighbor connections\n" > + "Neighbor to display information about\n" > + "Display the routes advertised to a BGP neighbor\n") > +{ > + int ret; > + struct peer *peer; > + union sockunion su; > + > + ret = str2sockunion (argv[0], &su); > + if (ret < 0) > + { > + vty_out (vty, "%% Malformed address: %s%s", argv[0], > VTY_NEWLINE); > + return CMD_WARNING; > + } > + peer = peer_lookup (NULL, &su); > + if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) > + { > + vty_out (vty, "%% No such neighbor or address family%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + return show_adj_route_encap (vty, peer, NULL); > +} > +#ifdef HAVE_IPV6 > +DEFUN (show_bgp_ipv6_encap_neighbor_advertised_routes, > + show_bgp_ipv6_encap_neighbor_advertised_routes_cmd, > + "show bgp ipv6 encap neighbors A.B.C.D advertised-routes", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Detailed information on TCP and BGP neighbor connections\n" > + "Neighbor to display information about\n" > + "Display the routes advertised to a BGP neighbor\n") > +{ > + int ret; > + struct peer *peer; > + union sockunion su; > + > + ret = str2sockunion (argv[0], &su); > + if (ret < 0) > + { > + vty_out (vty, "%% Malformed address: %s%s", argv[0], > VTY_NEWLINE); > + return CMD_WARNING; > + } > + peer = peer_lookup (NULL, &su); > + if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) > + { > + vty_out (vty, "%% No such neighbor or address family%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + return show_adj_route_encap (vty, peer, NULL); > +} > +#endif > + > +DEFUN (show_bgp_ipv4_encap_rd_neighbor_advertised_routes, > + show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd, > + "show bgp ipv4 encap rd ASN:nn_or_IP-address:nn neighbors > (A.B.C.D|X:X::X:X) advertised-routes", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display information for a route distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "Detailed information on TCP and BGP neighbor connections\n" > + "Neighbor to display information about\n" > + "Neighbor to display information about\n" > + "Display the routes advertised to a BGP neighbor\n") > +{ > + int ret; > + struct peer *peer; > + struct prefix_rd prd; > + union sockunion su; > + > + ret = str2sockunion (argv[1], &su); > + if (ret < 0) > + { > + vty_out (vty, "%% Malformed address: %s%s", argv[1], > VTY_NEWLINE); > + return CMD_WARNING; > + } > + peer = peer_lookup (NULL, &su); > + if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) > + { > + vty_out (vty, "%% No such neighbor or address family%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + ret = str2prefix_rd (argv[0], &prd); > + if (! ret) > + { > + vty_out (vty, "%% Malformed Route Distinguisher%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + return show_adj_route_encap (vty, peer, &prd); > +} > +#ifdef HAVE_IPV6 > +DEFUN (show_bgp_ipv6_encap_rd_neighbor_advertised_routes, > + show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd, > + "show bgp ipv6 encap rd ASN:nn_or_IP-address:nn neighbors > (A.B.C.D|X:X::X:X) advertised-routes", > + SHOW_STR > + BGP_STR > + "Address Family\n" > + "Display ENCAP NLRI specific information\n" > + "Display information for a route distinguisher\n" > + "ENCAP Route Distinguisher\n" > + "Detailed information on TCP and BGP neighbor connections\n" > + "Neighbor to display information about\n" > + "Neighbor to display information about\n" > + "Display the routes advertised to a BGP neighbor\n") > +{ > + int ret; > + struct peer *peer; > + struct prefix_rd prd; > + union sockunion su; > + > + ret = str2sockunion (argv[1], &su); > + if (ret < 0) > + { > + vty_out (vty, "%% Malformed address: %s%s", argv[1], > VTY_NEWLINE); > + return CMD_WARNING; > + } > + peer = peer_lookup (NULL, &su); > + if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) > + { > + vty_out (vty, "%% No such neighbor or address family%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + ret = str2prefix_rd (argv[0], &prd); > + if (! ret) > + { > + vty_out (vty, "%% Malformed Route Distinguisher%s", > VTY_NEWLINE); > + return CMD_WARNING; > + } > + > + return show_adj_route_encap (vty, peer, &prd); > +} > +#endif > + > +void > +bgp_encap_init (void) > +{ > + install_element (BGP_ENCAP_NODE, &encap_network_cmd); > + install_element (BGP_ENCAP_NODE, &no_encap_network_cmd); > + > + > + install_element (VIEW_NODE, &show_bgp_ipv4_encap_cmd); > + install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_cmd); > + install_element (VIEW_NODE, &show_bgp_ipv4_encap_tags_cmd); > + install_element (VIEW_NODE, &show_bgp_ipv4_encap_rd_tags_cmd); > + install_element (VIEW_NODE, > &show_bgp_ipv4_encap_neighbor_routes_cmd); > + install_element (VIEW_NODE, > &show_bgp_ipv4_encap_rd_neighbor_routes_cmd); > + install_element (VIEW_NODE, > &show_bgp_ipv4_encap_neighbor_advertised_routes_cmd); > + install_element (VIEW_NODE, > &show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd); > + > +#ifdef HAVE_IPV6 > + install_element (VIEW_NODE, &show_bgp_ipv6_encap_cmd); > + install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_cmd); > + install_element (VIEW_NODE, &show_bgp_ipv6_encap_tags_cmd); > + install_element (VIEW_NODE, &show_bgp_ipv6_encap_rd_tags_cmd); > + install_element (VIEW_NODE, > &show_bgp_ipv6_encap_neighbor_routes_cmd); > + install_element (VIEW_NODE, > &show_bgp_ipv6_encap_rd_neighbor_routes_cmd); > + install_element (VIEW_NODE, > &show_bgp_ipv6_encap_neighbor_advertised_routes_cmd); > + install_element (VIEW_NODE, > &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd); > +#endif > + > + > + install_element (ENABLE_NODE, &show_bgp_ipv4_encap_cmd); > + install_element (ENABLE_NODE, &show_bgp_ipv4_encap_rd_cmd); > + install_element (ENABLE_NODE, &show_bgp_ipv4_encap_tags_cmd); > + install_element (ENABLE_NODE, &show_bgp_ipv4_encap_rd_tags_cmd); > + install_element (ENABLE_NODE, > &show_bgp_ipv4_encap_neighbor_routes_cmd); > + install_element (ENABLE_NODE, > &show_bgp_ipv4_encap_rd_neighbor_routes_cmd); > + install_element (ENABLE_NODE, > &show_bgp_ipv4_encap_neighbor_advertised_routes_cmd); > + install_element (ENABLE_NODE, > &show_bgp_ipv4_encap_rd_neighbor_advertised_routes_cmd); > + > +#ifdef HAVE_IPV6 > + install_element (ENABLE_NODE, &show_bgp_ipv6_encap_cmd); > + install_element (ENABLE_NODE, &show_bgp_ipv6_encap_rd_cmd); > + install_element (ENABLE_NODE, &show_bgp_ipv6_encap_tags_cmd); > + install_element (ENABLE_NODE, &show_bgp_ipv6_encap_rd_tags_cmd); > + install_element (ENABLE_NODE, > &show_bgp_ipv6_encap_neighbor_routes_cmd); > + install_element (ENABLE_NODE, > &show_bgp_ipv6_encap_rd_neighbor_routes_cmd); > + install_element (ENABLE_NODE, > &show_bgp_ipv6_encap_neighbor_advertised_routes_cmd); > + install_element (ENABLE_NODE, > &show_bgp_ipv6_encap_rd_neighbor_advertised_routes_cmd); > +#endif > + > + > +} > diff --git a/bgpd/bgp_encap.h b/bgpd/bgp_encap.h > new file mode 100644 > index 0000000..6f43b7b > --- /dev/null > +++ b/bgpd/bgp_encap.h > @@ -0,0 +1,34 @@ > +/* > + * > + * Copyright 2009-2015, LabN Consulting, L.L.C. > + * > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA > 02111-1307, USA. > + * > + */ > + > +#ifndef _QUAGGA_BGP_ENCAP_H > +#define _QUAGGA_BGP_ENCAP_H > + > +extern void bgp_encap_init (void); > +extern int bgp_nlri_parse_encap ( > + afi_t, > + struct peer *, > + struct attr *, > + struct bgp_nlri *, > + int withdraw); > + > +#include "bgp_encap_types.h" > +#endif /* _QUAGGA_BGP_ENCAP_H */ > diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c > index 129c11f..eadc090 100644 > --- a/bgpd/bgp_open.c > +++ b/bgpd/bgp_open.c > @@ -96,6 +96,9 @@ bgp_capability_vty_out (struct vty *vty, struct > peer *peer) > case SAFI_MPLS_LABELED_VPN: > vty_out (vty, "SAFI MPLS-labeled VPN"); > break; > + case SAFI_ENCAP: > + vty_out (vty, "SAFI ENCAP"); > + break; > default: > vty_out (vty, "SAFI Unknown %d ", mpc.safi); > break; > @@ -138,6 +141,7 @@ bgp_afi_safi_valid_indices (afi_t afi, safi_t > *safi) > case SAFI_UNICAST: > case SAFI_MULTICAST: > case SAFI_MPLS_VPN: > + case SAFI_ENCAP: > return 1; > } > } > @@ -807,9 +811,11 @@ bgp_open_option_parse (struct peer *peer, > u_char length, int *mp_capability) > if (! peer->afc_nego[AFI_IP][SAFI_UNICAST] > && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST] > && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] > + && ! peer->afc_nego[AFI_IP][SAFI_ENCAP] > && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST] > && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST] > - && ! peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]) > + && ! peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN] > + && ! peer->afc_nego[AFI_IP6][SAFI_ENCAP]) > { > plog_err (peer->log, "%s [Error] Configured AFI/SAFIs do > not " > "overlap with received MP capabilities", > @@ -954,6 +960,18 @@ bgp_open_capability (struct stream *s, struct > peer *peer) > stream_putc (s, 0); > stream_putc (s, SAFI_MPLS_LABELED_VPN); > } > + /* ENCAP */ > + if (peer->afc[AFI_IP][SAFI_ENCAP]) > + { > + peer->afc_adv[AFI_IP][SAFI_ENCAP] = 1; > + stream_putc (s, BGP_OPEN_OPT_CAP); > + stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); > + stream_putc (s, CAPABILITY_CODE_MP); > + stream_putc (s, CAPABILITY_CODE_MP_LEN); > + stream_putw (s, AFI_IP); > + stream_putc (s, 0); > + stream_putc (s, SAFI_ENCAP); > + } > #ifdef HAVE_IPV6 > /* IPv6 unicast. */ > if (peer->afc[AFI_IP6][SAFI_UNICAST]) > @@ -991,6 +1009,18 @@ bgp_open_capability (struct stream *s, > struct peer *peer) > stream_putc (s, 0); > stream_putc (s, SAFI_MPLS_LABELED_VPN); > } > + /* IPv6 ENCAP. */ > + if (peer->afc[AFI_IP6][SAFI_ENCAP]) > + { > + peer->afc_adv[AFI_IP6][SAFI_ENCAP] = 1; > + stream_putc (s, BGP_OPEN_OPT_CAP); > + stream_putc (s, CAPABILITY_CODE_MP_LEN + 2); > + stream_putc (s, CAPABILITY_CODE_MP); > + stream_putc (s, CAPABILITY_CODE_MP_LEN); > + stream_putw (s, AFI_IP6); > + stream_putc (s, 0); > + stream_putc (s, SAFI_ENCAP); > + } > #endif /* HAVE_IPV6 */ > > /* Route refresh. */ > diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c > index 9d88e11..5902965 100644 > --- a/bgpd/bgp_packet.c > +++ b/bgpd/bgp_packet.c > @@ -46,6 +46,7 @@ Software Foundation, Inc., 59 Temple Place - > Suite 330, Boston, MA > #include "bgpd/bgp_ecommunity.h" > #include "bgpd/bgp_network.h" > #include "bgpd/bgp_mplsvpn.h" > +#include "bgpd/bgp_encap.h" > #include "bgpd/bgp_advertise.h" > #include "bgpd/bgp_vty.h" > > @@ -1938,6 +1939,54 @@ bgp_update_receive (struct peer *peer, > bgp_size_t size) > peer->host); > } > } > + if (peer->afc[AFI_IP][SAFI_ENCAP]) > + { > + if (mp_update.length > + && mp_update.afi == AFI_IP > + && mp_update.safi == SAFI_ENCAP) > + bgp_nlri_parse_encap (mp_update.afi, peer, &attr, > &mp_update, 0); > + > + if (mp_withdraw.length > + && mp_withdraw.afi == AFI_IP > + && mp_withdraw.safi == SAFI_ENCAP) > + bgp_nlri_parse_encap (mp_withdraw.afi, peer, &attr, > &mp_withdraw, 1); > + > + if (! withdraw_len > + && mp_withdraw.afi == AFI_IP > + && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN > + && mp_withdraw.length == 0) > + { > + /* End-of-RIB received */ > + > + if (BGP_DEBUG (update, UPDATE_IN)) > + zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for Encap > Unicast from %s", > + peer->host); > + } > + } > + if (peer->afc[AFI_IP6][SAFI_ENCAP]) > + { > + if (mp_update.length > + && mp_update.afi == AFI_IP6 > + && mp_update.safi == SAFI_ENCAP) > + bgp_nlri_parse_encap (mp_update.afi, peer, &attr, > &mp_update, 0); > + > + if (mp_withdraw.length > + && mp_withdraw.afi == AFI_IP6 > + && mp_withdraw.safi == SAFI_ENCAP) > + bgp_nlri_parse_encap (mp_withdraw.afi, peer, &attr, > &mp_withdraw, 1); > + > + if (! withdraw_len > + && mp_withdraw.afi == AFI_IP6 > + && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN > + && mp_withdraw.length == 0) > + { > + /* End-of-RIB received */ > + > + if (BGP_DEBUG (update, UPDATE_IN)) > + zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for Encap > Unicast from %s", > + peer->host); > + } > + } > > /* Everything is done. We unintern temporary structures which > interned in bgp_attr_parse(). */ > diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c > index 006f363..c4b87a0 100644 > --- a/bgpd/bgp_route.c > +++ b/bgpd/bgp_route.c > @@ -71,7 +71,7 @@ bgp_afi_node_get (struct bgp_table *table, afi_t > afi, safi_t safi, struct prefix > if (!table) > return NULL; > > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > { > prn = bgp_node_get (table, (struct prefix *) prd); > > @@ -84,7 +84,7 @@ bgp_afi_node_get (struct bgp_table *table, afi_t > afi, safi_t safi, struct prefix > > rn = bgp_node_get (table, p); > > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > rn->prn = prn; > > return rn; > @@ -989,13 +989,24 @@ bgp_announce_check (struct bgp_info *ri, > struct peer *peer, struct prefix *p, > attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)); > } > > + > +#define NEXTHOP_IS_V4 (\ > + (safi != SAFI_ENCAP && p->family == AF_INET) || \ > + (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 4)) > + > +#ifdef HAVE_IPV6 > +#define NEXTHOP_IS_V6 (\ > + (safi != SAFI_ENCAP && p->family == AF_INET6) || \ > + (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 16)) > +#endif > + > /* next-hop-set */ > if (transparent > || (reflect && ! CHECK_FLAG (peer->af_flags[afi][safi], > PEER_FLAG_NEXTHOP_SELF_ALL)) > || (CHECK_FLAG (peer->af_flags[afi][safi], > PEER_FLAG_NEXTHOP_UNCHANGED) > - && ((p->family == AF_INET && attr->nexthop.s_addr) > + && ((NEXTHOP_IS_V4 && attr->nexthop.s_addr) > #ifdef HAVE_IPV6 > - || (p->family == AF_INET6 && > + || (NEXTHOP_IS_V6 && > ! > IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global)) > #endif /* HAVE_IPV6 */ > ))) > @@ -1003,18 +1014,18 @@ bgp_announce_check (struct bgp_info *ri, > struct peer *peer, struct prefix *p, > /* NEXT-HOP Unchanged. */ > } > else if (CHECK_FLAG (peer->af_flags[afi][safi], > PEER_FLAG_NEXTHOP_SELF) > - || (p->family == AF_INET && attr->nexthop.s_addr == 0) > + || (NEXTHOP_IS_V4 && attr->nexthop.s_addr == 0) > #ifdef HAVE_IPV6 > - || (p->family == AF_INET6 && > + || (NEXTHOP_IS_V6 && > > IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global)) > #endif /* HAVE_IPV6 */ > || (peer->sort == BGP_PEER_EBGP > && bgp_multiaccess_check_v4 (attr->nexthop, > peer->host) == 0)) > { > /* Set IPv4 nexthop. */ > - if (p->family == AF_INET) > + if (NEXTHOP_IS_V4) > { > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > memcpy (&attr->extra->mp_nexthop_global_in, > &peer->nexthop.v4, > IPV4_MAX_BYTELEN); > else > @@ -1022,7 +1033,7 @@ bgp_announce_check (struct bgp_info *ri, > struct peer *peer, struct prefix *p, > } > #ifdef HAVE_IPV6 > /* Set IPv6 nexthop. */ > - if (p->family == AF_INET6) > + if (NEXTHOP_IS_V6) > { > /* IPv6 global nexthop must be included. */ > memcpy (&attr->extra->mp_nexthop_global, > &peer->nexthop.v6_global, > @@ -1033,7 +1044,7 @@ bgp_announce_check (struct bgp_info *ri, > struct peer *peer, struct prefix *p, > } > > #ifdef HAVE_IPV6 > - if (p->family == AF_INET6) > + if (p->family == AF_INET6 && safi != SAFI_ENCAP) > { > /* Left nexthop_local unchanged if so configured. */ > if ( CHECK_FLAG (peer->af_flags[afi][safi], > @@ -1223,7 +1234,7 @@ bgp_announce_check_rsclient (struct bgp_info > *ri, struct peer *rsclient, > /* Set IPv4 nexthop. */ > if (p->family == AF_INET) > { > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > memcpy (&attr->extra->mp_nexthop_global_in, > &rsclient->nexthop.v4, > IPV4_MAX_BYTELEN); > else > @@ -2644,7 +2655,7 @@ bgp_announce_table (struct peer *peer, afi_t > afi, safi_t safi, > if (! table) > table = (rsclient) ? peer->rib[afi][safi] : > peer->bgp->rib[afi][safi]; > > - if (safi != SAFI_MPLS_VPN > + if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP) > && CHECK_FLAG (peer->af_flags[afi][safi], > PEER_FLAG_DEFAULT_ORIGINATE)) > bgp_default_originate (peer, afi, safi, 0); > > @@ -2680,7 +2691,7 @@ bgp_announce_route (struct peer *peer, afi_t > afi, safi_t safi) > if (CHECK_FLAG (peer->af_sflags[afi][safi], > PEER_STATUS_ORF_WAIT_REFRESH)) > return; > > - if (safi != SAFI_MPLS_VPN) > + if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)) > bgp_announce_table (peer, afi, safi, NULL, 0); > else > for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; > @@ -2730,7 +2741,7 @@ bgp_soft_reconfig_rsclient (struct peer > *rsclient, afi_t afi, safi_t safi) > struct bgp_table *table; > struct bgp_node *rn; > > - if (safi != SAFI_MPLS_VPN) > + if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)) > bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, NULL, > NULL); > > else > @@ -2789,7 +2800,7 @@ bgp_soft_reconfig_in (struct peer *peer, > afi_t afi, safi_t safi) > if (peer->status != Established) > return; > > - if (safi != SAFI_MPLS_VPN) > + if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)) > bgp_soft_reconfig_table (peer, afi, safi, NULL, NULL); > else > for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; > @@ -3006,7 +3017,7 @@ bgp_clear_route (struct peer *peer, afi_t > afi, safi_t safi, > switch (purpose) > { > case BGP_CLEAR_ROUTE_NORMAL: > - if (safi != SAFI_MPLS_VPN) > + if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)) > bgp_clear_route_table (peer, afi, safi, NULL, NULL, purpose); > else > for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; > @@ -3185,6 +3196,16 @@ bgp_cleanup_routes (void) > bgp_unlock_node(rn); > } > > + for (rn = bgp_table_top(bgp->rib[afi][SAFI_ENCAP]); rn; > + rn = bgp_route_next (rn)) > + if (rn->info) > + { > + bgp_cleanup_table((struct bgp_table > *)(rn->info), SAFI_ENCAP); > + bgp_table_finish ((struct bgp_table > **)&(rn->info)); > + rn->info = NULL; > + bgp_unlock_node(rn); > + } > + } > } > } > > @@ -3307,7 +3328,7 @@ bgp_nlri_sanity_check (struct peer *peer, > int afi, safi_t safi, > u_char prefixlen; > int psize; > > - if (safi == BGP_SAFI_VPN || safi == SAFI_MPLS_VPN) { > + if (safi == SAFI_MPLS_LABELED_VPN || safi == SAFI_MPLS_VPN) { > > return 0; > } > @@ -3320,11 +3341,22 @@ bgp_nlri_sanity_check (struct peer *peer, > int afi, safi_t safi, > > while (pnt < end) > { > + int badlength; > prefixlen = *pnt++; > > /* Prefix length check. */ > - if ((afi == AFI_IP && prefixlen > 32) > - || (afi == AFI_IP6 && prefixlen > 128)) > + badlength = 0; > + if (safi == SAFI_ENCAP) { > + if (prefixlen > 128) > + badlength = 1; > + } else { > + if ((afi == AFI_IP && prefixlen > 32) || > + (afi == AFI_IP6 && prefixlen > 128)) { > + > + badlength = 1; > + } > + } > + if (badlength) > { > plog_err (peer->log, > "%s [Error] Update packet error (wrong prefix > length %d)", > @@ -4067,7 +4099,7 @@ bgp_static_delete (struct bgp *bgp) > for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = > bgp_route_next (rn)) > if (rn->info != NULL) > { > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > { > table = rn->info; > > @@ -4923,7 +4955,7 @@ bgp_aggregate_increment (struct bgp *bgp, > struct prefix *p, > struct bgp_table *table; > > /* MPLS-VPN aggregation is not yet supported. */ > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > return; > > table = bgp->aggregate[afi][safi]; > @@ -4960,7 +4992,7 @@ bgp_aggregate_decrement (struct bgp *bgp, > struct prefix *p, > struct bgp_table *table; > > /* MPLS-VPN aggregation is not yet supported. */ > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > return; > > table = bgp->aggregate[afi][safi]; > @@ -5903,30 +5935,71 @@ route_vty_out (struct vty *vty, struct > prefix *p, > attr = binfo->attr; > if (attr) > { > - if (p->family == AF_INET) > - { > - if (safi == SAFI_MPLS_VPN) > - vty_out (vty, "%-16s", > - inet_ntoa (attr->extra->mp_nexthop_global_in)); > - else > - vty_out (vty, "%-16s", inet_ntoa (attr->nexthop)); > + > + /* > + * NEXTHOP start > + */ > + > + /* > + * For ENCAP routes, nexthop address family is not > + * neccessarily the same as the prefix address family. > + * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field > + */ > + if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) { > + if (attr->extra) { > + char buf[BUFSIZ]; > + int af = > NEXTHOP_FAMILY(attr->extra->mp_nexthop_len); > + > + switch (af) { > + case AF_INET: > + vty_out (vty, "%s", inet_ntop(af, > + &attr->extra->mp_nexthop_global_in, buf, > BUFSIZ)); > + break; > +#if HAVE_IPV6 > + case AF_INET6: > + vty_out (vty, "%s", inet_ntop(af, > + &attr->extra->mp_nexthop_global, buf, > BUFSIZ)); > + break; > +#endif > + > + default: > + vty_out(vty, "?"); > + } > + } else { > + vty_out(vty, "?"); > } > + } else { > + > + if (p->family == AF_INET) > + { > + vty_out (vty, "%-16s", inet_ntoa (attr->nexthop)); > + } > #ifdef HAVE_IPV6 > - else if (p->family == AF_INET6) > - { > - int len; > - char buf[BUFSIZ]; > + else if (p->family == AF_INET6) > + { > + int len; > + char buf[BUFSIZ]; > > - len = vty_out (vty, "%s", > - inet_ntop (AF_INET6, > &attr->extra->mp_nexthop_global, > - buf, BUFSIZ)); > - len = 16 - len; > - if (len < 1) > - vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " "); > - else > - vty_out (vty, "%*s", len, " "); > - } > + len = vty_out (vty, "%s", > + inet_ntop (AF_INET6, > &attr->extra->mp_nexthop_global, > + buf, BUFSIZ)); > + len = 16 - len; > + if (len < 1) > + vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " "); > + else > + vty_out (vty, "%*s", len, " "); > + } > #endif /* HAVE_IPV6 */ > + else > + { > + vty_out(vty, "?"); > + } > + } > + > + /* > + * NEXTHOP end > + */ > + > > if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) > vty_out (vty, "%10u", attr->med); > @@ -5968,7 +6041,7 @@ route_vty_out_tmp (struct vty *vty, struct > prefix *p, > { > if (p->family == AF_INET) > { > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > vty_out (vty, "%-16s", > inet_ntoa (attr->extra->mp_nexthop_global_in)); > else > @@ -6041,7 +6114,7 @@ route_vty_out_tag (struct vty *vty, struct > prefix *p, > { > if (p->family == AF_INET) > { > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > vty_out (vty, "%-16s", > inet_ntoa (attr->extra->mp_nexthop_global_in)); > else > @@ -6224,7 +6297,7 @@ route_vty_out_detail (struct vty *vty, > struct bgp *bgp, struct prefix *p, > /* Line2 display Next-hop, Neighbor, Router-id */ > if (p->family == AF_INET) > { > - vty_out (vty, " %s", safi == SAFI_MPLS_VPN ? > + vty_out (vty, " %s", ((safi == SAFI_MPLS_VPN) || > (safi == SAFI_ENCAP)) ? > inet_ntoa (attr->extra->mp_nexthop_global_in) : > inet_ntoa (attr->nexthop)); > } > @@ -6660,12 +6733,12 @@ route_vty_out_detail_header (struct vty > *vty, struct bgp *bgp, > int no_advertise = 0; > int local_as = 0; > int first = 0; > + int printrd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)); > > p = &rn->p; > vty_out (vty, "BGP routing table entry for %s%s%s/%d%s", > - (safi == SAFI_MPLS_VPN ? > - prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""), > - safi == SAFI_MPLS_VPN ? ":" : "", > + (printrd ? prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""), > + printrd ? ":" : "", > inet_ntop (p->family, &p->u.prefix, buf2, > INET6_ADDRSTRLEN), > p->prefixlen, VTY_NEWLINE); > > @@ -6751,7 +6824,7 @@ bgp_show_route_in_table (struct vty *vty, > struct bgp *bgp, > > match.family = afi2family (afi); > > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > { > for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn)) > { > @@ -6775,12 +6848,12 @@ bgp_show_route_in_table (struct vty *vty, > struct bgp *bgp, > if (header) > { > route_vty_out_detail_header (vty, bgp, > rm, (struct prefix_rd *)&rn->p, > - AFI_IP, > SAFI_MPLS_VPN); > + AFI_IP, safi); > > header = 0; > } > display++; > - route_vty_out_detail (vty, bgp, &rm->p, ri, > AFI_IP, SAFI_MPLS_VPN); > + route_vty_out_detail (vty, bgp, &rm->p, ri, > AFI_IP, safi); > } > > bgp_unlock_node (rm); > @@ -9820,22 +9893,28 @@ bgp_table_stats_vty (struct vty *vty, > const char *name, > afi_str, VTY_NEWLINE); > return CMD_WARNING; > } > - if (strncmp (safi_str, "m", 1) == 0) > - safi = SAFI_MULTICAST; > - else if (strncmp (safi_str, "u", 1) == 0) > - safi = SAFI_UNICAST; > - else if (strncmp (safi_str, "vpnv4", 5) == 0 || strncmp > (safi_str, "vpnv6", 5) == 0) > - safi = SAFI_MPLS_LABELED_VPN; > - else > - { > - vty_out (vty, "%% Invalid subsequent address family %s%s", > + switch (safi_str[0]) { > + case 'm': > + safi = SAFI_MULTICAST; > + break; > + case 'u': > + safi = SAFI_UNICAST; > + break; > + case 'v': > + safi = SAFI_MPLS_LABELED_VPN; > + break; > + case 'e': > + safi = SAFI_ENCAP; > + break; > + default: > + vty_out (vty, "%% Invalid subsequent address family %s%s", > safi_str, VTY_NEWLINE); > - return CMD_WARNING; > - } > + return CMD_WARNING; > + } > } > else > { > - vty_out (vty, "%% Invalid address family %s%s", > + vty_out (vty, "%% Invalid address family \"%s\"%s", > afi_str, VTY_NEWLINE); > return CMD_WARNING; > } > @@ -9845,30 +9924,23 @@ bgp_table_stats_vty (struct vty *vty, > const char *name, > > DEFUN (show_bgp_statistics, > show_bgp_statistics_cmd, > - "show bgp (ipv4|ipv6) (unicast|multicast) statistics", > + "show bgp (ipv4|ipv6) (encap|multicast|unicast|vpn) > statistics", > SHOW_STR > BGP_STR > "Address family\n" > "Address family\n" > "Address Family modifier\n" > "Address Family modifier\n" > + "Address Family modifier\n" > + "Address Family modifier\n" > "BGP RIB advertisement statistics\n") > { > return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]); > } > > -ALIAS (show_bgp_statistics, > - show_bgp_statistics_vpnv4_cmd, > - "show bgp (ipv4) (vpnv4) statistics", > - SHOW_STR > - BGP_STR > - "Address family\n" > - "Address Family modifier\n" > - "BGP RIB advertisement statistics\n") > - > DEFUN (show_bgp_statistics_view, > show_bgp_statistics_view_cmd, > - "show bgp view WORD (ipv4|ipv6) (unicast|multicast) > statistics", > + "show bgp view WORD (ipv4|ipv6) > (encap|multicast|unicast|vpn) statistics", > SHOW_STR > BGP_STR > "BGP view\n" > @@ -9876,20 +9948,24 @@ DEFUN (show_bgp_statistics_view, > "Address family\n" > "Address Family modifier\n" > "Address Family modifier\n" > + "Address Family modifier\n" > + "Address Family modifier\n" > "BGP RIB advertisement statistics\n") > { > return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]); > } > > +#if 0 /* added as options to above command */ > ALIAS (show_bgp_statistics_view, > - show_bgp_statistics_view_vpnv4_cmd, > - "show bgp view WORD (ipv4) (vpnv4) statistics", > + show_bgp_statistics_view_encap_cmd, > + "show bgp view WORD (ipv4) (encap) statistics", > SHOW_STR > BGP_STR > "BGP view\n" > "Address family\n" > "Address Family modifier\n" > "BGP RIB advertisement statistics\n") > +#endif > > enum bgp_pcounts > { > @@ -12393,9 +12469,9 @@ bgp_clear_damp_route (struct vty *vty, > const char *view_name, > > match.family = afi2family (afi); > > - if (safi == SAFI_MPLS_VPN) > + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) > { > - for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); > rn; rn = bgp_route_next (rn)) > + for (rn = bgp_table_top (bgp->rib[AFI_IP][safi]); rn; rn = > bgp_route_next (rn)) > { > if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) > continue; > @@ -12512,6 +12588,7 @@ DEFUN (clear_ip_bgp_dampening_address_mask, > SAFI_UNICAST, NULL, 0); > } > > +/* also used for encap safi */ > static int > bgp_config_write_network_vpnv4 (struct vty *vty, struct bgp *bgp, > afi_t afi, safi_t safi, int *write) > @@ -12563,7 +12640,7 @@ bgp_config_write_network (struct vty *vty, > struct bgp *bgp, > struct bgp_aggregate *bgp_aggregate; > char buf[SU_ADDRSTRLEN]; > > - if (afi == AFI_IP && safi == SAFI_MPLS_VPN) > + if (afi == AFI_IP && ((safi == SAFI_MPLS_VPN) || (safi == > SAFI_ENCAP))) > return bgp_config_write_network_vpnv4 (vty, bgp, afi, safi, > write); > > /* Network configuration. */ > diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h > index d70d12a..455a413 100644 > --- a/bgpd/bgp_route.h > +++ b/bgpd/bgp_route.h > @@ -120,6 +120,9 @@ struct bgp_static > struct route_map *map; > } rmap; > > + /* Route Distinguisher */ > + struct prefix_rd prd; > + > /* MPLS label. */ > u_char tag[3]; > }; > diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c > index 20aaec6..8a102b3 100644 > --- a/bgpd/bgp_vty.c > +++ b/bgpd/bgp_vty.c > @@ -4801,6 +4801,33 @@ ALIAS (clear_ip_bgp_all_vpnv4_soft_out, > "Address Family Modifier\n" > "Soft reconfig outbound update\n") > > +DEFUN (clear_ip_bgp_all_encap_soft_out, > + clear_ip_bgp_all_encap_soft_out_cmd, > + "clear ip bgp * encap unicast soft out", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear all peers\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig\n" > + "Soft reconfig outbound update\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_all, > + BGP_CLEAR_SOFT_OUT, NULL); > +} > + > +ALIAS (clear_ip_bgp_all_encap_soft_out, > + clear_ip_bgp_all_encap_out_cmd, > + "clear ip bgp * encap unicast out", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear all peers\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig outbound update\n") > + > DEFUN (clear_bgp_all_soft_out, > clear_bgp_all_soft_out_cmd, > "clear bgp * soft out", > @@ -4939,6 +4966,33 @@ ALIAS (clear_ip_bgp_peer_vpnv4_soft_out, > "Address Family Modifier\n" > "Soft reconfig outbound update\n") > > +DEFUN (clear_ip_bgp_peer_encap_soft_out, > + clear_ip_bgp_peer_encap_soft_out_cmd, > + "clear ip bgp A.B.C.D encap unicast soft out", > + CLEAR_STR > + IP_STR > + BGP_STR > + "BGP neighbor address to clear\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig\n" > + "Soft reconfig outbound update\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_peer, > + BGP_CLEAR_SOFT_OUT, argv[0]); > +} > + > +ALIAS (clear_ip_bgp_peer_encap_soft_out, > + clear_ip_bgp_peer_encap_out_cmd, > + "clear ip bgp A.B.C.D encap unicast out", > + CLEAR_STR > + IP_STR > + BGP_STR > + "BGP neighbor address to clear\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig outbound update\n") > + > DEFUN (clear_bgp_peer_soft_out, > clear_bgp_peer_soft_out_cmd, > "clear bgp (A.B.C.D|X:X::X:X) soft out", > @@ -5266,6 +5320,33 @@ ALIAS (clear_ip_bgp_as_vpnv4_soft_out, > "Address Family modifier\n" > "Soft reconfig outbound update\n") > > +DEFUN (clear_ip_bgp_as_encap_soft_out, > + clear_ip_bgp_as_encap_soft_out_cmd, > + "clear ip bgp " CMD_AS_RANGE " encap unicast soft out", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear peers with the AS number\n" > + "Address family\n" > + "Address Family modifier\n" > + "Soft reconfig\n" > + "Soft reconfig outbound update\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_as, > + BGP_CLEAR_SOFT_OUT, argv[0]); > +} > + > +ALIAS (clear_ip_bgp_as_encap_soft_out, > + clear_ip_bgp_as_encap_out_cmd, > + "clear ip bgp " CMD_AS_RANGE " encap unicast out", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear peers with the AS number\n" > + "Address family\n" > + "Address Family modifier\n" > + "Soft reconfig outbound update\n") > + > DEFUN (clear_bgp_as_soft_out, > clear_bgp_as_soft_out_cmd, > "clear bgp " CMD_AS_RANGE " soft out", > @@ -5502,6 +5583,33 @@ ALIAS (clear_ip_bgp_all_vpnv4_soft_in, > "Address Family Modifier\n" > "Soft reconfig inbound update\n") > > +DEFUN (clear_ip_bgp_all_encap_soft_in, > + clear_ip_bgp_all_encap_soft_in_cmd, > + "clear ip bgp * encap unicast soft in", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear all peers\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig\n" > + "Soft reconfig inbound update\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_all, > + BGP_CLEAR_SOFT_IN, NULL); > +} > + > +ALIAS (clear_ip_bgp_all_encap_soft_in, > + clear_ip_bgp_all_encap_in_cmd, > + "clear ip bgp * encap unicast in", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear all peers\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig inbound update\n") > + > DEFUN (clear_bgp_all_soft_in, > clear_bgp_all_soft_in_cmd, > "clear bgp * soft in", > @@ -5698,6 +5806,33 @@ ALIAS (clear_ip_bgp_peer_vpnv4_soft_in, > "Address Family Modifier\n" > "Soft reconfig inbound update\n") > > +DEFUN (clear_ip_bgp_peer_encap_soft_in, > + clear_ip_bgp_peer_encap_soft_in_cmd, > + "clear ip bgp A.B.C.D encap unicast soft in", > + CLEAR_STR > + IP_STR > + BGP_STR > + "BGP neighbor address to clear\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig\n" > + "Soft reconfig inbound update\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_peer, > + BGP_CLEAR_SOFT_IN, argv[0]); > +} > + > +ALIAS (clear_ip_bgp_peer_encap_soft_in, > + clear_ip_bgp_peer_encap_in_cmd, > + "clear ip bgp A.B.C.D encap unicast in", > + CLEAR_STR > + IP_STR > + BGP_STR > + "BGP neighbor address to clear\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig inbound update\n") > + > DEFUN (clear_bgp_peer_soft_in, > clear_bgp_peer_soft_in_cmd, > "clear bgp (A.B.C.D|X:X::X:X) soft in", > @@ -6205,6 +6340,33 @@ ALIAS (clear_ip_bgp_as_vpnv4_soft_in, > "Address Family modifier\n" > "Soft reconfig inbound update\n") > > +DEFUN (clear_ip_bgp_as_encap_soft_in, > + clear_ip_bgp_as_encap_soft_in_cmd, > + "clear ip bgp " CMD_AS_RANGE " encap unicast soft in", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear peers with the AS number\n" > + "Address family\n" > + "Address Family modifier\n" > + "Soft reconfig\n" > + "Soft reconfig inbound update\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_as, > + BGP_CLEAR_SOFT_IN, argv[0]); > +} > + > +ALIAS (clear_ip_bgp_as_encap_soft_in, > + clear_ip_bgp_as_encap_in_cmd, > + "clear ip bgp " CMD_AS_RANGE " encap unicast in", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear peers with the AS number\n" > + "Address family\n" > + "Address Family modifier\n" > + "Soft reconfig inbound update\n") > + > DEFUN (clear_bgp_as_soft_in, > clear_bgp_as_soft_in_cmd, > "clear bgp " CMD_AS_RANGE " soft in", > @@ -6355,6 +6517,21 @@ DEFUN (clear_ip_bgp_all_vpnv4_soft, > BGP_CLEAR_SOFT_BOTH, argv[0]); > } > > +DEFUN (clear_ip_bgp_all_encap_soft, > + clear_ip_bgp_all_encap_soft_cmd, > + "clear ip bgp * encap unicast soft", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear all peers\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_all, > + BGP_CLEAR_SOFT_BOTH, argv[0]); > +} > + > DEFUN (clear_bgp_all_soft, > clear_bgp_all_soft_cmd, > "clear bgp * soft", > @@ -6438,6 +6615,21 @@ DEFUN (clear_ip_bgp_peer_vpnv4_soft, > BGP_CLEAR_SOFT_BOTH, argv[0]); > } > > +DEFUN (clear_ip_bgp_peer_encap_soft, > + clear_ip_bgp_peer_encap_soft_cmd, > + "clear ip bgp A.B.C.D encap unicast soft", > + CLEAR_STR > + IP_STR > + BGP_STR > + "BGP neighbor address to clear\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_peer, > + BGP_CLEAR_SOFT_BOTH, argv[0]); > +} > + > DEFUN (clear_bgp_peer_soft, > clear_bgp_peer_soft_cmd, > "clear bgp (A.B.C.D|X:X::X:X) soft", > @@ -6621,6 +6813,21 @@ DEFUN (clear_ip_bgp_as_vpnv4_soft, > BGP_CLEAR_SOFT_BOTH, argv[0]); > } > > +DEFUN (clear_ip_bgp_as_encap_soft, > + clear_ip_bgp_as_encap_soft_cmd, > + "clear ip bgp " CMD_AS_RANGE " encap unicast soft", > + CLEAR_STR > + IP_STR > + BGP_STR > + "Clear peers with the AS number\n" > + "Address family\n" > + "Address Family Modifier\n" > + "Soft reconfig\n") > +{ > + return bgp_clear_vty (vty, NULL, AFI_IP, SAFI_ENCAP, clear_as, > + BGP_CLEAR_SOFT_BOTH, argv[0]); > +} > + > DEFUN (clear_bgp_as_soft, > clear_bgp_as_soft_cmd, > "clear bgp " CMD_AS_RANGE " soft", > @@ -10028,6 +10235,12 @@ bgp_vty_init (void) > install_element (ENABLE_NODE, &clear_ip_bgp_peer_vpnv4_in_cmd); > install_element (ENABLE_NODE, &clear_ip_bgp_as_vpnv4_soft_in_cmd); > install_element (ENABLE_NODE, &clear_ip_bgp_as_vpnv4_in_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_all_encap_soft_in_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_all_encap_in_cmd); > + install_element (ENABLE_NODE, > &clear_ip_bgp_peer_encap_soft_in_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_peer_encap_in_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_as_encap_soft_in_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_as_encap_in_cmd); > #ifdef HAVE_IPV6 > install_element (ENABLE_NODE, &clear_bgp_all_soft_in_cmd); > install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_in_cmd); > @@ -10091,6 +10304,12 @@ bgp_vty_init (void) > install_element (ENABLE_NODE, &clear_ip_bgp_peer_vpnv4_out_cmd); > install_element (ENABLE_NODE, &clear_ip_bgp_as_vpnv4_soft_out_cmd); > install_element (ENABLE_NODE, &clear_ip_bgp_as_vpnv4_out_cmd); > + install_element (ENABLE_NODE, > &clear_ip_bgp_all_encap_soft_out_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_all_encap_out_cmd); > + install_element (ENABLE_NODE, > &clear_ip_bgp_peer_encap_soft_out_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_peer_encap_out_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_as_encap_soft_out_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_as_encap_out_cmd); > #ifdef HAVE_IPV6 > install_element (ENABLE_NODE, &clear_bgp_all_soft_out_cmd); > install_element (ENABLE_NODE, > &clear_bgp_instance_all_soft_out_cmd); > @@ -10131,6 +10350,9 @@ bgp_vty_init (void) > install_element (ENABLE_NODE, &clear_ip_bgp_all_vpnv4_soft_cmd); > install_element (ENABLE_NODE, &clear_ip_bgp_peer_vpnv4_soft_cmd); > install_element (ENABLE_NODE, &clear_ip_bgp_as_vpnv4_soft_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_all_encap_soft_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_peer_encap_soft_cmd); > + install_element (ENABLE_NODE, &clear_ip_bgp_as_encap_soft_cmd); > #ifdef HAVE_IPV6 > install_element (ENABLE_NODE, &clear_bgp_all_soft_cmd); > install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_cmd); > diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c > index 8401e9f..94a0514 100644 > --- a/bgpd/bgpd.c > +++ b/bgpd/bgpd.c > @@ -36,6 +36,7 @@ Software Foundation, Inc., 59 Temple Place - > Suite 330, Boston, MA > #include "plist.h" > #include "linklist.h" > #include "workqueue.h" > +#include "table.h" > > #include "bgpd/bgpd.h" > #include "bgpd/bgp_table.h" > @@ -55,6 +56,7 @@ Software Foundation, Inc., 59 Temple Place - > Suite 330, Boston, MA > #include "bgpd/bgp_nexthop.h" > #include "bgpd/bgp_damp.h" > #include "bgpd/bgp_mplsvpn.h" > +#include "bgpd/bgp_encap.h" > #include "bgpd/bgp_advertise.h" > #include "bgpd/bgp_network.h" > #include "bgpd/bgp_vty.h" > @@ -974,12 +976,16 @@ peer_as_change (struct peer *peer, as_t as) > PEER_FLAG_REFLECTOR_CLIENT); > UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN], > PEER_FLAG_REFLECTOR_CLIENT); > + UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_ENCAP], > + PEER_FLAG_REFLECTOR_CLIENT); > UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST], > PEER_FLAG_REFLECTOR_CLIENT); > UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST], > PEER_FLAG_REFLECTOR_CLIENT); > UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MPLS_VPN], > PEER_FLAG_REFLECTOR_CLIENT); > + UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_ENCAP], > + PEER_FLAG_REFLECTOR_CLIENT); > } > > /* local-as reset */ > @@ -1398,9 +1404,11 @@ peer_group_active (struct peer *peer) > if (peer->af_group[AFI_IP][SAFI_UNICAST] > || peer->af_group[AFI_IP][SAFI_MULTICAST] > || peer->af_group[AFI_IP][SAFI_MPLS_VPN] > + || peer->af_group[AFI_IP][SAFI_ENCAP] > || peer->af_group[AFI_IP6][SAFI_UNICAST] > || peer->af_group[AFI_IP6][SAFI_MULTICAST] > - || peer->af_group[AFI_IP6][SAFI_MPLS_VPN]) > + || peer->af_group[AFI_IP6][SAFI_MPLS_VPN] > + || peer->af_group[AFI_IP6][SAFI_ENCAP]) > return 1; > return 0; > } > @@ -2356,9 +2364,11 @@ peer_active (struct peer *peer) > if (peer->afc[AFI_IP][SAFI_UNICAST] > || peer->afc[AFI_IP][SAFI_MULTICAST] > || peer->afc[AFI_IP][SAFI_MPLS_VPN] > + || peer->afc[AFI_IP][SAFI_ENCAP] > || peer->afc[AFI_IP6][SAFI_UNICAST] > || peer->afc[AFI_IP6][SAFI_MULTICAST] > - || peer->afc[AFI_IP6][SAFI_MPLS_VPN]) > + || peer->afc[AFI_IP6][SAFI_MPLS_VPN] > + || peer->afc[AFI_IP6][SAFI_ENCAP]) > return 1; > return 0; > } > @@ -2370,9 +2380,11 @@ peer_active_nego (struct peer *peer) > if (peer->afc_nego[AFI_IP][SAFI_UNICAST] > || peer->afc_nego[AFI_IP][SAFI_MULTICAST] > || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] > + || peer->afc_nego[AFI_IP][SAFI_ENCAP] > || peer->afc_nego[AFI_IP6][SAFI_UNICAST] > || peer->afc_nego[AFI_IP6][SAFI_MULTICAST] > - || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]) > + || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN] > + || peer->afc_nego[AFI_IP6][SAFI_ENCAP]) > return 1; > return 0; > } > @@ -5594,6 +5606,7 @@ bgp_init (void) > bgp_address_init (); > bgp_scan_init (); > bgp_mplsvpn_init (); > + bgp_encap_init (); > > /* Access list initialize. */ > access_list_init (); > -- > 2.1.3 > > > _______________________________________________ > Quagga-dev mailing list > [email protected] <mailto:[email protected]> > https://lists.quagga.net/mailman/listinfo/quagga-dev > > _______________________________________________ Quagga-dev mailing list [email protected] https://lists.quagga.net/mailman/listinfo/quagga-dev
