vcl: ldp support for ip_pktinfo
Type: improvement Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I3c15f38a4a3f5e92506059277948e7fca9cd8b55
This commit is contained in:

committed by
Dave Barach

parent
7c7231fc30
commit
eff5f7aea8
143
src/vcl/ldp.c
143
src/vcl/ldp.c
@ -26,7 +26,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <sys/resource.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#include <vcl/ldp_socket_wrapper.h>
|
||||
#include <vcl/ldp.h>
|
||||
@ -1556,17 +1556,14 @@ __recv_chk (int fd, void *buf, size_t n, size_t buflen, int flags)
|
||||
|
||||
static inline int
|
||||
ldp_vls_sendo (vls_handle_t vlsh, const void *buf, size_t n,
|
||||
vppcom_endpt_tlv_t *ep_tlv, int flags,
|
||||
vppcom_endpt_tlv_t *app_tlvs, int flags,
|
||||
__CONST_SOCKADDR_ARG _addr, socklen_t addr_len)
|
||||
{
|
||||
const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
|
||||
vppcom_endpt_t *ep = 0;
|
||||
vppcom_endpt_t _ep;
|
||||
|
||||
if (ep_tlv)
|
||||
{
|
||||
_ep.app_data = *ep_tlv;
|
||||
}
|
||||
_ep.app_tlvs = app_tlvs;
|
||||
|
||||
if (addr)
|
||||
{
|
||||
@ -1679,6 +1676,97 @@ recvfrom (int fd, void *__restrict buf, size_t n, int flags,
|
||||
return size;
|
||||
}
|
||||
|
||||
static int
|
||||
ldp_parse_cmsg (vls_handle_t vlsh, const struct msghdr *msg,
|
||||
vppcom_endpt_tlv_t **app_tlvs)
|
||||
{
|
||||
uint8_t *ad, *at = (uint8_t *) *app_tlvs;
|
||||
vppcom_endpt_tlv_t *adh;
|
||||
struct in_pktinfo *pi;
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR (msg);
|
||||
|
||||
while (cmsg != NULL)
|
||||
{
|
||||
switch (cmsg->cmsg_level)
|
||||
{
|
||||
case SOL_UDP:
|
||||
switch (cmsg->cmsg_type)
|
||||
{
|
||||
case UDP_SEGMENT:
|
||||
vec_add2 (at, adh, sizeof (*adh));
|
||||
adh->data_type = VCL_UDP_SEGMENT;
|
||||
adh->data_len = sizeof (uint16_t);
|
||||
vec_add2 (at, ad, sizeof (uint16_t));
|
||||
*(uint16_t *) ad = *(uint16_t *) CMSG_DATA (cmsg);
|
||||
break;
|
||||
default:
|
||||
LDBG (1, "SOL_UDP cmsg_type %u not supported", cmsg->cmsg_type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SOL_IP:
|
||||
switch (cmsg->cmsg_type)
|
||||
{
|
||||
case IP_PKTINFO:
|
||||
vec_add2 (at, adh, sizeof (*adh));
|
||||
adh->data_type = VCL_IP_PKTINFO;
|
||||
adh->data_len = sizeof (struct in_addr);
|
||||
vec_add2 (at, ad, sizeof (struct in_addr));
|
||||
pi = (void *) CMSG_DATA (cmsg);
|
||||
clib_memcpy_fast (ad, &pi->ipi_spec_dst,
|
||||
sizeof (struct in_addr));
|
||||
break;
|
||||
default:
|
||||
LDBG (1, "SOL_IP cmsg_type %u not supported", cmsg->cmsg_type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LDBG (1, "cmsg_level %u not supported", cmsg->cmsg_level);
|
||||
break;
|
||||
}
|
||||
cmsg = CMSG_NXTHDR ((struct msghdr *) msg, cmsg);
|
||||
}
|
||||
*app_tlvs = (vppcom_endpt_tlv_t *) at;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ldp_make_cmsg (vls_handle_t vlsh, struct msghdr *msg)
|
||||
{
|
||||
u32 optval, optlen = sizeof (optval);
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR (msg);
|
||||
|
||||
if (!vls_attr (vlsh, VPPCOM_ATTR_GET_IP_PKTINFO, (void *) &optval, &optlen))
|
||||
return 0;
|
||||
|
||||
if (optval)
|
||||
{
|
||||
vppcom_endpt_t ep;
|
||||
u8 addr_buf[sizeof (struct in_addr)];
|
||||
u32 size = sizeof (ep);
|
||||
|
||||
ep.ip = addr_buf;
|
||||
|
||||
if (!vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size))
|
||||
{
|
||||
struct in_pktinfo pi = {};
|
||||
|
||||
clib_memcpy (&pi.ipi_addr, ep.ip, sizeof (struct in_addr));
|
||||
cmsg->cmsg_level = SOL_IP;
|
||||
cmsg->cmsg_type = IP_PKTINFO;
|
||||
cmsg->cmsg_len = CMSG_LEN (sizeof (pi));
|
||||
clib_memcpy (CMSG_DATA (cmsg), &pi, sizeof (pi));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
sendmsg (int fd, const struct msghdr * msg, int flags)
|
||||
{
|
||||
@ -1690,29 +1778,17 @@ sendmsg (int fd, const struct msghdr * msg, int flags)
|
||||
vlsh = ldp_fd_to_vlsh (fd);
|
||||
if (vlsh != VLS_INVALID_HANDLE)
|
||||
{
|
||||
vppcom_endpt_tlv_t *app_tlvs = 0;
|
||||
struct iovec *iov = msg->msg_iov;
|
||||
ssize_t total = 0;
|
||||
int i, rv = 0;
|
||||
struct cmsghdr *cmsg;
|
||||
uint16_t *valp;
|
||||
vppcom_endpt_tlv_t _app_data;
|
||||
vppcom_endpt_tlv_t *p_app_data = NULL;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR (msg);
|
||||
if (cmsg && cmsg->cmsg_type == UDP_SEGMENT)
|
||||
{
|
||||
p_app_data = &_app_data;
|
||||
valp = (void *) CMSG_DATA (cmsg);
|
||||
p_app_data->data_type = VCL_UDP_SEGMENT;
|
||||
p_app_data->data_len = sizeof (*valp);
|
||||
p_app_data->value = *valp;
|
||||
}
|
||||
ldp_parse_cmsg (vlsh, msg, &app_tlvs);
|
||||
|
||||
for (i = 0; i < msg->msg_iovlen; ++i)
|
||||
{
|
||||
rv =
|
||||
ldp_vls_sendo (vlsh, iov[i].iov_base, iov[i].iov_len, p_app_data,
|
||||
flags, msg->msg_name, msg->msg_namelen);
|
||||
rv = ldp_vls_sendo (vlsh, iov[i].iov_base, iov[i].iov_len, app_tlvs,
|
||||
flags, msg->msg_name, msg->msg_namelen);
|
||||
if (rv < 0)
|
||||
break;
|
||||
else
|
||||
@ -1723,6 +1799,8 @@ sendmsg (int fd, const struct msghdr * msg, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
vec_free (app_tlvs);
|
||||
|
||||
if (rv < 0 && total == 0)
|
||||
{
|
||||
errno = -rv;
|
||||
@ -1828,7 +1906,11 @@ recvmsg (int fd, struct msghdr * msg, int flags)
|
||||
size = -1;
|
||||
}
|
||||
else
|
||||
size = total;
|
||||
{
|
||||
if (msg->msg_controllen)
|
||||
ldp_make_cmsg (vlsh, msg);
|
||||
size = total;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2114,6 +2196,21 @@ setsockopt (int fd, int level, int optname,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SOL_IP:
|
||||
switch (optname)
|
||||
{
|
||||
case IP_PKTINFO:
|
||||
rv = vls_attr (vlsh, VPPCOM_ATTR_SET_IP_PKTINFO, (void *) optval,
|
||||
&optlen);
|
||||
break;
|
||||
default:
|
||||
LDBG (0,
|
||||
"ERROR: fd %d: setsockopt SOL_IP: vlsh %u optname %d"
|
||||
"unsupported!",
|
||||
fd, vlsh, optname);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -118,16 +118,17 @@ typedef enum
|
||||
VCL_SESS_ATTR_CUT_THRU,
|
||||
VCL_SESS_ATTR_VEP,
|
||||
VCL_SESS_ATTR_VEP_SESSION,
|
||||
VCL_SESS_ATTR_LISTEN, // SOL_SOCKET,SO_ACCEPTCONN
|
||||
VCL_SESS_ATTR_NONBLOCK, // fcntl,O_NONBLOCK
|
||||
VCL_SESS_ATTR_REUSEADDR, // SOL_SOCKET,SO_REUSEADDR
|
||||
VCL_SESS_ATTR_REUSEPORT, // SOL_SOCKET,SO_REUSEPORT
|
||||
VCL_SESS_ATTR_BROADCAST, // SOL_SOCKET,SO_BROADCAST
|
||||
VCL_SESS_ATTR_V6ONLY, // SOL_TCP,IPV6_V6ONLY
|
||||
VCL_SESS_ATTR_KEEPALIVE, // SOL_SOCKET,SO_KEEPALIVE
|
||||
VCL_SESS_ATTR_TCP_NODELAY, // SOL_TCP,TCP_NODELAY
|
||||
VCL_SESS_ATTR_TCP_KEEPIDLE, // SOL_TCP,TCP_KEEPIDLE
|
||||
VCL_SESS_ATTR_TCP_KEEPINTVL, // SOL_TCP,TCP_KEEPINTVL
|
||||
VCL_SESS_ATTR_LISTEN, // SOL_SOCKET,SO_ACCEPTCONN
|
||||
VCL_SESS_ATTR_NONBLOCK, // fcntl,O_NONBLOCK
|
||||
VCL_SESS_ATTR_REUSEADDR, // SOL_SOCKET,SO_REUSEADDR
|
||||
VCL_SESS_ATTR_REUSEPORT, // SOL_SOCKET,SO_REUSEPORT
|
||||
VCL_SESS_ATTR_BROADCAST, // SOL_SOCKET,SO_BROADCAST
|
||||
VCL_SESS_ATTR_V6ONLY, // SOL_TCP,IPV6_V6ONLY
|
||||
VCL_SESS_ATTR_KEEPALIVE, // SOL_SOCKET,SO_KEEPALIVE
|
||||
VCL_SESS_ATTR_TCP_NODELAY, // SOL_TCP,TCP_NODELAY
|
||||
VCL_SESS_ATTR_TCP_KEEPIDLE, // SOL_TCP,TCP_KEEPIDLE
|
||||
VCL_SESS_ATTR_TCP_KEEPINTVL, // SOL_TCP,TCP_KEEPINTVL
|
||||
VCL_SESS_ATTR_IP_PKTINFO, /* IPPROTO_IP, IP_PKTINFO */
|
||||
VCL_SESS_ATTR_MAX
|
||||
} vppcom_session_attr_t;
|
||||
|
||||
@ -165,6 +166,7 @@ typedef struct vcl_session_
|
||||
u32 attributes; /**< see @ref vppcom_session_attr_t */
|
||||
int libc_epfd;
|
||||
u32 vrf;
|
||||
u16 gso_size;
|
||||
|
||||
u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF)
|
||||
u32 rcvbuf_size; // VPP-TBD: Hack until support setsockopt(SO_RCVBUF)
|
||||
|
@ -2228,7 +2228,7 @@ vcl_fifo_is_writeable (svm_fifo_t * f, u32 len, u8 is_dgram)
|
||||
|
||||
always_inline int
|
||||
vppcom_session_write_inline (vcl_worker_t *wrk, vcl_session_t *s, void *buf,
|
||||
size_t n, u16 gso_size, u8 is_flush, u8 is_dgram)
|
||||
size_t n, u8 is_flush, u8 is_dgram)
|
||||
{
|
||||
int n_write, is_nonblocking;
|
||||
session_evt_type_t et;
|
||||
@ -2295,7 +2295,7 @@ vppcom_session_write_inline (vcl_worker_t *wrk, vcl_session_t *s, void *buf,
|
||||
if (is_dgram)
|
||||
n_write =
|
||||
app_send_dgram_raw_gso (tx_fifo, &s->transport, s->vpp_evt_q, buf, n,
|
||||
gso_size, et, 0 /* do_evt */, SVM_Q_WAIT);
|
||||
s->gso_size, et, 0 /* do_evt */, SVM_Q_WAIT);
|
||||
else
|
||||
n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
|
||||
0 /* do_evt */ , SVM_Q_WAIT);
|
||||
@ -2324,7 +2324,7 @@ vppcom_session_write (uint32_t session_handle, void *buf, size_t n)
|
||||
if (PREDICT_FALSE (!s))
|
||||
return VPPCOM_EBADFD;
|
||||
|
||||
return vppcom_session_write_inline (wrk, s, buf, n, 0, 0 /* is_flush */,
|
||||
return vppcom_session_write_inline (wrk, s, buf, n, 0 /* is_flush */,
|
||||
s->is_dgram ? 1 : 0);
|
||||
}
|
||||
|
||||
@ -2338,7 +2338,7 @@ vppcom_session_write_msg (uint32_t session_handle, void *buf, size_t n)
|
||||
if (PREDICT_FALSE (!s))
|
||||
return VPPCOM_EBADFD;
|
||||
|
||||
return vppcom_session_write_inline (wrk, s, buf, n, 0, 1 /* is_flush */,
|
||||
return vppcom_session_write_inline (wrk, s, buf, n, 1 /* is_flush */,
|
||||
s->is_dgram ? 1 : 0);
|
||||
}
|
||||
|
||||
@ -4105,6 +4105,36 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
|
||||
clib_memcpy (session->ext_config->data, buffer, *buflen);
|
||||
session->ext_config->len = *buflen;
|
||||
break;
|
||||
case VPPCOM_ATTR_SET_IP_PKTINFO:
|
||||
if (buffer && buflen && (*buflen == sizeof (int)) &&
|
||||
!vcl_session_has_attr (session, VCL_SESS_ATTR_IP_PKTINFO))
|
||||
{
|
||||
if (*(int *) buffer)
|
||||
vcl_session_set_attr (session, VCL_SESS_ATTR_IP_PKTINFO);
|
||||
else
|
||||
vcl_session_clear_attr (session, VCL_SESS_ATTR_IP_PKTINFO);
|
||||
|
||||
VDBG (2, "VCL_SESS_ATTR_IP_PKTINFO: %d, buflen %d",
|
||||
vcl_session_has_attr (session, VCL_SESS_ATTR_IP_PKTINFO),
|
||||
*buflen);
|
||||
}
|
||||
else
|
||||
rv = VPPCOM_EINVAL;
|
||||
break;
|
||||
|
||||
case VPPCOM_ATTR_GET_IP_PKTINFO:
|
||||
if (buffer && buflen && (*buflen >= sizeof (int)))
|
||||
{
|
||||
*(int *) buffer =
|
||||
vcl_session_has_attr (session, VCL_SESS_ATTR_IP_PKTINFO);
|
||||
*buflen = sizeof (int);
|
||||
|
||||
VDBG (2, "VCL_SESS_ATTR_IP_PKTINFO: %d, buflen %d", *(int *) buffer,
|
||||
*buflen);
|
||||
}
|
||||
else
|
||||
rv = VPPCOM_EINVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = VPPCOM_EINVAL;
|
||||
@ -4148,13 +4178,37 @@ vppcom_session_recvfrom (uint32_t session_handle, void *buffer,
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
vcl_handle_ep_app_tlvs (vcl_session_t *s, vppcom_endpt_t *ep)
|
||||
{
|
||||
vppcom_endpt_tlv_t *tlv = ep->app_tlvs;
|
||||
|
||||
do
|
||||
{
|
||||
switch (tlv->data_type)
|
||||
{
|
||||
case VCL_UDP_SEGMENT:
|
||||
s->gso_size = *(u16 *) tlv->data;
|
||||
break;
|
||||
case VCL_IP_PKTINFO:
|
||||
clib_memcpy_fast (&s->transport.lcl_ip, (ip4_address_t *) tlv->data,
|
||||
sizeof (ip4_address_t));
|
||||
break;
|
||||
default:
|
||||
VDBG (0, "Ignorning unsupported app tlv %u", tlv->data_type);
|
||||
break;
|
||||
}
|
||||
tlv = VCL_EP_NEXT_APP_TLV (ep, tlv);
|
||||
}
|
||||
while (tlv);
|
||||
}
|
||||
|
||||
int
|
||||
vppcom_session_sendto (uint32_t session_handle, void *buffer,
|
||||
uint32_t buflen, int flags, vppcom_endpt_t * ep)
|
||||
{
|
||||
vcl_worker_t *wrk = vcl_worker_get_current ();
|
||||
vcl_session_t *s;
|
||||
u16 gso_size = 0;
|
||||
|
||||
s = vcl_session_get_w_handle (wrk, session_handle);
|
||||
if (PREDICT_FALSE (!s))
|
||||
@ -4169,12 +4223,9 @@ vppcom_session_sendto (uint32_t session_handle, void *buffer,
|
||||
s->transport.rmt_port = ep->port;
|
||||
vcl_ip_copy_from_ep (&s->transport.rmt_ip, ep);
|
||||
|
||||
vppcom_endpt_tlv_t *p_app_data = &ep->app_data;
|
||||
if (ep->app_tlvs)
|
||||
vcl_handle_ep_app_tlvs (s, ep);
|
||||
|
||||
if (p_app_data && (p_app_data->data_type == VCL_UDP_SEGMENT))
|
||||
{
|
||||
gso_size = p_app_data->value;
|
||||
}
|
||||
/* Session not connected/bound in vpp. Create it by 'connecting' it */
|
||||
if (PREDICT_FALSE (s->session_state == VCL_STATE_CLOSED))
|
||||
{
|
||||
@ -4198,7 +4249,7 @@ vppcom_session_sendto (uint32_t session_handle, void *buffer,
|
||||
VDBG (2, "handling flags 0x%u (%d) not implemented yet.", flags, flags);
|
||||
}
|
||||
|
||||
return (vppcom_session_write_inline (wrk, s, buffer, buflen, gso_size, 1,
|
||||
return (vppcom_session_write_inline (wrk, s, buffer, buflen, 1,
|
||||
s->is_dgram ? 1 : 0));
|
||||
}
|
||||
|
||||
|
@ -22,12 +22,12 @@
|
||||
#include <poll.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
* VPPCOM Public API Definitions, Enums, and Data Structures
|
||||
@ -46,49 +46,56 @@ extern "C"
|
||||
#define VPPCOM_ENV_VPP_API_SOCKET "VCL_VPP_API_SOCKET"
|
||||
#define VPPCOM_ENV_VPP_SAPI_SOCKET "VCL_VPP_SAPI_SOCKET"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VPPCOM_PROTO_TCP = 0,
|
||||
VPPCOM_PROTO_UDP,
|
||||
VPPCOM_PROTO_NONE,
|
||||
VPPCOM_PROTO_TLS,
|
||||
VPPCOM_PROTO_QUIC,
|
||||
VPPCOM_PROTO_DTLS,
|
||||
VPPCOM_PROTO_SRTP,
|
||||
} vppcom_proto_t;
|
||||
typedef enum vppcom_proto_
|
||||
{
|
||||
VPPCOM_PROTO_TCP = 0,
|
||||
VPPCOM_PROTO_UDP,
|
||||
VPPCOM_PROTO_NONE,
|
||||
VPPCOM_PROTO_TLS,
|
||||
VPPCOM_PROTO_QUIC,
|
||||
VPPCOM_PROTO_DTLS,
|
||||
VPPCOM_PROTO_SRTP,
|
||||
} vppcom_proto_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VPPCOM_IS_IP6 = 0,
|
||||
VPPCOM_IS_IP4,
|
||||
} vppcom_is_ip4_t;
|
||||
typedef enum
|
||||
{
|
||||
VPPCOM_IS_IP6 = 0,
|
||||
VPPCOM_IS_IP4,
|
||||
} vppcom_is_ip4_t;
|
||||
|
||||
typedef struct vppcom_endpt_tlv_t_
|
||||
{
|
||||
uint32_t data_type;
|
||||
uint32_t data_len;
|
||||
uint8_t data[0];
|
||||
} vppcom_endpt_tlv_t;
|
||||
|
||||
typedef struct vppcom_endpt_t_
|
||||
{
|
||||
uint8_t unused; /**< unused */
|
||||
uint8_t is_ip4; /**< flag set if if ip is ipv4 */
|
||||
uint8_t *ip; /**< pointer to ip address */
|
||||
uint16_t port; /**< transport port */
|
||||
uint64_t unused2; /**< unused */
|
||||
uint32_t app_tlv_len; /**< length of app provided tlvs */
|
||||
vppcom_endpt_tlv_t *app_tlvs; /**< array of app provided tlvs */
|
||||
} vppcom_endpt_t;
|
||||
|
||||
#define VCL_UDP_OPTS_BASE (VPPCOM_PROTO_UDP << 16)
|
||||
#define VCL_UDP_SEGMENT (VCL_UDP_OPTS_BASE + 0)
|
||||
|
||||
typedef struct vppcom_endpt_tlv_t_
|
||||
{
|
||||
uint32_t data_type;
|
||||
uint32_t data_len;
|
||||
union
|
||||
{
|
||||
/* data */
|
||||
uint64_t value;
|
||||
uint32_t as_u32[2];
|
||||
uint16_t as_u16[4];
|
||||
uint8_t as_u8[8];
|
||||
};
|
||||
} vppcom_endpt_tlv_t;
|
||||
/* By convention we'll use 127 for IP since we don't support IP as protocol */
|
||||
#define VCL_IP_OPTS_BASE (127 << 16)
|
||||
#define VCL_IP_PKTINFO (VCL_IP_OPTS_BASE + 1)
|
||||
|
||||
typedef struct vppcom_endpt_t_
|
||||
{
|
||||
uint8_t is_cut_thru;
|
||||
uint8_t is_ip4;
|
||||
uint8_t *ip;
|
||||
uint16_t port;
|
||||
uint64_t parent_handle;
|
||||
vppcom_endpt_tlv_t app_data;
|
||||
} vppcom_endpt_t;
|
||||
#define VCL_EP_APP_TLV_LEN(tlv_) (sizeof (vppcom_endpt_tlv_t) + tlv->data_len)
|
||||
#define VCL_EP_APP_TLV_POS(ep_, tlv_) ((void *)ep_->app_tlvs - (void *)tlv_)
|
||||
#define VCL_EP_APP_TLV_LEN_LEFT(ep_, tlv_) \
|
||||
(ep_->app_tlv_len - VCL_EP_APP_TLV_POS (ep_, tlv_))
|
||||
#define VCL_EP_NEXT_APP_TLV(ep_, tlv_) \
|
||||
(VCL_EP_APP_TLV_LEN (tlv_) < VCL_EP_APP_TLV_POS (ep_, tlv_) ? ( \
|
||||
(vppcom_endpt_tlv_t *)((uint8_t *)tlv_ + VCL_EP_APP_TLV_LEN (tlv_))) \
|
||||
: 0)
|
||||
|
||||
typedef uint32_t vcl_session_handle_t;
|
||||
|
||||
@ -167,6 +174,8 @@ typedef enum
|
||||
VPPCOM_ATTR_GET_DOMAIN,
|
||||
VPPCOM_ATTR_SET_ENDPT_EXT_CFG,
|
||||
VPPCOM_ATTR_SET_DSCP,
|
||||
VPPCOM_ATTR_SET_IP_PKTINFO,
|
||||
VPPCOM_ATTR_GET_IP_PKTINFO,
|
||||
} vppcom_attr_op_t;
|
||||
|
||||
typedef struct _vcl_poll
|
||||
@ -299,11 +308,10 @@ extern int vppcom_session_get_error (uint32_t session_handle);
|
||||
*/
|
||||
extern int vppcom_worker_is_detached (void);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
/* clang-format on */
|
||||
|
||||
#endif /* included_vppcom_h */
|
||||
|
||||
|
Reference in New Issue
Block a user