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>