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