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