mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 22:05:19 +00:00
conntrack: Allow to dump userspace conntrack expectations.
The patch introduces a new commands ovs-appctl dpctl/dump-conntrack-exp that allows to dump the existing expectations for the userspace ct. Signed-off-by: Paolo Valerio <pvalerio@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
committed by
Ilya Maximets
parent
34ace16cb8
commit
9b4d2ad8e8
2
NEWS
2
NEWS
@@ -24,6 +24,8 @@ Post-v3.1.0
|
|||||||
* New commands "dpctl/{ct-get-sweep-interval,ct-set-sweep-interval}" that
|
* New commands "dpctl/{ct-get-sweep-interval,ct-set-sweep-interval}" that
|
||||||
allow to get and set, for the userspace datapath, the sweep interval
|
allow to get and set, for the userspace datapath, the sweep interval
|
||||||
for the conntrack garbage collector.
|
for the conntrack garbage collector.
|
||||||
|
* New commands "dpctl/dump-conntrack-exp" that allows to dump
|
||||||
|
conntrack's expectations for the userspace datapath.
|
||||||
- ovs-ctl:
|
- ovs-ctl:
|
||||||
* Added new options --[ovsdb-server|ovs-vswitchd]-umask=MODE to set umask
|
* Added new options --[ovsdb-server|ovs-vswitchd]-umask=MODE to set umask
|
||||||
value when starting OVS daemons. E.g., use --ovsdb-server-umask=0002
|
value when starting OVS daemons. E.g., use --ovsdb-server-umask=0002
|
||||||
|
@@ -2670,6 +2670,72 @@ conntrack_dump_done(struct conntrack_dump *dump OVS_UNUSED)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
exp_node_to_ct_dpif_exp(const struct alg_exp_node *exp,
|
||||||
|
struct ct_dpif_exp *entry)
|
||||||
|
{
|
||||||
|
memset(entry, 0, sizeof *entry);
|
||||||
|
|
||||||
|
conn_key_to_tuple(&exp->key, &entry->tuple_orig);
|
||||||
|
conn_key_to_tuple(&exp->parent_key, &entry->tuple_parent);
|
||||||
|
entry->zone = exp->key.zone;
|
||||||
|
entry->mark = exp->parent_mark;
|
||||||
|
memcpy(&entry->labels, &exp->parent_label, sizeof entry->labels);
|
||||||
|
entry->protoinfo.proto = exp->key.nw_proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
conntrack_exp_dump_start(struct conntrack *ct, struct conntrack_dump *dump,
|
||||||
|
const uint16_t *pzone)
|
||||||
|
{
|
||||||
|
memset(dump, 0, sizeof(*dump));
|
||||||
|
|
||||||
|
if (pzone) {
|
||||||
|
dump->zone = *pzone;
|
||||||
|
dump->filter_zone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dump->ct = ct;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
conntrack_exp_dump_next(struct conntrack_dump *dump, struct ct_dpif_exp *entry)
|
||||||
|
{
|
||||||
|
struct conntrack *ct = dump->ct;
|
||||||
|
struct alg_exp_node *enode;
|
||||||
|
int ret = EOF;
|
||||||
|
|
||||||
|
ovs_rwlock_rdlock(&ct->resources_lock);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
struct hmap_node *node = hmap_at_position(&ct->alg_expectations,
|
||||||
|
&dump->hmap_pos);
|
||||||
|
if (!node) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
enode = CONTAINER_OF(node, struct alg_exp_node, node);
|
||||||
|
|
||||||
|
if (!dump->filter_zone || enode->key.zone == dump->zone) {
|
||||||
|
ret = 0;
|
||||||
|
exp_node_to_ct_dpif_exp(enode, entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ovs_rwlock_unlock(&ct->resources_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
conntrack_exp_dump_done(struct conntrack_dump *dump OVS_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
conntrack_flush(struct conntrack *ct, const uint16_t *zone)
|
conntrack_flush(struct conntrack *ct, const uint16_t *zone)
|
||||||
{
|
{
|
||||||
|
@@ -100,7 +100,10 @@ void conntrack_clear(struct dp_packet *packet);
|
|||||||
struct conntrack_dump {
|
struct conntrack_dump {
|
||||||
struct conntrack *ct;
|
struct conntrack *ct;
|
||||||
unsigned bucket;
|
unsigned bucket;
|
||||||
|
union {
|
||||||
struct cmap_position cm_pos;
|
struct cmap_position cm_pos;
|
||||||
|
struct hmap_position hmap_pos;
|
||||||
|
};
|
||||||
bool filter_zone;
|
bool filter_zone;
|
||||||
uint16_t zone;
|
uint16_t zone;
|
||||||
};
|
};
|
||||||
@@ -132,6 +135,11 @@ int conntrack_dump_start(struct conntrack *, struct conntrack_dump *,
|
|||||||
int conntrack_dump_next(struct conntrack_dump *, struct ct_dpif_entry *);
|
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_exp_dump_start(struct conntrack *, struct conntrack_dump *,
|
||||||
|
const uint16_t *);
|
||||||
|
int conntrack_exp_dump_next(struct conntrack_dump *, struct ct_dpif_exp *);
|
||||||
|
int conntrack_exp_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 *,
|
int conntrack_flush_tuple(struct conntrack *, const struct ct_dpif_tuple *,
|
||||||
uint16_t zone);
|
uint16_t zone);
|
||||||
|
@@ -101,6 +101,65 @@ ct_dpif_dump_done(struct ct_dpif_dump_state *dump)
|
|||||||
? dpif->dpif_class->ct_dump_done(dpif, dump)
|
? dpif->dpif_class->ct_dump_done(dpif, dump)
|
||||||
: EOPNOTSUPP);
|
: EOPNOTSUPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Start dumping the expectations from the connection tracker.
|
||||||
|
*
|
||||||
|
* 'dump' must be the address of a pointer to a struct ct_dpif_dump_state,
|
||||||
|
* which should be passed (unaltered) to ct_exp_dpif_dump_{next,done}().
|
||||||
|
*
|
||||||
|
* If 'zone' is not NULL, it should point to an integer identifing a
|
||||||
|
* conntrack zone to which the dump will be limited. If it is NULL,
|
||||||
|
* conntrack entries from all zones will be dumped.
|
||||||
|
*
|
||||||
|
* If there has been a problem the function returns a non-zero value
|
||||||
|
* that represents the error. Otherwise it returns zero. */
|
||||||
|
int
|
||||||
|
ct_exp_dpif_dump_start(struct dpif *dpif, struct ct_dpif_dump_state **dump,
|
||||||
|
const uint16_t *zone)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = (dpif->dpif_class->ct_exp_dump_start
|
||||||
|
? dpif->dpif_class->ct_exp_dump_start(dpif, dump, zone)
|
||||||
|
: EOPNOTSUPP);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
(*dump)->dpif = dpif;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dump one expectation and put it in 'entry'.
|
||||||
|
*
|
||||||
|
* 'dump' should have been initialized by ct_exp_dpif_dump_start().
|
||||||
|
*
|
||||||
|
* The function returns 0, if an entry has been dumped succesfully.
|
||||||
|
* Otherwise it returns a non-zero value which can be:
|
||||||
|
* - EOF: meaning that there are no more entries to dump.
|
||||||
|
* - an error value.
|
||||||
|
* In both cases, the user should call ct_exp_dpif_dump_done(). */
|
||||||
|
int
|
||||||
|
ct_exp_dpif_dump_next(struct ct_dpif_dump_state *dump,
|
||||||
|
struct ct_dpif_exp *entry)
|
||||||
|
{
|
||||||
|
struct dpif *dpif = dump->dpif;
|
||||||
|
|
||||||
|
return (dpif->dpif_class->ct_exp_dump_next
|
||||||
|
? dpif->dpif_class->ct_exp_dump_next(dpif, dump, entry)
|
||||||
|
: EOPNOTSUPP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free resources used by 'dump', if any. */
|
||||||
|
int
|
||||||
|
ct_exp_dpif_dump_done(struct ct_dpif_dump_state *dump)
|
||||||
|
{
|
||||||
|
struct dpif *dpif = dump->dpif;
|
||||||
|
|
||||||
|
return (dpif->dpif_class->ct_exp_dump_done
|
||||||
|
? dpif->dpif_class->ct_exp_dump_done(dpif, dump)
|
||||||
|
: EOPNOTSUPP);
|
||||||
|
}
|
||||||
|
|
||||||
/* Flushing. */
|
/* Flushing. */
|
||||||
|
|
||||||
@@ -462,6 +521,34 @@ ct_dpif_status_flags(uint32_t flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ct_dpif_format_exp_entry(const struct ct_dpif_exp *entry, struct ds *ds)
|
||||||
|
{
|
||||||
|
ct_dpif_format_ipproto(ds, entry->tuple_orig.ip_proto);
|
||||||
|
|
||||||
|
ds_put_cstr(ds, ",orig=(");
|
||||||
|
ct_dpif_format_tuple(ds, &entry->tuple_orig);
|
||||||
|
ds_put_cstr(ds, ")");
|
||||||
|
|
||||||
|
if (entry->zone) {
|
||||||
|
ds_put_format(ds, ",zone=%"PRIu16, entry->zone);
|
||||||
|
}
|
||||||
|
if (entry->mark) {
|
||||||
|
ds_put_format(ds, ",mark=%"PRIu32, entry->mark);
|
||||||
|
}
|
||||||
|
if (!ovs_u128_is_zero(entry->labels)) {
|
||||||
|
ovs_be128 value;
|
||||||
|
|
||||||
|
ds_put_cstr(ds, ",labels=");
|
||||||
|
value = hton128(entry->labels);
|
||||||
|
ds_put_hex(ds, &value, sizeof value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ds_put_cstr(ds, ",parent=(");
|
||||||
|
ct_dpif_format_tuple(ds, &entry->tuple_parent);
|
||||||
|
ds_put_cstr(ds, ")");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ct_dpif_format_entry(const struct ct_dpif_entry *entry, struct ds *ds,
|
ct_dpif_format_entry(const struct ct_dpif_entry *entry, struct ds *ds,
|
||||||
bool verbose, bool print_stats)
|
bool verbose, bool print_stats)
|
||||||
|
@@ -179,6 +179,16 @@ enum ct_dpif_status_flags {
|
|||||||
|
|
||||||
#define CT_DPIF_STATUS_MASK ((CT_DPIF_STATUS_UNTRACKED << 1) - 1)
|
#define CT_DPIF_STATUS_MASK ((CT_DPIF_STATUS_UNTRACKED << 1) - 1)
|
||||||
|
|
||||||
|
struct ct_dpif_exp {
|
||||||
|
struct ct_dpif_tuple tuple_orig;
|
||||||
|
struct ct_dpif_tuple tuple_parent;
|
||||||
|
uint16_t zone;
|
||||||
|
struct ct_dpif_protoinfo protoinfo;
|
||||||
|
ovs_u128 labels;
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t mark;
|
||||||
|
};
|
||||||
|
|
||||||
struct ct_dpif_entry {
|
struct ct_dpif_entry {
|
||||||
/* Const members. */
|
/* Const members. */
|
||||||
struct ct_dpif_tuple tuple_orig;
|
struct ct_dpif_tuple tuple_orig;
|
||||||
@@ -286,6 +296,10 @@ int ct_dpif_dump_start(struct dpif *, struct ct_dpif_dump_state **,
|
|||||||
const uint16_t *zone, int *);
|
const uint16_t *zone, int *);
|
||||||
int ct_dpif_dump_next(struct ct_dpif_dump_state *, struct ct_dpif_entry *);
|
int ct_dpif_dump_next(struct ct_dpif_dump_state *, struct ct_dpif_entry *);
|
||||||
int ct_dpif_dump_done(struct ct_dpif_dump_state *);
|
int ct_dpif_dump_done(struct ct_dpif_dump_state *);
|
||||||
|
int ct_exp_dpif_dump_start(struct dpif *, struct ct_dpif_dump_state **,
|
||||||
|
const uint16_t *zone);
|
||||||
|
int ct_exp_dpif_dump_next(struct ct_dpif_dump_state *, struct ct_dpif_exp *);
|
||||||
|
int ct_exp_dpif_dump_done(struct ct_dpif_dump_state *);
|
||||||
int ct_dpif_flush(struct dpif *, const uint16_t *zone,
|
int ct_dpif_flush(struct dpif *, const uint16_t *zone,
|
||||||
const struct ofp_ct_match *);
|
const struct ofp_ct_match *);
|
||||||
int ct_dpif_set_maxconns(struct dpif *dpif, uint32_t maxconns);
|
int ct_dpif_set_maxconns(struct dpif *dpif, uint32_t maxconns);
|
||||||
@@ -310,6 +324,7 @@ int ct_dpif_ipf_dump_done(struct dpif *dpif, void *);
|
|||||||
void ct_dpif_entry_uninit(struct ct_dpif_entry *);
|
void ct_dpif_entry_uninit(struct ct_dpif_entry *);
|
||||||
void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *,
|
void ct_dpif_format_entry(const struct ct_dpif_entry *, struct ds *,
|
||||||
bool verbose, bool print_stats);
|
bool verbose, bool print_stats);
|
||||||
|
void ct_dpif_format_exp_entry(const struct ct_dpif_exp *, struct ds *);
|
||||||
void ct_dpif_format_ipproto(struct ds *ds, uint16_t ipproto);
|
void ct_dpif_format_ipproto(struct ds *ds, uint16_t ipproto);
|
||||||
void ct_dpif_format_tuple(struct ds *, const struct ct_dpif_tuple *);
|
void ct_dpif_format_tuple(struct ds *, const struct ct_dpif_tuple *);
|
||||||
uint8_t ct_dpif_coalesce_tcp_state(uint8_t state);
|
uint8_t ct_dpif_coalesce_tcp_state(uint8_t state);
|
||||||
|
49
lib/dpctl.c
49
lib/dpctl.c
@@ -1707,6 +1707,53 @@ dpctl_dump_conntrack(int argc, const char *argv[],
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dpctl_dump_conntrack_exp(int argc, const char *argv[],
|
||||||
|
struct dpctl_params *dpctl_p)
|
||||||
|
{
|
||||||
|
struct ct_dpif_dump_state *dump;
|
||||||
|
uint16_t zone, *pzone = NULL;
|
||||||
|
struct ct_dpif_exp cte;
|
||||||
|
struct dpif *dpif;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (argc > 1 && ovs_scan(argv[argc - 1], "zone=%"SCNu16, &zone)) {
|
||||||
|
pzone = &zone;
|
||||||
|
argc--;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = opt_dpif_open(argc, argv, dpctl_p, 2, &dpif);
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = ct_exp_dpif_dump_start(dpif, &dump, pzone);
|
||||||
|
if (error) {
|
||||||
|
dpctl_error(dpctl_p, error, "starting conntrack expectations dump");
|
||||||
|
dpif_close(dpif);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!(error = ct_exp_dpif_dump_next(dump, &cte))) {
|
||||||
|
struct ds s = DS_EMPTY_INITIALIZER;
|
||||||
|
|
||||||
|
ct_dpif_format_exp_entry(&cte, &s);
|
||||||
|
|
||||||
|
dpctl_print(dpctl_p, "%s\n", ds_cstr(&s));
|
||||||
|
ds_destroy(&s);
|
||||||
|
}
|
||||||
|
if (error == EOF) {
|
||||||
|
error = 0;
|
||||||
|
} else if (error) {
|
||||||
|
dpctl_error(dpctl_p, error, "dumping conntrack expectation");
|
||||||
|
}
|
||||||
|
|
||||||
|
ct_exp_dpif_dump_done(dump);
|
||||||
|
dpif_close(dpif);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dpctl_flush_conntrack(int argc, const char *argv[],
|
dpctl_flush_conntrack(int argc, const char *argv[],
|
||||||
struct dpctl_params *dpctl_p)
|
struct dpctl_params *dpctl_p)
|
||||||
@@ -2951,6 +2998,8 @@ static const struct dpctl_command all_commands[] = {
|
|||||||
0, 1, dpctl_offload_stats_show, DP_RO },
|
0, 1, dpctl_offload_stats_show, DP_RO },
|
||||||
{ "dump-conntrack", "[-m] [-s] [dp] [zone=N]",
|
{ "dump-conntrack", "[-m] [-s] [dp] [zone=N]",
|
||||||
0, 4, dpctl_dump_conntrack, DP_RO },
|
0, 4, dpctl_dump_conntrack, DP_RO },
|
||||||
|
{ "dump-conntrack-exp", "[dp] [zone=N]",
|
||||||
|
0, 2, dpctl_dump_conntrack_exp, DP_RO },
|
||||||
{ "flush-conntrack", "[dp] [zone=N] [ct-orig-tuple] [ct-reply-tuple]",
|
{ "flush-conntrack", "[dp] [zone=N] [ct-orig-tuple] [ct-reply-tuple]",
|
||||||
0, 4, dpctl_flush_conntrack, DP_RW },
|
0, 4, dpctl_flush_conntrack, DP_RW },
|
||||||
{ "cache-get-size", "[dp]", 0, 1, dpctl_cache_get_size, DP_RO },
|
{ "cache-get-size", "[dp]", 0, 1, dpctl_cache_get_size, DP_RO },
|
||||||
|
@@ -302,6 +302,12 @@ are included. With \fB\-\-statistics\fR timeouts and timestamps are
|
|||||||
added to the output.
|
added to the output.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
|
\*(DX\fBdump\-conntrack\-exp\fR [\fIdp\fR] [\fBzone=\fIzone\fR]
|
||||||
|
Prints to the console all the expectation entries in the tracker used by
|
||||||
|
\fIdp\fR. If \fBzone=\fIzone\fR is specified, only shows the expectations
|
||||||
|
in \fIzone\fR. Only supported for userspace datapath.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
\*(DX\fBflush\-conntrack\fR [\fIdp\fR] [\fBzone=\fIzone\fR] [\fIct-origin-tuple\fR [\fIct-reply-tuple\fR]]
|
\*(DX\fBflush\-conntrack\fR [\fIdp\fR] [\fBzone=\fIzone\fR] [\fIct-origin-tuple\fR [\fIct-reply-tuple\fR]]
|
||||||
Flushes the connection entries in the tracker used by \fIdp\fR based on
|
Flushes the connection entries in the tracker used by \fIdp\fR based on
|
||||||
\fIzone\fR and connection tracking tuple \fIct-origin-tuple\fR.
|
\fIzone\fR and connection tracking tuple \fIct-origin-tuple\fR.
|
||||||
|
@@ -9267,6 +9267,53 @@ dpif_netdev_ct_dump_done(struct dpif *dpif OVS_UNUSED,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dpif_netdev_ct_exp_dump_start(struct dpif *dpif,
|
||||||
|
struct ct_dpif_dump_state **dump_,
|
||||||
|
const uint16_t *pzone)
|
||||||
|
{
|
||||||
|
struct dp_netdev *dp = get_dp_netdev(dpif);
|
||||||
|
struct dp_netdev_ct_dump *dump;
|
||||||
|
|
||||||
|
dump = xzalloc(sizeof *dump);
|
||||||
|
dump->dp = dp;
|
||||||
|
dump->ct = dp->conntrack;
|
||||||
|
|
||||||
|
conntrack_exp_dump_start(dp->conntrack, &dump->dump, pzone);
|
||||||
|
|
||||||
|
*dump_ = &dump->up;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dpif_netdev_ct_exp_dump_next(struct dpif *dpif OVS_UNUSED,
|
||||||
|
struct ct_dpif_dump_state *dump_,
|
||||||
|
struct ct_dpif_exp *entry)
|
||||||
|
{
|
||||||
|
struct dp_netdev_ct_dump *dump;
|
||||||
|
|
||||||
|
INIT_CONTAINER(dump, dump_, up);
|
||||||
|
|
||||||
|
return conntrack_exp_dump_next(&dump->dump, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dpif_netdev_ct_exp_dump_done(struct dpif *dpif OVS_UNUSED,
|
||||||
|
struct ct_dpif_dump_state *dump_)
|
||||||
|
{
|
||||||
|
struct dp_netdev_ct_dump *dump;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
INIT_CONTAINER(dump, dump_, up);
|
||||||
|
|
||||||
|
err = conntrack_exp_dump_done(&dump->dump);
|
||||||
|
|
||||||
|
free(dump);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dpif_netdev_ct_flush(struct dpif *dpif, const uint16_t *zone,
|
dpif_netdev_ct_flush(struct dpif *dpif, const uint16_t *zone,
|
||||||
const struct ct_dpif_tuple *tuple)
|
const struct ct_dpif_tuple *tuple)
|
||||||
@@ -9679,6 +9726,9 @@ const struct dpif_class dpif_netdev_class = {
|
|||||||
dpif_netdev_ct_dump_start,
|
dpif_netdev_ct_dump_start,
|
||||||
dpif_netdev_ct_dump_next,
|
dpif_netdev_ct_dump_next,
|
||||||
dpif_netdev_ct_dump_done,
|
dpif_netdev_ct_dump_done,
|
||||||
|
dpif_netdev_ct_exp_dump_start,
|
||||||
|
dpif_netdev_ct_exp_dump_next,
|
||||||
|
dpif_netdev_ct_exp_dump_done,
|
||||||
dpif_netdev_ct_flush,
|
dpif_netdev_ct_flush,
|
||||||
dpif_netdev_ct_set_maxconns,
|
dpif_netdev_ct_set_maxconns,
|
||||||
dpif_netdev_ct_get_maxconns,
|
dpif_netdev_ct_get_maxconns,
|
||||||
|
@@ -4566,6 +4566,9 @@ const struct dpif_class dpif_netlink_class = {
|
|||||||
dpif_netlink_ct_dump_start,
|
dpif_netlink_ct_dump_start,
|
||||||
dpif_netlink_ct_dump_next,
|
dpif_netlink_ct_dump_next,
|
||||||
dpif_netlink_ct_dump_done,
|
dpif_netlink_ct_dump_done,
|
||||||
|
NULL, /* ct_exp_dump_start */
|
||||||
|
NULL, /* ct_exp_dump_next */
|
||||||
|
NULL, /* ct_exp_dump_done */
|
||||||
dpif_netlink_ct_flush,
|
dpif_netlink_ct_flush,
|
||||||
NULL, /* ct_set_maxconns */
|
NULL, /* ct_set_maxconns */
|
||||||
NULL, /* ct_get_maxconns */
|
NULL, /* ct_get_maxconns */
|
||||||
|
@@ -79,6 +79,7 @@ dpif_flow_dump_thread_init(struct dpif_flow_dump_thread *thread,
|
|||||||
|
|
||||||
struct ct_dpif_dump_state;
|
struct ct_dpif_dump_state;
|
||||||
struct ct_dpif_entry;
|
struct ct_dpif_entry;
|
||||||
|
struct ct_dpif_exp;
|
||||||
struct ct_dpif_tuple;
|
struct ct_dpif_tuple;
|
||||||
struct ct_dpif_timeout_policy;
|
struct ct_dpif_timeout_policy;
|
||||||
enum ct_features;
|
enum ct_features;
|
||||||
@@ -471,6 +472,16 @@ struct dpif_class {
|
|||||||
struct ct_dpif_entry *entry);
|
struct ct_dpif_entry *entry);
|
||||||
int (*ct_dump_done)(struct dpif *, struct ct_dpif_dump_state *state);
|
int (*ct_dump_done)(struct dpif *, struct ct_dpif_dump_state *state);
|
||||||
|
|
||||||
|
/* Starts the dump initializing the structures involved and the zone
|
||||||
|
* filter. */
|
||||||
|
int (*ct_exp_dump_start)(struct dpif *, struct ct_dpif_dump_state **state,
|
||||||
|
const uint16_t *zone);
|
||||||
|
/* Fill the expectation 'entry' with the related information. */
|
||||||
|
int (*ct_exp_dump_next)(struct dpif *, struct ct_dpif_dump_state *state,
|
||||||
|
struct ct_dpif_exp *entry);
|
||||||
|
/* Ends the dump cleaning up any potential pending state, if any. */
|
||||||
|
int (*ct_exp_dump_done)(struct dpif *, struct ct_dpif_dump_state *state);
|
||||||
|
|
||||||
/* Flushes the connection tracking tables. The arguments have the
|
/* Flushes the connection tracking tables. The arguments have the
|
||||||
* following behavior:
|
* following behavior:
|
||||||
*
|
*
|
||||||
|
@@ -123,6 +123,15 @@ m4_define([CHECK_CONNTRACK_TIMEOUT],
|
|||||||
on_exit 'modprobe -r nfnetlink_cttimeout'
|
on_exit 'modprobe -r nfnetlink_cttimeout'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# CHECK_CONNTRACK_DUMP_EXPECTATIONS()
|
||||||
|
#
|
||||||
|
# Perform requirements checks for dumping conntrack expectations.
|
||||||
|
#
|
||||||
|
m4_define([CHECK_CONNTRACK_DUMP_EXPECTATIONS],
|
||||||
|
[
|
||||||
|
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
|
||||||
|
@@ -5195,6 +5195,50 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=
|
|||||||
OVS_TRAFFIC_VSWITCHD_STOP
|
OVS_TRAFFIC_VSWITCHD_STOP
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
AT_SETUP([conntrack - FTP with expectation dump])
|
||||||
|
AT_SKIP_IF([test $HAVE_FTP = no])
|
||||||
|
CHECK_CONNTRACK()
|
||||||
|
CHECK_CONNTRACK_ALG()
|
||||||
|
CHECK_CONNTRACK_DUMP_EXPECTATIONS()
|
||||||
|
OVS_TRAFFIC_VSWITCHD_START()
|
||||||
|
|
||||||
|
ADD_NAMESPACES(at_ns0, at_ns1)
|
||||||
|
|
||||||
|
ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
|
||||||
|
ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
|
||||||
|
|
||||||
|
AT_DATA([flows.txt], [dnl
|
||||||
|
table=0,priority=1,action=drop
|
||||||
|
table=0,priority=10,arp,action=normal
|
||||||
|
table=0,priority=10,icmp,action=normal
|
||||||
|
table=0,priority=100,in_port=1,tcp,action=ct(alg=ftp,commit),2
|
||||||
|
table=0,priority=100,in_port=2,tcp,action=ct(table=1)
|
||||||
|
table=1,in_port=2,tcp,ct_state=+trk+est,action=1
|
||||||
|
table=1,in_port=2,tcp,ct_state=+trk+rel,action=1
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows.txt])
|
||||||
|
|
||||||
|
OVS_START_L7([at_ns1], [ftp])
|
||||||
|
|
||||||
|
dnl FTP requests from p0->p1 should work fine.
|
||||||
|
NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v -o wget0.log])
|
||||||
|
|
||||||
|
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
|
||||||
|
tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>),helper=ftp
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Verify that a dump with zero entries in a zone doesn't return any entry.
|
||||||
|
AT_CHECK([ovs-appctl dpctl/dump-conntrack-exp zone=42], [0], [dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_CHECK([ovs-appctl dpctl/dump-conntrack-exp | FORMAT_CT(10.1.1.2)], [0], [dnl
|
||||||
|
tcp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),parent=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>)
|
||||||
|
])
|
||||||
|
|
||||||
|
OVS_TRAFFIC_VSWITCHD_STOP
|
||||||
|
AT_CLEANUP
|
||||||
|
|
||||||
AT_SETUP([conntrack - FTP over IPv6])
|
AT_SETUP([conntrack - FTP over IPv6])
|
||||||
AT_SKIP_IF([test $HAVE_FTP = no])
|
AT_SKIP_IF([test $HAVE_FTP = no])
|
||||||
CHECK_CONNTRACK()
|
CHECK_CONNTRACK()
|
||||||
|
@@ -112,6 +112,12 @@ m4_define([CHECK_CONNTRACK_ZEROIP_SNAT])
|
|||||||
#
|
#
|
||||||
m4_define([CHECK_CONNTRACK_TIMEOUT])
|
m4_define([CHECK_CONNTRACK_TIMEOUT])
|
||||||
|
|
||||||
|
# CHECK_CONNTRACK_DUMP_EXPECTATIONS()
|
||||||
|
#
|
||||||
|
# Perform requirements checks for dumping conntrack expectations.
|
||||||
|
#
|
||||||
|
m4_define([CHECK_CONNTRACK_DUMP_EXPECTATIONS])
|
||||||
|
|
||||||
# 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