File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgp_encap_tlv.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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>