blob: 058b41eb562ecab94ea949691d3a168fac3dcc7b [file] [log] [blame]
Lou Bergerc3741782016-01-12 13:42:01 -05001/*
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
199
200/***********************************************************************
201 * TUNNEL TYPE-SPECIFIC TLV ENCODE
202 ***********************************************************************/
203
204/*
205 * requires "extra" and "last" to be defined in caller
206 */
207#define ENC_SUBTLV(flag, function, field) do {\
208 struct bgp_attr_encap_subtlv *new;\
209 if (CHECK_FLAG(bet->valid_subtlvs, (flag))) {\
210 new = function(&bet->field);\
211 if (last) {\
212 last->next = new;\
213 } else {\
214 extra->encap_subtlvs = new;\
215 }\
216 last = new;\
217 }\
218} while (0)
219
220void
221bgp_encap_type_l2tpv3overip_to_tlv(
222 struct bgp_encap_type_l2tpv3_over_ip *bet, /* input structure */
223 struct attr *attr)
224{
225 struct attr_extra *extra = bgp_attr_extra_get(attr);
226 struct bgp_attr_encap_subtlv *last;
227
228 /* advance to last subtlv */
229 for (last = extra->encap_subtlvs; last && last->next; last = last->next);
230
231 extra->encap_tunneltype = BGP_ENCAP_TYPE_L2TPV3_OVER_IP;
232
233 assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
234
235 ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_l2tpv3_over_ip, st_encap);
236 ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type, st_proto);
237 ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
238}
239
240void
241bgp_encap_type_gre_to_tlv(
242 struct bgp_encap_type_gre *bet, /* input structure */
243 struct attr *attr)
244{
245 struct attr_extra *extra = bgp_attr_extra_get(attr);
246 struct bgp_attr_encap_subtlv *last;
247
248 /* advance to last subtlv */
249 for (last = extra->encap_subtlvs; last && last->next; last = last->next);
250
251 extra->encap_tunneltype = BGP_ENCAP_TYPE_GRE;
252
253 ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_gre, st_encap);
254 ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type, st_proto);
255 ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
256}
257
258void
259bgp_encap_type_ip_in_ip_to_tlv(
260 struct bgp_encap_type_ip_in_ip *bet, /* input structure */
261 struct attr *attr)
262{
263 struct attr_extra *extra = bgp_attr_extra_get(attr);
264 struct bgp_attr_encap_subtlv *last;
265
266 /* advance to last subtlv */
267 for (last = extra->encap_subtlvs; last && last->next; last = last->next);
268
269 extra->encap_tunneltype = BGP_ENCAP_TYPE_IP_IN_IP;
270
271 ENC_SUBTLV(BGP_TEA_SUBTLV_PROTO_TYPE, subtlv_encode_proto_type, st_proto);
272 ENC_SUBTLV(BGP_TEA_SUBTLV_COLOR, subtlv_encode_color, st_color);
273}
274
275void
276bgp_encap_type_transmit_tunnel_endpoint(
277 struct bgp_encap_type_transmit_tunnel_endpoint *bet, /* input structure */
278 struct attr *attr)
279{
280 struct attr_extra *extra = bgp_attr_extra_get(attr);
281 struct bgp_attr_encap_subtlv *last;
282
283 /* advance to last subtlv */
284 for (last = extra->encap_subtlvs; last && last->next; last = last->next);
285
286 extra->encap_tunneltype = BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT;
287
288 /* no subtlvs for this type */
289}
290
291void
292bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
293 struct bgp_encap_type_ipsec_in_tunnel_mode *bet, /* input structure */
294 struct attr *attr)
295{
296 struct attr_extra *extra = bgp_attr_extra_get(attr);
297 struct bgp_attr_encap_subtlv *last;
298
299 /* advance to last subtlv */
300 for (last = extra->encap_subtlvs; last && last->next; last = last->next);
301
302 extra->encap_tunneltype = BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE;
303
304 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta, st_ipsec_ta);
305}
306
307void
308bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
309 struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet, /* input structure */
310 struct attr *attr)
311{
312 struct attr_extra *extra = bgp_attr_extra_get(attr);
313 struct bgp_attr_encap_subtlv *last;
314
315 /* advance to last subtlv */
316 for (last = extra->encap_subtlvs; last && last->next; last = last->next);
317
318 extra->encap_tunneltype = BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
319
320 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta, st_ipsec_ta);
321}
322
323void
324bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
325 struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet, /* input structure */
326 struct attr *attr)
327{
328 struct attr_extra *extra = bgp_attr_extra_get(attr);
329 struct bgp_attr_encap_subtlv *last;
330
331 /* advance to last subtlv */
332 for (last = extra->encap_subtlvs; last && last->next; last = last->next);
333
334 extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE;
335
336 ENC_SUBTLV(BGP_TEA_SUBTLV_IPSEC_TA, subtlv_encode_ipsec_ta, st_ipsec_ta);
337}
338
339void
340bgp_encap_type_pbb_to_tlv(
341 struct bgp_encap_type_pbb *bet, /* input structure */
342 struct attr *attr)
343{
344 struct attr_extra *extra = bgp_attr_extra_get(attr);
345 struct bgp_attr_encap_subtlv *last;
346
347 /* advance to last subtlv */
348 for (last = extra->encap_subtlvs; last && last->next; last = last->next);
349
350 extra->encap_tunneltype = BGP_ENCAP_TYPE_PBB;
351
352 assert(CHECK_FLAG(bet->valid_subtlvs, BGP_TEA_SUBTLV_ENCAP));
353 ENC_SUBTLV(BGP_TEA_SUBTLV_ENCAP, subtlv_encode_encap_pbb, st_encap);
354}
355
356void
357bgp_encap_type_vxlan_to_tlv(
358 struct bgp_encap_type_vxlan *bet, /* input structure */
359 struct attr *attr)
360{
361 struct attr_extra *extra = bgp_attr_extra_get(attr);
362
363 extra->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN;
364}
365
366void
367bgp_encap_type_nvgre_to_tlv(
368 struct bgp_encap_type_nvgre *bet, /* input structure */
369 struct attr *attr)
370{
371 struct attr_extra *extra = bgp_attr_extra_get(attr);
372
373 extra->encap_tunneltype = BGP_ENCAP_TYPE_NVGRE;
374}
375
376void
377bgp_encap_type_mpls_to_tlv(
378 struct bgp_encap_type_mpls *bet, /* input structure */
379 struct attr *attr)
380{
381 struct attr_extra *extra = bgp_attr_extra_get(attr);
382
383 extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS;
384}
385
386void
387bgp_encap_type_mpls_in_gre_to_tlv(
388 struct bgp_encap_type_mpls_in_gre *bet, /* input structure */
389 struct attr *attr)
390{
391 struct attr_extra *extra = bgp_attr_extra_get(attr);
392
393 extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_GRE;
394}
395
396void
397bgp_encap_type_vxlan_gpe_to_tlv(
398 struct bgp_encap_type_vxlan_gpe *bet, /* input structure */
399 struct attr *attr)
400{
401 struct attr_extra *extra = bgp_attr_extra_get(attr);
402
403 extra->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN_GPE;
404}
405
406void
407bgp_encap_type_mpls_in_udp_to_tlv(
408 struct bgp_encap_type_mpls_in_udp *bet, /* input structure */
409 struct attr *attr)
410{
411 struct attr_extra *extra = bgp_attr_extra_get(attr);
412
413 extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_UDP;
414}
415
416
417/***********************************************************************
418 * SUBTLV DECODE
419 ***********************************************************************/
420/* rfc5512 4.1 */
421static int
422subtlv_decode_encap_l2tpv3_over_ip(
423 struct bgp_attr_encap_subtlv *subtlv,
424 struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
425{
426 if (subtlv->length < 4) {
427 zlog_debug("%s, subtlv length %d is less than 4",
428 __func__, subtlv->length);
429 return -1;
430 }
431
432 st->sessionid = (subtlv->value[0] << 24) |
433 (subtlv->value[1] << 16) |
434 (subtlv->value[2] << 8) |
435 subtlv->value[3];
436 st->cookie_length = subtlv->length - 4;
437 if (st->cookie_length > sizeof(st->cookie)) {
438 zlog_debug("%s, subtlv length %d is greater than %d",
439 __func__, st->cookie_length, (int)sizeof(st->cookie));
440 return -1;
441 }
442 memcpy(st->cookie, subtlv->value + 4, st->cookie_length);
443 return 0;
444}
445
446/* rfc5512 4.1 */
447static int
448subtlv_decode_encap_gre(
449 struct bgp_attr_encap_subtlv *subtlv,
450 struct bgp_tea_subtlv_encap_gre_key *st)
451{
452 if (subtlv->length != 4) {
453 zlog_debug("%s, subtlv length %d does not equal 4",
454 __func__, subtlv->length);
455 return -1;
456 }
457 st->gre_key = (subtlv->value[0] << 24) |
458 (subtlv->value[1] << 16) |
459 (subtlv->value[2] << 8) |
460 subtlv->value[3];
461 return 0;
462}
463
464static int
465subtlv_decode_encap_pbb(
466 struct bgp_attr_encap_subtlv *subtlv,
467 struct bgp_tea_subtlv_encap_pbb *st)
468{
469 if (subtlv->length != 1 + 3 + 6 + 2) {
470 zlog_debug("%s, subtlv length %d does not equal %d",
471 __func__, subtlv->length, 1 + 3 + 6 + 2);
472 return -1;
473 }
474 if (subtlv->value[0] & 0x80) {
475 st->flag_isid = 1;
476 st->isid = (subtlv->value[1] << 16) |
477 (subtlv->value[2] << 8) |
478 subtlv->value[3];
479 }
480 if (subtlv->value[0] & 0x40) {
481 st->flag_vid = 1;
482 st->vid = ((subtlv->value[10] & 0x0f) << 8) | subtlv->value[11];
483 }
484 memcpy(st->macaddr, subtlv->value + 4, 6);
485 return 0;
486}
487
488/* rfc5512 4.2 */
489static int
490subtlv_decode_proto_type(
491 struct bgp_attr_encap_subtlv *subtlv,
492 struct bgp_tea_subtlv_proto_type *st)
493{
494 if (subtlv->length != 2) {
495 zlog_debug("%s, subtlv length %d does not equal 2",
496 __func__, subtlv->length);
497 return -1;
498 }
499 st->proto = (subtlv->value[0] << 8) | subtlv->value[1];
500 return 0;
501}
502
503/* rfc5512 4.3 */
504static int
505subtlv_decode_color(
506 struct bgp_attr_encap_subtlv *subtlv,
507 struct bgp_tea_subtlv_color *st)
508{
509 if (subtlv->length != 8) {
510 zlog_debug("%s, subtlv length %d does not equal 8",
511 __func__, subtlv->length);
512 return -1;
513 }
514 if ((subtlv->value[0] != 0x03) ||
515 (subtlv->value[1] != 0x0b) ||
516 (subtlv->value[2] != 0) ||
517 (subtlv->value[3] != 0)) {
518 zlog_debug("%s, subtlv value 1st 4 bytes are not 0x030b0000", __func__);
519 return -1;
520 }
521 st->color = (subtlv->value[4] << 24) |
522 (subtlv->value[5] << 16) |
523 (subtlv->value[6] << 8) |
524 subtlv->value[7];
525 return 0;
526}
527
528/* rfc 5566 4. */
529static int
530subtlv_decode_ipsec_ta(
531 struct bgp_attr_encap_subtlv *subtlv,
532 struct bgp_tea_subtlv_ipsec_ta *st)
533{
534 st->authenticator_length = subtlv->length - 2;
535 if (st->authenticator_length > sizeof(st->value)) {
536 zlog_debug("%s, authenticator length %d exceeds storage maximum %d",
537 __func__, st->authenticator_length, (int)sizeof(st->value));
538 return -1;
539 }
540 st->authenticator_type = (subtlv->value[0] << 8) | subtlv->value[1];
541 memcpy(st->value, subtlv->value + 2, st->authenticator_length);
542 return 0;
543}
544
545/***********************************************************************
546 * TUNNEL TYPE-SPECIFIC TLV DECODE
547 ***********************************************************************/
548
549int
550tlv_to_bgp_encap_type_l2tpv3overip(
551 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
552 struct bgp_encap_type_l2tpv3_over_ip *bet) /* caller-allocated */
553{
554 struct bgp_attr_encap_subtlv *st;
555 int rc = 0;
556
557 for (st = stlv; st; st = st->next) {
558 switch (st->type) {
559 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
560 rc |= subtlv_decode_encap_l2tpv3_over_ip(st, &bet->st_encap);
561 bet->valid_subtlvs |= BGP_TEA_SUBTLV_ENCAP;
562 break;
563
564 case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
565 rc |= subtlv_decode_proto_type(st, &bet->st_proto);
566 bet->valid_subtlvs |= BGP_TEA_SUBTLV_PROTO_TYPE;
567 break;
568
569 case BGP_ENCAP_SUBTLV_TYPE_COLOR:
570 rc |= subtlv_decode_color(st, &bet->st_color);
571 bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
572 break;
573
574 default:
575 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
576 rc |= -1;
577 break;
578 }
579 }
580 return rc;
581}
582
583int
584tlv_to_bgp_encap_type_gre(
585 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
586 struct bgp_encap_type_gre *bet) /* caller-allocated */
587{
588 struct bgp_attr_encap_subtlv *st;
589 int rc = 0;
590
591 for (st = stlv; st; st = st->next) {
592 switch (st->type) {
593 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
594 rc |= subtlv_decode_encap_gre(st, &bet->st_encap);
595 bet->valid_subtlvs |= 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 bet->valid_subtlvs |= 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 bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
606 break;
607
608 default:
609 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
610 rc |= -1;
611 break;
612 }
613 }
614 return rc;
615}
616
617int
618tlv_to_bgp_encap_type_ip_in_ip(
619 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
620 struct bgp_encap_type_ip_in_ip *bet) /* caller-allocated */
621{
622 struct bgp_attr_encap_subtlv *st;
623 int rc = 0;
624
625 for (st = stlv; st; st = st->next) {
626 switch (st->type) {
627 case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
628 rc |= subtlv_decode_proto_type(st, &bet->st_proto);
629 bet->valid_subtlvs |= BGP_TEA_SUBTLV_PROTO_TYPE;
630 break;
631
632 case BGP_ENCAP_SUBTLV_TYPE_COLOR:
633 rc |= subtlv_decode_color(st, &bet->st_color);
634 bet->valid_subtlvs |= BGP_TEA_SUBTLV_COLOR;
635 break;
636
637 default:
638 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
639 rc |= -1;
640 break;
641 }
642 }
643 return rc;
644}
645
646int
647tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
648 struct bgp_attr_encap_subtlv *stlv,
649 struct bgp_encap_type_transmit_tunnel_endpoint *bet)
650{
651 struct bgp_attr_encap_subtlv *st;
652 int rc = 0;
653
654 for (st = stlv; st; st = st->next) {
655 switch (st->type) {
656 default:
657 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
658 rc |= -1;
659 break;
660 }
661 }
662 return rc;
663}
664
665int
666tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
667 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
668 struct bgp_encap_type_ipsec_in_tunnel_mode *bet) /* caller-allocated */
669{
670 struct bgp_attr_encap_subtlv *st;
671 int rc = 0;
672
673 for (st = stlv; st; st = st->next) {
674 switch (st->type) {
675 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
676 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
677 bet->valid_subtlvs |= BGP_TEA_SUBTLV_IPSEC_TA;
678 break;
679
680 default:
681 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
682 rc |= -1;
683 break;
684 }
685 }
686 return rc;
687}
688
689int
690tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
691 struct bgp_attr_encap_subtlv *stlv,
692 struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
693{
694 struct bgp_attr_encap_subtlv *st;
695 int rc = 0;
696
697 for (st = stlv; st; st = st->next) {
698 switch (st->type) {
699 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
700 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
701 bet->valid_subtlvs |= BGP_TEA_SUBTLV_IPSEC_TA;
702 break;
703
704 default:
705 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
706 rc |= -1;
707 break;
708 }
709 }
710 return rc;
711}
712
713int
714tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
715 struct bgp_attr_encap_subtlv *stlv,
716 struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
717{
718 struct bgp_attr_encap_subtlv *st;
719 int rc = 0;
720
721 for (st = stlv; st; st = st->next) {
722 switch (st->type) {
723 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
724 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
725 bet->valid_subtlvs |= BGP_TEA_SUBTLV_IPSEC_TA;
726 break;
727
728 default:
729 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
730 rc |= -1;
731 break;
732 }
733 }
734 return rc;
735}
736
737int
738tlv_to_bgp_encap_type_vxlan(
739 struct bgp_attr_encap_subtlv *stlv,
740 struct bgp_encap_type_vxlan *bet)
741{
742 struct bgp_attr_encap_subtlv *st;
743 int rc = 0;
744
745 for (st = stlv; st; st = st->next) {
746 switch (st->type) {
747 default:
748 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
749 rc |= -1;
750 break;
751 }
752 }
753 return rc;
754}
755
756int
757tlv_to_bgp_encap_type_nvgre(
758 struct bgp_attr_encap_subtlv *stlv,
759 struct bgp_encap_type_nvgre *bet)
760{
761 struct bgp_attr_encap_subtlv *st;
762 int rc = 0;
763
764 for (st = stlv; st; st = st->next) {
765 switch (st->type) {
766 default:
767 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
768 rc |= -1;
769 break;
770 }
771 }
772 return rc;
773}
774
775int
776tlv_to_bgp_encap_type_mpls(
777 struct bgp_attr_encap_subtlv *stlv,
778 struct bgp_encap_type_mpls *bet)
779{
780 struct bgp_attr_encap_subtlv *st;
781 int rc = 0;
782
783 for (st = stlv; st; st = st->next) {
784 switch (st->type) {
785 default:
786 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
787 rc |= -1;
788 break;
789 }
790 }
791 return rc;
792}
793
794int
795tlv_to_bgp_encap_type_mpls_in_gre(
796 struct bgp_attr_encap_subtlv *stlv,
797 struct bgp_encap_type_mpls_in_gre *bet)
798{
799 struct bgp_attr_encap_subtlv *st;
800 int rc = 0;
801
802 for (st = stlv; st; st = st->next) {
803 switch (st->type) {
804 default:
805 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
806 rc |= -1;
807 break;
808 }
809 }
810 return rc;
811}
812
813int
814tlv_to_bgp_encap_type_vxlan_gpe(
815 struct bgp_attr_encap_subtlv *stlv,
816 struct bgp_encap_type_vxlan_gpe *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 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_mpls_in_udp(
834 struct bgp_attr_encap_subtlv *stlv,
835 struct bgp_encap_type_mpls_in_udp *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) {
842 default:
843 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
844 rc |= -1;
845 break;
846 }
847 }
848 return rc;
849}
850
851int
852tlv_to_bgp_encap_type_pbb(
853 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
854 struct bgp_encap_type_pbb *bet) /* caller-allocated */
855{
856 struct bgp_attr_encap_subtlv *st;
857 int rc = 0;
858
859 for (st = stlv; st; st = st->next) {
860 switch (st->type) {
861 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
862 rc |= subtlv_decode_encap_pbb(st, &bet->st_encap);
863 bet->valid_subtlvs |= BGP_TEA_SUBTLV_ENCAP;
864 break;
865
866 default:
867 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
868 rc |= -1;
869 break;
870 }
871 }
872 return rc;
873}
874