flow, icmp, tcp: Clean up helpers for getting flow from index
TCP (both regular and spliced) and ICMP both have macros to retrieve the relevant protcol specific flow structure from a flow index. In most cases what we actually want is to get the specific flow from a sidx. Replace those simple macros with a more precise inline, which also asserts that the flow is of the type we expect. While we're they're also add a pif_at_sidx() helper to get the interface of a specific flow & side, which is useful in some places. Finally, fix some minor style issues in the comments on some of the existing sidx related helpers. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
2fa91ee391
commit
9b125e7776
4 changed files with 80 additions and 17 deletions
26
flow_table.h
26
flow_table.h
|
@ -42,7 +42,7 @@ extern unsigned flow_first_free;
|
||||||
extern union flow flowtab[];
|
extern union flow flowtab[];
|
||||||
|
|
||||||
|
|
||||||
/** flow_idx - Index of flow from common structure
|
/** flow_idx() - Index of flow from common structure
|
||||||
* @f: Common flow fields pointer
|
* @f: Common flow fields pointer
|
||||||
*
|
*
|
||||||
* Return: index of @f in the flow table
|
* Return: index of @f in the flow table
|
||||||
|
@ -52,21 +52,21 @@ static inline unsigned flow_idx(const struct flow_common *f)
|
||||||
return (union flow *)f - flowtab;
|
return (union flow *)f - flowtab;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** FLOW_IDX - Find the index of a flow
|
/** FLOW_IDX() - Find the index of a flow
|
||||||
* @f_: Flow pointer, either union flow * or protocol specific
|
* @f_: Flow pointer, either union flow * or protocol specific
|
||||||
*
|
*
|
||||||
* Return: index of @f in the flow table
|
* Return: index of @f in the flow table
|
||||||
*/
|
*/
|
||||||
#define FLOW_IDX(f_) (flow_idx(&(f_)->f))
|
#define FLOW_IDX(f_) (flow_idx(&(f_)->f))
|
||||||
|
|
||||||
/** FLOW - Flow entry at a given index
|
/** FLOW() - Flow entry at a given index
|
||||||
* @idx: Flow index
|
* @idx: Flow index
|
||||||
*
|
*
|
||||||
* Return: pointer to entry @idx in the flow table
|
* Return: pointer to entry @idx in the flow table
|
||||||
*/
|
*/
|
||||||
#define FLOW(idx) (&flowtab[(idx)])
|
#define FLOW(idx) (&flowtab[(idx)])
|
||||||
|
|
||||||
/** flow_at_sidx - Flow entry for a given sidx
|
/** flow_at_sidx() - Flow entry for a given sidx
|
||||||
* @sidx: Flow & side index
|
* @sidx: Flow & side index
|
||||||
*
|
*
|
||||||
* Return: pointer to the corresponding flow entry, or NULL
|
* Return: pointer to the corresponding flow entry, or NULL
|
||||||
|
@ -78,7 +78,21 @@ static inline union flow *flow_at_sidx(flow_sidx_t sidx)
|
||||||
return FLOW(sidx.flow);
|
return FLOW(sidx.flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** flow_sidx_t - Index of one side of a flow from common structure
|
/** pif_at_sidx() - Interface for a given flow and side
|
||||||
|
* @sidx: Flow & side index
|
||||||
|
*
|
||||||
|
* Return: pif for the flow & side given by @sidx
|
||||||
|
*/
|
||||||
|
static inline uint8_t pif_at_sidx(flow_sidx_t sidx)
|
||||||
|
{
|
||||||
|
const union flow *flow = flow_at_sidx(sidx);
|
||||||
|
|
||||||
|
if (!flow)
|
||||||
|
return PIF_NONE;
|
||||||
|
return flow->f.pif[sidx.side];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** flow_sidx() - Index of one side of a flow from common structure
|
||||||
* @f: Common flow fields pointer
|
* @f: Common flow fields pointer
|
||||||
* @side: Which side to refer to (0 or 1)
|
* @side: Which side to refer to (0 or 1)
|
||||||
*
|
*
|
||||||
|
@ -96,7 +110,7 @@ static inline flow_sidx_t flow_sidx(const struct flow_common *f,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** FLOW_SIDX - Find the index of one side of a flow
|
/** FLOW_SIDX() - Find the index of one side of a flow
|
||||||
* @f_: Flow pointer, either union flow * or protocol specific
|
* @f_: Flow pointer, either union flow * or protocol specific
|
||||||
* @side: Which side to index (0 or 1)
|
* @side: Which side to index (0 or 1)
|
||||||
*
|
*
|
||||||
|
|
22
icmp.c
22
icmp.c
|
@ -45,11 +45,27 @@
|
||||||
#define ICMP_ECHO_TIMEOUT 60 /* s, timeout for ICMP socket activity */
|
#define ICMP_ECHO_TIMEOUT 60 /* s, timeout for ICMP socket activity */
|
||||||
#define ICMP_NUM_IDS (1U << 16)
|
#define ICMP_NUM_IDS (1U << 16)
|
||||||
|
|
||||||
#define PINGF(idx) (&(FLOW(idx)->ping))
|
|
||||||
|
|
||||||
/* Indexed by ICMP echo identifier */
|
/* Indexed by ICMP echo identifier */
|
||||||
static struct icmp_ping_flow *icmp_id_map[IP_VERSIONS][ICMP_NUM_IDS];
|
static struct icmp_ping_flow *icmp_id_map[IP_VERSIONS][ICMP_NUM_IDS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ping_at_sidx() - Get ping specific flow at given sidx
|
||||||
|
* @sidx: Flow and side to retrieve
|
||||||
|
*
|
||||||
|
* Return: ping specific flow at @sidx, or NULL of @sidx is invalid. Asserts if
|
||||||
|
* the flow at @sidx is not FLOW_PING4 or FLOW_PING6
|
||||||
|
*/
|
||||||
|
static struct icmp_ping_flow *ping_at_sidx(flow_sidx_t sidx)
|
||||||
|
{
|
||||||
|
union flow *flow = flow_at_sidx(sidx);
|
||||||
|
|
||||||
|
if (!flow)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ASSERT(flow->f.type == FLOW_PING4 || flow->f.type == FLOW_PING6);
|
||||||
|
return &flow->ping;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* icmp_sock_handler() - Handle new data from ICMP or ICMPv6 socket
|
* icmp_sock_handler() - Handle new data from ICMP or ICMPv6 socket
|
||||||
* @c: Execution context
|
* @c: Execution context
|
||||||
|
@ -57,7 +73,7 @@ static struct icmp_ping_flow *icmp_id_map[IP_VERSIONS][ICMP_NUM_IDS];
|
||||||
*/
|
*/
|
||||||
void icmp_sock_handler(const struct ctx *c, union epoll_ref ref)
|
void icmp_sock_handler(const struct ctx *c, union epoll_ref ref)
|
||||||
{
|
{
|
||||||
struct icmp_ping_flow *pingf = PINGF(ref.flowside.flow);
|
struct icmp_ping_flow *pingf = ping_at_sidx(ref.flowside);
|
||||||
union sockaddr_inany sr;
|
union sockaddr_inany sr;
|
||||||
socklen_t sl = sizeof(sr);
|
socklen_t sl = sizeof(sr);
|
||||||
char buf[USHRT_MAX];
|
char buf[USHRT_MAX];
|
||||||
|
|
28
tcp.c
28
tcp.c
|
@ -379,8 +379,6 @@ bool peek_offset_cap;
|
||||||
/* sendmsg() to socket */
|
/* sendmsg() to socket */
|
||||||
static struct iovec tcp_iov [UIO_MAXIOV];
|
static struct iovec tcp_iov [UIO_MAXIOV];
|
||||||
|
|
||||||
#define CONN(idx) (&(FLOW(idx)->tcp))
|
|
||||||
|
|
||||||
/* Table for lookup from remote address, local port, remote port */
|
/* Table for lookup from remote address, local port, remote port */
|
||||||
static flow_sidx_t tc_hash[TCP_HASH_TABLE_SIZE];
|
static flow_sidx_t tc_hash[TCP_HASH_TABLE_SIZE];
|
||||||
|
|
||||||
|
@ -391,6 +389,24 @@ static_assert(ARRAY_SIZE(tc_hash) >= FLOW_MAX,
|
||||||
int init_sock_pool4 [TCP_SOCK_POOL_SIZE];
|
int init_sock_pool4 [TCP_SOCK_POOL_SIZE];
|
||||||
int init_sock_pool6 [TCP_SOCK_POOL_SIZE];
|
int init_sock_pool6 [TCP_SOCK_POOL_SIZE];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* conn_at_sidx() - Get TCP connection specific flow at given sidx
|
||||||
|
* @sidx: Flow and side to retrieve
|
||||||
|
*
|
||||||
|
* Return: TCP connection at @sidx, or NULL of @sidx is invalid. Asserts if the
|
||||||
|
* flow at @sidx is not FLOW_TCP.
|
||||||
|
*/
|
||||||
|
static struct tcp_tap_conn *conn_at_sidx(flow_sidx_t sidx)
|
||||||
|
{
|
||||||
|
union flow *flow = flow_at_sidx(sidx);
|
||||||
|
|
||||||
|
if (!flow)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ASSERT(flow->f.type == FLOW_TCP);
|
||||||
|
return &flow->tcp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tcp_set_peek_offset() - Set SO_PEEK_OFF offset on a socket if supported
|
* tcp_set_peek_offset() - Set SO_PEEK_OFF offset on a socket if supported
|
||||||
* @s: Socket to update
|
* @s: Socket to update
|
||||||
|
@ -2379,9 +2395,10 @@ cancel:
|
||||||
void tcp_timer_handler(struct ctx *c, union epoll_ref ref)
|
void tcp_timer_handler(struct ctx *c, union epoll_ref ref)
|
||||||
{
|
{
|
||||||
struct itimerspec check_armed = { { 0 }, { 0 } };
|
struct itimerspec check_armed = { { 0 }, { 0 } };
|
||||||
struct tcp_tap_conn *conn = CONN(ref.flow);
|
struct tcp_tap_conn *conn = &FLOW(ref.flow)->tcp;
|
||||||
|
|
||||||
ASSERT(!c->no_tcp);
|
ASSERT(!c->no_tcp);
|
||||||
|
ASSERT(conn->f.type == FLOW_TCP);
|
||||||
|
|
||||||
/* We don't reset timers on ~ACK_FROM_TAP_DUE, ~ACK_TO_TAP_DUE. If the
|
/* We don't reset timers on ~ACK_FROM_TAP_DUE, ~ACK_TO_TAP_DUE. If the
|
||||||
* timer is currently armed, this event came from a previous setting,
|
* timer is currently armed, this event came from a previous setting,
|
||||||
|
@ -2441,11 +2458,10 @@ void tcp_timer_handler(struct ctx *c, union epoll_ref ref)
|
||||||
*/
|
*/
|
||||||
void tcp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events)
|
void tcp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events)
|
||||||
{
|
{
|
||||||
struct tcp_tap_conn *conn = CONN(ref.flowside.flow);
|
struct tcp_tap_conn *conn = conn_at_sidx(ref.flowside);
|
||||||
|
|
||||||
ASSERT(!c->no_tcp);
|
ASSERT(!c->no_tcp);
|
||||||
ASSERT(conn->f.type == FLOW_TCP);
|
ASSERT(pif_at_sidx(ref.flowside) != PIF_TAP);
|
||||||
ASSERT(conn->f.pif[ref.flowside.side] != PIF_TAP);
|
|
||||||
|
|
||||||
if (conn->events == CLOSED)
|
if (conn->events == CLOSED)
|
||||||
return;
|
return;
|
||||||
|
|
21
tcp_splice.c
21
tcp_splice.c
|
@ -76,7 +76,6 @@ static int splice_pipe_pool [TCP_SPLICE_PIPE_POOL_SIZE][2];
|
||||||
#define CONN_V6(x) ((x)->flags & SPLICE_V6)
|
#define CONN_V6(x) ((x)->flags & SPLICE_V6)
|
||||||
#define CONN_V4(x) (!CONN_V6(x))
|
#define CONN_V4(x) (!CONN_V6(x))
|
||||||
#define CONN_HAS(conn, set) (((conn)->events & (set)) == (set))
|
#define CONN_HAS(conn, set) (((conn)->events & (set)) == (set))
|
||||||
#define CONN(idx) (&FLOW(idx)->tcp_splice)
|
|
||||||
|
|
||||||
/* Display strings for connection events */
|
/* Display strings for connection events */
|
||||||
static const char *tcp_splice_event_str[] __attribute((__unused__)) = {
|
static const char *tcp_splice_event_str[] __attribute((__unused__)) = {
|
||||||
|
@ -94,6 +93,24 @@ static const char *tcp_splice_flag_str[] __attribute((__unused__)) = {
|
||||||
static int tcp_sock_refill_ns(void *arg);
|
static int tcp_sock_refill_ns(void *arg);
|
||||||
static int tcp_conn_sock_ns(const struct ctx *c, sa_family_t af);
|
static int tcp_conn_sock_ns(const struct ctx *c, sa_family_t af);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* conn_at_sidx() - Get spliced TCP connection specific flow at given sidx
|
||||||
|
* @sidx: Flow and side to retrieve
|
||||||
|
*
|
||||||
|
* Return: Spliced TCP connection at @sidx, or NULL of @sidx is invalid.
|
||||||
|
* Asserts if the flow at @sidx is not FLOW_TCP_SPLICE.
|
||||||
|
*/
|
||||||
|
static struct tcp_splice_conn *conn_at_sidx(flow_sidx_t sidx)
|
||||||
|
{
|
||||||
|
union flow *flow = flow_at_sidx(sidx);
|
||||||
|
|
||||||
|
if (!flow)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ASSERT(flow->f.type == FLOW_TCP_SPLICE);
|
||||||
|
return &flow->tcp_splice;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tcp_splice_conn_epoll_events() - epoll events masks for given state
|
* tcp_splice_conn_epoll_events() - epoll events masks for given state
|
||||||
* @events: Connection event flags
|
* @events: Connection event flags
|
||||||
|
@ -502,7 +519,7 @@ bool tcp_splice_conn_from_sock(const struct ctx *c,
|
||||||
void tcp_splice_sock_handler(struct ctx *c, union epoll_ref ref,
|
void tcp_splice_sock_handler(struct ctx *c, union epoll_ref ref,
|
||||||
uint32_t events)
|
uint32_t events)
|
||||||
{
|
{
|
||||||
struct tcp_splice_conn *conn = CONN(ref.flowside.flow);
|
struct tcp_splice_conn *conn = conn_at_sidx(ref.flowside);
|
||||||
unsigned side = ref.flowside.side, fromside;
|
unsigned side = ref.flowside.side, fromside;
|
||||||
uint8_t lowat_set_flag, lowat_act_flag;
|
uint8_t lowat_set_flag, lowat_act_flag;
|
||||||
int eof, never_read;
|
int eof, never_read;
|
||||||
|
|
Loading…
Reference in a new issue