2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

Userspace datapath: Add fragmentation handling.

Fragmentation handling is added for supporting conntrack.
Both v4 and v6 are supported.

After discussion with several people, I decided to not store
configuration state in the database to be more consistent with
the kernel in future, similarity with other conntrack configuration
which will not be in the database as well and overall simplicity.
Accordingly, fragmentation handling is enabled by default.

This patch enables fragmentation tests for the userspace datapath.

Signed-off-by: Darrell Ball <dlu998@gmail.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Darrell Ball 2019-02-13 15:34:21 -08:00 committed by Ben Pfaff
parent 9f17f104fe
commit 4ea96698f6
18 changed files with 2330 additions and 83 deletions

View File

@ -105,31 +105,32 @@ Q: Are all features available with all datapaths?
The following table lists the datapath supported features from an Open
vSwitch user's perspective.
===================== ============== ============== ========= =======
Feature Linux upstream Linux OVS tree Userspace Hyper-V
===================== ============== ============== ========= =======
NAT 4.6 YES Yes NO
Connection tracking 4.3 YES PARTIAL PARTIAL
Tunnel - LISP NO YES NO NO
Tunnel - STT NO YES NO YES
Tunnel - GRE 3.11 YES YES YES
Tunnel - VXLAN 3.12 YES YES YES
Tunnel - Geneve 3.18 YES YES YES
Tunnel - GRE-IPv6 4.18 YES YES NO
Tunnel - VXLAN-IPv6 4.3 YES YES NO
Tunnel - Geneve-IPv6 4.4 YES YES NO
Tunnel - ERSPAN 4.18 YES YES NO
Tunnel - ERSPAN-IPv6 4.18 YES YES NO
QoS - Policing YES YES YES NO
QoS - Shaping YES YES NO NO
sFlow YES YES YES NO
IPFIX 3.10 YES YES NO
Set action YES YES YES PARTIAL
NIC Bonding YES YES YES YES
Multiple VTEPs YES YES YES YES
Meters 4.15 YES YES NO
Conntrack zone limit 4.18 YES NO NO
===================== ============== ============== ========= =======
========================== ============== ============== ========= =======
Feature Linux upstream Linux OVS tree Userspace Hyper-V
========================== ============== ============== ========= =======
Connection tracking 4.3 YES YES YES
Conntrack Fragment Reass. 4.3 YES YES YES
NAT 4.6 YES YES NO
Conntrack zone limit 4.18 YES NO NO
Tunnel - LISP NO YES NO NO
Tunnel - STT NO YES NO YES
Tunnel - GRE 3.11 YES YES YES
Tunnel - VXLAN 3.12 YES YES YES
Tunnel - Geneve 3.18 YES YES YES
Tunnel - GRE-IPv6 NO NO YES NO
Tunnel - VXLAN-IPv6 4.3 YES YES NO
Tunnel - Geneve-IPv6 4.4 YES YES NO
Tunnel - ERSPAN 4.18 YES YES NO
Tunnel - ERSPAN-IPv6 4.18 YES YES NO
QoS - Policing YES YES YES NO
QoS - Shaping YES YES NO NO
sFlow YES YES YES NO
IPFIX 3.10 YES YES NO
Set action YES YES YES PARTIAL
NIC Bonding YES YES YES YES
Multiple VTEPs YES YES YES YES
Meters 4.15 YES YES NO
========================== ============== ============== ========= =======
Do note, however:

10
NEWS
View File

@ -8,7 +8,15 @@ Post-v2.11.0
- Userspace datapath:
* ICMPv6 ND enhancements: support for match and set ND options type
and reserved fields.
* Add v4/v6 fragmentation support for conntrack.
* New ovs-appctl "dpctl/ipf-set-enabled" and "dpctl/ipf-set-disabled"
commands for userspace datapath conntrack fragmentation support.
* New "ovs-appctl dpctl/ipf-set-min-frag" command for userspace
datapath conntrack fragmentation support.
* New "ovs-appctl dpctl/ipf-set-max-nfrags" command for userspace datapath
conntrack fragmentation support.
* New "ovs-appctl dpctl/ipf-get-status" command for userspace datapath
conntrack fragmentation support.
v2.11.0 - xx xxx xxxx
---------------------

View File

