]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - bgpd/bgp_encap_tlv.c
Import Upstream version 1.2.2
[quagga-debian.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 "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