mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-01 21:16:26 +00:00
bgpd: encap: add attribute handling
Signed-off-by: Lou Berger <lberger@labn.net> Reviewed-by: David Lamparter <equinox@opensourcerouting.org> (cherry picked from commit c3741789530ee824693fd606356acac2ad695f83) Conflicts: bgpd/Makefile.am bgpd/bgp_attr.c bgpd/bgp_attr.h lib/memtypes.c
This commit is contained in:
parent
eaafc874d0
commit
f4c89855b5
@ -16,7 +16,8 @@ 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_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c
|
||||
bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
|
||||
bgp_encap_tlv.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
bgp_aspath.h bgp_attr.h bgp_community.h bgp_debug.h bgp_fsm.h \
|
||||
@ -24,7 +25,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_nht.h \
|
||||
bgp_updgrp.h bgp_bfd.h
|
||||
bgp_updgrp.h bgp_bfd.h bgp_encap_tlv.h bgp_encap_types.h
|
||||
|
||||
bgpd_SOURCES = bgp_main.c
|
||||
bgpd_LDADD = libbgp.a ../lib/libzebra.la @LIBCAP@ @LIBM@
|
||||
|
324
bgpd/bgp_attr.c
324
bgpd/bgp_attr.c
@ -30,6 +30,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "hash.h"
|
||||
#include "jhash.h"
|
||||
#include "queue.h"
|
||||
#include "table.h"
|
||||
|
||||
#include "bgpd/bgpd.h"
|
||||
#include "bgpd/bgp_attr.h"
|
||||
@ -40,6 +41,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_packet.h"
|
||||
#include "bgpd/bgp_ecommunity.h"
|
||||
#include "bgpd/bgp_updgrp.h"
|
||||
#include "bgp_encap_types.h"
|
||||
|
||||
/* Attribute strings for logging. */
|
||||
static const struct message attr_str [] =
|
||||
@ -63,6 +65,7 @@ static const struct message attr_str [] =
|
||||
{ BGP_ATTR_AS4_PATH, "AS4_PATH" },
|
||||
{ BGP_ATTR_AS4_AGGREGATOR, "AS4_AGGREGATOR" },
|
||||
{ BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT" },
|
||||
{ BGP_ATTR_ENCAP, "ENCAP" },
|
||||
};
|
||||
static const int attr_str_max = array_size(attr_str);
|
||||
|
||||
@ -207,6 +210,105 @@ cluster_finish (void)
|
||||
cluster_hash = NULL;
|
||||
}
|
||||
|
||||
struct bgp_attr_encap_subtlv *
|
||||
encap_tlv_dup(struct bgp_attr_encap_subtlv *orig)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *new;
|
||||
struct bgp_attr_encap_subtlv *tail;
|
||||
struct bgp_attr_encap_subtlv *p;
|
||||
|
||||
for (p = orig, tail = new = NULL; p; p = p->next) {
|
||||
int size = sizeof(struct bgp_attr_encap_subtlv) - 1 + p->length;
|
||||
if (tail) {
|
||||
tail->next = XCALLOC(MTYPE_ENCAP_TLV, size);
|
||||
tail = tail->next;
|
||||
} else {
|
||||
tail = new = XCALLOC(MTYPE_ENCAP_TLV, size);
|
||||
}
|
||||
assert(tail);
|
||||
memcpy(tail, p, size);
|
||||
tail->next = NULL;
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static void
|
||||
encap_free(struct bgp_attr_encap_subtlv *p)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *next;
|
||||
while (p) {
|
||||
next = p->next;
|
||||
p->next = NULL;
|
||||
XFREE(MTYPE_ENCAP_TLV, p);
|
||||
p = next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bgp_attr_flush_encap(struct attr *attr)
|
||||
{
|
||||
if (!attr || !attr->extra)
|
||||
return;
|
||||
|
||||
if (attr->extra->encap_subtlvs) {
|
||||
encap_free(attr->extra->encap_subtlvs);
|
||||
attr->extra->encap_subtlvs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare encap sub-tlv chains
|
||||
*
|
||||
* 1 = equivalent
|
||||
* 0 = not equivalent
|
||||
*
|
||||
* This algorithm could be made faster if needed
|
||||
*/
|
||||
static int
|
||||
encap_same(struct bgp_attr_encap_subtlv *h1, struct bgp_attr_encap_subtlv *h2)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *p;
|
||||
struct bgp_attr_encap_subtlv *q;
|
||||
|
||||
if (!h1 && !h2)
|
||||
return 1;
|
||||
if (h1 && !h2)
|
||||
return 0;
|
||||
if (!h1 && h2)
|
||||
return 0;
|
||||
if (h1 == h2)
|
||||
return 1;
|
||||
|
||||
for (p = h1; p; p = p->next) {
|
||||
for (q = h2; q; q = q->next) {
|
||||
if ((p->type == q->type) &&
|
||||
(p->length == q->length) &&
|
||||
!memcmp(p->value, q->value, p->length)) {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!q)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = h2; p; p = p->next) {
|
||||
for (q = h1; q; q = q->next) {
|
||||
if ((p->type == q->type) &&
|
||||
(p->length == q->length) &&
|
||||
!memcmp(p->value, q->value, p->length)) {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!q)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Unknown transit attribute. */
|
||||
static struct hash *transit_hash;
|
||||
|
||||
@ -314,6 +416,10 @@ bgp_attr_extra_free (struct attr *attr)
|
||||
{
|
||||
if (attr->extra)
|
||||
{
|
||||
if (attr->extra->encap_subtlvs) {
|
||||
encap_free(attr->extra->encap_subtlvs);
|
||||
attr->extra->encap_subtlvs = NULL;
|
||||
}
|
||||
XFREE (MTYPE_ATTR_EXTRA, attr->extra);
|
||||
attr->extra = NULL;
|
||||
}
|
||||
@ -349,13 +455,20 @@ bgp_attr_dup (struct attr *new, struct attr *orig)
|
||||
{
|
||||
new->extra = extra;
|
||||
memset(new->extra, 0, sizeof(struct attr_extra));
|
||||
if (orig->extra)
|
||||
if (orig->extra) {
|
||||
*new->extra = *orig->extra;
|
||||
if (orig->extra->encap_subtlvs) {
|
||||
new->extra->encap_subtlvs = encap_tlv_dup(orig->extra->encap_subtlvs);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (orig->extra)
|
||||
{
|
||||
new->extra = bgp_attr_extra_new();
|
||||
*new->extra = *orig->extra;
|
||||
if (orig->extra->encap_subtlvs) {
|
||||
new->extra->encap_subtlvs = encap_tlv_dup(orig->extra->encap_subtlvs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,6 +608,8 @@ attrhash_cmp (const void *p1, const void *p2)
|
||||
&& ae1->ecommunity == ae2->ecommunity
|
||||
&& ae1->cluster == ae2->cluster
|
||||
&& ae1->transit == ae2->transit
|
||||
&& (ae1->encap_tunneltype == ae2->encap_tunneltype)
|
||||
&& encap_same(ae1->encap_subtlvs, ae2->encap_subtlvs)
|
||||
&& IPV4_ADDR_SAME (&ae1->originator_id, &ae2->originator_id))
|
||||
return 1;
|
||||
else if (ae1 || ae2)
|
||||
@ -549,6 +664,10 @@ bgp_attr_hash_alloc (void *p)
|
||||
{
|
||||
attr->extra = bgp_attr_extra_new ();
|
||||
*attr->extra = *val->extra;
|
||||
|
||||
if (attr->extra->encap_subtlvs) {
|
||||
attr->extra->encap_subtlvs = encap_tlv_dup(attr->extra->encap_subtlvs);
|
||||
}
|
||||
}
|
||||
attr->refcnt = 0;
|
||||
return attr;
|
||||
@ -673,6 +792,9 @@ bgp_attr_default_intern (u_char origin)
|
||||
struct attr attr;
|
||||
struct attr *new;
|
||||
|
||||
memset (&attr, 0, sizeof (struct attr));
|
||||
bgp_attr_extra_get (&attr);
|
||||
|
||||
bgp_attr_default_set(&attr, origin);
|
||||
|
||||
new = bgp_attr_intern (&attr);
|
||||
@ -814,6 +936,8 @@ bgp_attr_flush (struct attr *attr)
|
||||
cluster_free (attre->cluster);
|
||||
if (attre->transit && ! attre->transit->refcnt)
|
||||
transit_free (attre->transit);
|
||||
encap_free(attre->encap_subtlvs);
|
||||
attre->encap_subtlvs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1771,6 +1895,118 @@ bgp_attr_ext_communities (struct bgp_attr_parser_args *args)
|
||||
return BGP_ATTR_PARSE_PROCEED;
|
||||
}
|
||||
|
||||
/* Parse Tunnel Encap attribute in an UPDATE */
|
||||
static int
|
||||
bgp_attr_encap(
|
||||
uint8_t type,
|
||||
struct peer *peer, /* IN */
|
||||
bgp_size_t length, /* IN: attr's length field */
|
||||
struct attr *attr, /* IN: caller already allocated */
|
||||
u_char flag, /* IN: attr's flags field */
|
||||
u_char *startp)
|
||||
{
|
||||
bgp_size_t total;
|
||||
struct attr_extra *attre = NULL;
|
||||
struct bgp_attr_encap_subtlv *stlv_last = NULL;
|
||||
uint16_t tunneltype;
|
||||
|
||||
total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
|
||||
|
||||
if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
|
||||
|| !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL))
|
||||
{
|
||||
zlog_info ("Tunnel Encap attribute flag isn't optional and transitive %d", flag);
|
||||
bgp_notify_send_with_data (peer,
|
||||
BGP_NOTIFY_UPDATE_ERR,
|
||||
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
|
||||
startp, total);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (BGP_ATTR_ENCAP == type) {
|
||||
/* read outer TLV type and length */
|
||||
uint16_t tlv_length;
|
||||
|
||||
if (length < 4) {
|
||||
zlog_info ("Tunnel Encap attribute not long enough to contain outer T,L");
|
||||
bgp_notify_send_with_data(peer,
|
||||
BGP_NOTIFY_UPDATE_ERR,
|
||||
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
|
||||
startp, total);
|
||||
return -1;
|
||||
}
|
||||
tunneltype = stream_getw (BGP_INPUT (peer));
|
||||
tlv_length = stream_getw (BGP_INPUT (peer));
|
||||
length -= 4;
|
||||
|
||||
if (tlv_length != length) {
|
||||
zlog_info ("%s: tlv_length(%d) != length(%d)",
|
||||
__func__, tlv_length, length);
|
||||
}
|
||||
}
|
||||
|
||||
while (length >= 4) {
|
||||
uint16_t subtype;
|
||||
uint16_t sublength;
|
||||
struct bgp_attr_encap_subtlv *tlv;
|
||||
|
||||
subtype = stream_getw (BGP_INPUT (peer));
|
||||
sublength = stream_getw (BGP_INPUT (peer));
|
||||
length -= 4;
|
||||
|
||||
if (sublength > length) {
|
||||
zlog_info ("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
|
||||
sublength, length);
|
||||
bgp_notify_send_with_data (peer,
|
||||
BGP_NOTIFY_UPDATE_ERR,
|
||||
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
|
||||
startp, total);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* alloc and copy sub-tlv */
|
||||
/* TBD make sure these are freed when attributes are released */
|
||||
tlv = XCALLOC (MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv)-1+sublength);
|
||||
tlv->type = subtype;
|
||||
tlv->length = sublength;
|
||||
stream_get(tlv->value, peer->ibuf, sublength);
|
||||
length -= sublength;
|
||||
|
||||
/* attach tlv to encap chain */
|
||||
if (!attre) {
|
||||
attre = bgp_attr_extra_get(attr);
|
||||
if (BGP_ATTR_ENCAP == type) {
|
||||
for (stlv_last = attre->encap_subtlvs; stlv_last && stlv_last->next;
|
||||
stlv_last = stlv_last->next);
|
||||
if (stlv_last) {
|
||||
stlv_last->next = tlv;
|
||||
} else {
|
||||
attre->encap_subtlvs = tlv;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stlv_last->next = tlv;
|
||||
}
|
||||
stlv_last = tlv;
|
||||
}
|
||||
|
||||
if (attre && (BGP_ATTR_ENCAP == type)) {
|
||||
attre->encap_tunneltype = tunneltype;
|
||||
}
|
||||
|
||||
if (length) {
|
||||
/* spurious leftover data */
|
||||
zlog_info ("Tunnel Encap attribute length is bad: %d leftover octets", length);
|
||||
bgp_notify_send_with_data (peer,
|
||||
BGP_NOTIFY_UPDATE_ERR,
|
||||
BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
|
||||
startp, total);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* BGP unknown attribute treatment. */
|
||||
static bgp_attr_parse_ret_t
|
||||
bgp_attr_unknown (struct bgp_attr_parser_args *args)
|
||||
@ -2060,6 +2296,9 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
|
||||
case BGP_ATTR_EXT_COMMUNITIES:
|
||||
ret = bgp_attr_ext_communities (&attr_args);
|
||||
break;
|
||||
case BGP_ATTR_ENCAP:
|
||||
ret = bgp_attr_encap (type, peer, length, attr, flag, startp);
|
||||
break;
|
||||
default:
|
||||
ret = bgp_attr_unknown (&attr_args);
|
||||
break;
|
||||
@ -2316,6 +2555,89 @@ bgp_packet_mpattr_prefix_size (afi_t afi, safi_t safi, struct prefix *p)
|
||||
return size;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Encodes the tunnel encapsulation attribute
|
||||
*/
|
||||
static void
|
||||
bgp_packet_mpattr_tea(
|
||||
struct bgp *bgp,
|
||||
struct peer *peer,
|
||||
struct stream *s,
|
||||
struct attr *attr,
|
||||
uint8_t attrtype)
|
||||
{
|
||||
unsigned int attrlenfield = 0;
|
||||
struct bgp_attr_encap_subtlv *subtlvs;
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
const char *attrname;
|
||||
|
||||
if (!attr || !attr->extra)
|
||||
return;
|
||||
|
||||
switch (attrtype) {
|
||||
case BGP_ATTR_ENCAP:
|
||||
attrname = "Tunnel Encap";
|
||||
subtlvs = attr->extra->encap_subtlvs;
|
||||
|
||||
/*
|
||||
* The tunnel encap attr has an "outer" tlv.
|
||||
* T = tunneltype,
|
||||
* L = total length of subtlvs,
|
||||
* V = concatenated subtlvs.
|
||||
*/
|
||||
attrlenfield = 2 + 2; /* T + L */
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
/* compute attr length */
|
||||
for (st = subtlvs; st; st = st->next) {
|
||||
attrlenfield += (4 + 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,
|
||||
attrlenfield);
|
||||
return;
|
||||
}
|
||||
|
||||
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, attrtype);
|
||||
stream_putw (s, attrlenfield & 0xffff);
|
||||
} else {
|
||||
/* 1-octet length field */
|
||||
stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL);
|
||||
stream_putc (s, attrtype);
|
||||
stream_putc (s, attrlenfield & 0xff);
|
||||
}
|
||||
|
||||
if (attrtype == BGP_ATTR_ENCAP) {
|
||||
/* write outer T+L */
|
||||
stream_putw(s, attr->extra->encap_tunneltype);
|
||||
stream_putw(s, attrlenfield - 4);
|
||||
}
|
||||
|
||||
/* write each sub-tlv */
|
||||
for (st = subtlvs; st; st = st->next) {
|
||||
stream_putw (s, st->type);
|
||||
stream_putw (s, st->length);
|
||||
stream_put (s, st->value, st->length);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
bgp_packet_mpattr_end (struct stream *s, size_t sizep)
|
||||
{
|
||||
|
@ -55,6 +55,14 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#define BGP_ATTR_NHLEN_VPNV6_GLOBAL 8+IPV6_MAX_BYTELEN
|
||||
#define BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL ((8+IPV6_MAX_BYTELEN) * 2)
|
||||
|
||||
|
||||
struct bgp_attr_encap_subtlv {
|
||||
struct bgp_attr_encap_subtlv *next; /* for chaining */
|
||||
uint16_t type;
|
||||
uint16_t length;
|
||||
uint8_t value[1]; /* will be extended */
|
||||
};
|
||||
|
||||
/* Additional/uncommon BGP attributes.
|
||||
* lazily allocated as and when a struct attr
|
||||
* requires it.
|
||||
@ -93,6 +101,9 @@ struct attr_extra
|
||||
|
||||
/* route tag */
|
||||
u_short tag;
|
||||
|
||||
uint16_t encap_tunneltype; /* grr */
|
||||
struct bgp_attr_encap_subtlv *encap_subtlvs; /* rfc5512 */
|
||||
};
|
||||
|
||||
/* BGP core attribute structure. */
|
||||
@ -225,6 +236,12 @@ extern int bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
|
||||
extern int bgp_mp_unreach_parse (struct bgp_attr_parser_args *args,
|
||||
struct bgp_nlri *);
|
||||
|
||||
extern struct bgp_attr_encap_subtlv *
|
||||
encap_tlv_dup(struct bgp_attr_encap_subtlv *orig);
|
||||
|
||||
extern void
|
||||
bgp_attr_flush_encap(struct attr *attr);
|
||||
|
||||
/**
|
||||
* Set of functions to encode MP_REACH_NLRI and MP_UNREACH_NLRI attributes.
|
||||
* Typical call sequence is to call _start(), followed by multiple _prefix(),
|
||||
|
874
bgpd/bgp_encap_tlv.c
Normal file
874
bgpd/bgp_encap_tlv.c
Normal file
@ -0,0 +1,874 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <zebra.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "prefix.h"
|
||||
#include "vty.h"
|
||||
#include "filter.h"
|
||||
|
||||
#include "bgpd.h"
|
||||
#include "bgp_attr.h"
|
||||
|
||||
#include "bgp_encap_types.h"
|
||||
#include "bgp_encap_tlv.h"
|
||||
|
||||
/***********************************************************************
|
||||
* SUBTLV ENCODE
|
||||
***********************************************************************/
|
||||
|
||||
/* rfc5512 4.1 */
|
||||
static struct bgp_attr_encap_subtlv *
|
||||
subtlv_encode_encap_l2tpv3_over_ip(
|
||||
struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *new;
|
||||
uint8_t *p;
|
||||
int total = 4 + st->cookie_length;
|
||||
|
||||
/* sanity check */
|
||||
assert(st->cookie_length <= sizeof(st->cookie));
|
||||
assert(total <= 0xff);
|
||||
|
||||
new = XCALLOC(MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv) - 1 + total);
|
||||
assert(new);
|
||||
new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
|
||||
new->length = total;
|
||||
p = new->value;
|
||||
|
||||
*p++ = (st->sessionid & 0xff000000) >> 24;
|
||||
*p++ = (st->sessionid & 0xff0000) >> 16;
|
||||
*p++ = (st->sessionid & 0xff00) >> 8;
|
||||
*p++ = (st->sessionid & 0xff);
|
||||
memcpy(p, st->cookie, st->cookie_length);
|
||||
return new;
|
||||
}
|
||||
|
||||
/* rfc5512 4.1 */
|
||||
static struct bgp_attr_encap_subtlv *
|
||||
subtlv_encode_encap_gre(
|
||||
struct bgp_tea_subtlv_encap_gre_key *st)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *new;
|
||||
uint8_t *p;
|
||||
int total = 4;
|
||||
|
||||
assert(total <= 0xff);
|
||||
|
||||
new = XCALLOC(MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv) - 1 + total);
|
||||
assert(new);
|
||||
new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
|
||||
new->length = total;
|
||||
p = new->value;
|
||||
|
||||
*p++ = (st->gre_key & 0xff000000) >> 24;
|
||||
*p++ = (st->gre_key & 0xff0000) >> 16;
|
||||
*p++ = (st->gre_key & 0xff00) >> 8;
|
||||
*p++ = (st->gre_key & 0xff);
|
||||
return new;
|
||||
}
|
||||
|
||||
static struct bgp_attr_encap_subtlv *
|
||||
subtlv_encode_encap_pbb(
|
||||
struct bgp_tea_subtlv_encap_pbb *st)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *new;
|
||||
uint8_t *p;
|
||||
int total = 1 + 3 + 6 + 2; /* flags + isid + madaddr + vid */
|
||||
|
||||
assert(total <= 0xff);
|
||||
|
||||
new = XCALLOC(MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv) - 1 + total);
|
||||
assert(new);
|
||||
new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
|
||||
new->length = total;
|
||||
p = new->value;
|
||||
|
||||
*p++ = (st->flag_isid? 0x80: 0) |
|
||||
(st->flag_vid? 0x40: 0) |
|
||||
0;
|
||||
if (st->flag_isid) {
|
||||
*p = (st->isid & 0xff0000) >> 16;
|
||||
*(p+1) = (st->isid & 0xff00) >> 8;
|
||||
*(p+2) = (st->isid & 0xff);
|
||||
}
|
||||
p += 3;
|
||||
memcpy(p, st->macaddr, 6);
|
||||
p += 6;
|
||||
if (st->flag_vid) {
|
||||
*p++ = (st->vid & 0xf00) >> 8;
|
||||
*p++ = st->vid & 0xff;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
/* rfc5512 4.2 */
|
||||
static struct bgp_attr_encap_subtlv *
|
||||
subtlv_encode_proto_type(
|
||||
struct bgp_tea_subtlv_proto_type *st)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *new;
|
||||
uint8_t *p;
|
||||
int total = 2;
|
||||
|
||||
assert(total <= 0xff);
|
||||
|
||||
new = XCALLOC(MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv) - 1 + total);
|
||||
assert(new);
|
||||
new->type = BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE;
|
||||
new->length = total;
|
||||
p = new->value;
|
||||
|
||||
*p++ = (st->proto & 0xff00) >> 8;
|
||||
*p++ = (st->proto & 0xff);
|
||||
return new;
|
||||
}
|
||||
|
||||
/* rfc5512 4.3 */
|
||||
static struct bgp_attr_encap_subtlv *
|
||||
subtlv_encode_color(
|
||||
struct bgp_tea_subtlv_color *st)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *new;
|
||||
uint8_t *p;
|
||||
int total = 8;
|
||||
|
||||
assert(total <= 0xff);
|
||||
|
||||
new = XCALLOC(MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv) - 1 + total);
|
||||
assert(new);
|
||||
new->type = BGP_ENCAP_SUBTLV_TYPE_COLOR;
|
||||
new->length = total;
|
||||
p = new->value;
|
||||
|
||||
*p++ = 0x03; /* transitive*/
|
||||
*p++ = 0x0b;
|
||||
*p++ = 0; /* reserved */
|
||||
*p++ = 0; /* reserved */
|
||||
|
||||
*p++ = (st->color & 0xff000000) >> 24;
|
||||
*p++ = (st->color & 0xff0000) >> 16;
|
||||
*p++ = (st->color & 0xff00) >> 8;
|
||||
*p++ = (st->color & 0xff);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/* rfc 5566 4. */
|
||||
static struct bgp_attr_encap_subtlv *
|
||||
subtlv_encode_ipsec_ta(
|
||||
struct bgp_tea_subtlv_ipsec_ta *st)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *new;
|
||||
uint8_t *p;
|
||||
int total = 2 + st->authenticator_length;
|
||||
|
||||
/* sanity check */
|
||||
assert(st->authenticator_length <= sizeof(st->value));
|
||||
assert(total <= 0xff);
|
||||
|
||||
new = XCALLOC(MTYPE_ENCAP_TLV, sizeof(struct bgp_attr_encap_subtlv) - 1 + total);
|
||||
assert(new);
|
||||
new->type = BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA;
|
||||
new->length = total;
|
||||
p = new->value;
|
||||
|
||||
*p++ = (st->authenticator_type & 0xff00) >> 8;
|
||||
*p++ = st->authenticator_type & 0xff;
|
||||
memcpy(p, st->value, st->authenticator_length);
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TUNNEL TYPE-SPECIFIC TLV ENCODE
|
||||
***********************************************************************/
|
||||
|
||||
/*
|
||||
* requires "extra" and "last" to be defined in caller
|
||||
*/
|
||||
#define ENC_SUBTLV(flag, function, field) do {\
|
||||
struct bgp_attr_encap_subtlv *new;\
|
||||
if (CHECK_FLAG(bet->valid_subtlvs, (flag))) {\
|
||||
new = function(&bet->field);\
|
||||
if (last) {\
|
||||
last->next = new;\
|
||||
} else {\
|
||||
extra->encap_subtlvs = new;\
|
||||
}\
|
||||
last = new;\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
void
|
||||
bgp_encap_type_l2tpv3overip_to_tlv(
|
||||
struct bgp_encap_type_l2tpv3_over_ip *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
struct bgp_attr_encap_subtlv *last;
|
||||
|
||||
/* advance to last subtlv */
|
||||
for (last = extra->encap_subtlvs; last && last->next; last = last->next);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_L2TPV3_OVER_IP;
|
||||
|
||||
assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_gre_to_tlv(
|
||||
struct bgp_encap_type_gre *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
struct bgp_attr_encap_subtlv *last;
|
||||
|
||||
/* advance to last subtlv */
|
||||
for (last = extra->encap_subtlvs; last && last->next; last = last->next);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_GRE;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_ip_in_ip_to_tlv(
|
||||
struct bgp_encap_type_ip_in_ip *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
struct bgp_attr_encap_subtlv *last;
|
||||
|
||||
/* advance to last subtlv */
|
||||
for (last = extra->encap_subtlvs; last && last->next; last = last->next);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_IP_IN_IP;
|
||||
|
||||
ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type, st_proto);
|
||||
ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_transmit_tunnel_endpoint(
|
||||
struct bgp_encap_type_transmit_tunnel_endpoint *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
struct bgp_attr_encap_subtlv *last;
|
||||
|
||||
/* advance to last subtlv */
|
||||
for (last = extra->encap_subtlvs; last && last->next; last = last->next);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT;
|
||||
|
||||
/* no subtlvs for this type */
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
|
||||
struct bgp_encap_type_ipsec_in_tunnel_mode *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
struct bgp_attr_encap_subtlv *last;
|
||||
|
||||
/* advance to last subtlv */
|
||||
for (last = extra->encap_subtlvs; last && last->next; last = last->next);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE;
|
||||
|
||||
ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta, st_ipsec_ta);
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
|
||||
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
struct bgp_attr_encap_subtlv *last;
|
||||
|
||||
/* advance to last subtlv */
|
||||
for (last = extra->encap_subtlvs; last && last->next; last = last->next);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
|
||||
|
||||
ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta, st_ipsec_ta);
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
|
||||
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
struct bgp_attr_encap_subtlv *last;
|
||||
|
||||
/* advance to last subtlv */
|
||||
for (last = extra->encap_subtlvs; last && last->next; last = last->next);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
|
||||
|
||||
ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta, st_ipsec_ta);
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_pbb_to_tlv(
|
||||
struct bgp_encap_type_pbb *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
struct bgp_attr_encap_subtlv *last;
|
||||
|
||||
/* advance to last subtlv */
|
||||
for (last = extra->encap_subtlvs; last && last->next; last = last->next);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_PBB;
|
||||
|
||||
assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
|
||||
ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_pbb, st_encap);
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_vxlan_to_tlv(
|
||||
struct bgp_encap_type_vxlan *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN;
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_nvgre_to_tlv(
|
||||
struct bgp_encap_type_nvgre *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_NVGRE;
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_mpls_to_tlv(
|
||||
struct bgp_encap_type_mpls *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS;
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_mpls_in_gre_to_tlv(
|
||||
struct bgp_encap_type_mpls_in_gre *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_GRE;
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_vxlan_gpe_to_tlv(
|
||||
struct bgp_encap_type_vxlan_gpe *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN_GPE;
|
||||
}
|
||||
|
||||
void
|
||||
bgp_encap_type_mpls_in_udp_to_tlv(
|
||||
struct bgp_encap_type_mpls_in_udp *bet, /* input structure */
|
||||
struct attr *attr)
|
||||
{
|
||||
struct attr_extra *extra = bgp_attr_extra_get(attr);
|
||||
|
||||
extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_UDP;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SUBTLV DECODE
|
||||
***********************************************************************/
|
||||
/* rfc5512 4.1 */
|
||||
static int
|
||||
subtlv_decode_encap_l2tpv3_over_ip(
|
||||
struct bgp_attr_encap_subtlv *subtlv,
|
||||
struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
|
||||
{
|
||||
if (subtlv->length < 4) {
|
||||
zlog_debug("%s, subtlv length %d is less than 4",
|
||||
__func__, subtlv->length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
st->sessionid = (subtlv->value[0] << 24) |
|
||||
(subtlv->value[1] << 16) |
|
||||
(subtlv->value[2] << 8) |
|
||||
subtlv->value[3];
|
||||
st->cookie_length = subtlv->length - 4;
|
||||
if (st->cookie_length > sizeof(st->cookie)) {
|
||||
zlog_debug("%s, subtlv length %d is greater than %d",
|
||||
__func__, st->cookie_length, (int)sizeof(st->cookie));
|
||||
return -1;
|
||||
}
|
||||
memcpy(st->cookie, subtlv->value + 4, st->cookie_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rfc5512 4.1 */
|
||||
static int
|
||||
subtlv_decode_encap_gre(
|
||||
struct bgp_attr_encap_subtlv *subtlv,
|
||||
struct bgp_tea_subtlv_encap_gre_key *st)
|
||||
{
|
||||
if (subtlv->length != 4) {
|
||||
zlog_debug("%s, subtlv length %d does not equal 4",
|
||||
__func__, subtlv->length);
|
||||
return -1;
|
||||
}
|
||||
st->gre_key = (subtlv->value[0] << 24) |
|
||||
(subtlv->value[1] << 16) |
|
||||
(subtlv->value[2] << 8) |
|
||||
subtlv->value[3];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
subtlv_decode_encap_pbb(
|
||||
struct bgp_attr_encap_subtlv *subtlv,
|
||||
struct bgp_tea_subtlv_encap_pbb *st)
|
||||
{
|
||||
if (subtlv->length != 1 + 3 + 6 + 2) {
|
||||
zlog_debug("%s, subtlv length %d does not equal %d",
|
||||
__func__, subtlv->length, 1 + 3 + 6 + 2);
|
||||
return -1;
|
||||
}
|
||||
if (subtlv->value[0] & 0x80) {
|
||||
st->flag_isid = 1;
|
||||
st->isid = (subtlv->value[1] << 16) |
|
||||
(subtlv->value[2] << 8) |
|
||||
subtlv->value[3];
|
||||
}
|
||||
if (subtlv->value[0] & 0x40) {
|
||||
st->flag_vid = 1;
|
||||
st->vid = ((subtlv->value[10] & 0x0f) << 8) | subtlv->value[11];
|
||||
}
|
||||
memcpy(st->macaddr, subtlv->value + 4, 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rfc5512 4.2 */
|
||||
static int
|
||||
subtlv_decode_proto_type(
|
||||
struct bgp_attr_encap_subtlv *subtlv,
|
||||
struct bgp_tea_subtlv_proto_type *st)
|
||||
{
|
||||
if (subtlv->length != 2) {
|
||||
zlog_debug("%s, subtlv length %d does not equal 2",
|
||||
__func__, subtlv->length);
|
||||
return -1;
|
||||
}
|
||||
st->proto = (subtlv->value[0] << 8) | subtlv->value[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rfc5512 4.3 */
|
||||
static int
|
||||
subtlv_decode_color(
|
||||
struct bgp_attr_encap_subtlv *subtlv,
|
||||
struct bgp_tea_subtlv_color *st)
|
||||
{
|
||||
if (subtlv->length != 8) {
|
||||
zlog_debug("%s, subtlv length %d does not equal 8",
|
||||
__func__, subtlv->length);
|
||||
return -1;
|
||||
}
|
||||
if ((subtlv->value[0] != 0x03) ||
|
||||
(subtlv->value[1] != 0x0b) ||
|
||||
(subtlv->value[2] != 0) ||
|
||||
(subtlv->value[3] != 0)) {
|
||||
zlog_debug("%s, subtlv value 1st 4 bytes are not 0x030b0000", __func__);
|
||||
return -1;
|
||||
}
|
||||
st->color = (subtlv->value[4] << 24) |
|
||||
(subtlv->value[5] << 16) |
|
||||
(subtlv->value[6] << 8) |
|
||||
subtlv->value[7];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rfc 5566 4. */
|
||||
static int
|
||||
subtlv_decode_ipsec_ta(
|
||||
struct bgp_attr_encap_subtlv *subtlv,
|
||||
struct bgp_tea_subtlv_ipsec_ta *st)
|
||||
{
|
||||
st->authenticator_length = subtlv->length - 2;
|
||||
if (st->authenticator_length > sizeof(st->value)) {
|
||||
zlog_debug("%s, authenticator length %d exceeds storage maximum %d",
|
||||
__func__, st->authenticator_length, (int)sizeof(st->value));
|
||||
return -1;
|
||||
}
|
||||
st->authenticator_type = (subtlv->value[0] << 8) | subtlv->value[1];
|
||||
memcpy(st->value, subtlv->value + 2, st->authenticator_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* TUNNEL TYPE-SPECIFIC TLV DECODE
|
||||
***********************************************************************/
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_l2tpv3overip(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_l2tpv3_over_ip *bet) /* caller-allocated */
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
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;
|
||||
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;
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_SUBTLV_TYPE_COLOR:
|
||||
rc |= subtlv_decode_color(st, &bet->st_color);
|
||||
bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_gre(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_gre *bet) /* caller-allocated */
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
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;
|
||||
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;
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_SUBTLV_TYPE_COLOR:
|
||||
rc |= subtlv_decode_color(st, &bet->st_color);
|
||||
bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_ip_in_ip(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_ip_in_ip *bet) /* caller-allocated */
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
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;
|
||||
break;
|
||||
|
||||
case BGP_ENCAP_SUBTLV_TYPE_COLOR:
|
||||
rc |= subtlv_decode_color(st, &bet->st_color);
|
||||
bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_transmit_tunnel_endpoint *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
switch (st->type) {
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_ipsec_in_tunnel_mode *bet) /* caller-allocated */
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
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;
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
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;
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
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;
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_vxlan(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_vxlan *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
switch (st->type) {
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_nvgre(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_nvgre *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
switch (st->type) {
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_mpls(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
switch (st->type) {
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_mpls_in_gre(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls_in_gre *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
switch (st->type) {
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_vxlan_gpe(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_vxlan_gpe *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
switch (st->type) {
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_mpls_in_udp(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls_in_udp *bet)
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
switch (st->type) {
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
tlv_to_bgp_encap_type_pbb(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_pbb *bet) /* caller-allocated */
|
||||
{
|
||||
struct bgp_attr_encap_subtlv *st;
|
||||
int rc = 0;
|
||||
|
||||
for (st = stlv; st; st = st->next) {
|
||||
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;
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
|
||||
rc |= -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
177
bgpd/bgp_encap_tlv.h
Normal file
177
bgpd/bgp_encap_tlv.h
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright 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_TLV_H
|
||||
#define _QUAGGA_BGP_ENCAP_TLV_H
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TUNNEL TYPE-SPECIFIC TLV ENCODE
|
||||
***********************************************************************/
|
||||
|
||||
extern void
|
||||
bgp_encap_type_l2tpv3overip_to_tlv(
|
||||
struct bgp_encap_type_l2tpv3_over_ip *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_gre_to_tlv(
|
||||
struct bgp_encap_type_gre *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_ip_in_ip_to_tlv(
|
||||
struct bgp_encap_type_ip_in_ip *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_transmit_tunnel_endpoint(
|
||||
struct bgp_encap_type_transmit_tunnel_endpoint *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
|
||||
struct bgp_encap_type_ipsec_in_tunnel_mode *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
|
||||
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
|
||||
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_pbb_to_tlv(
|
||||
struct bgp_encap_type_pbb *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_vxlan_to_tlv(
|
||||
struct bgp_encap_type_vxlan *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_nvgre_to_tlv(
|
||||
struct bgp_encap_type_nvgre *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_mpls_to_tlv(
|
||||
struct bgp_encap_type_mpls *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_mpls_in_gre_to_tlv(
|
||||
struct bgp_encap_type_mpls_in_gre *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_vxlan_gpe_to_tlv(
|
||||
struct bgp_encap_type_vxlan_gpe *bet,
|
||||
struct attr *attr);
|
||||
|
||||
extern void
|
||||
bgp_encap_type_mpls_in_udp_to_tlv(
|
||||
struct bgp_encap_type_mpls_in_udp *bet,
|
||||
struct attr *attr);
|
||||
|
||||
/***********************************************************************
|
||||
* TUNNEL TYPE-SPECIFIC TLV DECODE
|
||||
***********************************************************************/
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_l2tpv3overip(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_l2tpv3_over_ip *bet); /* caller-allocated */
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_gre(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_gre *bet); /* caller-allocated */
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_ip_in_ip(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_ip_in_ip *bet); /* caller-allocated */
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_transmit_tunnel_endpoint *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_ipsec_in_tunnel_mode *bet); /* caller-allocated */
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_vxlan(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_vxlan *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_nvgre(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_nvgre *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_mpls(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_mpls(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_mpls_in_gre(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls_in_gre *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_vxlan_gpe(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_vxlan_gpe *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_mpls_in_udp(
|
||||
struct bgp_attr_encap_subtlv *stlv,
|
||||
struct bgp_encap_type_mpls_in_udp *bet);
|
||||
|
||||
extern int
|
||||
tlv_to_bgp_encap_type_pbb(
|
||||
struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
|
||||
struct bgp_encap_type_pbb *bet); /* caller-allocated */
|
||||
|
||||
#endif /* _QUAGGA_BGP_ENCAP_TLV_H */
|
174
bgpd/bgp_encap_types.h
Normal file
174
bgpd/bgp_encap_types.h
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 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_TYPES_H
|
||||
#define _QUAGGA_BGP_ENCAP_TYPES_H
|
||||
|
||||
/* from http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#tunnel-types */
|
||||
typedef enum {
|
||||
BGP_ENCAP_TYPE_RESERVED=0,
|
||||
BGP_ENCAP_TYPE_L2TPV3_OVER_IP=1,
|
||||
BGP_ENCAP_TYPE_GRE=2,
|
||||
BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT=3,
|
||||
BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE=4,
|
||||
BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE=5,
|
||||
BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE=6,
|
||||
BGP_ENCAP_TYPE_IP_IN_IP=7,
|
||||
BGP_ENCAP_TYPE_VXLAN=8,
|
||||
BGP_ENCAP_TYPE_NVGRE=9,
|
||||
BGP_ENCAP_TYPE_MPLS=10,
|
||||
BGP_ENCAP_TYPE_MPLS_IN_GRE=11,
|
||||
BGP_ENCAP_TYPE_VXLAN_GPE=12,
|
||||
BGP_ENCAP_TYPE_MPLS_IN_UDP=13,
|
||||
BGP_ENCAP_TYPE_PBB
|
||||
} bgp_encap_types;
|
||||
|
||||
typedef enum {
|
||||
BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION=1,
|
||||
BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE=2,
|
||||
BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA=3,
|
||||
BGP_ENCAP_SUBTLV_TYPE_COLOR=4,
|
||||
} bgp_encap_subtlv_types;
|
||||
|
||||
/*
|
||||
* Tunnel Encapsulation Attribute subtlvs
|
||||
*/
|
||||
struct bgp_tea_subtlv_encap_l2tpv3_over_ip {
|
||||
uint32_t sessionid;
|
||||
uint8_t cookie_length;
|
||||
uint8_t cookie[8];
|
||||
};
|
||||
|
||||
struct bgp_tea_subtlv_encap_gre_key {
|
||||
uint32_t gre_key;
|
||||
};
|
||||
|
||||
struct bgp_tea_subtlv_encap_pbb {
|
||||
uint32_t flag_isid:1;
|
||||
uint32_t flag_vid:1;
|
||||
uint32_t isid:24;
|
||||
uint16_t vid:12;
|
||||
uint8_t macaddr[6];
|
||||
};
|
||||
|
||||
struct bgp_tea_subtlv_proto_type {
|
||||
uint16_t proto; /* ether-type */
|
||||
};
|
||||
|
||||
struct bgp_tea_subtlv_color {
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
/*
|
||||
* 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_ENCAP_SUBTLV_IPSEC_TA_SIZE 20
|
||||
|
||||
struct bgp_tea_subtlv_ipsec_ta {
|
||||
uint16_t authenticator_type; /* only type 1 is supported so far */
|
||||
uint8_t authenticator_length; /* octets in value field */
|
||||
uint8_t value[BGP_ENCAP_SUBTLV_IPSEC_TA_SIZE];
|
||||
};
|
||||
|
||||
/*
|
||||
* Subtlv valid flags
|
||||
* TBD change names to add "VALID"
|
||||
*/
|
||||
#define BGP_TEA_SUBTLV_ENCAP 0x00000001
|
||||
#define BGP_TEA_SUBTLV_PROTO_TYPE 0x00000002
|
||||
#define BGP_TEA_SUBTLV_COLOR 0x00000004
|
||||
#define BGP_TEA_SUBTLV_IPSEC_TA 0x00000008
|
||||
|
||||
|
||||
/*
|
||||
* Tunnel Type-specific APIs
|
||||
*/
|
||||
struct bgp_encap_type_reserved {
|
||||
};
|
||||
|
||||
struct bgp_encap_type_l2tpv3_over_ip {
|
||||
uint32_t valid_subtlvs;
|
||||
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_encap_type_gre {
|
||||
uint32_t valid_subtlvs;
|
||||
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_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_encap_type_transmit_tunnel_endpoint {
|
||||
/* 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_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_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_encap_type_vxlan {
|
||||
/* No subtlvs defined in spec? */
|
||||
};
|
||||
|
||||
struct bgp_encap_type_nvgre {
|
||||
/* No subtlvs defined in spec? */
|
||||
};
|
||||
|
||||
struct bgp_encap_type_mpls {
|
||||
/* No subtlvs defined in spec? */
|
||||
};
|
||||
|
||||
struct bgp_encap_type_mpls_in_gre {
|
||||
/* No subtlvs defined in spec? */
|
||||
};
|
||||
|
||||
struct bgp_encap_type_vxlan_gpe {
|
||||
/* No subtlvs defined in spec? */
|
||||
};
|
||||
|
||||
struct bgp_encap_type_mpls_in_udp {
|
||||
/* No subtlvs defined in spec? */
|
||||
};
|
||||
|
||||
struct bgp_encap_type_pbb {
|
||||
uint32_t valid_subtlvs;
|
||||
struct bgp_tea_subtlv_encap_pbb st_encap;
|
||||
};
|
||||
|
||||
#endif /* _QUAGGA_BGP_ENCAP_TYPES_H */
|
@ -936,6 +936,7 @@ struct bgp_nlri
|
||||
#define BGP_ATTR_AS4_PATH 17
|
||||
#define BGP_ATTR_AS4_AGGREGATOR 18
|
||||
#define BGP_ATTR_AS_PATHLIMIT 21
|
||||
#define BGP_ATTR_ENCAP 23
|
||||
|
||||
/* BGP update origin. */
|
||||
#define BGP_ORIGIN_IGP 0
|
||||
|
@ -175,6 +175,7 @@ struct memory_list memory_list_bgp[] =
|
||||
{ MTYPE_BGP_REDIST, "BGP redistribution" },
|
||||
{ MTYPE_BGP_FILTER_NAME, "BGP Filter Information" },
|
||||
{ MTYPE_BGP_DUMP_STR, "BGP Dump String Information" },
|
||||
{ MTYPE_ENCAP_TLV, "ENCAP TLV", },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user