flow.dp_hash = 1;
ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
- odp_flow_key_from_flow(&key, &flow, 0);
+ odp_flow_key_from_flow(&key, &flow, NULL, 0);
error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE | DPIF_FP_MODIFY,
ofpbuf_data(&key), ofpbuf_size(&key), NULL, 0, NULL,
flow_set_mpls_bos(&flow, n, 1);
ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
- odp_flow_key_from_flow(&key, &flow, 0);
+ odp_flow_key_from_flow(&key, &flow, NULL, 0);
error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE | DPIF_FP_MODIFY,
ofpbuf_data(&key), ofpbuf_size(&key), NULL, 0, NULL, 0, NULL);
return rule_get_actions(&rule->up);
}
-static uint8_t
-rule_dpif_lookup__ (struct ofproto_dpif *ofproto, const struct flow *flow,
- struct flow_wildcards *wc, struct rule_dpif **rule)
+/* Lookup 'flow' in table 0 of 'ofproto''s classifier.
+ * If 'wc' is non-null, sets the fields that were relevant as part of
+ * the lookup. Returns the table_id where a match or miss occurred.
+ *
+ * The return value will be zero unless there was a miss and
+ * OFPTC11_TABLE_MISS_CONTINUE is in effect for the sequence of tables
+ * where misses occur. */
+uint8_t
+rule_dpif_lookup(struct ofproto_dpif *ofproto, struct flow *flow,
+ struct flow_wildcards *wc, struct rule_dpif **rule)
{
enum rule_dpif_lookup_verdict verdict;
enum ofputil_port_config config = 0;
- uint8_t table_id = TBL_INTERNAL;
+ uint8_t table_id;
+
+ if (ofproto_dpif_get_enable_recirc(ofproto)) {
+ /* Always exactly match recirc_id since datapath supports
+ * recirculation. */
+ if (wc) {
+ wc->masks.recirc_id = UINT32_MAX;
+ }
+
+ /* Start looking up from internal table for post recirculation flows
+ * or packets. We can also simply send all, including normal flows
+ * or packets to the internal table. They will not match any post
+ * recirculation rules except the 'catch all' rule that resubmit
+ * them to table 0.
+ *
+ * As an optimization, we send normal flows and packets to table 0
+ * directly, saving one table lookup. */
+ table_id = flow->recirc_id ? TBL_INTERNAL : 0;
+ } else {
+ table_id = 0;
+ }
verdict = rule_dpif_lookup_from_table(ofproto, flow, wc, true,
&table_id, rule);
return table_id;
}
-/* Lookup 'flow' in table 0 of 'ofproto''s classifier.
- * If 'wc' is non-null, sets the fields that were relevant as part of
- * the lookup. Returns the table_id where a match or miss occurred.
- *
- * The return value will be zero unless there was a miss and
- * OFPTC11_TABLE_MISS_CONTINUE is in effect for the sequence of tables
- * where misses occur. */
-uint8_t
-rule_dpif_lookup(struct ofproto_dpif *ofproto, struct flow *flow,
- struct flow_wildcards *wc, struct rule_dpif **rule)
-{
- /* Set metadata to the value of recirc_id to speed up internal
- * rule lookup. */
- flow->metadata = htonll(flow->recirc_id);
- return rule_dpif_lookup__(ofproto, flow, wc, rule);
-}
-
static struct rule_dpif *
rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto, uint8_t table_id,
const struct flow *flow, struct flow_wildcards *wc)