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