Skip to content

Commit

Permalink
Add OpenFlow command to flush conntrack table entries.
Browse files Browse the repository at this point in the history
Signed-off-by: Justin Pettit <jpettit@ovn.org>
Acked-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
justinpettit committed Sep 23, 2016
1 parent fa2202a commit 3871fd5
Show file tree
Hide file tree
Showing 15 changed files with 139 additions and 1 deletion.
1 change: 1 addition & 0 deletions NEWS
Expand Up @@ -46,6 +46,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+.
Expand Down
10 changes: 10 additions & 0 deletions debian/changelog
Expand Up @@ -26,6 +26,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+.
Expand Down
9 changes: 9 additions & 0 deletions include/openflow/nicira-ext.h
Expand Up @@ -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 */
4 changes: 4 additions & 0 deletions include/openvswitch/ofp-msgs.h
Expand Up @@ -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,

Expand Down Expand Up @@ -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. */
Expand Down
10 changes: 9 additions & 1 deletion lib/ct-dpif.c
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions lib/ofp-print.c
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
}

Expand Down
1 change: 1 addition & 0 deletions lib/ofp-util.c
Expand Up @@ -9989,6 +9989,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;
}

Expand Down
1 change: 1 addition & 0 deletions lib/rconn.c
Expand Up @@ -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;
}
Expand Down
10 changes: 10 additions & 0 deletions ofproto/ofproto-dpif.c
Expand Up @@ -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"
Expand Down Expand Up @@ -4441,6 +4442,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)
Expand Down Expand Up @@ -5693,4 +5702,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 */
};
7 changes: 7 additions & 0 deletions ofproto/ofproto-provider.h
Expand Up @@ -1831,6 +1831,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;
Expand Down
23 changes: 23 additions & 0 deletions ofproto/ofproto.c
Expand Up @@ -895,6 +895,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)
{
Expand Down Expand Up @@ -7724,6 +7744,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:
Expand Down
10 changes: 10 additions & 0 deletions tests/ofp-print.at
Expand Up @@ -3610,3 +3610,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
13 changes: 13 additions & 0 deletions tests/ovs-ofctl.at
Expand Up @@ -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
6 changes: 6 additions & 0 deletions utilities/ovs-ofctl.8.in
Expand Up @@ -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
Expand Down
25 changes: 25 additions & 0 deletions utilities/ovs-ofctl.c
Expand Up @@ -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"
Expand Down Expand Up @@ -2532,6 +2533,27 @@ ofctl_dump_ipfix_bridge(struct ovs_cmdl_context *ctx)
dump_trivial_transaction(ctx->argv[1], OFPRAW_NXST_IPFIX_BRIDGE_REQUEST);
}

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)
{
Expand Down Expand Up @@ -4398,6 +4420,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",
Expand Down

0 comments on commit 3871fd5

Please sign in to comment.