@ -64,5 +64,6 @@ struct ip6_frag {
};
#define IP6F_OFF_MASK ((OVS_FORCE ovs_be16) 0xfff8)
#define IP6F_MORE_FRAG ((OVS_FORCE ovs_be16) 0x0001)
#endif /* netinet/ip6.h sparse */

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
# Copyright (C) 2009-2018 Nicira, Inc.
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
@ -108,6 +108,8 @@ lib_libopenvswitch_la_SOURCES = \
lib/hmapx.h \
lib/id-pool.c \
lib/id-pool.h \
lib/ipf.c \
lib/ipf.h \
lib/jhash.c \
lib/jhash.h \
lib/json.c \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, 2017 Nicira, Inc.
* Copyright (c) 2015-2019 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,6 +30,7 @@
#include "ct-dpif.h"
#include "dp-packet.h"
#include "flow.h"
#include "ipf.h"
#include "netdev.h"
#include "odp-netlink.h"
#include "openvswitch/hmap.h"
@ -340,6 +341,7 @@ conntrack_init(struct conntrack *ct)
atomic_init(&ct->n_conn_limit, DEFAULT_N_CONN_LIMIT);
latch_init(&ct->clean_thread_exit);
ct->clean_thread = ovs_thread_create("ct_clean", clean_thread_main, ct);
ct->ipf = ipf_init();
}
/* Destroys the connection tracker 'ct' and frees all the allocated memory. */
@ -382,6 +384,7 @@ conntrack_destroy(struct conntrack *ct)
hindex_destroy(&ct->alg_expectation_refs);
ct_rwlock_unlock(&ct->resources_lock);
ct_rwlock_destroy(&ct->resources_lock);
ipf_destroy(ct->ipf);
}
static unsigned hash_to_bucket(uint32_t hash)
@ -1299,7 +1302,8 @@ process_one(struct conntrack *ct, struct dp_packet *pkt,
/* Sends the packets in '*pkt_batch' through the connection tracker 'ct'. All
* the packets must have the same 'dl_type' (IPv4 or IPv6) and should have
* the l3 and and l4 offset properly set.
* the l3 and and l4 offset properly set. Performs fragment reassembly with
* the help of ipf_preprocess_conntrack().
*
* If 'commit' is true, the packets are allowed to create new entries in the
* connection tables. 'setmark', if not NULL, should point to a two
@ -1314,11 +1318,15 @@ conntrack_execute(struct conntrack *ct, struct dp_packet_batch *pkt_batch,
const struct nat_action_info_t *nat_action_info,
long long now)
{
ipf_preprocess_conntrack(ct->ipf, pkt_batch, now, dl_type, zone,
ct->hash_basis);
struct dp_packet *packet;
struct conn_lookup_ctx ctx;
DP_PACKET_BATCH_FOR_EACH (i, packet, pkt_batch) {
if (!conn_key_extract(ct, packet, dl_type, &ctx, zone)) {
if (packet->md.ct_state == CS_INVALID
|| !conn_key_extract(ct, packet, dl_type, &ctx, zone)) {
packet->md.ct_state = CS_INVALID;
write_ct_md(packet, zone, NULL, NULL, NULL);
continue;
@ -1327,6 +1335,8 @@ conntrack_execute(struct conntrack *ct, struct dp_packet_batch *pkt_batch,
setlabel, nat_action_info, tp_src, tp_dst, helper);
}
ipf_postprocess_conntrack(ct->ipf, pkt_batch, now, dl_type);
return 0;
}
@ -2484,6 +2494,12 @@ conn_to_ct_dpif_entry(const struct conn *conn, struct ct_dpif_entry *entry,
}
}
struct ipf *
conntrack_ipf_ctx(struct conntrack *ct)
{
return ct->ipf;
}
int
conntrack_dump_start(struct conntrack *ct, struct conntrack_dump *dump,
const uint16_t *pzone, int *ptot_bkts)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, 2017 Nicira, Inc.
* Copyright (c) 2015, 2016, 2017, 2019 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -122,6 +122,7 @@ int conntrack_flush_tuple(struct conntrack *, const struct ct_dpif_tuple *,
int conntrack_set_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);
struct ipf *conntrack_ipf_ctx(struct conntrack *ct);
/* 'struct ct_lock' is a wrapper for an adaptive mutex. It's useful to try
* different types of locks (e.g. spinlocks) */
@ -293,6 +294,9 @@ struct conntrack {
*/
struct ct_rwlock resources_lock;
/* Fragmentation handling context. */
struct ipf *ipf;
};
#endif /* conntrack.h */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Nicira, Inc.
* Copyright (c) 2015, 2018 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -194,6 +194,62 @@ ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *zone_limits)
: EOPNOTSUPP);
}
int
ct_dpif_ipf_set_enabled(struct dpif *dpif, bool v6, bool enable)
{
return (dpif->dpif_class->ipf_set_enabled
? dpif->dpif_class->ipf_set_enabled(dpif, v6, enable)
: EOPNOTSUPP);
}
int
ct_dpif_ipf_set_min_frag(struct dpif *dpif, bool v6, uint32_t min_frag)
{
return (dpif->dpif_class->ipf_set_min_frag
? dpif->dpif_class->ipf_set_min_frag(dpif, v6, min_frag)
: EOPNOTSUPP);
}
int
ct_dpif_ipf_set_max_nfrags(struct dpif *dpif, uint32_t max_frags)
{
return (dpif->dpif_class->ipf_set_max_nfrags
? dpif->dpif_class->ipf_set_max_nfrags(dpif, max_frags)
: EOPNOTSUPP);
}
int ct_dpif_ipf_get_status(struct dpif *dpif,
struct dpif_ipf_status *dpif_ipf_status)
{
return (dpif->dpif_class->ipf_get_status
? dpif->dpif_class->ipf_get_status(dpif, dpif_ipf_status)
: EOPNOTSUPP);
}
int
ct_dpif_ipf_dump_start(struct dpif *dpif, struct ipf_dump_ctx **dump_ctx)
{
return (dpif->dpif_class->ipf_dump_start
? dpif->dpif_class->ipf_dump_start(dpif, dump_ctx)
: EOPNOTSUPP);
}
int
ct_dpif_ipf_dump_next(struct dpif *dpif, void *dump_ctx, char **dump)
{
return (dpif->dpif_class->ipf_dump_next
? dpif->dpif_class->ipf_dump_next(dpif, dump_ctx, dump)
: EOPNOTSUPP);
}
int
ct_dpif_ipf_dump_done(struct dpif *dpif, void *dump_ctx)
{
return (dpif->dpif_class->ipf_dump_done
? dpif->dpif_class->ipf_dump_done(dpif, dump_ctx)
: EOPNOTSUPP);
}
void
ct_dpif_entry_uninit(struct ct_dpif_entry *entry)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Nicira, Inc.
* Copyright (c) 2015, 2018 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -186,6 +186,8 @@ enum {
};
struct dpif;
struct dpif_ipf_status;
struct ipf_dump_ctx;
struct ct_dpif_dump_state {
struct dpif *dpif;
@ -212,6 +214,14 @@ int ct_dpif_set_limits(struct dpif *dpif, const uint32_t *default_limit,
int ct_dpif_get_limits(struct dpif *dpif, uint32_t *default_limit,
const struct ovs_list *, struct ovs_list *);
int ct_dpif_del_limits(struct dpif *dpif, const struct ovs_list *);
int ct_dpif_ipf_set_enabled(struct dpif *, bool v6, bool enable);
int ct_dpif_ipf_set_min_frag(struct dpif *, bool v6, uint32_t min_frag);
int ct_dpif_ipf_set_max_nfrags(struct dpif *, uint32_t max_frags);
int ct_dpif_ipf_get_status(struct dpif *dpif,
struct dpif_ipf_status *dpif_ipf_status);
int ct_dpif_ipf_dump_start(struct dpif *dpif, struct ipf_dump_ctx **);
int ct_dpif_ipf_dump_next(struct dpif *dpif, void *, char **);
int ct_dpif_ipf_dump_done(struct dpif *dpif, void *);
void ct_dpif_entry_uninit(struct ct_dpif_entry *);
void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *,
bool verbose, bool print_stats);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008-2017 Nicira, Inc.
* Copyright (c) 2008-2018 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -33,6 +33,7 @@
#include "dirs.h"
#include "dpctl.h"
#include "dpif.h"
#include "dpif-provider.h"
#include "openvswitch/dynamic-string.h"
#include "flow.h"
#include "openvswitch/match.h"
@ -1917,6 +1918,210 @@ out:
return error;
}
static int
ipf_set_enabled__(int argc, const char *argv[], struct dpctl_params *dpctl_p,
bool enabled)
{
struct dpif *dpif;
int error = opt_dpif_open(argc, argv, dpctl_p, 4, &dpif);
if (!error) {
char v4_or_v6[3] = {0};
if (ovs_scan(argv[argc - 1], "%2s", v4_or_v6) &&
(!strncmp(v4_or_v6, "v4", 2) || !strncmp(v4_or_v6, "v6", 2))) {
error = ct_dpif_ipf_set_enabled(
dpif, !strncmp(v4_or_v6, "v6", 2), enabled);
if (!error) {
dpctl_print(dpctl_p,
"%s fragmentation reassembly successful",
enabled ? "enabling" : "disabling");
} else {
dpctl_error(dpctl_p, error,
"%s fragmentation reassembly failed",
enabled ? "enabling" : "disabling");
}
} else {
error = EINVAL;
dpctl_error(dpctl_p, error,
"parameter missing: 'v4' for IPv4 or 'v6' for IPv6");
}
dpif_close(dpif);
}
return error;
}
static int
dpctl_ipf_set_enabled(int argc, const char *argv[],
struct dpctl_params *dpctl_p)
{
return ipf_set_enabled__(argc, argv, dpctl_p, true);
}
static int
dpctl_ipf_set_disabled(int argc, const char *argv[],
struct dpctl_params *dpctl_p)
{
return ipf_set_enabled__(argc, argv, dpctl_p, false);
}
static int
dpctl_ipf_set_min_frag(int argc, const char *argv[],
struct dpctl_params *dpctl_p)
{
struct dpif *dpif;
int error = opt_dpif_open(argc, argv, dpctl_p, 4, &dpif);
if (!error) {
char v4_or_v6[3] = {0};
if (ovs_scan(argv[argc - 2], "%2s", v4_or_v6) &&
(!strncmp(v4_or_v6, "v4", 2) || !strncmp(v4_or_v6, "v6", 2))) {
uint32_t min_fragment;
if (ovs_scan(argv[argc - 1], "%"SCNu32, &min_fragment)) {
error = ct_dpif_ipf_set_min_frag(
dpif, !strncmp(v4_or_v6, "v6", 2), min_fragment);
if (!error) {
dpctl_print(dpctl_p,
"setting minimum fragment size successful");
} else {
dpctl_error(dpctl_p, error,
"requested minimum fragment size too small;"
" see documentation");
}
} else {
error = EINVAL;
dpctl_error(dpctl_p, error,
"parameter missing for minimum fragment size");
}
} else {
error = EINVAL;
dpctl_error(dpctl_p, error,
"parameter missing: v4 for IPv4 or v6 for IPv6");
}
dpif_close(dpif);
}
return error;
}
static int
dpctl_ipf_set_max_nfrags(int argc, const char *argv[],
struct dpctl_params *dpctl_p)
{
struct dpif *dpif;
int error = opt_dpif_open(argc, argv, dpctl_p, 3, &dpif);
if (!error) {
uint32_t nfrags_max;
if (ovs_scan(argv[argc - 1], "%"SCNu32, &nfrags_max)) {
error = ct_dpif_ipf_set_max_nfrags(dpif, nfrags_max);
if (!error) {
dpctl_print(dpctl_p,
"setting maximum fragments successful");
} else {
dpctl_error(dpctl_p, error,
"setting maximum fragments failed");
}
} else {
error = EINVAL;
dpctl_error(dpctl_p, error,
"parameter missing for maximum fragments");
}
dpif_close(dpif);
}
return error;
}
static void
dpctl_dump_ipf(struct dpif *dpif, struct dpctl_params *dpctl_p)
{
struct ipf_dump_ctx *dump_ctx;
char *dump;
int error = ct_dpif_ipf_dump_start(dpif, &dump_ctx);
if (error) {
dpctl_error(dpctl_p, error, "starting ipf list dump");
/* Nothing to clean up, just return. */
return;
}
dpctl_print(dpctl_p, "\n Fragment Lists:\n\n");
while (!(error = ct_dpif_ipf_dump_next(dpif, dump_ctx, &dump))) {
dpctl_print(dpctl_p, "%s\n", dump);
free(dump);
}
if (error && error != EOF) {
dpctl_error(dpctl_p, error, "dumping ipf lists failed");
}
ct_dpif_ipf_dump_done(dpif, dump_ctx);
}
static int
dpctl_ct_ipf_get_status(int argc, const char *argv[],
struct dpctl_params *dpctl_p)
{
struct dpif *dpif;
int error = opt_dpif_open(argc, argv, dpctl_p, 2, &dpif);
if (!error) {
struct dpif_ipf_status dpif_ipf_status;
error = ct_dpif_ipf_get_status(dpif, &dpif_ipf_status);
if (!error) {
dpctl_print(dpctl_p, " Fragmentation Module Status\n");
dpctl_print(dpctl_p, " ---------------------------\n");
dpctl_print(dpctl_p, " v4 enabled: %u\n",
dpif_ipf_status.v4.enabled);
dpctl_print(dpctl_p, " v6 enabled: %u\n",
dpif_ipf_status.v6.enabled);
dpctl_print(dpctl_p, " max num frags (v4/v6): %u\n",
dpif_ipf_status.nfrag_max);
dpctl_print(dpctl_p, " num frag: %u\n",
dpif_ipf_status.nfrag);
dpctl_print(dpctl_p, " min v4 frag size: %u\n",
dpif_ipf_status.v4.min_frag_size);
dpctl_print(dpctl_p, " v4 frags accepted: %"PRIu64"\n",
dpif_ipf_status.v4.nfrag_accepted);
dpctl_print(dpctl_p, " v4 frags completed: %"PRIu64"\n",
dpif_ipf_status.v4.nfrag_completed_sent);
dpctl_print(dpctl_p, " v4 frags expired: %"PRIu64"\n",
dpif_ipf_status.v4.nfrag_expired_sent);
dpctl_print(dpctl_p, " v4 frags too small: %"PRIu64"\n",
dpif_ipf_status.v4.nfrag_too_small);
dpctl_print(dpctl_p, " v4 frags overlapped: %"PRIu64"\n",
dpif_ipf_status.v4.nfrag_overlap);
dpctl_print(dpctl_p, " v4 frags purged: %"PRIu64"\n",
dpif_ipf_status.v4.nfrag_purged);
dpctl_print(dpctl_p, " min v6 frag size: %u\n",
dpif_ipf_status.v6.min_frag_size);
dpctl_print(dpctl_p, " v6 frags accepted: %"PRIu64"\n",
dpif_ipf_status.v6.nfrag_accepted);
dpctl_print(dpctl_p, " v6 frags completed: %"PRIu64"\n",
dpif_ipf_status.v6.nfrag_completed_sent);
dpctl_print(dpctl_p, " v6 frags expired: %"PRIu64"\n",
dpif_ipf_status.v6.nfrag_expired_sent);
dpctl_print(dpctl_p, " v6 frags too small: %"PRIu64"\n",
dpif_ipf_status.v6.nfrag_too_small);
dpctl_print(dpctl_p, " v6 frags overlapped: %"PRIu64"\n",
dpif_ipf_status.v6.nfrag_overlap);
dpctl_print(dpctl_p, " v6 frags purged: %"PRIu64"\n",
dpif_ipf_status.v6.nfrag_purged);
} else {
dpctl_error(dpctl_p, error,
"ipf status could not be retrieved");
return error;
}
if (dpctl_p->verbosity) {
dpctl_dump_ipf(dpif, dpctl_p);
}
dpif_close(dpif);
}
return error;
}
/* Undocumented commands for unit testing. */
static int
@ -2222,6 +2427,14 @@ static const struct dpctl_command all_commands[] = {
DP_RO },
{ "ct-get-limits", "[dp] [zone=N1[,N2]...]", 0, 2, dpctl_ct_get_limits,
DP_RO },
{ "ipf-set-enabled", "[dp] v4|v6", 1, 2, dpctl_ipf_set_enabled, DP_RW },
{ "ipf-set-disabled", "[dp] v4|v6", 1, 2, dpctl_ipf_set_disabled, DP_RW },
{ "ipf-set-min-frag", "[dp] v4|v6 minfragment", 2, 3,
dpctl_ipf_set_min_frag, DP_RW },
{ "ipf-set-max-nfrags", "[dp] maxfrags", 1, 2,
dpctl_ipf_set_max_nfrags, DP_RW },
{ "ipf-get-status", "[dp]", 0, 1, dpctl_ct_ipf_get_status,
DP_RO },
{ "help", "", 0, INT_MAX, dpctl_help, DP_RO },
{ "list-commands", "", 0, INT_MAX, dpctl_list_commands, DP_RO },

