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_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.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 \
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_nht.h \
- bgp_updgrp.h bgp_bfd.h bgp_encap_tlv.h bgp_encap_types.h
+ bgp_updgrp.h bgp_bfd.h bgp_encap.h bgp_encap_tlv.h bgp_encap_types.h
bgpd_SOURCES = bgp_main.c
bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
uint16_t sublength;
struct bgp_attr_encap_subtlv *tlv;
- subtype = stream_getw (BGP_INPUT (peer));
- sublength = stream_getw (BGP_INPUT (peer));
- length -= 4;
+ if (BGP_ATTR_ENCAP == type) {
+ subtype = stream_getc (BGP_INPUT (peer));
+ sublength = stream_getc (BGP_INPUT (peer));
+ length -= 2;
+ }
if (sublength > length) {
zlog_info ("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
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;
}
}
}
break;
+ case SAFI_ENCAP:
+ assert (attr->extra);
+ stream_putc (s, IPV6_MAX_BYTELEN);
+ stream_put (s, &attr->extra->mp_nexthop_global, IPV6_MAX_BYTELEN);
+ break;
default:
break;
}
return size;
}
-#if 0
/*
* Encodes the tunnel encapsulation attribute
*/
uint8_t attrtype)
{
unsigned int attrlenfield = 0;
+ unsigned int attrhdrlen = 0;
struct bgp_attr_encap_subtlv *subtlvs;
struct bgp_attr_encap_subtlv *st;
const char *attrname;
* V = concatenated subtlvs.
*/
attrlenfield = 2 + 2; /* T + L */
+ attrhdrlen = 1 + 1; /* subTLV T + L */
break;
default:
}
+ /* if no tlvs, don't make attr */
+ if (subtlvs == NULL)
+ return;
+
/* compute attr length */
for (st = subtlvs; st; st = st->next) {
- attrlenfield += (4 + st->length);
+ attrlenfield += (attrhdrlen + st->length);
}
- /* if no tlvs, don't make attr */
- if (!attrlenfield)
- return;
-
if (attrlenfield > 0xffff) {
zlog_info ("%s attribute is too long (length=%d), can't send it",
attrname,
/* write each sub-tlv */
for (st = subtlvs; st; st = st->next) {
- stream_putw (s, st->type);
- stream_putw (s, st->length);
+ if (attrtype == BGP_ATTR_ENCAP) {
+ stream_putc (s, st->type);
+ stream_putc (s, st->length);
+ }
stream_put (s, st->value, st->length);
}
}
-#endif
void
bgp_packet_mpattr_end (struct stream *s, size_t sizep)
stream_putl (s, attr->extra->aggregator_as);
stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr);
}
-
+
+ if ((afi == AFI_IP || afi == AFI_IP6) &&
+ (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN))
+ {
+ /* Tunnel Encap attribute */
+ bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
+ }
+
/* Unknown transit attribute. */
if (attr->extra && attr->extra->transit)
stream_put (s, attr->extra->transit->val, attr->extra->transit->length);
--- /dev/null
+
+/*
+ * This file created by LabN Consulting, L.L.C.
+ *
+ *
+ * This file is based on bgp_mplsvpn.c which is Copyright (C) 2000
+ * Kunihiro Ishiguro <kunihiro@zebra.org>
+ *
+ */
+
+/*
+
+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 "filter.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, 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, 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, 0, attr, afi, SAFI_ENCAP,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0);
+ } else {
+ bgp_withdraw (peer, &p, 0, 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"
+ "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"
+ "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, 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, 0, NULL);
+ }
+ }
+ }
+ 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, 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, NULL);
+ else
+ route_vty_out (vty, &rm->p, ri, 0, SAFI_ENCAP, NULL);
+ 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
+
+
+}
--- /dev/null
+/*
+ *
+ * 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 */
return new;
}
+/* draft-rosen-idr-tunnel-encaps 2.1 */
+static struct bgp_attr_encap_subtlv *
+subtlv_encode_remote_endpoint(
+ struct bgp_tea_subtlv_remote_endpoint *st)
+{
+ struct bgp_attr_encap_subtlv *new;
+ uint8_t *p;
+
+ int total = (st->family==AF_INET?8:20);
+
+ assert(total <= 0xff);
+
+ new = XCALLOC(MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv) - 1 + total);
+ assert(new);
+ new->type = BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT;
+ new->length = total;
+ p = new->value;
+ if (st->family == AF_INET) {
+ memcpy (p, &(st->ip_address.v4.s_addr), 4);
+ p+=4;
+ } else {
+ assert (st->family == AF_INET6);
+ memcpy (p, &(st->ip_address.v6.s6_addr), 16);
+ p+=16;
+ }
+ memcpy (p, &(st->as4), 4);
+ return new;
+}
/***********************************************************************
* TUNNEL TYPE-SPECIFIC TLV ENCODE
ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_l2tpv3_over_ip, st_encap);
ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type, st_proto);
ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
+ ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT, subtlv_encode_remote_endpoint, st_endpoint);
}
void
ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_gre, st_encap);
ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type, st_proto);
ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
+ ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT, subtlv_encode_remote_endpoint, st_endpoint);
}
void
ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type, st_proto);
ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
+ ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT, subtlv_encode_remote_endpoint, st_endpoint);
}
void
return 0;
}
+/* draft-rosen-idr-tunnel-encaps 2.1 */
+static int
+subtlv_decode_remote_endpoint(
+ struct bgp_attr_encap_subtlv *subtlv,
+ struct bgp_tea_subtlv_remote_endpoint *st)
+{
+ int i;
+ if (subtlv->length != 8 && subtlv->length != 20 ) {
+ zlog_debug("%s, subtlv length %d does not equal 8 or 20",
+ __func__, subtlv->length);
+ return -1;
+ }
+ if (subtlv->length == 8) {
+ st->family = AF_INET;
+ st->ip_address.v4.s_addr = ((subtlv->value[0] << 24) |
+ (subtlv->value[1] << 16) |
+ (subtlv->value[2] << 8) |
+ subtlv->value[3]);
+ } else {
+ st->family = AF_INET6;
+ memcpy (&(st->ip_address.v6.s6_addr), subtlv->value, 16);
+ }
+ i = subtlv->length - 4;
+ st->as4 = ((subtlv->value[i] << 24) |
+ (subtlv->value[i+1] << 16) |
+ (subtlv->value[i+2] << 8) |
+ subtlv->value[i+3]);
+ return 0;
+}
+
/***********************************************************************
* TUNNEL TYPE-SPECIFIC TLV DECODE
***********************************************************************/
switch (st->type) {
case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
rc |= subtlv_decode_encap_l2tpv3_over_ip(st, &bet->st_encap);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_ENCAP;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
break;
case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
rc |= subtlv_decode_proto_type(st, &bet->st_proto);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_PROTO_TYPE;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
break;
case BGP_ENCAP_SUBTLV_TYPE_COLOR:
rc |= subtlv_decode_color(st, &bet->st_color);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
+ break;
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
break;
default:
switch (st->type) {
case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
rc |= subtlv_decode_encap_gre(st, &bet->st_encap);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_ENCAP;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
break;
case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
rc |= subtlv_decode_proto_type(st, &bet->st_proto);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_PROTO_TYPE;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
break;
case BGP_ENCAP_SUBTLV_TYPE_COLOR:
rc |= subtlv_decode_color(st, &bet->st_color);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
+ break;
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
break;
default:
switch (st->type) {
case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
rc |= subtlv_decode_proto_type(st, &bet->st_proto);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_PROTO_TYPE;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
break;
case BGP_ENCAP_SUBTLV_TYPE_COLOR:
rc |= subtlv_decode_color(st, &bet->st_color);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
+ break;
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
break;
default:
for (st = stlv; st; st = st->next) {
switch (st->type) {
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
+ break;
+
default:
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
rc |= -1;
switch (st->type) {
case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_IPSEC_TA;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
+ break;
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
break;
default:
switch (st->type) {
case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_IPSEC_TA;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
+ break;
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
break;
default:
switch (st->type) {
case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_IPSEC_TA;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
+ break;
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
break;
default:
for (st = stlv; st; st = st->next) {
switch (st->type) {
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
+ break;
+
default:
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
rc |= -1;
for (st = stlv; st; st = st->next) {
switch (st->type) {
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
+ break;
+
default:
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
rc |= -1;
for (st = stlv; st; st = st->next) {
switch (st->type) {
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
+ break;
+
default:
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
rc |= -1;
for (st = stlv; st; st = st->next) {
switch (st->type) {
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
+ break;
+
default:
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
rc |= -1;
for (st = stlv; st; st = st->next) {
switch (st->type) {
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
+ break;
+
default:
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
rc |= -1;
for (st = stlv; st; st = st->next) {
switch (st->type) {
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
+ break;
+
default:
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
rc |= -1;
switch (st->type) {
case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
rc |= subtlv_decode_encap_pbb(st, &bet->st_encap);
- bet->valid_subtlvs |= BGP_TEA_SUBTLV_ENCAP;
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
+ break;
+
+ case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
+ rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
+ SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
break;
default:
BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE=2,
BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA=3,
BGP_ENCAP_SUBTLV_TYPE_COLOR=4,
+ BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT=6 /* speculative, IANA assignment TBD */
} bgp_encap_subtlv_types;
/*
uint32_t color;
};
+/* per draft-rosen-idr-tunnel-encaps */
+struct bgp_tea_subtlv_remote_endpoint {
+ u_char family; /* IPv4 or IPv6 */
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ } ip_address;
+ as_t as4; /* always 4 bytes */
+};
+
/*
* This is the length of the value part of the ipsec tunnel authenticator
* subtlv. Currently we only support the length for authenticator type 1.
#define BGP_TEA_SUBTLV_PROTO_TYPE 0x00000002
#define BGP_TEA_SUBTLV_COLOR 0x00000004
#define BGP_TEA_SUBTLV_IPSEC_TA 0x00000008
+#define BGP_TEA_SUBTLV_REMOTE_ENDPOINT 0x00000010
+#define CHECK_SUBTLV_FLAG(ptr, flag) CHECK_FLAG((ptr)->valid_subtlvs, (flag))
+#define SET_SUBTLV_FLAG(ptr, flag) SET_FLAG((ptr)->valid_subtlvs, (flag))
+#define UNSET_SUBTLV_FLAG(ptr, flag) UNSET_FLAG((ptr)->valid_subtlvs, (flag))
/*
* Tunnel Type-specific APIs
*/
struct bgp_encap_type_reserved {
+ uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
};
struct bgp_encap_type_l2tpv3_over_ip {
struct bgp_tea_subtlv_encap_l2tpv3_over_ip st_encap;
struct bgp_tea_subtlv_proto_type st_proto; /* optional */
struct bgp_tea_subtlv_color st_color; /* optional */
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
};
struct bgp_encap_type_gre {
struct bgp_tea_subtlv_encap_gre_key st_encap; /* optional */
struct bgp_tea_subtlv_proto_type st_proto; /* optional */
struct bgp_tea_subtlv_color st_color; /* optional */
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
};
struct bgp_encap_type_ip_in_ip {
uint32_t valid_subtlvs;
struct bgp_tea_subtlv_proto_type st_proto; /* optional */
struct bgp_tea_subtlv_color st_color; /* optional */
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
};
struct bgp_encap_type_transmit_tunnel_endpoint {
+ uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
/* No subtlvs defined in spec? */
};
struct bgp_encap_type_ipsec_in_tunnel_mode {
uint32_t valid_subtlvs;
struct bgp_tea_subtlv_ipsec_ta st_ipsec_ta; /* optional */
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
};
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode {
uint32_t valid_subtlvs;
struct bgp_tea_subtlv_ipsec_ta st_ipsec_ta; /* optional */
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
};
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode {
uint32_t valid_subtlvs;
struct bgp_tea_subtlv_ipsec_ta st_ipsec_ta; /* optional */
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
};
struct bgp_encap_type_vxlan {
+ uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
/* No subtlvs defined in spec? */
};
struct bgp_encap_type_nvgre {
+ uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
/* No subtlvs defined in spec? */
};
struct bgp_encap_type_mpls {
+ uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
/* No subtlvs defined in spec? */
};
struct bgp_encap_type_mpls_in_gre {
+ uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
/* No subtlvs defined in spec? */
};
struct bgp_encap_type_vxlan_gpe {
+ uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
/* No subtlvs defined in spec? */
};
struct bgp_encap_type_mpls_in_udp {
+ uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
/* No subtlvs defined in spec? */
};
struct bgp_encap_type_pbb {
uint32_t valid_subtlvs;
+ struct bgp_tea_subtlv_remote_endpoint st_endpoint; /* optional */
struct bgp_tea_subtlv_encap_pbb st_encap;
};
case SAFI_MPLS_LABELED_VPN:
json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "MPLS-labeled VPN");
break;
+ case SAFI_ENCAP:
+ json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "encap");
+ break;
default:
json_object_int_add(json_cap, "capabilityErrorMultiProtocolSafiUnknown", mpc.safi);
break;
case SAFI_MULTICAST:
vty_out (vty, "SAFI Multicast");
break;
- case SAFI_MPLS_LABELED_VPN:
+ 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;
case SAFI_UNICAST:
case SAFI_MULTICAST:
case SAFI_MPLS_VPN:
+ case SAFI_ENCAP:
return 1;
}
break;
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])
{
zlog_err ("%s [Error] Configured AFI/SAFIs do not "
"overlap with received MP capabilities",
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
/* Currently supporting RFC-5549 for Link-Local peering only */
if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE) &&
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. */
#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"
#include "bgpd/bgp_updgrp.h"
/* Verify valid local address present based on negotiated address-families. */
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_MPLS_VPN] ||
+ peer->afc_nego[AFI_IP][SAFI_ENCAP])
{
if (!peer->nexthop.v4.s_addr)
{
}
if (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])
{
if (IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_global))
{
zlog_debug ("rcvd End-of-RIB for VPNv6 Unicast from %s", 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_ENCAP
+ && mp_withdraw.length == 0)
+ {
+ /* End-of-RIB received */
+ if (!CHECK_FLAG (peer->af_sflags[AFI_IP][SAFI_ENCAP],
+ PEER_STATUS_EOR_RECEIVED))
+ {
+ SET_FLAG (peer->af_sflags[AFI_IP][SAFI_ENCAP], PEER_STATUS_EOR_RECEIVED);
+ bgp_update_explicit_eors(peer);
+ }
+
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug ("rcvd End-of-RIB for IPv4 Encap 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_ENCAP
+ && mp_withdraw.length == 0)
+ {
+ /* End-of-RIB received */
+ if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_ENCAP],
+ PEER_STATUS_EOR_RECEIVED))
+ {
+ SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_ENCAP], PEER_STATUS_EOR_RECEIVED);
+ bgp_update_explicit_eors(peer);
+ }
+
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug ("rcvd End-of-RIB for IPv6 Encap from %s", peer->host);
+ }
+ }
/* Everything is done. We unintern temporary structures which
interned in bgp_attr_parse(). */
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);
rn = bgp_node_get (table, p);
- if (safi == SAFI_MPLS_VPN)
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
rn->prn = prn;
return rn;
SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
#ifdef HAVE_IPV6
+#define NEXTHOP_IS_V6 (\
+ (safi != SAFI_ENCAP && \
+ (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
+ (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 16))
+
/* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
* the peer (group) is configured to receive link-local nexthop unchanged
* and it is available in the prefix OR we're not reflecting the route and
* the peer (group) to whom we're going to announce is on a shared network
* and this is either a self-originated route or the peer is EBGP.
*/
- if (p->family == AF_INET6 || peer_cap_enhe(peer))
+ if (NEXTHOP_IS_V6)
{
attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
if ((CHECK_FLAG (peer->af_flags[afi][safi],
struct peer_af *paf;
struct peer *peer;
-
paf = THREAD_ARG (t);
peer = paf->peer;
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;
if (!peer->clear_node_queue->thread)
peer_lock (peer);
- if (safi != SAFI_MPLS_VPN)
+ if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP)
bgp_clear_route_table (peer, afi, safi, NULL);
else
for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
*/
for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn;
rn = bgp_route_next (rn))
- if (rn->info)
+ {
+ if (rn->info)
{
- bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN);
- bgp_table_finish ((struct bgp_table **)&(rn->info));
- rn->info = NULL;
- bgp_unlock_node(rn);
+ bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_MPLS_VPN);
+ bgp_table_finish ((struct bgp_table **)&(rn->info));
+ rn->info = NULL;
+ 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);
+ }
+ }
}
}
}
while (pnt < end)
{
+ int badlength;
/* If the NLRI is encoded using addpath then the first 4 bytes are
* the addpath ID. */
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)
{
zlog_err ("%s [Error] Update packet error (wrong prefix length %d)",
peer->host, prefixlen);
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;
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];
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];
attr = binfo->attr;
if (attr)
{
+ /*
+ * 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, "?");
+ break;
+ }
+ }
+ else
+ vty_out(vty, "?");
+ }
/* IPv4 Next Hop */
- if (p->family == AF_INET
- && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
+ else if (p->family == AF_INET || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
{
if (json_paths)
{
vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
}
}
-
#ifdef HAVE_IPV6
/* IPv6 Next Hop */
else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
{
if (use_json)
{
- if (p->family == AF_INET && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
+ if (p->family == AF_INET &&
+ (safi == SAFI_MPLS_VPN ||
+ safi == SAFI_ENCAP ||
+ !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
{
- if (safi == SAFI_MPLS_VPN)
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
json_object_string_add(json_net, "nextHop", inet_ntoa (attr->extra->mp_nexthop_global_in));
else
json_object_string_add(json_net, "nextHop", inet_ntoa (attr->nexthop));
}
else
{
- if (p->family == AF_INET && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
+ if (p->family == AF_INET &&
+ (safi == SAFI_MPLS_VPN ||
+ safi == SAFI_ENCAP ||
+ !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
{
- 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
if (p->family == AF_INET
&& (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
{
- if (safi == SAFI_MPLS_VPN)
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
{
if (json)
json_object_string_add(json_out, "mpNexthopGlobalIn", inet_ntoa (attr->extra->mp_nexthop_global_in));
/* Line2 display Next-hop, Neighbor, Router-id */
/* Display the nexthop */
- if (p->family == AF_INET
- && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
+ if (p->family == AF_INET &&
+ (safi == SAFI_MPLS_VPN ||
+ safi == SAFI_ENCAP ||
+ !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
{
- if (safi == SAFI_MPLS_VPN)
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
{
if (json_paths)
json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->extra->mp_nexthop_global_in));
else
{
vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
- (safi == SAFI_MPLS_VPN ?
+ ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) ?
prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
safi == SAFI_MPLS_VPN ? ":" : "",
inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN),
json_paths = json_object_new_array();
}
- 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))
{
if (header)
{
route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
- AFI_IP, SAFI_MPLS_VPN, json);
-
+ AFI_IP, safi, json);
header = 0;
}
display++;
(pathtype == BGP_PATH_BESTPATH && CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) ||
(pathtype == BGP_PATH_MULTIPATH &&
(CHECK_FLAG (ri->flags, BGP_INFO_MULTIPATH) || CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))))
- route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN, json_paths);
+ route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, safi, json_paths);
}
bgp_unlock_node (rm);
safi = SAFI_MULTICAST;
else if (strncmp (safi_str, "u", 1) == 0)
safi = SAFI_UNICAST;
+ else if (strncmp (safi_str, "e", 1) == 0)
+ safi = SAFI_ENCAP;
else if (strncmp (safi_str, "vpnv4", 5) == 0 || strncmp (safi_str, "vpnv6", 5) == 0)
safi = SAFI_MPLS_VPN;
else
{
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;
}
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 " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast) statistics",
+ "show bgp " BGP_INSTANCE_CMD " (ipv4|ipv6) (unicast|multicast|vpn|encap) statistics",
SHOW_STR
BGP_STR
BGP_INSTANCE_HELP_STR
"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[1], argv[2]);
}
-ALIAS (show_bgp_statistics_view,
- show_bgp_statistics_view_vpnv4_cmd,
- "show bgp " BGP_INSTANCE_CMD " (ipv4) (vpnv4) statistics",
- SHOW_STR
- BGP_STR
- BGP_INSTANCE_HELP_STR
- "Address family\n"
- "Address Family modifier\n"
- "BGP RIB advertisement statistics\n")
-
enum bgp_pcounts
{
PCOUNT_ADJ_IN = 0,
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;
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)
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. */
/* Statistics */
install_element (ENABLE_NODE, &show_bgp_statistics_cmd);
- install_element (ENABLE_NODE, &show_bgp_statistics_vpnv4_cmd);
+ //install_element (ENABLE_NODE, &show_bgp_statistics_vpnv4_cmd);
install_element (ENABLE_NODE, &show_bgp_statistics_view_cmd);
- install_element (ENABLE_NODE, &show_bgp_statistics_view_vpnv4_cmd);
+ //install_element (ENABLE_NODE, &show_bgp_statistics_view_vpnv4_cmd);
/* old command */
install_element (VIEW_NODE, &show_ipv6_bgp_cmd);
table = peer->bgp->rib[afi][safi];
if (safi != SAFI_MPLS_VPN
+ && safi != SAFI_ENCAP
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
subgroup_default_originate (subgrp, 0);
PEER_STATUS_ORF_WAIT_REFRESH))
return;
- if (SUBGRP_SAFI (subgrp) != SAFI_MPLS_VPN)
+ if (SUBGRP_SAFI (subgrp) != SAFI_MPLS_VPN &&
+ SUBGRP_SAFI (subgrp) != SAFI_ENCAP)
subgroup_announce_table (subgrp, NULL);
else
for (rn = bgp_table_top (update_subgroup_rib (subgrp)); rn;
"Address Family Modifier\n"
BGP_SOFT_OUT_STR)
+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",
"Address Family Modifier\n"
BGP_SOFT_OUT_STR)
+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|WORD) soft out",
"Address Family modifier\n"
BGP_SOFT_OUT_STR)
+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",
"Address Family Modifier\n"
BGP_SOFT_IN_STR)
+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",
"Address Family Modifier\n"
BGP_SOFT_IN_STR)
+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|WORD) soft in",
"Address Family modifier\n"
BGP_SOFT_IN_STR)
+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",
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",
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|WORD) 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",
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);
install_element (ENABLE_NODE, &clear_bgp_all_soft_in_cmd);
install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_in_cmd);
install_element (ENABLE_NODE, &clear_bgp_all_in_cmd);
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);
install_element (ENABLE_NODE, &clear_bgp_all_soft_out_cmd);
install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_out_cmd);
install_element (ENABLE_NODE, &clear_bgp_all_out_cmd);
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);
install_element (ENABLE_NODE, &clear_bgp_all_soft_cmd);
install_element (ENABLE_NODE, &clear_bgp_instance_all_soft_cmd);
install_element (ENABLE_NODE, &clear_bgp_peer_soft_cmd);
#include "bfd.h"
#include "hash.h"
#include "jhash.h"
+#include "table.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
#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"
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 */
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;
}
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;
}
bgp_route_map_init ();
bgp_scan_vty_init();
bgp_mplsvpn_init ();
+ bgp_encap_init ();
/* Access list initialize. */
access_list_init ();
BGP_AF_IPV6_UNICAST,
BGP_AF_IPV6_MULTICAST,
BGP_AF_IPV6_VPN,
+ BGP_AF_IPV4_ENCAP,
+ BGP_AF_IPV6_ENCAP,
BGP_AF_MAX
};
case SAFI_MPLS_VPN:
return BGP_AF_IPV4_VPN;
break;
+ case SAFI_ENCAP:
+ return BGP_AF_IPV4_ENCAP;
+ break;
default:
return BGP_AF_MAX;
break;
case SAFI_MPLS_VPN:
return BGP_AF_IPV6_VPN;
break;
+ case SAFI_ENCAP:
+ return BGP_AF_IPV6_ENCAP;
+ break;
default:
return BGP_AF_MAX;
break;
{
if (peer->afc_nego[afi][SAFI_UNICAST]
|| peer->afc_nego[afi][SAFI_MULTICAST]
- || peer->afc_nego[afi][SAFI_MPLS_VPN])
+ || peer->afc_nego[afi][SAFI_MPLS_VPN]
+ || peer->afc_nego[afi][SAFI_ENCAP])
return 1;
return 0;
}
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;
}