]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_encap_tlv.c
Merge pull request #9374 from mjstapp/fix_nhg_add_leak
[mirror_frr.git] / bgpd / bgp_encap_tlv.c
CommitLineData
f4c89855
LB
1/*
2 * Copyright 2015, LabN Consulting, L.L.C.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
896014f4
DL
14 * You should have received a copy of the GNU General Public License along
15 * with this program; see the file COPYING; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
f4c89855
LB
17 */
18
19#include <zebra.h>
20
5bf15956 21#include "command.h"
f4c89855
LB
22#include "memory.h"
23#include "prefix.h"
f4c89855 24#include "filter.h"
937652c6 25#include "stream.h"
f4c89855
LB
26
27#include "bgpd.h"
28#include "bgp_attr.h"
29
30#include "bgp_encap_types.h"
31#include "bgp_encap_tlv.h"
32
33/***********************************************************************
34 * SUBTLV ENCODE
35 ***********************************************************************/
36
37/* rfc5512 4.1 */
d62a17ae 38static struct bgp_attr_encap_subtlv *subtlv_encode_encap_l2tpv3_over_ip(
39 struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
f4c89855 40{
d62a17ae 41 struct bgp_attr_encap_subtlv *new;
42 uint8_t *p;
43 int total = 4 + st->cookie_length;
f4c89855 44
d62a17ae 45 /* sanity check */
46 assert(st->cookie_length <= sizeof(st->cookie));
47 assert(total <= 0xff);
f4c89855 48
d62a17ae 49 new = XCALLOC(MTYPE_ENCAP_TLV,
12f70478 50 sizeof(struct bgp_attr_encap_subtlv) + total);
d62a17ae 51 assert(new);
52 new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
53 new->length = total;
54 p = new->value;
f4c89855 55
d62a17ae 56 *p++ = (st->sessionid & 0xff000000) >> 24;
57 *p++ = (st->sessionid & 0xff0000) >> 16;
58 *p++ = (st->sessionid & 0xff00) >> 8;
59 *p++ = (st->sessionid & 0xff);
60 memcpy(p, st->cookie, st->cookie_length);
61 return new;
f4c89855
LB
62}
63
64/* rfc5512 4.1 */
65static struct bgp_attr_encap_subtlv *
d62a17ae 66subtlv_encode_encap_gre(struct bgp_tea_subtlv_encap_gre_key *st)
f4c89855 67{
d62a17ae 68 struct bgp_attr_encap_subtlv *new;
69 uint8_t *p;
70 int total = 4;
f4c89855 71
d62a17ae 72 assert(total <= 0xff);
f4c89855 73
d62a17ae 74 new = XCALLOC(MTYPE_ENCAP_TLV,
12f70478 75 sizeof(struct bgp_attr_encap_subtlv) + total);
d62a17ae 76 assert(new);
77 new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
78 new->length = total;
79 p = new->value;
f4c89855 80
d62a17ae 81 *p++ = (st->gre_key & 0xff000000) >> 24;
82 *p++ = (st->gre_key & 0xff0000) >> 16;
83 *p++ = (st->gre_key & 0xff00) >> 8;
84 *p++ = (st->gre_key & 0xff);
85 return new;
f4c89855
LB
86}
87
88static struct bgp_attr_encap_subtlv *
d62a17ae 89subtlv_encode_encap_pbb(struct bgp_tea_subtlv_encap_pbb *st)
90{
91 struct bgp_attr_encap_subtlv *new;
92 uint8_t *p;
93 int total = 1 + 3 + 6 + 2; /* flags + isid + madaddr + vid */
94
95 assert(total <= 0xff);
96
97 new = XCALLOC(MTYPE_ENCAP_TLV,
12f70478 98 sizeof(struct bgp_attr_encap_subtlv) + total);
d62a17ae 99 assert(new);
100 new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
101 new->length = total;
102 p = new->value;
103
104 *p++ = (st->flag_isid ? 0x80 : 0) | (st->flag_vid ? 0x40 : 0) | 0;
105 if (st->flag_isid) {
106 *p = (st->isid & 0xff0000) >> 16;
107 *(p + 1) = (st->isid & 0xff00) >> 8;
108 *(p + 2) = (st->isid & 0xff);
109 }
110 p += 3;
111 memcpy(p, st->macaddr, 6);
112 p += 6;
113 if (st->flag_vid) {
114 *p++ = (st->vid & 0xf00) >> 8;
115 *p++ = st->vid & 0xff;
116 }
117 return new;
f4c89855
LB
118}
119
120/* rfc5512 4.2 */
121static struct bgp_attr_encap_subtlv *
d62a17ae 122subtlv_encode_proto_type(struct bgp_tea_subtlv_proto_type *st)
f4c89855 123{
d62a17ae 124 struct bgp_attr_encap_subtlv *new;
125 uint8_t *p;
126 int total = 2;
f4c89855 127
d62a17ae 128 assert(total <= 0xff);
f4c89855 129
d62a17ae 130 new = XCALLOC(MTYPE_ENCAP_TLV,
12f70478 131 sizeof(struct bgp_attr_encap_subtlv) + total);
d62a17ae 132 assert(new);
133 new->type = BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE;
134 new->length = total;
135 p = new->value;
f4c89855 136
d62a17ae 137 *p++ = (st->proto & 0xff00) >> 8;
138 *p++ = (st->proto & 0xff);
139 return new;
f4c89855
LB
140}
141
142/* rfc5512 4.3 */
143static struct bgp_attr_encap_subtlv *
d62a17ae 144subtlv_encode_color(struct bgp_tea_subtlv_color *st)
f4c89855 145{
d62a17ae 146 struct bgp_attr_encap_subtlv *new;
147 uint8_t *p;
148 int total = 8;
f4c89855 149
d62a17ae 150 assert(total <= 0xff);
f4c89855 151
d62a17ae 152 new = XCALLOC(MTYPE_ENCAP_TLV,
12f70478 153 sizeof(struct bgp_attr_encap_subtlv) + total);
d62a17ae 154 assert(new);
155 new->type = BGP_ENCAP_SUBTLV_TYPE_COLOR;
156 new->length = total;
157 p = new->value;
f4c89855 158
d62a17ae 159 *p++ = 0x03; /* transitive*/
160 *p++ = 0x0b;
161 *p++ = 0; /* reserved */
162 *p++ = 0; /* reserved */
f4c89855 163
d62a17ae 164 *p++ = (st->color & 0xff000000) >> 24;
165 *p++ = (st->color & 0xff0000) >> 16;
166 *p++ = (st->color & 0xff00) >> 8;
167 *p++ = (st->color & 0xff);
f4c89855 168
d62a17ae 169 return new;
f4c89855
LB
170}
171
172/* rfc 5566 4. */
173static struct bgp_attr_encap_subtlv *
d62a17ae 174subtlv_encode_ipsec_ta(struct bgp_tea_subtlv_ipsec_ta *st)
f4c89855 175{
d62a17ae 176 struct bgp_attr_encap_subtlv *new;
177 uint8_t *p;
178 int total = 2 + st->authenticator_length;
f4c89855 179
d62a17ae 180 /* sanity check */
181 assert(st->authenticator_length <= sizeof(st->value));
182 assert(total <= 0xff);
f4c89855 183
d62a17ae 184 new = XCALLOC(MTYPE_ENCAP_TLV,
12f70478 185 sizeof(struct bgp_attr_encap_subtlv) + total);
d62a17ae 186 assert(new);
187 new->type = BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA;
188 new->length = total;
189 p = new->value;
f4c89855 190
d62a17ae 191 *p++ = (st->authenticator_type & 0xff00) >> 8;
192 *p++ = st->authenticator_type & 0xff;
193 memcpy(p, st->value, st->authenticator_length);
194 return new;
f4c89855
LB
195}
196
587ff0fd
LB
197/* draft-rosen-idr-tunnel-encaps 2.1 */
198static struct bgp_attr_encap_subtlv *
d62a17ae 199subtlv_encode_remote_endpoint(struct bgp_tea_subtlv_remote_endpoint *st)
200{
201 struct bgp_attr_encap_subtlv *new;
202 uint8_t *p;
203
204 int total = (st->family == AF_INET ? 8 : 20);
205
206 assert(total <= 0xff);
207
208 new = XCALLOC(MTYPE_ENCAP_TLV,
12f70478 209 sizeof(struct bgp_attr_encap_subtlv) + total);
d62a17ae 210 assert(new);
211 new->type = BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT;
212 new->length = total;
213 p = new->value;
214 if (st->family == AF_INET) {
8643c2e5
DA
215 memcpy(p, &(st->ip_address.v4.s_addr), IPV4_MAX_BYTELEN);
216 p += IPV4_MAX_BYTELEN;
d62a17ae 217 } else {
218 assert(st->family == AF_INET6);
8643c2e5
DA
219 memcpy(p, &(st->ip_address.v6.s6_addr), IPV6_MAX_BYTELEN);
220 p += IPV6_MAX_BYTELEN;
d62a17ae 221 }
222 memcpy(p, &(st->as4), 4);
223 return new;
587ff0fd 224}
f4c89855
LB
225
226/***********************************************************************
227 * TUNNEL TYPE-SPECIFIC TLV ENCODE
228 ***********************************************************************/
229
230/*
231 * requires "extra" and "last" to be defined in caller
232 */
d62a17ae 233#define ENC_SUBTLV(flag, function, field) \
234 do { \
235 struct bgp_attr_encap_subtlv *new; \
236 if (CHECK_FLAG(bet->valid_subtlvs, (flag))) { \
237 new = function(&bet->field); \
238 if (last) { \
239 last->next = new; \
240 } else { \
241 attr->encap_subtlvs = new; \
242 } \
243 last = new; \
244 } \
245 } while (0)
f4c89855 246
d62a17ae 247void bgp_encap_type_l2tpv3overip_to_tlv(
248 struct bgp_encap_type_l2tpv3_over_ip *bet, /* input structure */
249 struct attr *attr)
f4c89855 250{
d62a17ae 251 struct bgp_attr_encap_subtlv *last;
f4c89855 252
d62a17ae 253 /* advance to last subtlv */
254 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
255 ;
f4c89855 256
d62a17ae 257 attr->encap_tunneltype = BGP_ENCAP_TYPE_L2TPV3_OVER_IP;
f4c89855 258
d62a17ae 259 assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
f4c89855 260
d62a17ae 261 ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_l2tpv3_over_ip,
262 st_encap);
263 ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type,
264 st_proto);
265 ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
266 ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT,
267 subtlv_encode_remote_endpoint, st_endpoint);
f4c89855
LB
268}
269
d62a17ae 270void bgp_encap_type_gre_to_tlv(
271 struct bgp_encap_type_gre *bet, /* input structure */
272 struct attr *attr)
f4c89855 273{
d62a17ae 274 struct bgp_attr_encap_subtlv *last;
f4c89855 275
d62a17ae 276 /* advance to last subtlv */
277 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
278 ;
f4c89855 279
d62a17ae 280 attr->encap_tunneltype = BGP_ENCAP_TYPE_GRE;
f4c89855 281
d62a17ae 282 ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_gre, st_encap);
283 ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type,
284 st_proto);
285 ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
286 ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT,
287 subtlv_encode_remote_endpoint, st_endpoint);
f4c89855
LB
288}
289
d62a17ae 290void bgp_encap_type_ip_in_ip_to_tlv(
291 struct bgp_encap_type_ip_in_ip *bet, /* input structure */
292 struct attr *attr)
f4c89855 293{
d62a17ae 294 struct bgp_attr_encap_subtlv *last;
f4c89855 295
d62a17ae 296 /* advance to last subtlv */
297 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
298 ;
f4c89855 299
d62a17ae 300 attr->encap_tunneltype = BGP_ENCAP_TYPE_IP_IN_IP;
f4c89855 301
d62a17ae 302 ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type,
303 st_proto);
304 ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
305 ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT,
306 subtlv_encode_remote_endpoint, st_endpoint);
f4c89855
LB
307}
308
d62a17ae 309void bgp_encap_type_transmit_tunnel_endpoint(
310 struct bgp_encap_type_transmit_tunnel_endpoint
311 *bet, /* input structure */
312 struct attr *attr)
f4c89855 313{
d62a17ae 314 struct bgp_attr_encap_subtlv *last;
f4c89855 315
d62a17ae 316 /* advance to last subtlv */
317 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
318 ;
f4c89855 319
d62a17ae 320 attr->encap_tunneltype = BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT;
f4c89855 321
d62a17ae 322 /* no subtlvs for this type */
f4c89855
LB
323}
324
d62a17ae 325void bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
326 struct bgp_encap_type_ipsec_in_tunnel_mode *bet, /* input structure */
327 struct attr *attr)
f4c89855 328{
d62a17ae 329 struct bgp_attr_encap_subtlv *last;
f4c89855 330
d62a17ae 331 /* advance to last subtlv */
332 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
333 ;
f4c89855 334
d62a17ae 335 attr->encap_tunneltype = BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE;
f4c89855 336
d62a17ae 337 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
338 st_ipsec_ta);
f4c89855
LB
339}
340
d62a17ae 341void bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
342 struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode
343 *bet, /* input structure */
344 struct attr *attr)
f4c89855 345{
d62a17ae 346 struct bgp_attr_encap_subtlv *last;
f4c89855 347
d62a17ae 348 /* advance to last subtlv */
349 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
350 ;
f4c89855 351
d62a17ae 352 attr->encap_tunneltype =
353 BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
f4c89855 354
d62a17ae 355 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
356 st_ipsec_ta);
f4c89855
LB
357}
358
d62a17ae 359void bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
360 struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode
361 *bet, /* input structure */
362 struct attr *attr)
f4c89855 363{
d62a17ae 364 struct bgp_attr_encap_subtlv *last;
f4c89855 365
d62a17ae 366 /* advance to last subtlv */
367 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
368 ;
f4c89855 369
d62a17ae 370 attr->encap_tunneltype =
371 BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
f4c89855 372
d62a17ae 373 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
374 st_ipsec_ta);
f4c89855
LB
375}
376
d62a17ae 377void bgp_encap_type_pbb_to_tlv(
378 struct bgp_encap_type_pbb *bet, /* input structure */
379 struct attr *attr)
f4c89855 380{
d62a17ae 381 struct bgp_attr_encap_subtlv *last;
f4c89855 382
d62a17ae 383 /* advance to last subtlv */
384 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
385 ;
f4c89855 386
d62a17ae 387 attr->encap_tunneltype = BGP_ENCAP_TYPE_PBB;
f4c89855 388
d62a17ae 389 assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
390 ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_pbb, st_encap);
f4c89855
LB
391}
392
d62a17ae 393void bgp_encap_type_vxlan_to_tlv(
394 struct bgp_encap_type_vxlan *bet, /* input structure */
395 struct attr *attr)
f4c89855 396{
d62a17ae 397 struct bgp_attr_encap_subtlv *tlv;
398 uint32_t vnid;
f4c89855 399
d62a17ae 400 attr->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN;
aee875b5 401
d62a17ae 402 if (bet == NULL || !bet->vnid)
403 return;
0a22ddfb 404 XFREE(MTYPE_ENCAP_TLV, attr->encap_subtlvs);
d62a17ae 405 tlv = XCALLOC(MTYPE_ENCAP_TLV,
12f70478 406 sizeof(struct bgp_attr_encap_subtlv) + 12);
d62a17ae 407 tlv->type = 1; /* encapsulation type */
408 tlv->length = 12;
409 if (bet->vnid) {
410 vnid = htonl(bet->vnid | VXLAN_ENCAP_MASK_VNID_VALID);
411 memcpy(&tlv->value, &vnid, 4);
412 }
413 if (bet->mac_address) {
414 char *ptr = (char *)&tlv->value + 4;
415 memcpy(ptr, bet->mac_address, 6);
416 }
417 attr->encap_subtlvs = tlv;
418 return;
f4c89855
LB
419}
420
d62a17ae 421void bgp_encap_type_nvgre_to_tlv(
422 struct bgp_encap_type_nvgre *bet, /* input structure */
423 struct attr *attr)
f4c89855 424{
d62a17ae 425 attr->encap_tunneltype = BGP_ENCAP_TYPE_NVGRE;
f4c89855
LB
426}
427
d62a17ae 428void bgp_encap_type_mpls_to_tlv(
429 struct bgp_encap_type_mpls *bet, /* input structure */
430 struct attr *attr)
f4c89855 431{
d62a17ae 432 return; /* no encap attribute for MPLS */
f4c89855
LB
433}
434
d62a17ae 435void bgp_encap_type_mpls_in_gre_to_tlv(
436 struct bgp_encap_type_mpls_in_gre *bet, /* input structure */
437 struct attr *attr)
f4c89855 438{
d62a17ae 439 attr->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_GRE;
f4c89855
LB
440}
441
d62a17ae 442void bgp_encap_type_vxlan_gpe_to_tlv(
443 struct bgp_encap_type_vxlan_gpe *bet, /* input structure */
444 struct attr *attr)
f4c89855 445{
f4c89855 446
d62a17ae 447 attr->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN_GPE;
f4c89855
LB
448}
449
d62a17ae 450void bgp_encap_type_mpls_in_udp_to_tlv(
451 struct bgp_encap_type_mpls_in_udp *bet, /* input structure */
452 struct attr *attr)
f4c89855 453{
f4c89855 454
d62a17ae 455 attr->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_UDP;
f4c89855
LB
456}
457
458
459/***********************************************************************
460 * SUBTLV DECODE
461 ***********************************************************************/
462/* rfc5512 4.1 */
d62a17ae 463static int subtlv_decode_encap_l2tpv3_over_ip(
464 struct bgp_attr_encap_subtlv *subtlv,
465 struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
466{
467 if (subtlv->length < 4) {
468 zlog_debug("%s, subtlv length %d is less than 4", __func__,
469 subtlv->length);
470 return -1;
471 }
472
937652c6 473 ptr_get_be32(subtlv->value, &st->sessionid);
d62a17ae 474 st->cookie_length = subtlv->length - 4;
475 if (st->cookie_length > sizeof(st->cookie)) {
476 zlog_debug("%s, subtlv length %d is greater than %d", __func__,
477 st->cookie_length, (int)sizeof(st->cookie));
478 return -1;
479 }
480 memcpy(st->cookie, subtlv->value + 4, st->cookie_length);
481 return 0;
f4c89855
LB
482}
483
484/* rfc5512 4.1 */
d62a17ae 485static int subtlv_decode_encap_gre(struct bgp_attr_encap_subtlv *subtlv,
486 struct bgp_tea_subtlv_encap_gre_key *st)
487{
488 if (subtlv->length != 4) {
489 zlog_debug("%s, subtlv length %d does not equal 4", __func__,
490 subtlv->length);
491 return -1;
492 }
937652c6 493 ptr_get_be32(subtlv->value, &st->gre_key);
d62a17ae 494 return 0;
f4c89855
LB
495}
496
d62a17ae 497static int subtlv_decode_encap_pbb(struct bgp_attr_encap_subtlv *subtlv,
498 struct bgp_tea_subtlv_encap_pbb *st)
499{
500 if (subtlv->length != 1 + 3 + 6 + 2) {
501 zlog_debug("%s, subtlv length %d does not equal %d", __func__,
502 subtlv->length, 1 + 3 + 6 + 2);
503 return -1;
504 }
505 if (subtlv->value[0] & 0x80) {
506 st->flag_isid = 1;
507 st->isid = (subtlv->value[1] << 16) | (subtlv->value[2] << 8)
508 | subtlv->value[3];
509 }
510 if (subtlv->value[0] & 0x40) {
511 st->flag_vid = 1;
512 st->vid = ((subtlv->value[10] & 0x0f) << 8) | subtlv->value[11];
513 }
514 memcpy(st->macaddr, subtlv->value + 4, 6);
515 return 0;
f4c89855
LB
516}
517
518/* rfc5512 4.2 */
d62a17ae 519static int subtlv_decode_proto_type(struct bgp_attr_encap_subtlv *subtlv,
520 struct bgp_tea_subtlv_proto_type *st)
f4c89855 521{
d62a17ae 522 if (subtlv->length != 2) {
523 zlog_debug("%s, subtlv length %d does not equal 2", __func__,
524 subtlv->length);
525 return -1;
526 }
527 st->proto = (subtlv->value[0] << 8) | subtlv->value[1];
528 return 0;
f4c89855
LB
529}
530
531/* rfc5512 4.3 */
d62a17ae 532static int subtlv_decode_color(struct bgp_attr_encap_subtlv *subtlv,
533 struct bgp_tea_subtlv_color *st)
534{
535 if (subtlv->length != 8) {
536 zlog_debug("%s, subtlv length %d does not equal 8", __func__,
537 subtlv->length);
538 return -1;
539 }
540 if ((subtlv->value[0] != 0x03) || (subtlv->value[1] != 0x0b)
541 || (subtlv->value[2] != 0) || (subtlv->value[3] != 0)) {
542 zlog_debug("%s, subtlv value 1st 4 bytes are not 0x030b0000",
543 __func__);
544 return -1;
545 }
937652c6 546 ptr_get_be32(subtlv->value + 4, &st->color);
d62a17ae 547 return 0;
f4c89855
LB
548}
549
550/* rfc 5566 4. */
d62a17ae 551static int subtlv_decode_ipsec_ta(struct bgp_attr_encap_subtlv *subtlv,
552 struct bgp_tea_subtlv_ipsec_ta *st)
553{
554 st->authenticator_length = subtlv->length - 2;
555 if (st->authenticator_length > sizeof(st->value)) {
556 zlog_debug(
557 "%s, authenticator length %d exceeds storage maximum %d",
558 __func__, st->authenticator_length,
559 (int)sizeof(st->value));
560 return -1;
561 }
562 st->authenticator_type = (subtlv->value[0] << 8) | subtlv->value[1];
563 memcpy(st->value, subtlv->value + 2, st->authenticator_length);
564 return 0;
f4c89855
LB
565}
566
587ff0fd
LB
567/* draft-rosen-idr-tunnel-encaps 2.1 */
568static int
d62a17ae 569subtlv_decode_remote_endpoint(struct bgp_attr_encap_subtlv *subtlv,
570 struct bgp_tea_subtlv_remote_endpoint *st)
571{
572 int i;
573 if (subtlv->length != 8 && subtlv->length != 20) {
574 zlog_debug("%s, subtlv length %d does not equal 8 or 20",
575 __func__, subtlv->length);
576 return -1;
577 }
578 if (subtlv->length == 8) {
579 st->family = AF_INET;
8643c2e5
DA
580 memcpy(&st->ip_address.v4.s_addr, subtlv->value,
581 IPV4_MAX_BYTELEN);
d62a17ae 582 } else {
583 st->family = AF_INET6;
8643c2e5
DA
584 memcpy(&(st->ip_address.v6.s6_addr), subtlv->value,
585 IPV6_MAX_BYTELEN);
d62a17ae 586 }
587 i = subtlv->length - 4;
937652c6 588 ptr_get_be32(subtlv->value + i, &st->as4);
d62a17ae 589 return 0;
587ff0fd
LB
590}
591
f4c89855
LB
592/***********************************************************************
593 * TUNNEL TYPE-SPECIFIC TLV DECODE
594 ***********************************************************************/
595
d62a17ae 596int tlv_to_bgp_encap_type_l2tpv3overip(
597 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
598 struct bgp_encap_type_l2tpv3_over_ip *bet) /* caller-allocated */
599{
600 struct bgp_attr_encap_subtlv *st;
601 int rc = 0;
602
603 for (st = stlv; st; st = st->next) {
604 switch (st->type) {
605 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
606 rc |= subtlv_decode_encap_l2tpv3_over_ip(
607 st, &bet->st_encap);
608 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
609 break;
610
611 case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
612 rc |= subtlv_decode_proto_type(st, &bet->st_proto);
613 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
614 break;
615
616 case BGP_ENCAP_SUBTLV_TYPE_COLOR:
617 rc |= subtlv_decode_color(st, &bet->st_color);
618 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
619 break;
620
621 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
622 rc |= subtlv_decode_remote_endpoint(st,
623 &bet->st_endpoint);
624 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
625 break;
626
627 default:
628 zlog_debug("%s: unexpected subtlv type %d", __func__,
629 st->type);
630 rc |= -1;
631 break;
632 }
f4c89855 633 }
d62a17ae 634 return rc;
635}
636
637int tlv_to_bgp_encap_type_gre(
638 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
639 struct bgp_encap_type_gre *bet) /* caller-allocated */
640{
641 struct bgp_attr_encap_subtlv *st;
642 int rc = 0;
643
644 for (st = stlv; st; st = st->next) {
645 switch (st->type) {
646 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
647 rc |= subtlv_decode_encap_gre(st, &bet->st_encap);
648 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
649 break;
650
651 case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
652 rc |= subtlv_decode_proto_type(st, &bet->st_proto);
653 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
654 break;
655
656 case BGP_ENCAP_SUBTLV_TYPE_COLOR:
657 rc |= subtlv_decode_color(st, &bet->st_color);
658 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
659 break;
660
661 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
662 rc |= subtlv_decode_remote_endpoint(st,
663 &bet->st_endpoint);
664 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
665 break;
666
667 default:
668 zlog_debug("%s: unexpected subtlv type %d", __func__,
669 st->type);
670 rc |= -1;
671 break;
672 }
f4c89855 673 }
d62a17ae 674 return rc;
675}
676
677int tlv_to_bgp_encap_type_ip_in_ip(
678 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
679 struct bgp_encap_type_ip_in_ip *bet) /* caller-allocated */
680{
681 struct bgp_attr_encap_subtlv *st;
682 int rc = 0;
683
684 for (st = stlv; st; st = st->next) {
685 switch (st->type) {
686 case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
687 rc |= subtlv_decode_proto_type(st, &bet->st_proto);
688 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
689 break;
690
691 case BGP_ENCAP_SUBTLV_TYPE_COLOR:
692 rc |= subtlv_decode_color(st, &bet->st_color);
693 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
694 break;
695
696 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
697 rc |= subtlv_decode_remote_endpoint(st,
698 &bet->st_endpoint);
699 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
700 break;
701
702 default:
703 zlog_debug("%s: unexpected subtlv type %d", __func__,
704 st->type);
705 rc |= -1;
706 break;
707 }
f4c89855 708 }
d62a17ae 709 return rc;
f4c89855
LB
710}
711
d62a17ae 712int tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
713 struct bgp_attr_encap_subtlv *stlv,
714 struct bgp_encap_type_transmit_tunnel_endpoint *bet)
f4c89855 715{
d62a17ae 716 struct bgp_attr_encap_subtlv *st;
717 int rc = 0;
f4c89855 718
d62a17ae 719 for (st = stlv; st; st = st->next) {
720 switch (st->type) {
587ff0fd 721
d62a17ae 722 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
723 rc |= subtlv_decode_remote_endpoint(st,
724 &bet->st_endpoint);
725 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
726 break;
587ff0fd 727
d62a17ae 728 default:
729 zlog_debug("%s: unexpected subtlv type %d", __func__,
730 st->type);
731 rc |= -1;
732 break;
733 }
f4c89855 734 }
d62a17ae 735 return rc;
736}
737
738int tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
739 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
740 struct bgp_encap_type_ipsec_in_tunnel_mode *bet) /* caller-allocated */
741{
742 struct bgp_attr_encap_subtlv *st;
743 int rc = 0;
744
745 for (st = stlv; st; st = st->next) {
746 switch (st->type) {
747 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
748 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
749 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
750 break;
751
752 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
753 rc |= subtlv_decode_remote_endpoint(st,
754 &bet->st_endpoint);
755 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
756 break;
757
758 default:
759 zlog_debug("%s: unexpected subtlv type %d", __func__,
760 st->type);
761 rc |= -1;
762 break;
763 }
f4c89855 764 }
d62a17ae 765 return rc;
766}
767
768int tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
769 struct bgp_attr_encap_subtlv *stlv,
770 struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
771{
772 struct bgp_attr_encap_subtlv *st;
773 int rc = 0;
774
775 for (st = stlv; st; st = st->next) {
776 switch (st->type) {
777 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
778 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
779 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
780 break;
781
782 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
783 rc |= subtlv_decode_remote_endpoint(st,
784 &bet->st_endpoint);
785 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
786 break;
787
788 default:
789 zlog_debug("%s: unexpected subtlv type %d", __func__,
790 st->type);
791 rc |= -1;
792 break;
793 }
f4c89855 794 }
d62a17ae 795 return rc;
796}
797
798int tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
799 struct bgp_attr_encap_subtlv *stlv,
800 struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
801{
802 struct bgp_attr_encap_subtlv *st;
803 int rc = 0;
804
805 for (st = stlv; st; st = st->next) {
806 switch (st->type) {
807 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
808 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
809 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
810 break;
811
812 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
813 rc |= subtlv_decode_remote_endpoint(st,
814 &bet->st_endpoint);
815 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
816 break;
817
818 default:
819 zlog_debug("%s: unexpected subtlv type %d", __func__,
820 st->type);
821 rc |= -1;
822 break;
823 }
f4c89855 824 }
d62a17ae 825 return rc;
f4c89855
LB
826}
827
d62a17ae 828int tlv_to_bgp_encap_type_vxlan(struct bgp_attr_encap_subtlv *stlv,
829 struct bgp_encap_type_vxlan *bet)
f4c89855 830{
d62a17ae 831 struct bgp_attr_encap_subtlv *st;
832 int rc = 0;
f4c89855 833
d62a17ae 834 for (st = stlv; st; st = st->next) {
835 switch (st->type) {
587ff0fd 836
d62a17ae 837 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
838 rc |= subtlv_decode_remote_endpoint(st,
839 &bet->st_endpoint);
840 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
841 break;
587ff0fd 842
d62a17ae 843 default:
844 zlog_debug("%s: unexpected subtlv type %d", __func__,
845 st->type);
846 rc |= -1;
847 break;
848 }
f4c89855 849 }
d62a17ae 850 return rc;
f4c89855
LB
851}
852
d62a17ae 853int tlv_to_bgp_encap_type_nvgre(struct bgp_attr_encap_subtlv *stlv,
854 struct bgp_encap_type_nvgre *bet)
f4c89855 855{
d62a17ae 856 struct bgp_attr_encap_subtlv *st;
857 int rc = 0;
f4c89855 858
d62a17ae 859 for (st = stlv; st; st = st->next) {
860 switch (st->type) {
587ff0fd 861
d62a17ae 862 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
863 rc |= subtlv_decode_remote_endpoint(st,
864 &bet->st_endpoint);
865 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
866 break;
587ff0fd 867
d62a17ae 868 default:
869 zlog_debug("%s: unexpected subtlv type %d", __func__,
870 st->type);
871 rc |= -1;
872 break;
873 }
f4c89855 874 }
d62a17ae 875 return rc;
f4c89855
LB
876}
877
d62a17ae 878int tlv_to_bgp_encap_type_mpls(struct bgp_attr_encap_subtlv *stlv,
879 struct bgp_encap_type_mpls *bet)
f4c89855 880{
d62a17ae 881 struct bgp_attr_encap_subtlv *st;
882 int rc = 0;
f4c89855 883
d62a17ae 884 for (st = stlv; st; st = st->next) {
885 switch (st->type) {
587ff0fd 886
d62a17ae 887 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
888 rc |= subtlv_decode_remote_endpoint(st,
889 &bet->st_endpoint);
890 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
891 break;
587ff0fd 892
d62a17ae 893 default:
894 zlog_debug("%s: unexpected subtlv type %d", __func__,
895 st->type);
896 rc |= -1;
897 break;
898 }
f4c89855 899 }
d62a17ae 900 return rc;
f4c89855
LB
901}
902
d62a17ae 903int tlv_to_bgp_encap_type_mpls_in_gre(struct bgp_attr_encap_subtlv *stlv,
904 struct bgp_encap_type_mpls_in_gre *bet)
f4c89855 905{
d62a17ae 906 struct bgp_attr_encap_subtlv *st;
907 int rc = 0;
f4c89855 908
d62a17ae 909 for (st = stlv; st; st = st->next) {
910 switch (st->type) {
587ff0fd 911
d62a17ae 912 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
913 rc |= subtlv_decode_remote_endpoint(st,
914 &bet->st_endpoint);
915 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
916 break;
587ff0fd 917
d62a17ae 918 default:
919 zlog_debug("%s: unexpected subtlv type %d", __func__,
920 st->type);
921 rc |= -1;
922 break;
923 }
f4c89855 924 }
d62a17ae 925 return rc;
f4c89855
LB
926}
927
d62a17ae 928int tlv_to_bgp_encap_type_vxlan_gpe(struct bgp_attr_encap_subtlv *stlv,
929 struct bgp_encap_type_vxlan_gpe *bet)
f4c89855 930{
d62a17ae 931 struct bgp_attr_encap_subtlv *st;
932 int rc = 0;
f4c89855 933
d62a17ae 934 for (st = stlv; st; st = st->next) {
935 switch (st->type) {
587ff0fd 936
d62a17ae 937 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
938 rc |= subtlv_decode_remote_endpoint(st,
939 &bet->st_endpoint);
940 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
941 break;
587ff0fd 942
d62a17ae 943 default:
944 zlog_debug("%s: unexpected subtlv type %d", __func__,
945 st->type);
946 rc |= -1;
947 break;
948 }
f4c89855 949 }
d62a17ae 950 return rc;
f4c89855
LB
951}
952
d62a17ae 953int tlv_to_bgp_encap_type_mpls_in_udp(struct bgp_attr_encap_subtlv *stlv,
954 struct bgp_encap_type_mpls_in_udp *bet)
f4c89855 955{
d62a17ae 956 struct bgp_attr_encap_subtlv *st;
957 int rc = 0;
f4c89855 958
d62a17ae 959 for (st = stlv; st; st = st->next) {
960 switch (st->type) {
587ff0fd 961
d62a17ae 962 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
963 rc |= subtlv_decode_remote_endpoint(st,
964 &bet->st_endpoint);
965 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
966 break;
587ff0fd 967
d62a17ae 968 default:
969 zlog_debug("%s: unexpected subtlv type %d", __func__,
970 st->type);
971 rc |= -1;
972 break;
973 }
f4c89855 974 }
d62a17ae 975 return rc;
976}
977
978int tlv_to_bgp_encap_type_pbb(
979 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
980 struct bgp_encap_type_pbb *bet) /* caller-allocated */
981{
982 struct bgp_attr_encap_subtlv *st;
983 int rc = 0;
984
985 for (st = stlv; st; st = st->next) {
986 switch (st->type) {
987 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
988 rc |= subtlv_decode_encap_pbb(st, &bet->st_encap);
989 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
990 break;
991
992 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
993 rc |= subtlv_decode_remote_endpoint(st,
994 &bet->st_endpoint);
995 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
996 break;
997
998 default:
999 zlog_debug("%s: unexpected subtlv type %d", __func__,
1000 st->type);
1001 rc |= -1;
1002 break;
1003 }
f4c89855 1004 }
d62a17ae 1005 return rc;
f4c89855 1006}