mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 01:43:38 +00:00 
			
		
		
		
	cleanup memory allocations asserting that it didn't fail as well as clean up some thread shenanigans. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
		
			
				
	
	
		
			744 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			744 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright 2015-2016, LabN Consulting, L.L.C.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU General Public License
 | 
						|
 * as published by the Free Software Foundation; either version 2
 | 
						|
 * of the License, or (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License along
 | 
						|
 * with this program; see the file COPYING; if not, write to the Free Software
 | 
						|
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 | 
						|
 */
 | 
						|
 | 
						|
#include "lib/zebra.h"
 | 
						|
 | 
						|
#include "lib/memory.h"
 | 
						|
#include "lib/prefix.h"
 | 
						|
#include "lib/table.h"
 | 
						|
#include "lib/vty.h"
 | 
						|
 | 
						|
#include "bgpd/bgpd.h"
 | 
						|
#include "bgpd/bgp_attr.h"
 | 
						|
 | 
						|
#include "bgpd/bgp_encap_types.h"
 | 
						|
#include "bgpd/bgp_encap_tlv.h"
 | 
						|
 | 
						|
#include "bgpd/rfapi/rfapi.h"
 | 
						|
#include "bgpd/rfapi/rfapi_encap_tlv.h"
 | 
						|
#include "bgpd/rfapi/rfapi_private.h"
 | 
						|
#include "bgpd/rfapi/rfapi_monitor.h"
 | 
						|
#include "bgpd/rfapi/rfapi_vty.h"
 | 
						|
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
 | 
						|
#include "bgpd/rfapi/vnc_debug.h"
 | 
						|
 | 
						|
static void rfapi_add_endpoint_address_to_subtlv(
 | 
						|
	struct bgp *bgp, struct rfapi_ip_addr *ea,
 | 
						|
	struct bgp_tea_subtlv_remote_endpoint *subtlv)
 | 
						|
{
 | 
						|
	subtlv->family = ea->addr_family;
 | 
						|
	if (subtlv->family == AF_INET)
 | 
						|
		subtlv->ip_address.v4 = ea->addr.v4;
 | 
						|
	else
 | 
						|
		subtlv->ip_address.v6 = ea->addr.v6;
 | 
						|
	subtlv->as4 = htonl(bgp->as);
 | 
						|
}
 | 
						|
 | 
						|
bgp_encap_types
 | 
						|
rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea,
 | 
						|
			       struct rfapi_tunneltype_option *tto,
 | 
						|
			       struct attr *attr, int always_add)
 | 
						|
{
 | 
						|
 | 
						|
#define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype)                                \
 | 
						|
	if ((always_add                                                        \
 | 
						|
	     || (bgp->rfapi_cfg                                                \
 | 
						|
		 && !CHECK_FLAG(bgp->rfapi_cfg->flags,                         \
 | 
						|
				BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)))          \
 | 
						|
	    && ea                                                              \
 | 
						|
	    && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype,                         \
 | 
						|
				  BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) {           \
 | 
						|
		rfapi_add_endpoint_address_to_subtlv(                          \
 | 
						|
			bgp, ea, &tto->bgpinfo.ttype.st_endpoint);             \
 | 
						|
		SET_SUBTLV_FLAG(&tto->bgpinfo.ttype,                           \
 | 
						|
				BGP_TEA_SUBTLV_REMOTE_ENDPOINT);               \
 | 
						|
	}
 | 
						|
 | 
						|
	struct rfapi_tunneltype_option dto;
 | 
						|
	if (tto == NULL) { /* create default type */
 | 
						|
		tto = &dto;
 | 
						|
		memset(tto, 0, sizeof(dto));
 | 
						|
		tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT;
 | 
						|
	}
 | 
						|
	switch (tto->type) {
 | 
						|
	case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(l2tpv3_ip);
 | 
						|
		bgp_encap_type_l2tpv3overip_to_tlv(&tto->bgpinfo.l2tpv3_ip,
 | 
						|
						   attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_GRE:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(gre);
 | 
						|
		bgp_encap_type_gre_to_tlv(&tto->bgpinfo.gre, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(transmit_tunnel_endpoint);
 | 
						|
		bgp_encap_type_transmit_tunnel_endpoint(
 | 
						|
			&tto->bgpinfo.transmit_tunnel_endpoint, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ipsec_tunnel);
 | 
						|
		bgp_encap_type_ipsec_in_tunnel_mode_to_tlv(
 | 
						|
			&tto->bgpinfo.ipsec_tunnel, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ipsec);
 | 
						|
		bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
 | 
						|
			&tto->bgpinfo.ip_ipsec, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_ipsec);
 | 
						|
		bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv(
 | 
						|
			&tto->bgpinfo.mpls_ipsec, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IP_IN_IP:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ip);
 | 
						|
		bgp_encap_type_ip_in_ip_to_tlv(&tto->bgpinfo.ip_ip, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_VXLAN:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan);
 | 
						|
		bgp_encap_type_vxlan_to_tlv(&tto->bgpinfo.vxlan, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_NVGRE:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(nvgre);
 | 
						|
		bgp_encap_type_nvgre_to_tlv(&tto->bgpinfo.nvgre, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS:
 | 
						|
		/* nothing to do for MPLS */
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_GRE:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_gre);
 | 
						|
		bgp_encap_type_mpls_in_gre_to_tlv(&tto->bgpinfo.mpls_gre, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_VXLAN_GPE:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan_gpe);
 | 
						|
		bgp_encap_type_vxlan_gpe_to_tlv(&tto->bgpinfo.vxlan_gpe, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_UDP:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_udp);
 | 
						|
		bgp_encap_type_mpls_in_udp_to_tlv(&tto->bgpinfo.mpls_udp, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_PBB:
 | 
						|
		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(pbb);
 | 
						|
		bgp_encap_type_pbb_to_tlv(&tto->bgpinfo.pbb, attr);
 | 
						|
		break;
 | 
						|
 | 
						|
	default:
 | 
						|
		assert(0);
 | 
						|
	}
 | 
						|
	return tto->type;
 | 
						|
}
 | 
						|
 | 
						|
struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr)
 | 
						|
{
 | 
						|
	struct rfapi_un_option *uo = NULL;
 | 
						|
	struct rfapi_tunneltype_option *tto;
 | 
						|
	int rc;
 | 
						|
	struct bgp_attr_encap_subtlv *stlv;
 | 
						|
 | 
						|
	/* no tunnel encap attr stored */
 | 
						|
	if (!attr->encap_tunneltype)
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	stlv = attr->encap_subtlvs;
 | 
						|
 | 
						|
	uo = XCALLOC(MTYPE_RFAPI_UN_OPTION, sizeof(struct rfapi_un_option));
 | 
						|
	uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE;
 | 
						|
	uo->v.tunnel.type = attr->encap_tunneltype;
 | 
						|
	tto = &uo->v.tunnel;
 | 
						|
 | 
						|
	switch (attr->encap_tunneltype) {
 | 
						|
	case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
 | 
						|
		rc = tlv_to_bgp_encap_type_l2tpv3overip(
 | 
						|
			stlv, &tto->bgpinfo.l2tpv3_ip);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_GRE:
 | 
						|
		rc = tlv_to_bgp_encap_type_gre(stlv, &tto->bgpinfo.gre);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
 | 
						|
		rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint(
 | 
						|
			stlv, &tto->bgpinfo.transmit_tunnel_endpoint);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
 | 
						|
		rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode(
 | 
						|
			stlv, &tto->bgpinfo.ipsec_tunnel);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
 | 
						|
		rc = tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
 | 
						|
			stlv, &tto->bgpinfo.ip_ipsec);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
 | 
						|
		rc = tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
 | 
						|
			stlv, &tto->bgpinfo.mpls_ipsec);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IP_IN_IP:
 | 
						|
		rc = tlv_to_bgp_encap_type_ip_in_ip(stlv, &tto->bgpinfo.ip_ip);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_VXLAN:
 | 
						|
		rc = tlv_to_bgp_encap_type_vxlan(stlv, &tto->bgpinfo.vxlan);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_NVGRE:
 | 
						|
		rc = tlv_to_bgp_encap_type_nvgre(stlv, &tto->bgpinfo.nvgre);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS:
 | 
						|
		rc = tlv_to_bgp_encap_type_mpls(stlv, &tto->bgpinfo.mpls);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_GRE:
 | 
						|
		rc = tlv_to_bgp_encap_type_mpls_in_gre(stlv,
 | 
						|
						       &tto->bgpinfo.mpls_gre);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_VXLAN_GPE:
 | 
						|
		rc = tlv_to_bgp_encap_type_vxlan_gpe(stlv,
 | 
						|
						     &tto->bgpinfo.vxlan_gpe);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_UDP:
 | 
						|
		rc = tlv_to_bgp_encap_type_mpls_in_udp(stlv,
 | 
						|
						       &tto->bgpinfo.mpls_udp);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_PBB:
 | 
						|
		rc = tlv_to_bgp_encap_type_pbb(stlv, &tto->bgpinfo.pbb);
 | 
						|
		break;
 | 
						|
 | 
						|
	default:
 | 
						|
		vnc_zlog_debug_verbose("%s: unknown tunnel type %d", __func__,
 | 
						|
				       attr->encap_tunneltype);
 | 
						|
		rc = -1;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	if (rc) {
 | 
						|
		XFREE(MTYPE_RFAPI_UN_OPTION, uo);
 | 
						|
	}
 | 
						|
	return uo;
 | 
						|
}
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *			SUBTLV PRINT
 | 
						|
 ***********************************************************************/
 | 
						|
 | 
						|
static void subtlv_print_encap_l2tpv3_over_ip(
 | 
						|
	void *stream, int column_offset,
 | 
						|
	struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)
 | 
						|
{
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!st)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)",
 | 
						|
	   vty_newline);
 | 
						|
	fp(out, "%*s  SessionID: %d%s", column_offset, "", st->sessionid,
 | 
						|
	   vty_newline);
 | 
						|
	fp(out, "%*s  Cookie: (length %d)%s", column_offset, "",
 | 
						|
	   st->cookie_length, vty_newline);
 | 
						|
}
 | 
						|
 | 
						|