View File

@ -220,6 +220,42 @@ nftables and the regular host stack). Therefore, the following commands
do not apply specifically to one datapath.
.
.TP
\*(DX\fBipf\-set\-enabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
.TQ
\*(DX\fBipf\-set\-disabled\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR
Enables or disables IP fragmentation handling for the userspace
connection tracker. Either \fBv4\fR or \fBv6\fR must be specified.
Both IPv4 and IPv6 fragment reassembly are enabled by default. Only
supported for the userspace datapath.
.
.TP
\*(DX\fBipf\-set\-min\-frag\fR [\fIdp\fR] \fBv4\fR|\fBv6\fR \fIminfrag\fR
Sets the minimum fragment size for non-final fragments to
\fIminfrag\fR. Either \fBv4\fR or \fBv6\fR must be specified. For
enhanced DOS security, higher minimum fragment sizes can usually be used.
The default IPv4 value is 1200 and the clamped minimum is 400. The default
IPv6 value is 1280, with a clamped minimum of 400, for testing
flexibility. The maximum fragment size is not clamped, however, setting
this value too high might result in valid fragments being dropped. Only
supported for userspace datapath.
.
.TP
\*(DX\fBipf\-set\-max\-nfrags\fR [\fIdp\fR] \fImaxfrags\fR
Sets the maximum number of fragments tracked by the userspace datapath
connection tracker to \fImaxfrags\fR. The default value is 1000 and the
clamped maximum is 5000. Note that packet buffers can be held by the
fragmentation module while fragments are incomplete, but will timeout
after 15 seconds. Memory pool sizing should be set accordingly when
fragmentation is enabled. Only supported for userspace datapath.
.
.TP
.DO "[\fB\-m\fR | \fB\-\-more\fR]" "\*(DX\fBipf\-get\-status\fR [\fIdp\fR]"
Gets the configuration settings and fragment counters associated with the
fragmentation handling of the userspace datapath connection tracker.
With \fB\-m\fR or \fB\-\-more\fR, also dumps the IP fragment lists.
Only supported for userspace datapath.
.
.TP
.DO "[\fB\-m\fR | \fB\-\-more\fR] [\fB\-s\fR | \fB\-\-statistics\fR]" "\*(DX\fBdump\-conntrack\fR" "[\fIdp\fR] [\fBzone=\fIzone\fR]"
Prints to the console all the connection entries in the tracker used by
\fIdp\fR. If \fBzone=\fIzone\fR is specified, only shows the connections

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017 Nicira, Inc.
* Copyright (c) 2009-2014, 2016-2018 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -47,6 +47,7 @@
#include "flow.h"
#include "hmapx.h"
#include "id-pool.h"
#include "ipf.h"
#include "latch.h"
#include "netdev.h"
#include "netdev-provider.h"
@ -7356,6 +7357,61 @@ dpif_netdev_ct_get_nconns(struct dpif *dpif, uint32_t *nconns)
return conntrack_get_nconns(&dp->conntrack, nconns);
}
static int
dpif_netdev_ipf_set_enabled(struct dpif *dpif, bool v6, bool enable)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
return ipf_set_enabled(conntrack_ipf_ctx(&dp->conntrack), v6, enable);
}
static int
dpif_netdev_ipf_set_min_frag(struct dpif *dpif, bool v6, uint32_t min_frag)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
return ipf_set_min_frag(conntrack_ipf_ctx(&dp->conntrack), v6, min_frag);
}
static int
dpif_netdev_ipf_set_max_nfrags(struct dpif *dpif, uint32_t max_frags)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
return ipf_set_max_nfrags(conntrack_ipf_ctx(&dp->conntrack), max_frags);
}
/* Adjust this function if 'dpif_ipf_status' and 'ipf_status' were to
* diverge. */
static int
dpif_netdev_ipf_get_status(struct dpif *dpif,
struct dpif_ipf_status *dpif_ipf_status)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
ipf_get_status(conntrack_ipf_ctx(&dp->conntrack),
(struct ipf_status *) dpif_ipf_status);
return 0;
}
static int
dpif_netdev_ipf_dump_start(struct dpif *dpif OVS_UNUSED,
struct ipf_dump_ctx **ipf_dump_ctx)
{
return ipf_dump_start(ipf_dump_ctx);
}
static int
dpif_netdev_ipf_dump_next(struct dpif *dpif, void *ipf_dump_ctx, char **dump)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
return ipf_dump_next(conntrack_ipf_ctx(&dp->conntrack), ipf_dump_ctx,
dump);
}
static int
dpif_netdev_ipf_dump_done(struct dpif *dpif OVS_UNUSED, void *ipf_dump_ctx)
{
return ipf_dump_done(ipf_dump_ctx);
}
const struct dpif_class dpif_netdev_class = {
"netdev",
dpif_netdev_init,
@ -7407,6 +7463,13 @@ const struct dpif_class dpif_netdev_class = {
NULL, /* ct_set_limits */
NULL, /* ct_get_limits */
NULL, /* ct_del_limits */
dpif_netdev_ipf_set_enabled,
dpif_netdev_ipf_set_min_frag,
dpif_netdev_ipf_set_max_nfrags,
dpif_netdev_ipf_get_status,
dpif_netdev_ipf_dump_start,
dpif_netdev_ipf_dump_next,
dpif_netdev_ipf_dump_done,
dpif_netdev_meter_get_features,
dpif_netdev_meter_set,
dpif_netdev_meter_get,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008-2017 Nicira, Inc.
* Copyright (c) 2008-2018 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -3429,6 +3429,13 @@ const struct dpif_class dpif_netlink_class = {
dpif_netlink_ct_set_limits,
dpif_netlink_ct_get_limits,
dpif_netlink_ct_del_limits,
NULL, /* ipf_set_enabled */
NULL, /* ipf_set_min_frag */
NULL, /* ipf_set_max_nfrags */
NULL, /* ipf_get_status */
NULL, /* ipf_dump_start */
NULL, /* ipf_dump_next */
NULL, /* ipf_dump_done */
dpif_netlink_meter_get_features,
dpif_netlink_meter_set,
dpif_netlink_meter_get,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
* Copyright (c) 2009-2014, 2018 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -42,6 +42,9 @@ struct dpif {
long long int current_ms;
};
struct dpif_ipf_status;
struct ipf_dump_ctx;
void dpif_init(struct dpif *, const struct dpif_class *, const char *name,
uint8_t netflow_engine_type, uint8_t netflow_engine_id);
void dpif_uninit(struct dpif *dpif, bool close);
@ -78,6 +81,27 @@ struct ct_dpif_dump_state;
struct ct_dpif_entry;
struct ct_dpif_tuple;
/* 'dpif_ipf_proto_status' and 'dpif_ipf_status' are presently in
* sync with 'ipf_proto_status' and 'ipf_status', but more
* generally represent a superset of present and future support. */
struct dpif_ipf_proto_status {
uint64_t nfrag_accepted;
uint64_t nfrag_completed_sent;
uint64_t nfrag_expired_sent;
uint64_t nfrag_too_small;
uint64_t nfrag_overlap;
uint64_t nfrag_purged;
unsigned int min_frag_size;
bool enabled;
};
struct dpif_ipf_status {
struct dpif_ipf_proto_status v4;
struct dpif_ipf_proto_status v6;
unsigned int nfrag;
unsigned int nfrag_max;
};
/* Datapath interface class structure, to be defined by each implementation of
* a datapath interface.
*
@ -468,6 +492,33 @@ struct dpif_class {
* list of 'struct ct_dpif_zone_limit' entries. */
int (*ct_del_limits)(struct dpif *, const struct ovs_list *zone_limits);
/* IP Fragmentation. */
/* Disables or enables conntrack fragment reassembly. The default
* setting is enabled. */
int (*ipf_set_enabled)(struct dpif *, bool v6, bool enabled);
/* Set minimum fragment allowed. */
int (*ipf_set_min_frag)(struct dpif *, bool v6, uint32_t min_frag);
/* Set maximum number of fragments tracked. */
int (*ipf_set_max_nfrags)(struct dpif *, uint32_t max_nfrags);
/* Get fragmentation configuration status and counters. */
int (*ipf_get_status)(struct dpif *,
struct dpif_ipf_status *dpif_ipf_status);
/* The following 3 apis find and print ipf lists by creating a string
* representation of the state of an ipf list, to which 'dump' is pointed
* to. 'ipf_dump_start()' allocates memory for 'ipf_dump_ctx'.
* 'ipf_dump_next()' finds the next ipf list and copies it's
* characteristics to a string, which is freed by the caller.
* 'ipf_dump_done()' frees the 'ipf_dump_ctx' that was allocated in
* 'ipf_dump_start'. */
int (*ipf_dump_start)(struct dpif *, struct ipf_dump_ctx **ipf_dump_ctx);
int (*ipf_dump_next)(struct dpif *, void *ipf_dump_ctx, char **dump);
int (*ipf_dump_done)(struct dpif *, void *ipf_dump_ctx);
/* Meters */
/* Queries 'dpif' for supported meter features.

1525
lib/ipf.c Normal file

File diff suppressed because it is too large Load Diff

63
lib/ipf.h Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2019 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef IPF_H
#define IPF_H 1
#include "dp-packet.h"
#include "openvswitch/types.h"
struct ipf;
struct ipf_proto_status {
uint64_t nfrag_accepted;
uint64_t nfrag_completed_sent;
uint64_t nfrag_expired_sent;
uint64_t nfrag_too_small;
uint64_t nfrag_overlap;
uint64_t nfrag_purged;
unsigned int min_frag_size;
bool enabled;
};
struct ipf_status {
struct ipf_proto_status v4;
struct ipf_proto_status v6;
unsigned int nfrag;
unsigned int nfrag_max;
};
struct ipf *ipf_init(void);
void ipf_destroy(struct ipf *ipf);
void ipf_preprocess_conntrack(struct ipf *ipf, struct dp_packet_batch *pb,
long long now, ovs_be16 dl_type, uint16_t zone,
uint32_t hash_basis);
void ipf_postprocess_conntrack(struct ipf *ipf, struct dp_packet_batch *pb,
long long now, ovs_be16 dl_type);
int ipf_set_enabled(struct ipf *ipf, bool v6, bool enable);
int ipf_set_min_frag(struct ipf *ipf, bool v6, uint32_t value);
int ipf_set_max_nfrags(struct ipf *ipf, uint32_t value);
int ipf_get_status(struct ipf *ipf, struct ipf_status *ipf_status);
struct ipf_dump_ctx;
int ipf_dump_start(struct ipf_dump_ctx **ipf_dump_ctx);
int ipf_dump_next(struct ipf *ipf, struct ipf_dump_ctx *ipf_dump_ctx,
char **dump);
int ipf_dump_done(struct ipf_dump_ctx *ipf_dump_ctx);
#endif /* ipf.h */

View File

@ -77,12 +77,6 @@ m4_define([CHECK_CONNTRACK],
#
m4_define([CHECK_CONNTRACK_ALG])
# CHECK_CONNTRACK_FRAG()
#
# Perform requirements checks for running conntrack fragmentations tests.
# The kernel always supports fragmentation, so no check is needed.
m4_define([CHECK_CONNTRACK_FRAG])
# CHECK_CONNTRACK_LOCAL_STACK()
#
# Perform requirements checks for running conntrack tests with local stack.
@ -140,6 +134,46 @@ m4_define([CHECK_CT_DPIF_GET_NCONNS],
AT_SKIP_IF([:])
])
# DPCTL_SET_MIN_FRAG_SIZE()
#
# The kernel does not support this command.
m4_define([DPCTL_SET_MIN_FRAG_SIZE],
[
])
# DPCTL_MODIFY_FRAGMENTATION()
#
# The kernel does not support this command.
m4_define([DPCTL_MODIFY_FRAGMENTATION],
[
])
# DPCTL_CHECK_FRAGMENTATION_PASS()
#
# The kernel does not support this command.
m4_define([DPCTL_CHECK_FRAGMENTATION_PASS],
[
])
# DPCTL_CHECK_V6_FRAGMENTATION_PASS()
#
# The kernel does not support this command.
m4_define([DPCTL_CHECK_V6_FRAGMENTATION_PASS],
[
])
# DPCTL_CHECK_FRAGMENTATION_FAIL()
#
# The kernel does not support this command.
m4_define([DPCTL_CHECK_FRAGMENTATION_FAIL],
[
])
# OVS_CHECK_KERNEL([minversion], [minsublevel], [maxversion], [maxsublevel])
#
# Check if kernel version falls between minversion.minsublevel and

View File

@ -2356,7 +2356,6 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv4 fragmentation])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2375,6 +2374,9 @@ priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1
AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
dnl Modify userspace conntrack fragmentation handling.
DPCTL_MODIFY_FRAGMENTATION()
dnl Ipv4 fragmentation connectivity check.
NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
@ -2385,12 +2387,14 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])
dnl Check userspace conntrack fragmentation counters.
DPCTL_CHECK_FRAGMENTATION_PASS()
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conntrack - IPv4 fragmentation expiry])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2411,17 +2415,22 @@ priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1
AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
dnl Modify userspace conntrack fragmentation handling.
DPCTL_MODIFY_FRAGMENTATION()
dnl Ipv4 fragmentation connectivity check.
NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 1 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl
7 packets transmitted, 0 received, 100% packet loss, time 0ms
])
dnl Check userspace conntrack fragmentation counters.
DPCTL_CHECK_FRAGMENTATION_FAIL()
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conntrack - IPv4 fragmentation + vlan])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2442,6 +2451,9 @@ priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1
AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
dnl Modify userspace conntrack fragmentation handling.
DPCTL_MODIFY_FRAGMENTATION()
dnl Ipv4 fragmentation connectivity check.
NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
@ -2452,12 +2464,14 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])
dnl Check userspace conntrack fragmentation counters.
DPCTL_CHECK_FRAGMENTATION_PASS()
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conntrack - IPv4 fragmentation + cvlan])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0])
OVS_CHECK_8021AD()
@ -2511,6 +2525,8 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv4 fragmentation incomplete reassembled packet])
CHECK_CONNTRACK()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2532,8 +2548,8 @@ AT_CLEANUP
dnl Uses same first fragment as above 'incomplete reassembled packet' test.
AT_SETUP([conntrack - IPv4 fragmentation with fragments specified])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2556,8 +2572,8 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv4 fragmentation out of order])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2580,9 +2596,9 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv4 fragmentation overlapping fragments by 1 octet])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
CHECK_CONNTRACK_FRAG_OVERLAP()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2604,9 +2620,9 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv4 fragmentation overlapping fragments by 1 octet out of order])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
CHECK_CONNTRACK_FRAG_OVERLAP()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2628,7 +2644,6 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2668,7 +2683,6 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation expiry])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2709,7 +2723,6 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation + vlan])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2752,7 +2765,6 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation + cvlan])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0])
OVS_CHECK_8021AD()
@ -2807,6 +2819,7 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation incomplete reassembled packet])
CHECK_CONNTRACK()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2827,8 +2840,8 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation with fragments specified])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2851,8 +2864,8 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation out of order])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2875,9 +2888,9 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation, multiple extension headers])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
CHECK_CONNTRACK_FRAG_IPV6_MULT_EXTEN()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2901,9 +2914,9 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation, multiple extension headers + out of order])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
CHECK_CONNTRACK_FRAG_IPV6_MULT_EXTEN()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2927,9 +2940,9 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation, multiple extension headers 2])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
CHECK_CONNTRACK_FRAG_IPV6_MULT_EXTEN()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2953,9 +2966,9 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 fragmentation, multiple extension headers 2 + out of order])
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
CHECK_CONNTRACK_FRAG_IPV6_MULT_EXTEN()
OVS_TRAFFIC_VSWITCHD_START()
DPCTL_SET_MIN_FRAG_SIZE()
ADD_NAMESPACES(at_ns0, at_ns1)
@ -2980,7 +2993,6 @@ AT_CLEANUP
AT_SETUP([conntrack - Fragmentation over vxlan])
OVS_CHECK_VXLAN()
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
CHECK_CONNTRACK_LOCAL_STACK()
OVS_TRAFFIC_VSWITCHD_START()
@ -3033,7 +3045,6 @@ AT_CLEANUP
AT_SETUP([conntrack - IPv6 Fragmentation over vxlan])
OVS_CHECK_VXLAN()
CHECK_CONNTRACK()
CHECK_CONNTRACK_FRAG()
CHECK_CONNTRACK_LOCAL_STACK()
OVS_TRAFFIC_VSWITCHD_START()

