Skip to content

Commit

Permalink
OpenFlow: Add extn to set conntrack entries limit per zone.
Browse files Browse the repository at this point in the history
Add OpenFlow extn to set conntrack entries limit per zone.

Signed-off-by: Naveen Yerramneni <naveen.yerramneni@nutanix.com>
  • Loading branch information
naveen-yerramneni authored and Simon Horman committed Mar 14, 2023
1 parent 10f172d commit 35b673e
Show file tree
Hide file tree
Showing 13 changed files with 141 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NEWS
Expand Up @@ -45,6 +45,8 @@ v3.1.0 - 16 Feb 2023
- OpenFlow:
* New OpenFlow extension NXT_CT_FLUSH to flush connections matching
the specified fields.
* New OpenFlow extension NXT_CT_SET_ZONE_LIMIT to set conntrack table
limit at zone level.
- ovs-ctl:
* New option '--dump-hugepages' to include hugepages in core dumps. This
can assist with postmortem analysis involving DPDK, but may also produce
Expand Down
10 changes: 10 additions & 0 deletions include/openflow/nicira-ext.h
Expand Up @@ -1101,4 +1101,14 @@ struct nx_ct_flush {
};
OFP_ASSERT(sizeof(struct nx_ct_flush) == 8);

/* NXT_CT_SET_ZONE_LIMIT.
*
* Sets connection tracking table zone limit. */
struct nx_ct_zone_limit {
uint8_t zero[2]; /* Must be zero. */
ovs_be16 zone_id; /* Connection tracking zone. */
ovs_be32 limit; /* Drop limit. */
};
OFP_ASSERT(sizeof(struct nx_ct_zone_limit) == 8);

