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