Make the packet out and trace processing perform the same actions
checks as flow mod processing does.
This used to be the case before, but at some point these have diverged
to perform different combinations of checks.
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
goto exit;
}
if (enforce_consistency) {
goto exit;
}
if (enforce_consistency) {
- retval = ofpacts_check_consistency(ofpacts.data, ofpacts.size,
- &flow, u16_to_ofp(ofproto->up.max_ports),
- 0, 0, usable_protocols);
+ retval = ofpacts_check_consistency(ofpacts.data, ofpacts.size, &flow,
+ u16_to_ofp(ofproto->up.max_ports),
+ 0, ofproto->up.n_tables,
+ usable_protocols);
} else {
retval = ofpacts_check(ofpacts.data, ofpacts.size, &flow,
} else {
retval = ofpacts_check(ofpacts.data, ofpacts.size, &flow,
- u16_to_ofp(ofproto->up.max_ports), 0, 0,
- &usable_protocols);
+ u16_to_ofp(ofproto->up.max_ports), 0,
+ ofproto->up.n_tables, &usable_protocols);
+ }
+ if (!retval) {
+ retval = ofproto_check_ofpacts(&ofproto->up, ofpacts.data,
+ ofpacts.size);
OVS_EXCLUDED(ofproto_mutex);
void ofproto_flush_flows(struct ofproto *);
OVS_EXCLUDED(ofproto_mutex);
void ofproto_flush_flows(struct ofproto *);
+enum ofperr ofproto_check_ofpacts(struct ofproto *,
+ const struct ofpact ofpacts[],
+ size_t ofpacts_len);
\f
static inline const struct rule_actions *
rule_get_actions(const struct rule *rule)
\f
static inline const struct rule_actions *
rule_get_actions(const struct rule *rule)
* - If they use any groups, then 'ofproto' has that group configured.
*
* Returns 0 if successful, otherwise an OpenFlow error. */
* - If they use any groups, then 'ofproto' has that group configured.
*
* Returns 0 if successful, otherwise an OpenFlow error. */
ofproto_check_ofpacts(struct ofproto *ofproto,
const struct ofpact ofpacts[], size_t ofpacts_len)
{
ofproto_check_ofpacts(struct ofproto *ofproto,
const struct ofpact ofpacts[], size_t ofpacts_len)
{
/* Verify actions against packet, then send packet if successful. */
flow_extract(payload, &flow);
flow.in_port.ofp_port = po.in_port;
/* Verify actions against packet, then send packet if successful. */
flow_extract(payload, &flow);
flow.in_port.ofp_port = po.in_port;
- error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len);
+
+ /* Check actions like for flow mods. We pass a 'table_id' of 0 to
+ * ofproto_check_consistency(), which isn't strictly correct because these
+ * actions aren't in any table. This is OK as 'table_id' is only used to
+ * check instructions (e.g., goto-table), which can't appear on the action
+ * list of a packet-out. */
+ error = ofpacts_check_consistency(po.ofpacts, po.ofpacts_len,
+ &flow, u16_to_ofp(p->max_ports),
+ 0, p->n_tables,
+ ofconn_get_protocol(ofconn));
- error = p->ofproto_class->packet_out(p, payload, &flow,
- po.ofpacts, po.ofpacts_len);
+ error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len);
+ if (!error) {
+ error = p->ofproto_class->packet_out(p, payload, &flow,
+ po.ofpacts, po.ofpacts_len);
+ }
}
dp_packet_delete(payload);
}
dp_packet_delete(payload);