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