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