]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_encap_tlv.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / bgpd / bgp_encap_tlv.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright 2015, LabN Consulting, L.L.C.
4 */
5
6 #include <zebra.h>
7
8 #include "command.h"
9 #include "memory.h"
10 #include "prefix.h"
11 #include "filter.h"
12 #include "stream.h"
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 */
25 static struct bgp_attr_encap_subtlv *subtlv_encode_encap_l2tpv3_over_ip(
26 struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
27 {
28 struct bgp_attr_encap_subtlv *new;
29 uint8_t *p;
30 int total = 4 + st->cookie_length;
31
32 /* sanity check */
33 assert(st->cookie_length <= sizeof(st->cookie));
34 assert(total <= 0xff);
35
36 new = XCALLOC(MTYPE_ENCAP_TLV,
37 sizeof(struct bgp_attr_encap_subtlv) + total);
38 assert(new);
39 new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
40 new->length = total;
41 p = new->value;
42
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;
49 }
50
51 /* rfc5512 4.1 */
52 static struct bgp_attr_encap_subtlv *
53 subtlv_encode_encap_gre(struct bgp_tea_subtlv_encap_gre_key *st)
54 {
55 struct bgp_attr_encap_subtlv *new;
56 uint8_t *p;
57 int total = 4;
58
59 assert(total <= 0xff);
60
61 new = XCALLOC(MTYPE_ENCAP_TLV,
62 sizeof(struct bgp_attr_encap_subtlv) + total);
63 assert(new);
64 new->type = BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION;
65 new->length = total;
66 p = new->value;
67
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;
73 }
74
75 static struct bgp_attr_encap_subtlv *
76 subtlv_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,
85 sizeof(struct bgp_attr_encap_subtlv) + total);
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;
105 }
106
107 /* rfc5512 4.2 */
108 static struct bgp_attr_encap_subtlv *
109 subtlv_encode_proto_type(struct bgp_tea_subtlv_proto_type *st)
110 {
111 struct bgp_attr_encap_subtlv *new;
112 uint8_t *p;
113 int total = 2;
114
115 assert(total <= 0xff);
116
117 new = XCALLOC(MTYPE_ENCAP_TLV,
118 sizeof(struct bgp_attr_encap_subtlv) + total);
119 assert(new);
120 new->type = BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE;
121 new->length = total;
122 p = new->value;
123
124 *p++ = (st->proto & 0xff00) >> 8;
125 *p++ = (st->proto & 0xff);
126 return new;
127 }
128
129 /* rfc5512 4.3 */
130 static struct bgp_attr_encap_subtlv *
131 subtlv_encode_color(struct bgp_tea_subtlv_color *st)
132 {
133 struct bgp_attr_encap_subtlv *new;
134 uint8_t *p;
135 int total = 8;
136
137 assert(total <= 0xff);
138
139 new = XCALLOC(MTYPE_ENCAP_TLV,
140 sizeof(struct bgp_attr_encap_subtlv) + total);
141 assert(new);
142 new->type = BGP_ENCAP_SUBTLV_TYPE_COLOR;
143 new->length = total;
144 p = new->value;
145
146 *p++ = 0x03; /* transitive*/
147 *p++ = 0x0b;
148 *p++ = 0; /* reserved */
149 *p++ = 0; /* reserved */
150
151 *p++ = (st->color & 0xff000000) >> 24;
152 *p++ = (st->color & 0xff0000) >> 16;
153 *p++ = (st->color & 0xff00) >> 8;
154 *p++ = (st->color & 0xff);
155
156 return new;
157 }
158
159 /* rfc 5566 4. */
160 static struct bgp_attr_encap_subtlv *
161 subtlv_encode_ipsec_ta(struct bgp_tea_subtlv_ipsec_ta *st)
162 {
163 struct bgp_attr_encap_subtlv *new;
164 uint8_t *p;
165 int total = 2 + st->authenticator_length;
166
167 /* sanity check */
168 assert(st->authenticator_length <= sizeof(st->value));
169 assert(total <= 0xff);
170
171 new = XCALLOC(MTYPE_ENCAP_TLV,
172 sizeof(struct bgp_attr_encap_subtlv) + total);
173 assert(new);
174 new->type = BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA;
175 new->length = total;
176 p = new->value;
177
178 *p++ = (st->authenticator_type & 0xff00) >> 8;
179 *p++ = st->authenticator_type & 0xff;
180 memcpy(p, st->value, st->authenticator_length);
181 return new;
182 }
183
184 /* draft-rosen-idr-tunnel-encaps 2.1 */
185 static struct bgp_attr_encap_subtlv *
186 subtlv_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,
196 sizeof(struct bgp_attr_encap_subtlv) + total);
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) {
202 memcpy(p, &(st->ip_address.v4.s_addr), IPV4_MAX_BYTELEN);
203 p += IPV4_MAX_BYTELEN;
204 } else {
205 assert(st->family == AF_INET6);
206 memcpy(p, &(st->ip_address.v6.s6_addr), IPV6_MAX_BYTELEN);
207 p += IPV6_MAX_BYTELEN;
208 }
209 memcpy(p, &(st->as4), 4);
210 return new;
211 }
212
213 /***********************************************************************
214 * TUNNEL TYPE-SPECIFIC TLV ENCODE
215 ***********************************************************************/
216
217 /*
218 * requires "extra" and "last" to be defined in caller
219 */
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)
233
234 void bgp_encap_type_l2tpv3overip_to_tlv(
235 struct bgp_encap_type_l2tpv3_over_ip *bet, /* input structure */
236 struct attr *attr)
237 {
238 struct bgp_attr_encap_subtlv *last;
239
240 /* advance to last subtlv */
241 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
242 ;
243
244 attr->encap_tunneltype = BGP_ENCAP_TYPE_L2TPV3_OVER_IP;
245
246 assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
247
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);
255 }
256
257 void bgp_encap_type_gre_to_tlv(
258 struct bgp_encap_type_gre *bet, /* input structure */
259 struct attr *attr)
260 {
261 struct bgp_attr_encap_subtlv *last;
262
263 /* advance to last subtlv */
264 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
265 ;
266
267 attr->encap_tunneltype = BGP_ENCAP_TYPE_GRE;
268
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);
275 }
276
277 void bgp_encap_type_ip_in_ip_to_tlv(
278 struct bgp_encap_type_ip_in_ip *bet, /* input structure */
279 struct attr *attr)
280 {
281 struct bgp_attr_encap_subtlv *last;
282
283 /* advance to last subtlv */
284 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
285 ;
286
287 attr->encap_tunneltype = BGP_ENCAP_TYPE_IP_IN_IP;
288
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);
294 }
295
296 void bgp_encap_type_transmit_tunnel_endpoint(
297 struct bgp_encap_type_transmit_tunnel_endpoint
298 *bet, /* input structure */
299 struct attr *attr)
300 {
301 struct bgp_attr_encap_subtlv *last;
302
303 /* advance to last subtlv */
304 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
305 ;
306
307 attr->encap_tunneltype = BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT;
308
309 /* no subtlvs for this type */
310 }
311
312 void 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)
315 {
316 struct bgp_attr_encap_subtlv *last;
317
318 /* advance to last subtlv */
319 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
320 ;
321
322 attr->encap_tunneltype = BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE;
323
324 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
325 st_ipsec_ta);
326 }
327
328 void 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)
332 {
333 struct bgp_attr_encap_subtlv *last;
334
335 /* advance to last subtlv */
336 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
337 ;
338
339 attr->encap_tunneltype =
340 BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
341
342 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
343 st_ipsec_ta);
344 }
345
346 void 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)
350 {
351 struct bgp_attr_encap_subtlv *last;
352
353 /* advance to last subtlv */
354 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
355 ;
356
357 attr->encap_tunneltype =
358 BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
359
360 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta,
361 st_ipsec_ta);
362 }
363
364 void bgp_encap_type_pbb_to_tlv(
365 struct bgp_encap_type_pbb *bet, /* input structure */
366 struct attr *attr)
367 {
368 struct bgp_attr_encap_subtlv *last;
369
370 /* advance to last subtlv */
371 for (last = attr->encap_subtlvs; last && last->next; last = last->next)
372 ;
373
374 attr->encap_tunneltype = BGP_ENCAP_TYPE_PBB;
375
376 assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
377 ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_pbb, st_encap);
378 }
379
380 void bgp_encap_type_vxlan_to_tlv(
381 struct bgp_encap_type_vxlan *bet, /* input structure */
382 struct attr *attr)
383 {
384 struct bgp_attr_encap_subtlv *tlv;
385 uint32_t vnid;
386
387 attr->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN;
388
389 if (bet == NULL || !bet->vnid)
390 return;
391 XFREE(MTYPE_ENCAP_TLV, attr->encap_subtlvs);
392 tlv = XCALLOC(MTYPE_ENCAP_TLV,
393 sizeof(struct bgp_attr_encap_subtlv) + 12);
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;
406 }
407
408 void bgp_encap_type_nvgre_to_tlv(
409 struct bgp_encap_type_nvgre *bet, /* input structure */
410 struct attr *attr)
411 {
412 attr->encap_tunneltype = BGP_ENCAP_TYPE_NVGRE;
413 }
414
415 void bgp_encap_type_mpls_to_tlv(
416 struct bgp_encap_type_mpls *bet, /* input structure */
417 struct attr *attr)
418 {
419 return; /* no encap attribute for MPLS */
420 }
421
422 void bgp_encap_type_mpls_in_gre_to_tlv(
423 struct bgp_encap_type_mpls_in_gre *bet, /* input structure */
424 struct attr *attr)
425 {
426 attr->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_GRE;
427 }
428
429 void bgp_encap_type_vxlan_gpe_to_tlv(
430 struct bgp_encap_type_vxlan_gpe *bet, /* input structure */
431 struct attr *attr)
432 {
433
434 attr->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN_GPE;
435 }
436
437 void bgp_encap_type_mpls_in_udp_to_tlv(
438 struct bgp_encap_type_mpls_in_udp *bet, /* input structure */
439 struct attr *attr)
440 {
441
442 attr->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_UDP;
443 }
444
445
446 /***********************************************************************
447 * SUBTLV DECODE
448 ***********************************************************************/
449 /* rfc5512 4.1 */
450 static 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
460 ptr_get_be32(subtlv->value, &st->sessionid);
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;
469 }
470
471 /* rfc5512 4.1 */
472 static 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 }
480 ptr_get_be32(subtlv->value, &st->gre_key);
481 return 0;
482 }
483
484 static 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;
503 }
504
505 /* rfc5512 4.2 */
506 static int subtlv_decode_proto_type(struct bgp_attr_encap_subtlv *subtlv,
507 struct bgp_tea_subtlv_proto_type *st)
508 {
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;
516 }
517
518 /* rfc5512 4.3 */
519 static 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 }
533 ptr_get_be32(subtlv->value + 4, &st->color);
534 return 0;
535 }
536
537 /* rfc 5566 4. */
538 static 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;
552 }
553
554 /* draft-rosen-idr-tunnel-encaps 2.1 */
555 static int
556 subtlv_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;
567 memcpy(&st->ip_address.v4.s_addr, subtlv->value,
568 IPV4_MAX_BYTELEN);
569 } else {
570 st->family = AF_INET6;
571 memcpy(&(st->ip_address.v6.s6_addr), subtlv->value,
572 IPV6_MAX_BYTELEN);
573 }
574 i = subtlv->length - 4;
575 ptr_get_be32(subtlv->value + i, &st->as4);
576 return 0;
577 }
578
579 /***********************************************************************
580 * TUNNEL TYPE-SPECIFIC TLV DECODE
581 ***********************************************************************/
582
583 int 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 }
620 }
621 return rc;
622 }
623
624 int 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 }
660 }
661 return rc;
662 }
663
664 int 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 }
695 }
696 return rc;
697 }
698
699 int tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
700 struct bgp_attr_encap_subtlv *stlv,
701 struct bgp_encap_type_transmit_tunnel_endpoint *bet)
702 {
703 struct bgp_attr_encap_subtlv *st;
704 int rc = 0;
705
706 for (st = stlv; st; st = st->next) {
707 switch (st->type) {
708
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;
714
715 default:
716 zlog_debug("%s: unexpected subtlv type %d", __func__,
717 st->type);
718 rc |= -1;
719 break;
720 }
721 }
722 return rc;
723 }
724
725 int 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 }
751 }
752 return rc;
753 }
754
755 int 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 }
781 }
782 return rc;
783 }
784
785 int 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 }
811 }
812 return rc;
813 }
814
815 int tlv_to_bgp_encap_type_vxlan(struct bgp_attr_encap_subtlv *stlv,
816 struct bgp_encap_type_vxlan *bet)
817 {
818 struct bgp_attr_encap_subtlv *st;
819 int rc = 0;
820
821 for (st = stlv; st; st = st->next) {
822 switch (st->type) {
823
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;
829
830 default:
831 zlog_debug("%s: unexpected subtlv type %d", __func__,
832 st->type);
833 rc |= -1;
834 break;
835 }
836 }
837 return rc;
838 }
839
840 int tlv_to_bgp_encap_type_nvgre(struct bgp_attr_encap_subtlv *stlv,
841 struct bgp_encap_type_nvgre *bet)
842 {
843 struct bgp_attr_encap_subtlv *st;
844 int rc = 0;
845
846 for (st = stlv; st; st = st->next) {
847 switch (st->type) {
848
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;
854
855 default:
856 zlog_debug("%s: unexpected subtlv type %d", __func__,
857 st->type);
858 rc |= -1;
859 break;
860 }
861 }
862 return rc;
863 }
864
865 int tlv_to_bgp_encap_type_mpls(struct bgp_attr_encap_subtlv *stlv,
866 struct bgp_encap_type_mpls *bet)
867 {
868 struct bgp_attr_encap_subtlv *st;
869 int rc = 0;
870
871 for (st = stlv; st; st = st->next) {
872 switch (st->type) {
873
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;
879
880 default:
881 zlog_debug("%s: unexpected subtlv type %d", __func__,
882 st->type);
883 rc |= -1;
884 break;
885 }
886 }
887 return rc;
888 }
889
890 int tlv_to_bgp_encap_type_mpls_in_gre(struct bgp_attr_encap_subtlv *stlv,
891 struct bgp_encap_type_mpls_in_gre *bet)
892 {
893 struct bgp_attr_encap_subtlv *st;
894 int rc = 0;
895
896 for (st = stlv; st; st = st->next) {
897 switch (st->type) {
898
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;
904
905 default:
906 zlog_debug("%s: unexpected subtlv type %d", __func__,
907 st->type);
908 rc |= -1;
909 break;
910 }
911 }
912 return rc;
913 }
914
915 int tlv_to_bgp_encap_type_vxlan_gpe(struct bgp_attr_encap_subtlv *stlv,
916 struct bgp_encap_type_vxlan_gpe *bet)
917 {
918 struct bgp_attr_encap_subtlv *st;
919 int rc = 0;
920
921 for (st = stlv; st; st = st->next) {
922 switch (st->type) {
923
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;
929
930 default:
931 zlog_debug("%s: unexpected subtlv type %d", __func__,
932 st->type);
933 rc |= -1;
934 break;
935 }
936 }
937 return rc;
938 }
939
940 int tlv_to_bgp_encap_type_mpls_in_udp(struct bgp_attr_encap_subtlv *stlv,
941 struct bgp_encap_type_mpls_in_udp *bet)
942 {
943 struct bgp_attr_encap_subtlv *st;
944 int rc = 0;
945
946 for (st = stlv; st; st = st->next) {
947 switch (st->type) {
948
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;
954
955 default:
956 zlog_debug("%s: unexpected subtlv type %d", __func__,
957 st->type);
958 rc |= -1;
959 break;
960 }
961 }
962 return rc;
963 }
964
965 int 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 }
991 }
992 return rc;
993 }