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