static void subtlv_print_encap_gre(void *stream, int column_offset,
 | 
						|
				   struct bgp_tea_subtlv_encap_gre_key *st)
 | 
						|
{
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!st)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)",
 | 
						|
	   vty_newline);
 | 
						|
	fp(out, "%*s  GRE key: %d (0x%x)%s", column_offset, "", st->gre_key,
 | 
						|
	   st->gre_key, vty_newline);
 | 
						|
}
 | 
						|
 | 
						|
static void subtlv_print_encap_pbb(void *stream, int column_offset,
 | 
						|
				   struct bgp_tea_subtlv_encap_pbb *st)
 | 
						|
{
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!st)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)",
 | 
						|
	   vty_newline);
 | 
						|
	if (st->flag_isid) {
 | 
						|
		fp(out, "%*s  ISID: %d (0x%x)%s", column_offset, "", st->isid,
 | 
						|
		   st->isid, vty_newline);
 | 
						|
	}
 | 
						|
	if (st->flag_vid) {
 | 
						|
		fp(out, "%*s  VID: %d (0x%x)%s", column_offset, "", st->vid,
 | 
						|
		   st->vid, vty_newline);
 | 
						|
	}
 | 
						|
	fp(out, "%*s  MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s", column_offset,
 | 
						|
	   "", st->macaddr[0], st->macaddr[1], st->macaddr[2], st->macaddr[3],
 | 
						|
	   st->macaddr[4], st->macaddr[5], vty_newline);
 | 
						|
}
 | 
						|
 | 
						|
