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