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:
parent
9f17f104fe
commit
4ea96698f6
@ -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
10
NEWS
@ -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
|
||||
---------------------
|
||||
|
@ -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 */
|
||||
|
@ -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 \
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
215
lib/dpctl.c
215
lib/dpctl.c
@ -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 },
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
63
lib/ipf.h
Normal file
63
lib/ipf.h
Normal 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 */
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user