Annotation of embedaddon/quagga/bgpd/bgp_encap_tlv.c, revision 1.1.1.1
1.1 misho 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 "memory.h"
23: #include "prefix.h"
24: #include "vty.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:
394: extra->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN;
395: }
396:
397: void
398: bgp_encap_type_nvgre_to_tlv(
399: struct bgp_encap_type_nvgre *bet, /* input structure */
400: struct attr *attr)
401: {
402: struct attr_extra *extra = bgp_attr_extra_get(attr);
403:
404: extra->encap_tunneltype = BGP_ENCAP_TYPE_NVGRE;
405: }
406:
407: void
408: bgp_encap_type_mpls_to_tlv(
409: struct bgp_encap_type_mpls *bet, /* input structure */
410: struct attr *attr)
411: {
412: struct attr_extra *extra = bgp_attr_extra_get(attr);
413:
414: extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS;
415: }
416:
417: void
418: bgp_encap_type_mpls_in_gre_to_tlv(
419: struct bgp_encap_type_mpls_in_gre *bet, /* input structure */
420: struct attr *attr)
421: {
422: struct attr_extra *extra = bgp_attr_extra_get(attr);
423:
424: extra->encap_tunneltype = BGP_ENCAP_TYPE_MPLS_IN_GRE;
425: }
426:
427: void
428: bgp_encap_type_vxlan_gpe_to_tlv(
429: struct bgp_encap_type_vxlan_gpe *bet, /* input structure */
430: struct attr *attr)
431: {
432: struct attr_extra *extra = bgp_attr_extra_get(attr);
433:
434: extra->encap_tunneltype = BGP_ENCAP_TYPE_VXLAN_GPE;
435: }
436:
437: void
438: bgp_encap_type_mpls_in_udp_to_tlv(
439: struct bgp_encap_type_mpls_in_udp *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_UDP;
445: }
446:
447:
448: /***********************************************************************
449: * SUBTLV DECODE
450: ***********************************************************************/
451: /* rfc5512 4.1 */
452: static int
453: subtlv_decode_encap_l2tpv3_over_ip(
454: struct bgp_attr_encap_subtlv *subtlv,
455: struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
456: {
457: if (subtlv->length < 4) {
458: zlog_debug("%s, subtlv length %d is less than 4",
459: __func__, subtlv->length);
460: return -1;
461: }
462:
463: st->sessionid = (subtlv->value[0] << 24) |
464: (subtlv->value[1] << 16) |
465: (subtlv->value[2] << 8) |
466: subtlv->value[3];
467: st->cookie_length = subtlv->length - 4;
468: if (st->cookie_length > sizeof(st->cookie)) {
469: zlog_debug("%s, subtlv length %d is greater than %d",
470: __func__, st->cookie_length, (int)sizeof(st->cookie));
471: return -1;
472: }
473: memcpy(st->cookie, subtlv->value + 4, st->cookie_length);
474: return 0;
475: }
476:
477: /* rfc5512 4.1 */
478: static int
479: subtlv_decode_encap_gre(
480: struct bgp_attr_encap_subtlv *subtlv,
481: struct bgp_tea_subtlv_encap_gre_key *st)
482: {
483: if (subtlv->length != 4) {
484: zlog_debug("%s, subtlv length %d does not equal 4",
485: __func__, subtlv->length);
486: return -1;
487: }
488: st->gre_key = (subtlv->value[0] << 24) |
489: (subtlv->value[1] << 16) |
490: (subtlv->value[2] << 8) |
491: subtlv->value[3];
492: return 0;
493: }
494:
495: static int
496: subtlv_decode_encap_pbb(
497: struct bgp_attr_encap_subtlv *subtlv,
498: struct bgp_tea_subtlv_encap_pbb *st)
499: {
500: if (subtlv->length != 1 + 3 + 6 + 2) {
501: zlog_debug("%s, subtlv length %d does not equal %d",
502: __func__, subtlv->length, 1 + 3 + 6 + 2);
503: return -1;
504: }
505: if (subtlv->value[0] & 0x80) {
506: st->flag_isid = 1;
507: st->isid = (subtlv->value[1] << 16) |
508: (subtlv->value[2] << 8) |
509: subtlv->value[3];
510: }
511: if (subtlv->value[0] & 0x40) {
512: st->flag_vid = 1;
513: st->vid = ((subtlv->value[10] & 0x0f) << 8) | subtlv->value[11];
514: }
515: memcpy(st->macaddr, subtlv->value + 4, 6);
516: return 0;
517: }
518:
519: /* rfc5512 4.2 */
520: static int
521: subtlv_decode_proto_type(
522: struct bgp_attr_encap_subtlv *subtlv,
523: struct bgp_tea_subtlv_proto_type *st)
524: {
525: if (subtlv->length != 2) {
526: zlog_debug("%s, subtlv length %d does not equal 2",
527: __func__, subtlv->length);
528: return -1;
529: }
530: st->proto = (subtlv->value[0] << 8) | subtlv->value[1];
531: return 0;
532: }
533:
534: /* rfc5512 4.3 */
535: static int
536: subtlv_decode_color(
537: struct bgp_attr_encap_subtlv *subtlv,
538: struct bgp_tea_subtlv_color *st)
539: {
540: if (subtlv->length != 8) {
541: zlog_debug("%s, subtlv length %d does not equal 8",
542: __func__, subtlv->length);
543: return -1;
544: }
545: if ((subtlv->value[0] != 0x03) ||
546: (subtlv->value[1] != 0x0b) ||
547: (subtlv->value[2] != 0) ||
548: (subtlv->value[3] != 0)) {
549: zlog_debug("%s, subtlv value 1st 4 bytes are not 0x030b0000", __func__);
550: return -1;
551: }
552: st->color = (subtlv->value[4] << 24) |
553: (subtlv->value[5] << 16) |
554: (subtlv->value[6] << 8) |
555: subtlv->value[7];
556: return 0;
557: }
558:
559: /* rfc 5566 4. */
560: static int
561: subtlv_decode_ipsec_ta(
562: struct bgp_attr_encap_subtlv *subtlv,
563: struct bgp_tea_subtlv_ipsec_ta *st)
564: {
565: st->authenticator_length = subtlv->length - 2;
566: if (st->authenticator_length > sizeof(st->value)) {
567: zlog_debug("%s, authenticator length %d exceeds storage maximum %d",
568: __func__, st->authenticator_length, (int)sizeof(st->value));
569: return -1;
570: }
571: st->authenticator_type = (subtlv->value[0] << 8) | subtlv->value[1];
572: memcpy(st->value, subtlv->value + 2, st->authenticator_length);
573: return 0;
574: }
575:
576: /* draft-rosen-idr-tunnel-encaps 2.1 */
577: static int
578: subtlv_decode_remote_endpoint(
579: struct bgp_attr_encap_subtlv *subtlv,
580: struct bgp_tea_subtlv_remote_endpoint *st)
581: {
582: int i;
583: if (subtlv->length != 8 && subtlv->length != 20 ) {
584: zlog_debug("%s, subtlv length %d does not equal 8 or 20",
585: __func__, subtlv->length);
586: return -1;
587: }
588: if (subtlv->length == 8) {
589: st->family = AF_INET;
590: st->ip_address.v4.s_addr = ((subtlv->value[0] << 24) |
591: (subtlv->value[1] << 16) |
592: (subtlv->value[2] << 8) |
593: subtlv->value[3]);
594: } else {
595: st->family = AF_INET6;
596: memcpy (&(st->ip_address.v6.s6_addr), subtlv->value, 16);
597: }
598: i = subtlv->length - 4;
599: st->as4 = ((subtlv->value[i] << 24) |
600: (subtlv->value[i+1] << 16) |
601: (subtlv->value[i+2] << 8) |
602: subtlv->value[i+3]);
603: return 0;
604: }
605:
606: /***********************************************************************
607: * TUNNEL TYPE-SPECIFIC TLV DECODE
608: ***********************************************************************/
609:
610: int
611: tlv_to_bgp_encap_type_l2tpv3overip(
612: struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
613: struct bgp_encap_type_l2tpv3_over_ip *bet) /* caller-allocated */
614: {
615: struct bgp_attr_encap_subtlv *st;
616: int rc = 0;
617:
618: for (st = stlv; st; st = st->next) {
619: switch (st->type) {
620: case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
621: rc |= subtlv_decode_encap_l2tpv3_over_ip(st, &bet->st_encap);
622: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
623: break;
624:
625: case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
626: rc |= subtlv_decode_proto_type(st, &bet->st_proto);
627: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
628: break;
629:
630: case BGP_ENCAP_SUBTLV_TYPE_COLOR:
631: rc |= subtlv_decode_color(st, &bet->st_color);
632: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
633: break;
634:
635: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
636: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
637: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
638: break;
639:
640: default:
641: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
642: rc |= -1;
643: break;
644: }
645: }
646: return rc;
647: }
648:
649: int
650: tlv_to_bgp_encap_type_gre(
651: struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
652: struct bgp_encap_type_gre *bet) /* caller-allocated */
653: {
654: struct bgp_attr_encap_subtlv *st;
655: int rc = 0;
656:
657: for (st = stlv; st; st = st->next) {
658: switch (st->type) {
659: case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
660: rc |= subtlv_decode_encap_gre(st, &bet->st_encap);
661: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
662: break;
663:
664: case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
665: rc |= subtlv_decode_proto_type(st, &bet->st_proto);
666: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
667: break;
668:
669: case BGP_ENCAP_SUBTLV_TYPE_COLOR:
670: rc |= subtlv_decode_color(st, &bet->st_color);
671: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
672: break;
673:
674: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
675: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
676: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
677: break;
678:
679: default:
680: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
681: rc |= -1;
682: break;
683: }
684: }
685: return rc;
686: }
687:
688: int
689: tlv_to_bgp_encap_type_ip_in_ip(
690: struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
691: struct bgp_encap_type_ip_in_ip *bet) /* caller-allocated */
692: {
693: struct bgp_attr_encap_subtlv *st;
694: int rc = 0;
695:
696: for (st = stlv; st; st = st->next) {
697: switch (st->type) {
698: case BGP_ENCAP_SUBTLV_TYPE_PROTO_TYPE:
699: rc |= subtlv_decode_proto_type(st, &bet->st_proto);
700: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_PROTO_TYPE);
701: break;
702:
703: case BGP_ENCAP_SUBTLV_TYPE_COLOR:
704: rc |= subtlv_decode_color(st, &bet->st_color);
705: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_COLOR);
706: break;
707:
708: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
709: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
710: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
711: break;
712:
713: default:
714: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
715: rc |= -1;
716: break;
717: }
718: }
719: return rc;
720: }
721:
722: int
723: tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
724: struct bgp_attr_encap_subtlv *stlv,
725: struct bgp_encap_type_transmit_tunnel_endpoint *bet)
726: {
727: struct bgp_attr_encap_subtlv *st;
728: int rc = 0;
729:
730: for (st = stlv; st; st = st->next) {
731: switch (st->type) {
732:
733: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
734: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
735: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
736: break;
737:
738: default:
739: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
740: rc |= -1;
741: break;
742: }
743: }
744: return rc;
745: }
746:
747: int
748: tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
749: struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
750: struct bgp_encap_type_ipsec_in_tunnel_mode *bet) /* caller-allocated */
751: {
752: struct bgp_attr_encap_subtlv *st;
753: int rc = 0;
754:
755: for (st = stlv; st; st = st->next) {
756: switch (st->type) {
757: case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
758: rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
759: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
760: break;
761:
762: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
763: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
764: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
765: break;
766:
767: default:
768: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
769: rc |= -1;
770: break;
771: }
772: }
773: return rc;
774: }
775:
776: int
777: tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
778: struct bgp_attr_encap_subtlv *stlv,
779: struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
780: {
781: struct bgp_attr_encap_subtlv *st;
782: int rc = 0;
783:
784: for (st = stlv; st; st = st->next) {
785: switch (st->type) {
786: case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
787: rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
788: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
789: break;
790:
791: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
792: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
793: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
794: break;
795:
796: default:
797: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
798: rc |= -1;
799: break;
800: }
801: }
802: return rc;
803: }
804:
805: int
806: tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
807: struct bgp_attr_encap_subtlv *stlv,
808: struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
809: {
810: struct bgp_attr_encap_subtlv *st;
811: int rc = 0;
812:
813: for (st = stlv; st; st = st->next) {
814: switch (st->type) {
815: case BGP_ENCAP_SUBTLV_TYPE_IPSEC_TA:
816: rc |= subtlv_decode_ipsec_ta(st, &bet->st_ipsec_ta);
817: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_IPSEC_TA);
818: break;
819:
820: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
821: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
822: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
823: break;
824:
825: default:
826: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
827: rc |= -1;
828: break;
829: }
830: }
831: return rc;
832: }
833:
834: int
835: tlv_to_bgp_encap_type_vxlan(
836: struct bgp_attr_encap_subtlv *stlv,
837: struct bgp_encap_type_vxlan *bet)
838: {
839: struct bgp_attr_encap_subtlv *st;
840: int rc = 0;
841:
842: for (st = stlv; st; st = st->next) {
843: switch (st->type) {
844:
845: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
846: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
847: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
848: break;
849:
850: default:
851: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
852: rc |= -1;
853: break;
854: }
855: }
856: return rc;
857: }
858:
859: int
860: tlv_to_bgp_encap_type_nvgre(
861: struct bgp_attr_encap_subtlv *stlv,
862: struct bgp_encap_type_nvgre *bet)
863: {
864: struct bgp_attr_encap_subtlv *st;
865: int rc = 0;
866:
867: for (st = stlv; st; st = st->next) {
868: switch (st->type) {
869:
870: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
871: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
872: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
873: break;
874:
875: default:
876: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
877: rc |= -1;
878: break;
879: }
880: }
881: return rc;
882: }
883:
884: int
885: tlv_to_bgp_encap_type_mpls(
886: struct bgp_attr_encap_subtlv *stlv,
887: struct bgp_encap_type_mpls *bet)
888: {
889: struct bgp_attr_encap_subtlv *st;
890: int rc = 0;
891:
892: for (st = stlv; st; st = st->next) {
893: switch (st->type) {
894:
895: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
896: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
897: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
898: break;
899:
900: default:
901: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
902: rc |= -1;
903: break;
904: }
905: }
906: return rc;
907: }
908:
909: int
910: tlv_to_bgp_encap_type_mpls_in_gre(
911: struct bgp_attr_encap_subtlv *stlv,
912: struct bgp_encap_type_mpls_in_gre *bet)
913: {
914: struct bgp_attr_encap_subtlv *st;
915: int rc = 0;
916:
917: for (st = stlv; st; st = st->next) {
918: switch (st->type) {
919:
920: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
921: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
922: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
923: break;
924:
925: default:
926: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
927: rc |= -1;
928: break;
929: }
930: }
931: return rc;
932: }
933:
934: int
935: tlv_to_bgp_encap_type_vxlan_gpe(
936: struct bgp_attr_encap_subtlv *stlv,
937: struct bgp_encap_type_vxlan_gpe *bet)
938: {
939: struct bgp_attr_encap_subtlv *st;
940: int rc = 0;
941:
942: for (st = stlv; st; st = st->next) {
943: switch (st->type) {
944:
945: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
946: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
947: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
948: break;
949:
950: default:
951: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
952: rc |= -1;
953: break;
954: }
955: }
956: return rc;
957: }
958:
959: int
960: tlv_to_bgp_encap_type_mpls_in_udp(
961: struct bgp_attr_encap_subtlv *stlv,
962: struct bgp_encap_type_mpls_in_udp *bet)
963: {
964: struct bgp_attr_encap_subtlv *st;
965: int rc = 0;
966:
967: for (st = stlv; st; st = st->next) {
968: switch (st->type) {
969:
970: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
971: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
972: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
973: break;
974:
975: default:
976: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
977: rc |= -1;
978: break;
979: }
980: }
981: return rc;
982: }
983:
984: int
985: tlv_to_bgp_encap_type_pbb(
986: struct bgp_attr_encap_subtlv *stlv, /* subtlv chain */
987: struct bgp_encap_type_pbb *bet) /* caller-allocated */
988: {
989: struct bgp_attr_encap_subtlv *st;
990: int rc = 0;
991:
992: for (st = stlv; st; st = st->next) {
993: switch (st->type) {
994: case BGP_ENCAP_SUBTLV_TYPE_ENCAPSULATION:
995: rc |= subtlv_decode_encap_pbb(st, &bet->st_encap);
996: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_ENCAP);
997: break;
998:
999: case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT:
1000: rc |= subtlv_decode_remote_endpoint(st, &bet->st_endpoint);
1001: SET_SUBTLV_FLAG(bet, BGP_TEA_SUBTLV_REMOTE_ENDPOINT);
1002: break;
1003:
1004: default:
1005: zlog_debug("%s: unexpected subtlv type %d", __func__, st->type);
1006: rc |= -1;
1007: break;
1008: }
1009: }
1010: return rc;
1011: }
1012:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>