static void subtlv_print_proto_type(void *stream, int column_offset,
 | 
						|
				    struct bgp_tea_subtlv_proto_type *st)
 | 
						|
{
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!st)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)",
 | 
						|
	   vty_newline);
 | 
						|
	fp(out, "%*s  Proto %d (0x%x)%s", column_offset, "", st->proto,
 | 
						|
	   st->proto, vty_newline);
 | 
						|
}
 | 
						|
 | 
						|
static void subtlv_print_color(void *stream, int column_offset,
 | 
						|
			       struct bgp_tea_subtlv_color *st)
 | 
						|
{
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!st)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline);
 | 
						|
	fp(out, "%*s  Color: %d (0x%x)", column_offset, "", st->color,
 | 
						|
	   st->color, vty_newline);
 | 
						|
}
 | 
						|
 | 
						|
static void subtlv_print_ipsec_ta(void *stream, int column_offset,
 | 
						|
				  struct bgp_tea_subtlv_ipsec_ta *st)
 | 
						|
{
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!st)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline);
 | 
						|
	fp(out, "%*s  Authenticator Type: %d (0x%x)", column_offset, "",
 | 
						|
	   st->authenticator_type, st->authenticator_type, vty_newline);
 | 
						|
	fp(out, "%*s  Authenticator: (length %d)", column_offset, "",
 | 
						|
	   st->authenticator_length, vty_newline);
 | 
						|
}
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 *			TLV PRINT
 | 
						|
 ***********************************************************************/
 | 
						|
 | 
						|
