*
* - Do include packets and bytes that were obtained from the datapath
* when a flow was deleted (e.g. dpif_flow_del()) or when its
- * statistics were reset (e.g. dpif_flow_put() with ODPPF_ZERO_STATS).
+ * statistics were reset (e.g. dpif_flow_put() with
+ * DPIF_FP_ZERO_STATS).
*
* - Do not include any packets or bytes that can currently be obtained
* from the datapath by, e.g., dpif_flow_get().
}
static int
-facet_put__(struct ofproto *ofproto, struct facet *facet, int flags)
+facet_put__(struct ofproto *ofproto, struct facet *facet,
+ const struct nlattr *actions, size_t actions_len,
+ struct dpif_flow_stats *stats)
{
uint32_t keybuf[ODPUTIL_FLOW_KEY_U32S];
+ enum dpif_flow_put_flags flags;
struct ofpbuf key;
+ flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
+ if (stats) {
+ flags |= DPIF_FP_ZERO_STATS;
+ }
+
ofpbuf_use_stack(&key, keybuf, sizeof keybuf);
odp_flow_key_from_flow(&key, &facet->flow);
assert(key.base == keybuf);
return dpif_flow_put(ofproto->dpif, flags, key.data, key.size,
- facet->actions, facet->actions_len, NULL);
+ actions, actions_len, stats);
}
/* If 'facet' is installable, inserts or re-inserts it into 'p''s datapath. If
static void
facet_install(struct ofproto *p, struct facet *facet, bool zero_stats)
{
- if (facet->may_install) {
- int flags = ODPPF_CREATE | ODPPF_MODIFY;
- if (zero_stats) {
- flags |= ODPPF_ZERO_STATS;
- }
- if (!facet_put__(p, facet, flags)) {
- facet->installed = true;
- }
+ struct dpif_flow_stats stats;
+
+ if (facet->may_install
+ && !facet_put__(p, facet, facet->actions, facet->actions_len,
+ zero_stats ? &stats : NULL)) {
+ facet->installed = true;
}
}
/* If the ODP actions changed or the installability changed, then we need
* to talk to the datapath. */
- if (actions_changed || facet->may_install != facet->installed) {
- if (facet->may_install) {
- uint32_t keybuf[ODPUTIL_FLOW_KEY_U32S];
+ if (actions_changed || ctx.may_set_up_flow != facet->installed) {
+ if (ctx.may_set_up_flow) {
struct dpif_flow_stats stats;
- struct ofpbuf key;
-
- ofpbuf_use_stack(&key, keybuf, sizeof keybuf);
- odp_flow_key_from_flow(&key, &facet->flow);
-
- dpif_flow_put(ofproto->dpif,
- ODPPF_CREATE | ODPPF_MODIFY | ODPPF_ZERO_STATS,
- key.data, key.size,
- odp_actions->data, odp_actions->size, &stats);
+ facet_put__(ofproto, facet,
+ odp_actions->data, odp_actions->size, &stats);
facet_update_stats(ofproto, facet, &stats);
} else {
facet_uninstall(ofproto, facet);
ofpbuf_clear(&key);
odp_flow_key_from_flow(&key, &facet->flow);
- dpif_flow_get(p->dpif, 0, key.data, key.size, NULL, &stats);
+ dpif_flow_get(p->dpif, key.data, key.size, NULL, &stats);
packet_count += stats.n_packets + facet->packet_count;
byte_count += stats.n_bytes + facet->byte_count;
netflow_active_timeout_expired(ofproto->netflow, &facet->nf_flow)) {
struct ofexpired expired;
- expired.flow = facet->flow;
- expired.packet_count = facet->packet_count;
- expired.byte_count = facet->byte_count;
- expired.used = facet->used;
-
- /* Get updated flow stats.
- *
- * XXX We could avoid this call entirely if (1) ofproto_update_used()
- * updated TCP flags and (2) the dpif_flow_list_all() in
- * ofproto_update_used() zeroed TCP flags. */
if (facet->installed) {
- uint32_t keybuf[ODPUTIL_FLOW_KEY_U32S];
struct dpif_flow_stats stats;
- struct ofpbuf key;
-
- ofpbuf_use_stack(&key, keybuf, sizeof keybuf);
- odp_flow_key_from_flow(&key, &facet->flow);
-
- if (!dpif_flow_get(ofproto->dpif, ODPFF_ZERO_TCP_FLAGS,
- key.data, key.size, NULL, &stats)) {
- expired.packet_count += stats.n_packets;
- expired.byte_count += stats.n_bytes;
- if (stats.n_packets) {
- facet_update_time(ofproto, facet, &stats);
- netflow_flow_update_flags(&facet->nf_flow,
- stats.tcp_flags);
- }
- }
+
+ facet_put__(ofproto, facet, facet->actions, facet->actions_len,
+ &stats);
+ facet_update_stats(ofproto, facet, &stats);
}
+ expired.flow = facet->flow;
+ expired.packet_count = facet->packet_count;
+ expired.byte_count = facet->byte_count;
+ expired.used = facet->used;
netflow_expire(ofproto->netflow, &facet->nf_flow, &expired);
}
}