#endif /* openflow/nicira-ext.h */
4 changes: 4 additions & 0 deletions include/openvswitch/ofp-msgs.h
Expand Up @@ -518,6 +518,9 @@ enum ofpraw {
/* NXT 1.0+ (32): struct nx_ct_flush, uint8_t[8][]. */
OFPRAW_NXT_CT_FLUSH,

/* NXT 1.0+ (35): struct nx_ct_zone_limit. */
OFPRAW_NXT_CT_SET_ZONE_LIMIT,

/* NXST 1.0+ (3): void. */
OFPRAW_NXST_IPFIX_BRIDGE_REQUEST,

Expand Down Expand Up @@ -776,6 +779,7 @@ enum ofptype {
OFPTYPE_IPFIX_FLOW_STATS_REPLY, /* OFPRAW_NXST_IPFIX_FLOW_REPLY */
OFPTYPE_CT_FLUSH_ZONE, /* OFPRAW_NXT_CT_FLUSH_ZONE. */
OFPTYPE_CT_FLUSH, /* OFPRAW_NXT_CT_FLUSH. */
OFPTYPE_CT_SET_ZONE_LIMIT, /* OFPRAW_NXT_CT_SET_ZONE_LIMIT. */

/* Flow monitor extension. */
OFPTYPE_FLOW_MONITOR_CANCEL, /* OFPRAW_NXT_FLOW_MONITOR_CANCEL.
Expand Down
1 change: 1 addition & 0 deletions lib/ofp-bundle.c
Expand Up @@ -293,6 +293,7 @@ ofputil_is_bundlable(enum ofptype type)
case OFPTYPE_IPFIX_FLOW_STATS_REPLY:
case OFPTYPE_CT_FLUSH_ZONE:
case OFPTYPE_CT_FLUSH:
case OFPTYPE_CT_SET_ZONE_LIMIT:
break;
}

Expand Down
11 changes: 11 additions & 0 deletions lib/ofp-print.c
Expand Up @@ -967,6 +967,15 @@ ofp_print_nxt_ct_flush(struct ds *string, const struct ofp_header *oh)
return 0;
}

static enum ofperr
ofp_print_nxt_ct_set_zone_limit(struct ds *string,
const struct nx_ct_zone_limit *nzl)
{
ds_put_format(string, " zone_id=%"PRIu16, ntohs(nzl->zone_id));
ds_put_format(string, " limit=%"PRIu32, ntohl(nzl->limit));
return 0;
}

static enum ofperr
ofp_to_string__(const struct ofp_header *oh,
const struct ofputil_port_map *port_map,
Expand Down Expand Up @@ -1204,6 +1213,8 @@ ofp_to_string__(const struct ofp_header *oh,
return ofp_print_nxt_ct_flush_zone(string, ofpmsg_body(oh));
case OFPTYPE_CT_FLUSH:
return ofp_print_nxt_ct_flush(string, oh);
case OFPTYPE_CT_SET_ZONE_LIMIT:
return ofp_print_nxt_ct_set_zone_limit(string, ofpmsg_body(oh));
}

return 0;
Expand Down
1 change: 1 addition & 0 deletions lib/rconn.c
Expand Up @@ -1427,6 +1427,7 @@ is_admitted_msg(const struct ofpbuf *b)
case OFPTYPE_IPFIX_FLOW_STATS_REPLY:
case OFPTYPE_CT_FLUSH_ZONE:
case OFPTYPE_CT_FLUSH:
case OFPTYPE_CT_SET_ZONE_LIMIT:
default:
return true;
}
Expand Down
22 changes: 22 additions & 0 deletions ofproto/ofproto-dpif.c
Expand Up @@ -5621,6 +5621,27 @@ ct_del_zone_timeout_policy(const char *datapath_type, uint16_t zone_id)
}
}

static void
ct_set_zone_limit(const struct ofproto *ofproto_, const uint16_t zone_id,
const uint32_t limit)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
struct ovs_list zone_limits = OVS_LIST_INITIALIZER(&zone_limits);

ct_dpif_push_zone_limit(&zone_limits, zone_id, limit, 0);
int err = ct_dpif_set_limits(ofproto->backer->dpif, NULL, &zone_limits);
if (err) {
VLOG_ERR_RL(&rl, "failed to set zone limit id=%"PRIu16", "
"limit=%"PRIu32" (%s)", zone_id, limit,
ovs_strerror(err));
} else {
VLOG_DBG("configured zone limit for zone=%"PRIu16", limit=%"PRIu32"",
zone_id, limit);
}

ct_dpif_free_zone_limits(&zone_limits);
}

static void
get_datapath_cap(const char *datapath_type, struct smap *cap)
{
Expand Down Expand Up @@ -6910,4 +6931,5 @@ const struct ofproto_class ofproto_dpif_class = {
ct_flush, /* ct_flush */
ct_set_zone_timeout_policy,
ct_del_zone_timeout_policy,
ct_set_zone_limit, /* ct_set_zone_limit */
};
4 changes: 4 additions & 0 deletions ofproto/ofproto-provider.h
Expand Up @@ -1916,6 +1916,10 @@ struct ofproto_class {
/* Deletes the timeout policy associated with 'zone' in datapath type
* 'dp_type'. */
void (*ct_del_zone_timeout_policy)(const char *dp_type, uint16_t zone);

/* Sets conntrack zone limit */
void (*ct_set_zone_limit)(const struct ofproto *, const uint16_t zone,
const uint32_t limit);
};

extern const struct ofproto_class ofproto_dpif_class;
Expand Down
25 changes: 25 additions & 0 deletions ofproto/ofproto.c
Expand Up @@ -966,6 +966,28 @@ handle_nxt_ct_flush(struct ofconn *ofconn, const struct ofp_header *oh)
return 0;
}

static enum ofperr
handle_nxt_ct_set_zone_limit(struct ofconn *ofconn,
const struct ofp_header *oh)
{
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
const struct nx_ct_zone_limit *nzl = ofpmsg_body(oh);

if (!is_all_zeros(nzl->zero, sizeof nzl->zero)) {
return OFPERR_NXBRC_MUST_BE_ZERO;
}

uint16_t zone_id = ntohs(nzl->zone_id);
uint32_t limit = ntohl(nzl->limit);
if (ofproto->ofproto_class->ct_set_zone_limit) {
ofproto->ofproto_class->ct_set_zone_limit(ofproto, zone_id, limit);
} else {
return EOPNOTSUPP;
}

return 0;
}

