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