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