#include "ofpbuf.h"
#include "ofproto-dpif-ipfix.h"
#include "ofproto-dpif-sflow.h"
-#include "ofproto-dpif.h"
#include "packets.h"
#include "poll-loop.h"
#include "vlog.h"
* all the packets in each miss. */
fail_open = false;
HMAP_FOR_EACH (miss, hmap_node, &fmb->misses) {
- struct flow_wildcards wc;
- struct rule_dpif *rule;
struct xlate_in xin;
- flow_wildcards_init_catchall(&wc);
- rule_dpif_lookup(miss->ofproto, &miss->flow, &wc, &rule);
- if (rule_dpif_fail_open(rule)) {
- fail_open = true;
- }
- rule_dpif_credit_stats(rule, &miss->stats);
- xlate_in_init(&xin, miss->ofproto, &miss->flow, rule,
+ xlate_in_init(&xin, miss->ofproto, &miss->flow, NULL,
miss->stats.tcp_flags, NULL);
xin.may_learn = true;
xin.resubmit_stats = &miss->stats;
xlate_actions(&xin, &miss->xout);
- flow_wildcards_or(&miss->xout.wc, &miss->xout.wc, &wc);
- rule_dpif_unref(rule);
+ fail_open = fail_open || miss->xout.fail_open;
}
/* Now handle the packets individually in order of arrival. In the common
struct ofpbuf *packet = upcall->dpif_upcall.packet;
if (miss->xout.slow) {
- struct rule_dpif *rule;
struct xlate_in xin;
- rule_dpif_lookup(miss->ofproto, &miss->flow, NULL, &rule);
- xlate_in_init(&xin, miss->ofproto, &miss->flow, rule, 0, packet);
+ xlate_in_init(&xin, miss->ofproto, &miss->flow, NULL, 0, packet);
xlate_actions_for_side_effects(&xin);
- rule_dpif_unref(rule);
}
if (miss->xout.odp_actions.size) {
{
struct flow_wildcards *wc = &xout->wc;
struct flow *flow = &xin->flow;
+ struct rule_dpif *rule = NULL;
struct rule_actions *actions = NULL;
enum slow_path_reason special;
ctx.exit = false;
ctx.mpls_depth_delta = 0;
+ if (!xin->ofpacts && !ctx.rule) {
+ rule_dpif_lookup(ctx.xbridge->ofproto, flow, wc, &rule);
+ if (ctx.xin->resubmit_stats) {
+ rule_dpif_credit_stats(rule, ctx.xin->resubmit_stats);
+ }
+ ctx.rule = rule;
+ }
+ xout->fail_open = ctx.rule && rule_dpif_fail_open(ctx.rule);
+
if (xin->ofpacts) {
ofpacts = xin->ofpacts;
ofpacts_len = xin->ofpacts_len;
- } else if (xin->rule) {
- actions = rule_dpif_get_actions(xin->rule);
+ } else if (ctx.rule) {
+ actions = rule_dpif_get_actions(ctx.rule);
ofpacts = actions->ofpacts;
ofpacts_len = actions->ofpacts_len;
} else {
out:
rule_actions_unref(actions);
+ rule_dpif_unref(rule);
}
/* Sends 'packet' out 'ofport'.
struct flow_wildcards wc;
enum slow_path_reason slow; /* 0 if fast path may be used. */
+ bool fail_open; /* Initial rule is fail open? */
bool has_learn; /* Actions include NXAST_LEARN? */
bool has_normal; /* Actions output to OFPP_NORMAL? */
bool has_fin_timeout; /* Actions include NXAST_FIN_TIMEOUT? */
* not if we are just revalidating. */
bool may_learn;
- /* The rule initiating translation or NULL. */
+ /* The rule initiating translation or NULL. If both 'rule' and 'ofpacts'
+ * are NULL, xlate_actions() will do the initial rule lookup itself. */
struct rule_dpif *rule;
/* The actions to translate. If 'rule' is not NULL, these may be NULL. */
struct xlate_out xout;
struct xlate_in xin;
-
- struct rule_dpif *rule;
bool ok;
/* Check the datapath actions for consistency. */
- rule_dpif_lookup(facet->ofproto, &facet->flow, NULL, &rule);
- xlate_in_init(&xin, facet->ofproto, &facet->flow, rule, 0, NULL);
+ xlate_in_init(&xin, facet->ofproto, &facet->flow, NULL, 0, NULL);
xlate_actions(&xin, &xout);
- rule_dpif_unref(rule);
ok = ofpbuf_equal(&facet->xout.odp_actions, &xout.odp_actions)
&& facet->xout.slow == xout.slow;
struct dpif_flow_stats *stats, bool may_learn)
{
struct ofport_dpif *in_port;
- struct rule_dpif *rule;
struct xlate_in xin;
in_port = get_ofp_port(ofproto, flow->in_port.ofp_port);
netdev_vport_inc_rx(in_port->up.netdev, stats);
}
- rule_dpif_lookup(ofproto, flow, NULL, &rule);
- rule_dpif_credit_stats(rule, stats);
- xlate_in_init(&xin, ofproto, flow, rule, stats->tcp_flags, NULL);
+ xlate_in_init(&xin, ofproto, flow, NULL, stats->tcp_flags, NULL);
xin.resubmit_stats = stats;
xin.may_learn = may_learn;
xlate_actions_for_side_effects(&xin);
- rule_dpif_unref(rule);
}
static void