struct cls_rule target;
if (arg_size != sizeof *fsr) {
- return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH);
+ return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
}
fsr = (struct ofp_flow_stats_request *) osr->body;
struct ofpbuf *msg;
if (arg_size != sizeof *asr) {
- return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH);
+ return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
}
asr = (struct ofp_aggregate_stats_request *) osr->body;
uint16_t in_port;
int error;
+ if (ofm->flags & htons(OFPFF_CHECK_OVERLAP)) {
+ flow_t flow;
+ uint32_t wildcards;
+
+ flow_from_match(&flow, &wildcards, &ofm->match);
+ if (classifier_rule_overlaps(&p->cls, &flow, wildcards,
+ ntohs(ofm->priority))) {
+ return ofp_mkerr(OFPET_FLOW_MOD_FAILED, OFPFMFC_OVERLAP);
+ }
+ }
+
rule = rule_create(p, NULL, (const union ofp_action *) ofm->actions,
n_actions, ntohs(ofm->idle_timeout),
ntohs(ofm->hard_timeout));
return error;
}
+ /* We do not support the emergency flow cache. It will hopefully
+ * get dropped from OpenFlow in the near future. */
+ if (ofm->flags & htons(OFPFF_EMERG)) {
+ /* There isn't a good fit for an error code, so just state that the
+ * flow table is full. */
+ return ofp_mkerr(OFPET_FLOW_MOD_FAILED, OFPFMFC_ALL_TABLES_FULL);
+ }
+
normalize_match(&ofm->match);
if (!ofm->match.wildcards) {
ofm->priority = htons(UINT16_MAX);
size_t msg_len = ntohs(ofmph->header.header.length);
if (msg_len < sizeof(*ofmph)) {
VLOG_WARN_RL(&rl, "dropping short managment message: %zu\n", msg_len);
- return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH);
+ return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
}
if (ofmph->type == htons(OFMPT_CAPABILITY_REQUEST)) {
if (msg_len < sizeof(struct ofmp_capability_request)) {
VLOG_WARN_RL(&rl, "dropping short capability request: %zu\n",
msg_len);
- return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH);
+ return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
}
ofmpcr = (struct ofmp_capability_request *)ofmph;
struct nicira_header *nh;
if (ntohs(ovh->header.length) < sizeof(struct ofp_vendor_header)) {
- return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH);
+ return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
}
if (ovh->vendor != htonl(NX_VENDOR_ID)) {
return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_VENDOR);
}
if (ntohs(ovh->header.length) < sizeof(struct nicira_header)) {
- return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH);
+ return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN);
}
nh = msg;
{
struct ofp_flow_expired *ofe;
struct ofpbuf *buf;
+ long long int last_used = rule->used ? now - rule->used : 0;
ofe = make_openflow(sizeof *ofe, OFPT_FLOW_EXPIRED, &buf);
flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, &ofe->match);
ofe->priority = htons(rule->cr.priority);
ofe->reason = reason;
- ofe->duration = htonl((now - rule->created) / 1000);
+ ofe->duration = htonl((now - rule->created - last_used) / 1000);
ofe->packet_count = htonll(rule->packet_count);
ofe->byte_count = htonll(rule->byte_count);