From patchwork Fri Sep 23 08:53:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Justin Pettit X-Patchwork-Id: 673988 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3sgRwl5Xcjz9sf6 for ; Fri, 23 Sep 2016 18:53:43 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 09B7C108EB; Fri, 23 Sep 2016 01:53:43 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 7F8A5108DD for ; Fri, 23 Sep 2016 01:53:41 -0700 (PDT) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id 1573C420323 for ; Fri, 23 Sep 2016 02:53:41 -0600 (MDT) X-ASG-Debug-ID: 1474620820-09eadd7acc75080001-byXFYA Received: from mx1-pf1.cudamail.com ([192.168.24.1]) by bar5.cudamail.com with ESMTP id c1e0p3P9A0PXWceN (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Sep 2016 02:53:40 -0600 (MDT) X-Barracuda-Envelope-From: jpettit@ovn.org X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.1 Received: from unknown (HELO relay4-d.mail.gandi.net) (217.70.183.196) by mx1-pf1.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 23 Sep 2016 08:53:40 -0000 Received-SPF: pass (mx1-pf1.cudamail.com: SPF record at ovn.org designates 217.70.183.196 as permitted sender) X-Barracuda-Apparent-Source-IP: 217.70.183.196 X-Barracuda-RBL-IP: 217.70.183.196 Received: from mfilter45-d.gandi.net (mfilter45-d.gandi.net [217.70.178.176]) by relay4-d.mail.gandi.net (Postfix) with ESMTP id B91EE172143 for ; Fri, 23 Sep 2016 10:53:38 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter45-d.gandi.net Received: from relay4-d.mail.gandi.net ([IPv6:::ffff:217.70.183.196]) by mfilter45-d.gandi.net (mfilter45-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id O495R5DmmN_9 for ; Fri, 23 Sep 2016 10:53:06 +0200 (CEST) X-Originating-IP: 98.234.50.139 Received: from localhost.localdomain (unknown [98.234.50.139]) (Authenticated sender: jpettit@ovn.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id D4E711720B4 for ; Fri, 23 Sep 2016 10:53:05 +0200 (CEST) X-CudaMail-Envelope-Sender: jpettit@ovn.org From: Justin Pettit To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E1-922002395 X-CudaMail-DTE: 092316 X-CudaMail-Originating-IP: 217.70.183.196 Date: Fri, 23 Sep 2016 01:53:00 -0700 X-ASG-Orig-Subj: [##CM-E1-922002395##][PATCH 1/4] Add OpenFlow command to flush conntrack table entries. Message-Id: <1474620783-96388-1-git-send-email-jpettit@ovn.org> X-Mailer: git-send-email 1.9.1 X-Barracuda-Connect: UNKNOWN[192.168.24.1] X-Barracuda-Start-Time: 1474620820 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [PATCH 1/4] Add OpenFlow command to flush conntrack table entries. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Justin Pettit Acked-by: Ben Pfaff --- NEWS | 1 + debian/changelog | 10 ++++++++++ include/openflow/nicira-ext.h | 9 +++++++++ include/openvswitch/ofp-msgs.h | 4 ++++ lib/dpif.c | 14 ++++++++++++++ lib/dpif.h | 1 + lib/ofp-print.c | 10 ++++++++++ lib/ofp-util.c | 1 + lib/rconn.c | 1 + ofproto/ofproto-dpif.c | 9 +++++++++ ofproto/ofproto-provider.h | 7 +++++++ ofproto/ofproto.c | 23 +++++++++++++++++++++++ tests/ofp-print.at | 10 ++++++++++ tests/ovs-ofctl.at | 13 +++++++++++++ utilities/ovs-ofctl.8.in | 6 ++++++ utilities/ovs-ofctl.c | 25 +++++++++++++++++++++++++ 16 files changed, 144 insertions(+) diff --git a/NEWS b/NEWS index bb32c47..dba1950 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 d73e636..7f38d53 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 5ab026c..9d53623 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 8dab858..ffb88b3 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/dpif.c b/lib/dpif.c index 53958c5..3fcef77 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1760,3 +1760,17 @@ dpif_supports_tnl_push_pop(const struct dpif *dpif) { return dpif_is_netdev(dpif); } + +void +dpif_ct_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: ", dpif_name(dpif)); + } + + if (dpif->dpif_class->ct_flush) { + dpif->dpif_class->ct_flush(dpif, zone); + } +} diff --git a/lib/dpif.h b/lib/dpif.h index a7c5097..a6ead6e 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -859,6 +859,7 @@ int dpif_queue_to_priority(const struct dpif *, uint32_t queue_id, char *dpif_get_dp_version(const struct dpif *); bool dpif_supports_tnl_push_pop(const struct dpif *); +void dpif_ct_flush(struct dpif *, const uint16_t *zone); #ifdef __cplusplus } #endif diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 917dce8..0a68551 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 e2ccd6c..0445968 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 51e1b1b..0c1812a 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 0282ebd..cc71673 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -4656,6 +4656,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_); + + dpif_ct_flush(ofproto->backer->dpif, zone); +} + static bool set_frag_handling(struct ofproto *ofproto_, enum ofputil_frag_handling frag_handling) @@ -5924,4 +5932,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 6a523b4..bc5098a 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 93a24be..d601f71 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 6c7433d..6946438 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 8747a06..719736f 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 dpif:dbg]) +AT_CHECK([ovs-ofctl ct-flush-zone br0 123]) + +OVS_WAIT_UNTIL([grep -q "|dpif|DBG|.*ct_flush:" ovs-vswitchd.log]) +AT_CHECK([grep -q "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 6ab9638..c112e6a 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 f9138e9..5a43da4 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",