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