void
ofproto_set_flow_restore_wait(bool flow_restore_wait_db)
{
Expand Down Expand Up @@ -8818,6 +8840,9 @@ handle_single_part_openflow(struct ofconn *ofconn, const struct ofp_header *oh,
case OFPTYPE_CT_FLUSH:
return handle_nxt_ct_flush(ofconn, oh);

case OFPTYPE_CT_SET_ZONE_LIMIT:
return handle_nxt_ct_set_zone_limit(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 @@ -4181,3 +4181,13 @@ AT_CHECK([ovs-ofctl ofp-print "\
00 00 00 14 00 00 00 00 00 00 00 00 00 00 ff ff 0a 0a 00 02 00 00 00 00 \
" | grep -q OFPBPC_BAD_VALUE], [0])
AT_CLEANUP

AT_SETUP([NXT_CT_SET_ZONE_LIMIT])
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 23 \
00 00 00 12 00 01 86 a0 \
"], [0], [dnl
NXT_CT_SET_ZONE_LIMIT (xid=0x3): zone_id=18 limit=100000
])
AT_CLEANUP
12 changes: 12 additions & 0 deletions tests/ovs-ofctl.at
Expand Up @@ -3309,3 +3309,15 @@ AT_CHECK([grep -q "ct_dpif|DBG|.*ct_flush: <all>" ovs-vswitchd.log])

OVS_VSWITCHD_STOP
AT_CLEANUP


AT_SETUP([ovs-ofctl ct-set-zone-limit])
OVS_VSWITCHD_START

AT_CHECK([ovs-appctl vlog/set ct_dpif:dbg])
AT_CHECK([ovs-ofctl ct-set-zone-limit br0 1 200000])

OVS_WAIT_UNTIL([grep -q "ofproto_dpif|DBG|.*zone=1.*limit=200000" ovs-vswitchd.log])
AT_CHECK([grep -q "ofproto_dpif|DBG|.*zone=1.*limit=200000" ovs-vswitchd.log])
OVS_VSWITCHD_STOP
AT_CLEANUP
5 changes: 5 additions & 0 deletions utilities/ovs-ofctl.8.in
Expand Up @@ -326,6 +326,11 @@ An example of an IPv6 TCP \fIct-[orig|reply]-tuple\fR:
.IP
This command uses an Open vSwitch extension that is only in Open vSwitch 3.1
and later.
.IP "\fBct\-set\-zone\-limit \fIswitch zone limit\fR
Set the connection tracking entries limit in \fIzone\fR on \fIswitch\fR.
.IP
This command uses an Open vSwitch extension that is only in Open
vSwitch 3.1 and later.
.
.SS "OpenFlow Switch Flow Table Commands"
.
Expand Down
34 changes: 34 additions & 0 deletions utilities/ovs-ofctl.c
Expand Up @@ -489,6 +489,8 @@ usage(void)
" ct-flush SWITCH [ZONE] [CT_ORIG_TUPLE [CT_REPLY_TUPLE]]\n"
" flush conntrack entries specified\n"
" by CT_ORIG/REPLY_TUPLE and ZONE\n"
" ct-set-zone-limit SWITCH ZONE LIMIT set conntrack entries\n"
" limit for the 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 @@ -3098,6 +3100,35 @@ ofctl_ct_flush(struct ovs_cmdl_context *ctx)
vconn_close(vconn);
}

static void
ofctl_ct_set_zone_limit(struct ovs_cmdl_context *ctx)
{
uint16_t zone_id;
uint32_t limit;

char *error = str_to_u16(ctx->argv[2], "zone_id", &zone_id);
if (error) {
ovs_fatal(0, "%s", error);
}
error = str_to_u32(ctx->argv[3], &limit);
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_SET_ZONE_LIMIT, version,
0);
struct nx_ct_zone_limit *nzl = ofpbuf_put_zeros(msg, sizeof *nzl);
nzl->zone_id = htons(zone_id);
nzl->limit = htonl(limit);

transact_noreply(vconn, msg);
vconn_close(vconn);
}

static void
ofctl_dump_ipfix_flow(struct ovs_cmdl_context *ctx)
{
Expand Down Expand Up @@ -5114,6 +5145,9 @@ static const struct ovs_cmdl_command all_commands[] = {
{ "ct-flush", "switch [zone=N] [ct-orig-tuple [ct-reply-tuple]]",
1, 4, ofctl_ct_flush, OVS_RO },

{ "ct-set-zone-limit", "switch zone limit",
3, 3, ofctl_ct_set_zone_limit, OVS_RO },

{ "ofp-parse", "file",
1, 1, ofctl_ofp_parse, OVS_RW },
{ "ofp-parse-pcap", "pcap",
Expand Down

0 comments on commit 35b673e

Please sign in to comment.