blob: 347b4b3ce72c70ab29581e37b58c1b0b165e7bc6 [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
Lou Berger298cc2f2016-01-12 13:42:02 -0500199/* 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}
Lou Bergerc3741782016-01-12 13:42:01 -0500227
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);
Lou Berger298cc2f2016-01-12 13:42:02 -0500266 ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT, subtlv_encode_remote_endpoint, st_endpoint);
Lou Bergerc3741782016-01-12 13:42:01 -0500267}
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);
Lou Berger298cc2f2016-01-12 13:42:02 -0500285 ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT, subtlv_encode_remote_endpoint, st_endpoint);
Lou Bergerc3741782016-01-12 13:42:01 -0500286}
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);
Lou Berger298cc2f2016-01-12 13:42:02 -0500303 ENC_SUBTLV(BGP_TEA_SUBTLV_REMOTE_ENDPOINT, subtlv_encode_remote_endpoint, st_endpoint);
Lou Bergerc3741782016-01-12 13:42:01 -0500304}
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{
412 struct attr_extra *extra = bgp_attr_extra_get(attr);
413
414 extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS;
415}
416
417void
418bgp_encap_type_mpls_in_gre_to_tlv(
419 struct bgp_encap_type_mpls_in_gre *bet, /* input structure */
420 struct attr *attr)
421{
422 struct attr_extra *extra = bgp_attr_extra_get(attr);
423
424 extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_GRE;
425}
426
427void
428bgp_encap_type_vxlan_gpe_to_tlv(
429 struct bgp_encap_type_vxlan_gpe *bet, /* input structure */
430 struct attr *attr)
431{
432 struct attr_extra *extra = bgp_attr_extra_get(attr);
433
434 extra->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN_GPE;
435}
436
437void
438bgp_encap_type_mpls_in_udp_to_tlv(
439 struct bgp_encap_type_mpls_in_udp *bet, /* input structure */
440 struct attr *attr)
441{
442 struct attr_extra *extra = bgp_attr_extra_get(attr);
443
444 extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_UDP;
445}
446
447
448/***********************************************************************
449 * SUBTLV DECODE
450 ***********************************************************************/
451/* rfc5512 4.1 */
452static int
453subtlv_decode_encap_l2tpv3_over_ip(
454 struct bgp_attr_encap_subtlv *subtlv,
455 struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
456{
457 if (subtlv->length < 4) {
458 zlog_debug("%s, subtlv length %d is less than 4",
459 __func__, subtlv->length);
460 return -1;
461 }
462
463 st->sessionid = (subtlv->value[0] << 24) |
464 (subtlv->value[1] << 16) |
465 (subtlv->value[2] << 8) |
466 subtlv->value[3];
467 st->cookie_length = subtlv->length - 4;
468 if (st->cookie_length > sizeof(st->cookie)) {
469 zlog_debug("%s, subtlv length %d is greater than %d",
470 __func__, st->cookie_length, (int)sizeof(st->cookie));
471 return -1;
472 }
473 memcpy(st->cookie, subtlv->value + 4, st->cookie_length);
474 return 0;
475}
476
477/* rfc5512 4.1 */
478static int
479subtlv_decode_encap_gre(
480 struct bgp_attr_encap_subtlv *subtlv,
481 struct bgp_tea_subtlv_encap_gre_key *st)
482{
483 if (subtlv->length != 4) {
484 zlog_debug("%s, subtlv length %d does not equal 4",
485 __func__, subtlv->length);
486 return -1;
487 }
488 st->gre_key = (subtlv->value[0] << 24) |
489 (subtlv->value[1] << 16) |
490 (subtlv->value[2] << 8) |
491 subtlv->value[3];
492 return 0;
493}
494
495static int
496subtlv_decode_encap_pbb(
497 struct bgp_attr_encap_subtlv *subtlv,
498 struct bgp_tea_subtlv_encap_pbb *st)
499{
500 if (subtlv->length != 1 + 3 + 6 + 2) {
501 zlog_debug("%s, subtlv length %d does not equal %d",
502 __func__, subtlv->length, 1 + 3 + 6 + 2);
503 return -1;
504 }
505 if (subtlv->value[0] & 0x80) {
506 st->flag_isid = 1;
507 st->isid = (subtlv->value[1] << 16) |
508 (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 */
520static int
521subtlv_decode_proto_type(
522 struct bgp_attr_encap_subtlv *subtlv,
523 struct bgp_tea_subtlv_proto_type *st)
524{
525 if (subtlv->length != 2) {
526 zlog_debug("%s, subtlv length %d does not equal 2",
527 __func__, subtlv->length);
528 return -1;
529 }
530 st->proto = (subtlv->value[0] << 8) | subtlv->value[1];
531 return 0;
532}
533
534/* rfc5512 4.3 */
535static int
536subtlv_decode_color(
537 struct bgp_attr_encap_subtlv *subtlv,
538 struct bgp_tea_subtlv_color *st)
539{
540 if (subtlv->length != 8) {
541 zlog_debug("%s, subtlv length %d does not equal 8",
542 __func__, subtlv->length);
543 return -1;
544 }
545 if ((subtlv->value[0] != 0x03) ||
546 (subtlv->value[1] != 0x0b) ||
547 (subtlv->value[2] != 0) ||
548 (subtlv->value[3] != 0)) {
549 zlog_debug("%s, subtlv value 1st 4 bytes are not 0x030b0000", __func__);
550 return -1;
551 }
552 st->color = (subtlv->value[4] << 24) |
553 (subtlv->value[5] << 16) |
554 (subtlv->value[6] << 8) |
555 subtlv->value[7];
556 return 0;
557}
558
559/* rfc 5566 4. */
560static int
561subtlv_decode_ipsec_ta(
562 struct bgp_attr_encap_subtlv *subtlv,
563 struct bgp_tea_subtlv_ipsec_ta *st)
564{
565 st->authenticator_length = subtlv->length - 2;
566 if (st->authenticator_length > sizeof(st->value)) {
567 zlog_debug("%s, authenticator length %d exceeds storage maximum %d",
568 __func__, st->authenticator_length, (int)sizeof(st->value));
569 return -1;
570 }
571 st->authenticator_type = (subtlv->value[0] << 8) | subtlv->value[1];
572 memcpy(st->value, subtlv->value + 2, st->authenticator_length);
573 return 0;
574}
575
Lou Berger298cc2f2016-01-12 13:42:02 -0500576/* draft-rosen-idr-tunnel-encaps 2.1 */
577static int
578subtlv_decode_remote_endpoint(
579 struct bgp_attr_encap_subtlv *subtlv,
580 struct bgp_tea_subtlv_remote_endpoint *st)
581{
582 int i;
583 if (subtlv->length != 8 && subtlv->length != 20 ) {
584 zlog_debug("%s, subtlv length %d does not equal 8 or 20",
585 __func__, subtlv->length);
586 return -1;
587 }
588 if (subtlv->length == 8) {
589 st->family = AF_INET;
590 st->ip_address.v4.s_addr = ((subtlv->value[0] << 24) |
591 (subtlv->value[1] << 16) |
592 (subtlv->value[2] << 8) |
593 subtlv->value[3]);
594 } else {
595 st->family = AF_INET6;
596 memcpy (&(st->ip_address.v6.s6_addr), subtlv->value, 16);
597 }
598 i = subtlv->length - 4;
599 st->as4 = ((subtlv->value[i] << 24) |
600 (subtlv->value[i+1] << 16) |
601 (subtlv->value[i+2] << 8) |
602 subtlv->value[i+3]);
603 return 0;
604}
605
Lou Bergerc3741782016-01-12 13:42:01 -0500606/***********************************************************************
607 * TUNNEL TYPE-SPECIFIC TLV DECODE
608 ***********************************************************************/
609
610int
611tlv_to_bgp_encap_type_l2tpv3overip(
612 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
613 struct bgp_encap_type_l2tpv3_over_ip *bet) /* caller-allocated */
614{
615 struct bgp_attr_encap_subtlv *st;
616 int rc = 0;
617
618 for (st = stlv; st; st = st->next) {
619 switch (st->type) {
620 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
621 rc |= subtlv_decode_encap_l2tpv3_over_ip(st, &bet->st_encap);
Lou Berger298cc2f2016-01-12 13:42:02 -0500622 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
Lou Bergerc3741782016-01-12 13:42:01 -0500623 break;
624
625 case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
626 rc |= subtlv_decode_proto_type(st, &bet->st_proto);
Lou Berger298cc2f2016-01-12 13:42:02 -0500627 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
Lou Bergerc3741782016-01-12 13:42:01 -0500628 break;
629
630 case BGP_ENCAP_SUBTLV_TYPE_COLOR:
631 rc |= subtlv_decode_color(st, &bet->st_color);
Lou Berger298cc2f2016-01-12 13:42:02 -0500632 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
633 break;
634
635 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
636 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
637 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
Lou Bergerc3741782016-01-12 13:42:01 -0500638 break;
639
640 default:
641 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
642 rc |= -1;
643 break;
644 }
645 }
646 return rc;
647}
648
649int
650tlv_to_bgp_encap_type_gre(
651 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
652 struct bgp_encap_type_gre *bet) /* caller-allocated */
653{
654 struct bgp_attr_encap_subtlv *st;
655 int rc = 0;
656
657 for (st = stlv; st; st = st->next) {
658 switch (st->type) {
659 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
660 rc |= subtlv_decode_encap_gre(st, &bet->st_encap);
Lou Berger298cc2f2016-01-12 13:42:02 -0500661 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
Lou Bergerc3741782016-01-12 13:42:01 -0500662 break;
663
664 case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
665 rc |= subtlv_decode_proto_type(st, &bet->st_proto);
Lou Berger298cc2f2016-01-12 13:42:02 -0500666 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
Lou Bergerc3741782016-01-12 13:42:01 -0500667 break;
668
669 case BGP_ENCAP_SUBTLV_TYPE_COLOR:
670 rc |= subtlv_decode_color(st, &bet->st_color);
Lou Berger298cc2f2016-01-12 13:42:02 -0500671 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
672 break;
673
674 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
675 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
676 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
Lou Bergerc3741782016-01-12 13:42:01 -0500677 break;
678
679 default:
680 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
681 rc |= -1;
682 break;
683 }
684 }
685 return rc;
686}
687
688int
689tlv_to_bgp_encap_type_ip_in_ip(
690 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
691 struct bgp_encap_type_ip_in_ip *bet) /* caller-allocated */
692{
693 struct bgp_attr_encap_subtlv *st;
694 int rc = 0;
695
696 for (st = stlv; st; st = st->next) {
697 switch (st->type) {
698 case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
699 rc |= subtlv_decode_proto_type(st, &bet->st_proto);
Lou Berger298cc2f2016-01-12 13:42:02 -0500700 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
Lou Bergerc3741782016-01-12 13:42:01 -0500701 break;
702
703 case BGP_ENCAP_SUBTLV_TYPE_COLOR:
704 rc |= subtlv_decode_color(st, &bet->st_color);
Lou Berger298cc2f2016-01-12 13:42:02 -0500705 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
706 break;
707
708 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
709 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
710 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
Lou Bergerc3741782016-01-12 13:42:01 -0500711 break;
712
713 default:
714 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
715 rc |= -1;
716 break;
717 }
718 }
719 return rc;
720}
721
722int
723tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
724 struct bgp_attr_encap_subtlv *stlv,
725 struct bgp_encap_type_transmit_tunnel_endpoint *bet)
726{
727 struct bgp_attr_encap_subtlv *st;
728 int rc = 0;
729
730 for (st = stlv; st; st = st->next) {
731 switch (st->type) {
Lou Berger298cc2f2016-01-12 13:42:02 -0500732
733 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
734 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
735 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
736 break;
737
Lou Bergerc3741782016-01-12 13:42:01 -0500738 default:
739 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
740 rc |= -1;
741 break;
742 }
743 }
744 return rc;
745}
746
747int
748tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
749 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
750 struct bgp_encap_type_ipsec_in_tunnel_mode *bet) /* caller-allocated */
751{
752 struct bgp_attr_encap_subtlv *st;
753 int rc = 0;
754
755 for (st = stlv; st; st = st->next) {
756 switch (st->type) {
757 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
758 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
Lou Berger298cc2f2016-01-12 13:42:02 -0500759 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
760 break;
761
762 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
763 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
764 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
Lou Bergerc3741782016-01-12 13:42:01 -0500765 break;
766
767 default:
768 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
769 rc |= -1;
770 break;
771 }
772 }
773 return rc;
774}
775
776int
777tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
778 struct bgp_attr_encap_subtlv *stlv,
779 struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
780{
781 struct bgp_attr_encap_subtlv *st;
782 int rc = 0;
783
784 for (st = stlv; st; st = st->next) {
785 switch (st->type) {
786 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
787 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
Lou Berger298cc2f2016-01-12 13:42:02 -0500788 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
789 break;
790
791 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
792 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
793 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
Lou Bergerc3741782016-01-12 13:42:01 -0500794 break;
795
796 default:
797 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
798 rc |= -1;
799 break;
800 }
801 }
802 return rc;
803}
804
805int
806tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
807 struct bgp_attr_encap_subtlv *stlv,
808 struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
809{
810 struct bgp_attr_encap_subtlv *st;
811 int rc = 0;
812
813 for (st = stlv; st; st = st->next) {
814 switch (st->type) {
815 case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
816 rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
Lou Berger298cc2f2016-01-12 13:42:02 -0500817 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
818 break;
819
820 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
821 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
822 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
Lou Bergerc3741782016-01-12 13:42:01 -0500823 break;
824
825 default:
826 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
827 rc |= -1;
828 break;
829 }
830 }
831 return rc;
832}
833
834int
835tlv_to_bgp_encap_type_vxlan(
836 struct bgp_attr_encap_subtlv *stlv,
837 struct bgp_encap_type_vxlan *bet)
838{
839 struct bgp_attr_encap_subtlv *st;
840 int rc = 0;
841
842 for (st = stlv; st; st = st->next) {
843 switch (st->type) {
Lou Berger298cc2f2016-01-12 13:42:02 -0500844
845 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
846 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
847 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
848 break;
849
Lou Bergerc3741782016-01-12 13:42:01 -0500850 default:
851 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
852 rc |= -1;
853 break;
854 }
855 }
856 return rc;
857}
858
859int
860tlv_to_bgp_encap_type_nvgre(
861 struct bgp_attr_encap_subtlv *stlv,
862 struct bgp_encap_type_nvgre *bet)
863{
864 struct bgp_attr_encap_subtlv *st;
865 int rc = 0;
866
867 for (st = stlv; st; st = st->next) {
868 switch (st->type) {
Lou Berger298cc2f2016-01-12 13:42:02 -0500869
870 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
871 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
872 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
873 break;
874
Lou Bergerc3741782016-01-12 13:42:01 -0500875 default:
876 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
877 rc |= -1;
878 break;
879 }
880 }
881 return rc;
882}
883
884int
885tlv_to_bgp_encap_type_mpls(
886 struct bgp_attr_encap_subtlv *stlv,
887 struct bgp_encap_type_mpls *bet)
888{
889 struct bgp_attr_encap_subtlv *st;
890 int rc = 0;
891
892 for (st = stlv; st; st = st->next) {
893 switch (st->type) {
Lou Berger298cc2f2016-01-12 13:42:02 -0500894
895 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
896 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
897 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
898 break;
899
Lou Bergerc3741782016-01-12 13:42:01 -0500900 default:
901 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
902 rc |= -1;
903 break;
904 }
905 }
906 return rc;
907}
908
909int
910tlv_to_bgp_encap_type_mpls_in_gre(
911 struct bgp_attr_encap_subtlv *stlv,
912 struct bgp_encap_type_mpls_in_gre *bet)
913{
914 struct bgp_attr_encap_subtlv *st;
915 int rc = 0;
916
917 for (st = stlv; st; st = st->next) {
918 switch (st->type) {
Lou Berger298cc2f2016-01-12 13:42:02 -0500919
920 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
921 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
922 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
923 break;
924
Lou Bergerc3741782016-01-12 13:42:01 -0500925 default:
926 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
927 rc |= -1;
928 break;
929 }
930 }
931 return rc;
932}
933
934int
935tlv_to_bgp_encap_type_vxlan_gpe(
936 struct bgp_attr_encap_subtlv *stlv,
937 struct bgp_encap_type_vxlan_gpe *bet)
938{
939 struct bgp_attr_encap_subtlv *st;
940 int rc = 0;
941
942 for (st = stlv; st; st = st->next) {
943 switch (st->type) {
Lou Berger298cc2f2016-01-12 13:42:02 -0500944
945 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
946 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
947 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
948 break;
949
Lou Bergerc3741782016-01-12 13:42:01 -0500950 default:
951 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
952 rc |= -1;
953 break;
954 }
955 }
956 return rc;
957}
958
959int
960tlv_to_bgp_encap_type_mpls_in_udp(
961 struct bgp_attr_encap_subtlv *stlv,
962 struct bgp_encap_type_mpls_in_udp *bet)
963{
964 struct bgp_attr_encap_subtlv *st;
965 int rc = 0;
966
967 for (st = stlv; st; st = st->next) {
968 switch (st->type) {
Lou Berger298cc2f2016-01-12 13:42:02 -0500969
970 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
971 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
972 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
973 break;
974
Lou Bergerc3741782016-01-12 13:42:01 -0500975 default:
976 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
977 rc |= -1;
978 break;
979 }
980 }
981 return rc;
982}
983
984int
985tlv_to_bgp_encap_type_pbb(
986 struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
987 struct bgp_encap_type_pbb *bet) /* caller-allocated */
988{
989 struct bgp_attr_encap_subtlv *st;
990 int rc = 0;
991
992 for (st = stlv; st; st = st->next) {
993 switch (st->type) {
994 case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
995 rc |= subtlv_decode_encap_pbb(st, &bet->st_encap);
Lou Berger298cc2f2016-01-12 13:42:02 -0500996 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
997 break;
998
999 case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
1000 rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
1001 SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
Lou Bergerc3741782016-01-12 13:42:01 -05001002 break;
1003
1004 default:
1005 zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
1006 rc |= -1;
1007 break;
1008 }
1009 }
1010 return rc;
1011}
1012