View File

@ -73,15 +73,6 @@ m4_define([CHECK_CONNTRACK],
#
m4_define([CHECK_CONNTRACK_ALG])
# CHECK_CONNTRACK_FRAG()
#
# Perform requirements checks for running conntrack fragmentations tests.
# The userspace doesn't support fragmentation yet, so skip the tests.
m4_define([CHECK_CONNTRACK_FRAG],
[
AT_SKIP_IF([:])
])
# CHECK_CONNTRACK_LOCAL_STACK()
#
# Perform requirements checks for running conntrack tests with local stack.
@ -95,19 +86,13 @@ m4_define([CHECK_CONNTRACK_LOCAL_STACK],
# CHECK_CONNTRACK_FRAG_OVERLAP()
#
# The userspace datapath does not support fragments yet.
m4_define([CHECK_CONNTRACK_FRAG_OVERLAP],
[
AT_SKIP_IF([:])
])
# The userspace datapath supports fragment overlap check.
m4_define([CHECK_CONNTRACK_FRAG_OVERLAP])
# CHECK_CONNTRACK_FRAG_IPV6_MULT_EXTEN()
# CHECK_CONNTRACK_FRAG_IPV6_MULT_EXTEN
#
# The userspace datapath does not support fragments yet.
m4_define([CHECK_CONNTRACK_FRAG_IPV6_MULT_EXTEN],
[
AT_SKIP_IF([:])
])
# The userspace datapath supports fragments with multiple extension headers.
m4_define([CHECK_CONNTRACK_FRAG_IPV6_MULT_EXTEN])
# CHECK_CONNTRACK_NAT()
#
@ -137,6 +122,167 @@ m4_define([CHECK_CT_DPIF_SET_GET_MAXCONNS])
# userspace datapath does support this feature.
m4_define([CHECK_CT_DPIF_GET_NCONNS])
# DPCTL_SET_MIN_FRAG_SIZE()
#
# The userspace datapath supports this command.
m4_define([DPCTL_SET_MIN_FRAG_SIZE],
[
AT_CHECK([ovs-appctl dpctl/ipf-set-min-frag v4 400], [], [dnl
setting minimum fragment size successful
])
AT_CHECK([ovs-appctl dpctl/ipf-set-min-frag v6 400], [], [dnl
setting minimum fragment size successful
])
])
# DPCTL_MODIFY_FRAGMENTATION()
#
# The userspace datapath supports this command.
m4_define([DPCTL_MODIFY_FRAGMENTATION],
[
AT_CHECK([ovs-appctl dpctl/ipf-set-min-frag v4 1000], [], [dnl
setting minimum fragment size successful
])
AT_CHECK([ovs-appctl dpctl/ipf-set-max-nfrags 500], [], [dnl
setting maximum fragments successful
])
AT_CHECK([ovs-appctl dpctl/ipf-get-status], [], [dnl
Fragmentation Module Status
---------------------------
v4 enabled: 1
v6 enabled: 1
max num frags (v4/v6): 500
num frag: 0
min v4 frag size: 1000
v4 frags accepted: 0
v4 frags completed: 0
v4 frags expired: 0
v4 frags too small: 0
v4 frags overlapped: 0
v4 frags purged: 0
min v6 frag size: 1280
v6 frags accepted: 0
v6 frags completed: 0
v6 frags expired: 0
v6 frags too small: 0
v6 frags overlapped: 0
v6 frags purged: 0
])
])
# DPCTL_CHECK_FRAGMENTATION_PASS()
#
# Used to check fragmentation counters for some fragmentation tests using
# the userspace datapath.
m4_define([DPCTL_CHECK_FRAGMENTATION_PASS],
[
AT_CHECK([ovs-appctl dpctl/ipf-get-status --more], [], [dnl
Fragmentation Module Status
---------------------------
v4 enabled: 1
v6 enabled: 1
max num frags (v4/v6): 500
num frag: 0
min v4 frag size: 1000
v4 frags accepted: 30
v4 frags completed: 30
v4 frags expired: 0
v4 frags too small: 0
v4 frags overlapped: 0
v4 frags purged: 0
min v6 frag size: 1280
v6 frags accepted: 0
v6 frags completed: 0
v6 frags expired: 0
v6 frags too small: 0
v6 frags overlapped: 0
v6 frags purged: 0
Fragment Lists:
])
])
# DPCTL_CHECK_V6_FRAGMENTATION_PASS()
#
# Used to check fragmentation counters for some fragmentation tests using
# the userspace datapath.
m4_define([DPCTL_CHECK_V6_FRAGMENTATION_PASS],
[
AT_CHECK([ovs-appctl dpctl/ipf-get-status --more], [], [dnl
Fragmentation Module Status
---------------------------
v4 enabled: 1
v6 enabled: 1
max num frags (v4/v6): 1000
num frag: 0
min v4 frag size: 1200
v4 frags accepted: 0
v4 frags completed: 0
v4 frags expired: 0
v4 frags too small: 0
v4 frags overlapped: 0
v4 frags purged: 0
min v6 frag size: 1280
v6 frags accepted: 30
v6 frags completed: 30
v6 frags expired: 0
v6 frags too small: 0
v6 frags overlapped: 0
v6 frags purged: 0
Fragment Lists:
])
])
# FORMAT_FRAG_LIST([])
#
# Strip content from the piped input which can differ from test to test; recirc_id
# and ip_id fields in an ipf_list vary from test to test and hence are cleared.
m4_define([FORMAT_FRAG_LIST],
[[sed -e 's/ip_id=[0-9]*/ip_id=<cleared>/g' -e 's/recirc_id=[0-9]*/recirc_id=<cleared>/g']])
# DPCTL_CHECK_FRAGMENTATION_FAIL()
#
# Used to check fragmentation counters for some fragmentation tests using
# the userspace datapath, when failure to transmit fragments is expected.
m4_define([DPCTL_CHECK_FRAGMENTATION_FAIL],
[
AT_CHECK([ovs-appctl dpctl/ipf-get-status -m | FORMAT_FRAG_LIST()], [], [dnl
Fragmentation Module Status
---------------------------
v4 enabled: 1
v6 enabled: 1
max num frags (v4/v6): 500
num frag: 7
min v4 frag size: 1000
v4 frags accepted: 7
v4 frags completed: 0
v4 frags expired: 0
v4 frags too small: 0
v4 frags overlapped: 0
v4 frags purged: 0
min v6 frag size: 1280
v6 frags accepted: 0
v6 frags completed: 0
v6 frags expired: 0
v6 frags too small: 0
v6 frags overlapped: 0
v6 frags purged: 0
Fragment Lists:
(src=10.1.1.1,dst=10.1.1.2,recirc_id=<cleared>,ip_id=<cleared>,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag)
(src=10.1.1.1,dst=10.1.1.2,recirc_id=<cleared>,ip_id=<cleared>,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag)
(src=10.1.1.1,dst=10.1.1.2,recirc_id=<cleared>,ip_id=<cleared>,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag)
(src=10.1.1.1,dst=10.1.1.2,recirc_id=<cleared>,ip_id=<cleared>,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag)
(src=10.1.1.1,dst=10.1.1.2,recirc_id=<cleared>,ip_id=<cleared>,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag)
(src=10.1.1.1,dst=10.1.1.2,recirc_id=<cleared>,ip_id=<cleared>,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag)
(src=10.1.1.1,dst=10.1.1.2,recirc_id=<cleared>,ip_id=<cleared>,dl_type=0x800,zone=9,nw_proto=1,num_fragments=1,state=first frag)
])
])
# OVS_CHECK_KERNEL([minversion], [maxversion], [minsublevel], [maxsublevel])
#
# The userspace skips all tests that check kernel version.