static void
 | 
						|
print_encap_type_l2tpv3overip(void *stream, int column_offset,
 | 
						|
			      struct bgp_encap_type_l2tpv3_over_ip *bet)
 | 
						|
{
 | 
						|
	const char *type = "L2TPv3 over IP";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	subtlv_print_encap_l2tpv3_over_ip(stream, column_offset + 2,
 | 
						|
					  &bet->st_encap);
 | 
						|
	subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto);
 | 
						|
	subtlv_print_color(stream, column_offset + 2, &bet->st_color);
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_gre(void *stream, int column_offset,
 | 
						|
				 struct bgp_encap_type_gre *bet)
 | 
						|
{
 | 
						|
	const char *type = "GRE";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	subtlv_print_encap_gre(stream, column_offset + 2, &bet->st_encap);
 | 
						|
	subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto);
 | 
						|
	subtlv_print_color(stream, column_offset + 2, &bet->st_color);
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_ip_in_ip(void *stream, int column_offset,
 | 
						|
				      struct bgp_encap_type_ip_in_ip *bet)
 | 
						|
{
 | 
						|
	const char *type = "IP in IP";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto);
 | 
						|
	subtlv_print_color(stream, column_offset + 2, &bet->st_color);
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_transmit_tunnel_endpoint(
 | 
						|
	void *stream, int column_offset,
 | 
						|
	struct bgp_encap_type_transmit_tunnel_endpoint *bet)
 | 
						|
{
 | 
						|
	const char *type = "Transmit Tunnel Endpoint";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	/* no subtlvs for this type */
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_ipsec_in_tunnel_mode(
 | 
						|
	void *stream, int column_offset,
 | 
						|
	struct bgp_encap_type_ipsec_in_tunnel_mode *bet)
 | 
						|
{
 | 
						|
	const char *type = "IPSEC in Tunnel mode";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
	subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
 | 
						|
	void *stream, int column_offset,
 | 
						|
	struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)
 | 
						|
{
 | 
						|
	const char *type = "IP in IP Tunnel with IPSEC transport mode";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
 | 
						|
	void *stream, int column_offset,
 | 
						|
	struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)
 | 
						|
{
 | 
						|
	const char *type = "MPLS in IP Tunnel with IPSEC transport mode";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void print_encap_type_pbb(void *stream, int column_offset,
 | 
						|
				 struct bgp_encap_type_pbb *bet)
 | 
						|
{
 | 
						|
	const char *type = "PBB";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	subtlv_print_encap_pbb(stream, column_offset + 2, &bet->st_encap);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void print_encap_type_vxlan(void *stream, int column_offset,
 | 
						|
				   struct bgp_encap_type_vxlan *bet)
 | 
						|
{
 | 
						|
	const char *type = "VXLAN";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	/* no subtlvs for this type */
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void print_encap_type_nvgre(void *stream, int column_offset,
 | 
						|
				   struct bgp_encap_type_nvgre *bet)
 | 
						|
{
 | 
						|
	const char *type = "NVGRE";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	/* no subtlvs for this type */
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_mpls(void *stream, int column_offset,
 | 
						|
				  struct bgp_encap_type_mpls *bet)
 | 
						|
{
 | 
						|
	const char *type = "MPLS";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	/* no subtlvs for this type */
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_mpls_in_gre(void *stream, int column_offset,
 | 
						|
					 struct bgp_encap_type_mpls_in_gre *bet)
 | 
						|
{
 | 
						|
	const char *type = "MPLS in GRE";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	/* no subtlvs for this type */
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_vxlan_gpe(void *stream, int column_offset,
 | 
						|
				       struct bgp_encap_type_vxlan_gpe *bet)
 | 
						|
{
 | 
						|
	const char *type = "VXLAN GPE";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	/* no subtlvs for this type */
 | 
						|
}
 | 
						|
 | 
						|
static void print_encap_type_mpls_in_udp(void *stream, int column_offset,
 | 
						|
					 struct bgp_encap_type_mpls_in_udp *bet)
 | 
						|
{
 | 
						|
	const char *type = "MPLS in UDP";
 | 
						|
	int (*fp)(void *, const char *, ...);
 | 
						|
	struct vty *vty;
 | 
						|
	void *out;
 | 
						|
	const char *vty_newline;
 | 
						|
 | 
						|
	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
 | 
						|
		return;
 | 
						|
	if (!bet)
 | 
						|
		return;
 | 
						|
 | 
						|
	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline);
 | 
						|
 | 
						|
	/* no subtlvs for this type */
 | 
						|
}
 | 
						|
 | 
						|
void rfapi_print_tunneltype_option(void *stream, int column_offset,
 | 
						|
				   struct rfapi_tunneltype_option *tto)
 | 
						|
{
 | 
						|
	switch (tto->type) {
 | 
						|
	case BGP_ENCAP_TYPE_L2TPV3_OVER_IP:
 | 
						|
		print_encap_type_l2tpv3overip(stream, column_offset,
 | 
						|
					      &tto->bgpinfo.l2tpv3_ip);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_GRE:
 | 
						|
		print_encap_type_gre(stream, column_offset, &tto->bgpinfo.gre);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT:
 | 
						|
		print_encap_type_transmit_tunnel_endpoint(
 | 
						|
			stream, column_offset,
 | 
						|
			&tto->bgpinfo.transmit_tunnel_endpoint);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE:
 | 
						|
		print_encap_type_ipsec_in_tunnel_mode(
 | 
						|
			stream, column_offset, &tto->bgpinfo.ipsec_tunnel);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
 | 
						|
		print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode(
 | 
						|
			stream, column_offset, &tto->bgpinfo.ip_ipsec);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE:
 | 
						|
		print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode(
 | 
						|
			stream, column_offset, &tto->bgpinfo.mpls_ipsec);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_IP_IN_IP:
 | 
						|
		print_encap_type_ip_in_ip(stream, column_offset,
 | 
						|
					  &tto->bgpinfo.ip_ip);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_VXLAN:
 | 
						|
		print_encap_type_vxlan(stream, column_offset,
 | 
						|
				       &tto->bgpinfo.vxlan);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_NVGRE:
 | 
						|
		print_encap_type_nvgre(stream, column_offset,
 | 
						|
				       &tto->bgpinfo.nvgre);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS:
 | 
						|
		print_encap_type_mpls(stream, column_offset,
 | 
						|
				      &tto->bgpinfo.mpls);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_GRE:
 | 
						|
		print_encap_type_mpls_in_gre(stream, column_offset,
 | 
						|
					     &tto->bgpinfo.mpls_gre);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_VXLAN_GPE:
 | 
						|
		print_encap_type_vxlan_gpe(stream, column_offset,
 | 
						|
					   &tto->bgpinfo.vxlan_gpe);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_MPLS_IN_UDP:
 | 
						|
		print_encap_type_mpls_in_udp(stream, column_offset,
 | 
						|
					     &tto->bgpinfo.mpls_udp);
 | 
						|
		break;
 | 
						|
 | 
						|
	case BGP_ENCAP_TYPE_PBB:
 | 
						|
		print_encap_type_pbb(stream, column_offset, &tto->bgpinfo.pbb);
 | 
						|
		break;
 | 
						|
 | 
						|
	default:
 | 
						|
		assert(0);
 | 
						|
	}
 | 
						|
}
 |