summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Pettit <jpettit@ovn.org>2016-08-18 14:09:41 -0700
committerJustin Pettit <jpettit@ovn.org>2016-09-23 12:06:59 -0700
commit2a7c4805a76d5a06f28346e1cf992c57b1c8871d (patch)
tree45a8d647675d6ddf8d19a352af26f18823a0040b
parent14338f2263f5242f5caa3f97831961836e8891b8 (diff)
downloadopenvswitch-2a7c4805a76d5a06f28346e1cf992c57b1c8871d.tar.gz
Add OpenFlow command to flush conntrack table entries.
Signed-off-by: Justin Pettit <jpettit@ovn.org> Acked-by: Ben Pfaff <blp@ovn.org>
-rw-r--r--NEWS1
-rw-r--r--debian/changelog10
-rw-r--r--include/openflow/nicira-ext.h9
-rw-r--r--include/openvswitch/ofp-msgs.h4
-rw-r--r--lib/ct-dpif.c10
-rw-r--r--lib/ofp-print.c10
-rw-r--r--lib/ofp-util.c1
-rw-r--r--lib/rconn.c1
-rw-r--r--ofproto/ofproto-dpif.c10
-rw-r--r--ofproto/ofproto-provider.h7
-rw-r--r--ofproto/ofproto.c23
-rw-r--r--tests/ofp-print.at10
-rw-r--r--tests/ovs-ofctl.at13
-rw-r--r--utilities/ovs-ofctl.8.in6
-rw-r--r--utilities/ovs-ofctl.c25
15 files changed, 139 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index bb32c475a..dba1950e5 100644
--- a/NEWS
+++ b/NEWS
@@ -71,6 +71,7 @@ v2.6.0 - xx xxx xxxx
already expected to work properly in cases where the switch can
not buffer packets, so this change should not affect existing
users.
+ * New OpenFlow extension NXT_CT_FLUSH_ZONE to flush conntrack zones.
- Improved OpenFlow version compatibility for actions:
* New OpenFlow extension to support the "group" action in OpenFlow 1.0.
* OpenFlow 1.0 "enqueue" action now properly translated to OpenFlow 1.1+.
diff --git a/debian/changelog b/debian/changelog
index d73e63645..7f38d53e2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -33,6 +33,16 @@ openvswitch (2.6.0-1) unstable; urgency=low
packet to size M bytes when outputting to port N.
* New command OFPGC_ADD_OR_MOD for OFPT_GROUP_MOD message that adds a
new group or modifies an existing groups
+ * The optional OpenFlow packet buffering feature is deprecated in
+ this release, and will be removed in the next OVS release
+ (2.7). After the change OVS always sends the 'buffer_id' as
+ 0xffffffff in packet-in messages and will send an error
+ response if any other value of this field is included in
+ packet-out and flow mod sent by a controller. Controllers are
+ already expected to work properly in cases where the switch can
+ not buffer packets, so this change should not affect existing
+ users.
+ * New OpenFlow extension NXT_CT_FLUSH_ZONE to flush conntrack zones.
- Improved OpenFlow version compatibility for actions:
* New OpenFlow extension to support the "group" action in OpenFlow 1.0.
* OpenFlow 1.0 "enqueue" action now properly translated to OpenFlow 1.1+.
diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index 5ab026c46..9d53623e5 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -1128,5 +1128,14 @@ struct nx_tlv_table_reply {
from the length field in the header. */
};
OFP_ASSERT(sizeof(struct nx_tlv_table_reply) == 16);
+
+/* NXT_CT_FLUSH_ZONE.
+ *
+ * Flushes the connection tracking table. */
+struct nx_zone_id {
+ uint8_t zero[6]; /* Must be zero. */
+ ovs_be16 zone_id; /* Connection tracking zone. */
+};
+OFP_ASSERT(sizeof(struct nx_zone_id) == 8);
#endif /* openflow/nicira-ext.h */
diff --git a/include/openvswitch/ofp-msgs.h b/include/openvswitch/ofp-msgs.h
index 8dab85894..ffb88b332 100644
--- a/include/openvswitch/ofp-msgs.h
+++ b/include/openvswitch/ofp-msgs.h
@@ -468,6 +468,9 @@ enum ofpraw {
/* NXT 1.0+ (28): uint8_t[8][]. */
OFPRAW_NXT_RESUME,
+ /* NXT 1.0+ (29): struct nx_zone_id. */
+ OFPRAW_NXT_CT_FLUSH_ZONE,
+
/* NXST 1.0+ (3): void. */
OFPRAW_NXST_IPFIX_BRIDGE_REQUEST,
@@ -707,6 +710,7 @@ enum ofptype {
OFPTYPE_IPFIX_BRIDGE_STATS_REPLY, /* OFPRAW_NXST_IPFIX_BRIDGE_REPLY */
OFPTYPE_IPFIX_FLOW_STATS_REQUEST, /* OFPRAW_NXST_IPFIX_FLOW_REQUEST */
OFPTYPE_IPFIX_FLOW_STATS_REPLY, /* OFPRAW_NXST_IPFIX_FLOW_REPLY */
+ OFPTYPE_CT_FLUSH_ZONE, /* OFPRAW_NXT_CT_FLUSH_ZONE. */
/* Flow monitor extension. */
OFPTYPE_FLOW_MONITOR_CANCEL, /* OFPRAW_NXT_FLOW_MONITOR_CANCEL. */
diff --git a/lib/ct-dpif.c b/lib/ct-dpif.c
index 6c6a07be9..2cdecf668 100644
--- a/lib/ct-dpif.c
+++ b/lib/ct-dpif.c
@@ -15,12 +15,14 @@
*/
#include <config.h>
+#include "dpif-provider.h"
#include <errno.h>
#include "ct-dpif.h"
+#include "openvswitch/vlog.h"
-#include "dpif-provider.h"
+VLOG_DEFINE_THIS_MODULE(ct_dpif);
/* Declarations for conntrack entry formatting. */
struct flags {
@@ -114,6 +116,12 @@ ct_dpif_dump_done(struct ct_dpif_dump_state *dump)
int
ct_dpif_flush(struct dpif *dpif, const uint16_t *zone)
{
+ if (zone) {
+ VLOG_DBG("%s: ct_flush: %"PRIu16, dpif_name(dpif), *zone);
+ } else {
+ VLOG_DBG("%s: ct_flush: <all>", dpif_name(dpif));
+ }
+
return (dpif->dpif_class->ct_flush
? dpif->dpif_class->ct_flush(dpif, zone)
: EOPNOTSUPP);
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 917dce8f9..0a685517b 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -3324,6 +3324,12 @@ ofp_print_nxst_ipfix_flow_reply(struct ds *string, const struct ofp_header *oh)
}
}
+static void
+ofp_print_nxt_ct_flush_zone(struct ds *string, const struct nx_zone_id *nzi)
+{
+ ds_put_format(string, " zone_id=%"PRIu16, ntohs(nzi->zone_id));
+}
+
static void
ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
@@ -3625,6 +3631,10 @@ ofp_to_string__(const struct ofp_header *oh, enum ofpraw raw,
case OFPTYPE_IPFIX_FLOW_STATS_REPLY:
ofp_print_nxst_ipfix_flow_reply(string, oh);
break;
+
+ case OFPTYPE_CT_FLUSH_ZONE:
+ ofp_print_nxt_ct_flush_zone(string, ofpmsg_body(oh));
+ break;
}
}
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index e2ccd6cce..04459681c 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -9998,6 +9998,7 @@ ofputil_is_bundlable(enum ofptype type)
case OFPTYPE_IPFIX_BRIDGE_STATS_REPLY:
case OFPTYPE_IPFIX_FLOW_STATS_REQUEST:
case OFPTYPE_IPFIX_FLOW_STATS_REPLY:
+ case OFPTYPE_CT_FLUSH_ZONE:
break;
}
diff --git a/lib/rconn.c b/lib/rconn.c
index 51e1b1b3d..0c1812a27 100644
--- a/lib/rconn.c
+++ b/lib/rconn.c
@@ -1430,6 +1430,7 @@ is_admitted_msg(const struct ofpbuf *b)
case OFPTYPE_IPFIX_BRIDGE_STATS_REPLY:
case OFPTYPE_IPFIX_FLOW_STATS_REQUEST:
case OFPTYPE_IPFIX_FLOW_STATS_REPLY:
+ case OFPTYPE_CT_FLUSH_ZONE:
default:
return true;
}
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 0282ebdfb..7374ccca3 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -25,6 +25,7 @@
#include "connmgr.h"
#include "coverage.h"
#include "cfm.h"
+#include "ct-dpif.h"
#include "dpif.h"
#include "fail-open.h"
#include "guarded-list.h"
@@ -4656,6 +4657,14 @@ get_datapath_version(const struct ofproto *ofproto_)
return ofproto->backer->dp_version_string;
}
+static void
+ct_flush(const struct ofproto *ofproto_, const uint16_t *zone)
+{
+ struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
+
+ ct_dpif_flush(ofproto->backer->dpif, zone);
+}
+
static bool
set_frag_handling(struct ofproto *ofproto_,
enum ofputil_frag_handling frag_handling)
@@ -5924,4 +5933,5 @@ const struct ofproto_class ofproto_dpif_class = {
NULL, /* group_modify */
group_get_stats, /* group_get_stats */
get_datapath_version, /* get_datapath_version */
+ ct_flush, /* ct_flush */
};
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index 6a523b46b..bc5098a9e 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -1811,6 +1811,13 @@ struct ofproto_class {
* This function should be NULL if an implementation does not support it.
*/
const char *(*get_datapath_version)(const struct ofproto *);
+
+/* ## ------------------- ## */
+/* ## Connection tracking ## */
+/* ## ------------------- ## */
+ /* Flushes the connection tracking tables. If 'zone' is not NULL,
+ * only deletes connections in '*zone'. */
+ void (*ct_flush)(const struct ofproto *, const uint16_t *zone);
};
extern const struct ofproto_class ofproto_dpif_class;
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 93a24be35..d601f7128 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -879,6 +879,26 @@ handle_ipfix_flow_stats_request(struct ofconn *ofconn,
return error;
}
+static enum ofperr
+handle_nxt_ct_flush_zone(struct ofconn *ofconn, const struct ofp_header *oh)
+{
+ struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
+ const struct nx_zone_id *nzi = ofpmsg_body(oh);
+
+ if (!is_all_zeros(nzi->zero, sizeof nzi->zero)) {
+ return OFPERR_NXBRC_MUST_BE_ZERO;
+ }
+
+ uint16_t zone = ntohs(nzi->zone_id);
+ if (ofproto->ofproto_class->ct_flush) {
+ ofproto->ofproto_class->ct_flush(ofproto, &zone);
+ } else {
+ return EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
void
ofproto_set_flow_restore_wait(bool flow_restore_wait_db)
{
@@ -7930,6 +7950,9 @@ handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)
case OFPTYPE_IPFIX_FLOW_STATS_REQUEST:
return handle_ipfix_flow_stats_request(ofconn, oh);
+ case OFPTYPE_CT_FLUSH_ZONE:
+ return handle_nxt_ct_flush_zone(ofconn, oh);
+
case OFPTYPE_HELLO:
case OFPTYPE_ERROR:
case OFPTYPE_FEATURES_REPLY:
diff --git a/tests/ofp-print.at b/tests/ofp-print.at
index 6c7433d85..694643839 100644
--- a/tests/ofp-print.at
+++ b/tests/ofp-print.at
@@ -3629,3 +3629,13 @@ NXST_IPFIX_FLOW reply (xid=0x2): 2 ids
pkts errs=160, ipv4 errs=68719476738, ipv6 errs=3, tx errs=5
])
AT_CLEANUP
+
+AT_SETUP([NXT_CT_FLUSH_ZONE])
+AT_KEYWORDS([ofp-print])
+AT_CHECK([ovs-ofctl ofp-print "\
+01 04 00 18 00 00 00 03 00 00 23 20 00 00 00 1d \
+00 00 00 00 00 00 00 0d \
+"], [0], [dnl
+NXT_CT_FLUSH_ZONE (xid=0x3): zone_id=13
+])
+AT_CLEANUP
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index 8747a069d..da7b262b5 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -3086,3 +3086,16 @@ vconn|DBG|unix: sent (Success): OFPST_FLOW reply (OF1.4):
OVS_VSWITCHD_STOP
AT_CLEANUP
+
+
+AT_SETUP([ovs-ofctl ct-flush-zone])
+OVS_VSWITCHD_START
+
+AT_CHECK([ovs-appctl vlog/set ct_dpif:dbg])
+AT_CHECK([ovs-ofctl ct-flush-zone br0 123])
+
+OVS_WAIT_UNTIL([grep -q "|ct_dpif|DBG|.*ct_flush:" ovs-vswitchd.log])
+AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: 123" ovs-vswitchd.log])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 6ab9638b5..c112e6af1 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -275,6 +275,12 @@ flow based IPFIX and collector set ids.
This command uses an Open vSwitch extension that is only in Open
vSwitch 2.6 and later.
.
+.IP "\fBct\-flush\-zone \fIswitch zone\fR
+Flushes the connection tracking entries in \fIzone\fR on \fIswitch\fR.
+.IP
+This command uses an Open vSwitch extension that is only in Open
+vSwitch 2.6 and later.
+.
.SS "OpenFlow 1.1+ Group Table Commands"
.
The following commands work only with switches that support OpenFlow
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index f9138e983..5a43da4cd 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -450,6 +450,7 @@ usage(void)
" dump-tlv-map SWITCH print TLV option mappings\n"
" dump-ipfix-bridge SWITCH print ipfix stats of bridge\n"
" dump-ipfix-flow SWITCH print flow ipfix of a bridge\n"
+ " ct-flush-zone SWITCH ZONE flush conntrack entries in ZONE\n"
"\nFor OpenFlow switches and controllers:\n"
" probe TARGET probe whether TARGET is up\n"
" ping TARGET [N] latency of N-byte echos\n"
@@ -2606,6 +2607,27 @@ ofctl_dump_ipfix_bridge(struct ovs_cmdl_context *ctx)
}
static void
+ofctl_ct_flush_zone(struct ovs_cmdl_context *ctx)
+{
+ uint16_t zone_id;
+ char *error = str_to_u16(ctx->argv[2], "zone_id", &zone_id);
+ if (error) {
+ ovs_fatal(0, "%s", error);
+ }
+
+ struct vconn *vconn;
+ open_vconn(ctx->argv[1], &vconn);
+ enum ofp_version version = vconn_get_version(vconn);
+
+ struct ofpbuf *msg = ofpraw_alloc(OFPRAW_NXT_CT_FLUSH_ZONE, version, 0);
+ struct nx_zone_id *nzi = ofpbuf_put_zeros(msg, sizeof *nzi);
+ nzi->zone_id = htons(zone_id);
+
+ transact_noreply(vconn, msg);
+ vconn_close(vconn);
+}
+
+static void
ofctl_dump_ipfix_flow(struct ovs_cmdl_context *ctx)
{
dump_trivial_transaction(ctx->argv[1], OFPRAW_NXST_IPFIX_FLOW_REQUEST);
@@ -4488,6 +4510,9 @@ static const struct ovs_cmdl_command all_commands[] = {
{ "dump-ipfix-flow", "switch",
1, 1, ofctl_dump_ipfix_flow, OVS_RO },
+ { "ct-flush-zone", "switch zone",
+ 2, 2, ofctl_ct_flush_zone, OVS_RO },
+
{ "ofp-parse", "file",
1, 1, ofctl_ofp_parse, OVS_RW },
{ "ofp-parse-pcap", "pcap",