mirror of
https://github.com/openvswitch/ovs
synced 2025-09-03 15:55:19 +00:00
conntrack: Support conntrack flush by ct 5-tuple
This patch adds support of flushing a conntrack entry specified by the conntrack 5-tuple in dpif-netdev. Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Darrell Ball <dlu998@gmail.com>
This commit is contained in:
@@ -2368,6 +2368,10 @@ delete_conn(struct conn *conn)
|
|||||||
free(conn);
|
free(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a conntrack address 'a' into an IP address 'b' based on 'dl_type'.
|
||||||
|
*
|
||||||
|
* Note that 'dl_type' should be either "ETH_TYPE_IP" or "ETH_TYPE_IPv6"
|
||||||
|
* in network-byte order. */
|
||||||
static void
|
static void
|
||||||
ct_endpoint_to_ct_dpif_inet_addr(const struct ct_addr *a,
|
ct_endpoint_to_ct_dpif_inet_addr(const struct ct_addr *a,
|
||||||
union ct_dpif_inet_addr *b,
|
union ct_dpif_inet_addr *b,
|
||||||
@@ -2380,6 +2384,22 @@ ct_endpoint_to_ct_dpif_inet_addr(const struct ct_addr *a,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert an IP address 'a' into a conntrack address 'b' based on 'dl_type'.
|
||||||
|
*
|
||||||
|
* Note that 'dl_type' should be either "ETH_TYPE_IP" or "ETH_TYPE_IPv6"
|
||||||
|
* in network-byte order. */
|
||||||
|
static void
|
||||||
|
ct_dpif_inet_addr_to_ct_endpoint(const union ct_dpif_inet_addr *a,
|
||||||
|
struct ct_addr *b,
|
||||||
|
ovs_be16 dl_type)
|
||||||
|
{
|
||||||
|
if (dl_type == htons(ETH_TYPE_IP)) {
|
||||||
|
b->ipv4_aligned = a->ip;
|
||||||
|
} else if (dl_type == htons(ETH_TYPE_IPV6)){
|
||||||
|
b->ipv6_aligned = a->in6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
conn_key_to_tuple(const struct conn_key *key, struct ct_dpif_tuple *tuple)
|
conn_key_to_tuple(const struct conn_key *key, struct ct_dpif_tuple *tuple)
|
||||||
{
|
{
|
||||||
@@ -2404,6 +2424,35 @@ conn_key_to_tuple(const struct conn_key *key, struct ct_dpif_tuple *tuple)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tuple_to_conn_key(const struct ct_dpif_tuple *tuple, uint16_t zone,
|
||||||
|
struct conn_key *key)
|
||||||
|
{
|
||||||
|
if (tuple->l3_type == AF_INET) {
|
||||||
|
key->dl_type = htons(ETH_TYPE_IP);
|
||||||
|
} else if (tuple->l3_type == AF_INET6) {
|
||||||
|
key->dl_type = htons(ETH_TYPE_IPV6);
|
||||||
|
}
|
||||||
|
key->nw_proto = tuple->ip_proto;
|
||||||
|
ct_dpif_inet_addr_to_ct_endpoint(&tuple->src, &key->src.addr,
|
||||||
|
key->dl_type);
|
||||||
|
ct_dpif_inet_addr_to_ct_endpoint(&tuple->dst, &key->dst.addr,
|
||||||
|
key->dl_type);
|
||||||
|
|
||||||
|
if (tuple->ip_proto == IPPROTO_ICMP || tuple->ip_proto == IPPROTO_ICMPV6) {
|
||||||
|
key->src.icmp_id = tuple->icmp_id;
|
||||||
|
key->src.icmp_type = tuple->icmp_type;
|
||||||
|
key->src.icmp_code = tuple->icmp_code;
|
||||||
|
key->dst.icmp_id = tuple->icmp_id;
|
||||||
|
key->dst.icmp_type = reverse_icmp_type(tuple->icmp_type);
|
||||||
|
key->dst.icmp_code = tuple->icmp_code;
|
||||||
|
} else {
|
||||||
|
key->src.port = tuple->src_port;
|
||||||
|
key->dst.port = tuple->dst_port;
|
||||||
|
}
|
||||||
|
key->zone = zone;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry,
|
conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry,
|
||||||
long long now, int bkt)
|
long long now, int bkt)
|
||||||
@@ -2516,6 +2565,29 @@ conntrack_flush(struct conntrack *ct, const uint16_t *zone)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
conntrack_flush_tuple(struct conntrack *ct, const struct ct_dpif_tuple *tuple,
|
||||||
|
uint16_t zone)
|
||||||
|
{
|
||||||
|
struct conn_lookup_ctx ctx;
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
tuple_to_conn_key(tuple, zone, &ctx.key);
|
||||||
|
ctx.hash = conn_key_hash(&ctx.key, ct->hash_basis);
|
||||||
|
unsigned bucket = hash_to_bucket(ctx.hash);
|
||||||
|
|
||||||
|
ct_lock_lock(&ct->buckets[bucket].lock);
|
||||||
|
conn_key_lookup(&ct->buckets[bucket], &ctx, time_msec());
|
||||||
|
if (ctx.conn) {
|
||||||
|
conn_clean(ct, ctx.conn, &ct->buckets[bucket]);
|
||||||
|
} else {
|
||||||
|
error = ENOENT;
|
||||||
|
}
|
||||||
|
ct_lock_unlock(&ct->buckets[bucket].lock);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
conntrack_set_maxconns(struct conntrack *ct, uint32_t maxconns)
|
conntrack_set_maxconns(struct conntrack *ct, uint32_t maxconns)
|
||||||
{
|
{
|
||||||
|
@@ -109,6 +109,7 @@ struct conntrack_dump {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ct_dpif_entry;
|
struct ct_dpif_entry;
|
||||||
|
struct ct_dpif_tuple;
|
||||||
|
|
||||||
int conntrack_dump_start(struct conntrack *, struct conntrack_dump *,
|
int conntrack_dump_start(struct conntrack *, struct conntrack_dump *,
|
||||||
const uint16_t *pzone, int *);
|
const uint16_t *pzone, int *);
|
||||||
@@ -116,6 +117,8 @@ int conntrack_dump_next(struct conntrack_dump *, struct ct_dpif_entry *);
|
|||||||
int conntrack_dump_done(struct conntrack_dump *);
|
int conntrack_dump_done(struct conntrack_dump *);
|
||||||
|
|
||||||
int conntrack_flush(struct conntrack *, const uint16_t *zone);
|
int conntrack_flush(struct conntrack *, const uint16_t *zone);
|
||||||
|
int conntrack_flush_tuple(struct conntrack *, const struct ct_dpif_tuple *,
|
||||||
|
uint16_t zone);
|
||||||
int conntrack_set_maxconns(struct conntrack *ct, uint32_t maxconns);
|
int conntrack_set_maxconns(struct conntrack *ct, uint32_t maxconns);
|
||||||
int conntrack_get_maxconns(struct conntrack *ct, uint32_t *maxconns);
|
int conntrack_get_maxconns(struct conntrack *ct, uint32_t *maxconns);
|
||||||
int conntrack_get_nconns(struct conntrack *ct, uint32_t *nconns);
|
int conntrack_get_nconns(struct conntrack *ct, uint32_t *nconns);
|
||||||
|
@@ -5842,7 +5842,7 @@ dpif_netdev_ct_flush(struct dpif *dpif, const uint16_t *zone,
|
|||||||
struct dp_netdev *dp = get_dp_netdev(dpif);
|
struct dp_netdev *dp = get_dp_netdev(dpif);
|
||||||
|
|
||||||
if (tuple) {
|
if (tuple) {
|
||||||
return EOPNOTSUPP;
|
return conntrack_flush_tuple(&dp->conntrack, tuple, zone ? *zone : 0);
|
||||||
}
|
}
|
||||||
return conntrack_flush(&dp->conntrack, zone);
|
return conntrack_flush(&dp->conntrack, zone);
|
||||||
}
|
}
|
||||||
|
@@ -97,14 +97,6 @@ m4_define([CHECK_CONNTRACK_LOCAL_STACK])
|
|||||||
#
|
#
|
||||||
m4_define([CHECK_CONNTRACK_NAT])
|
m4_define([CHECK_CONNTRACK_NAT])
|
||||||
|
|
||||||
# CHECK_CT_DPIF_FLUSH_BY_CT_TUPLE()
|
|
||||||
#
|
|
||||||
# Perform requirements checks for running ovs-dpctl flush-conntrack by
|
|
||||||
# conntrack 5-tuple test. The kernel datapath does support this
|
|
||||||
# feature. Will remove this check after both kernel and userspace datapath
|
|
||||||
# support it.
|
|
||||||
m4_define([CHECK_CT_DPIF_FLUSH_BY_CT_TUPLE])
|
|
||||||
|
|
||||||
# CHECK_CT_DPIF_SET_GET_MAXCONNS()
|
# CHECK_CT_DPIF_SET_GET_MAXCONNS()
|
||||||
#
|
#
|
||||||
# Perform requirements checks for running ovs-dpctl ct-set-maxconns or
|
# Perform requirements checks for running ovs-dpctl ct-set-maxconns or
|
||||||
|
@@ -834,7 +834,6 @@ AT_CLEANUP
|
|||||||
|
|
||||||
AT_SETUP([conntrack - ct flush by 5-tuple])
|
AT_SETUP([conntrack - ct flush by 5-tuple])
|
||||||
CHECK_CONNTRACK()
|
CHECK_CONNTRACK()
|
||||||
CHECK_CT_DPIF_FLUSH_BY_CT_TUPLE()
|
|
||||||
OVS_TRAFFIC_VSWITCHD_START()
|
OVS_TRAFFIC_VSWITCHD_START()
|
||||||
|
|
||||||
ADD_NAMESPACES(at_ns0, at_ns1)
|
ADD_NAMESPACES(at_ns0, at_ns1)
|
||||||
|
@@ -100,16 +100,6 @@ m4_define([CHECK_CONNTRACK_LOCAL_STACK],
|
|||||||
#
|
#
|
||||||
m4_define([CHECK_CONNTRACK_NAT])
|
m4_define([CHECK_CONNTRACK_NAT])
|
||||||
|
|
||||||
# CHECK_CT_DPIF_FLUSH_BY_CT_TUPLE()
|
|
||||||
#
|
|
||||||
# Perform requirements checks for running ovs-dpctl flush-conntrack by
|
|
||||||
# conntrack 5-tuple test. The userspace datapath does not support
|
|
||||||
# this feature yet.
|
|
||||||
m4_define([CHECK_CT_DPIF_FLUSH_BY_CT_TUPLE],
|
|
||||||
[
|
|
||||||
AT_SKIP_IF([:])
|
|
||||||
])
|
|
||||||
|
|
||||||
# CHECK_CT_DPIF_SET_GET_MAXCONNS()
|
# CHECK_CT_DPIF_SET_GET_MAXCONNS()
|
||||||
#
|
#
|
||||||
# Perform requirements checks for running ovs-dpctl ct-set-maxconns or
|
# Perform requirements checks for running ovs-dpctl ct-set-maxconns or
|
||||||
|
Reference in New Issue
Block a user