ofproto: Retrieve ipfix, sflow and netflow in xlate_receive().
[sliver-openvswitch.git] / ofproto / ofproto-dpif-xlate.c
index 24bade1..cea4658 100644 (file)
@@ -76,6 +76,7 @@ struct xbridge {
     struct mbridge *mbridge;      /* Mirroring. */
     struct dpif_sflow *sflow;     /* SFlow handle, or null. */
     struct dpif_ipfix *ipfix;     /* Ipfix handle, or null. */
+    struct netflow *netflow;      /* Netflow handle, or null. */
     struct stp *stp;              /* STP or null if disabled. */
 
     /* Special rules installed by ofproto-dpif. */
@@ -83,7 +84,6 @@ struct xbridge {
     struct rule_dpif *no_packet_in_rule;
 
     enum ofp_config_flags frag;   /* Fragmentation handling. */
-    bool has_netflow;             /* Bridge runs netflow? */
     bool has_in_band;             /* Bridge has in band control? */
     bool forward_bpdu;            /* Bridge forwards STP BPDUs? */
 };
@@ -246,8 +246,9 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name,
                   const struct mac_learning *ml, struct stp *stp,
                   const struct mbridge *mbridge,
                   const struct dpif_sflow *sflow,
-                  const struct dpif_ipfix *ipfix, enum ofp_config_flags frag,
-                  bool forward_bpdu, bool has_in_band, bool has_netflow)
+                  const struct dpif_ipfix *ipfix,
+                  const struct netflow *netflow, enum ofp_config_flags frag,
+                  bool forward_bpdu, bool has_in_band)
 {
     struct xbridge *xbridge = xbridge_lookup(ofproto);
 
@@ -285,13 +286,17 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name,
         xbridge->stp = stp_ref(stp);
     }
 
+    if (xbridge->netflow != netflow) {
+        netflow_unref(xbridge->netflow);
+        xbridge->netflow = netflow_ref(netflow);
+    }
+
     free(xbridge->name);
     xbridge->name = xstrdup(name);
 
     xbridge->dpif = dpif;
     xbridge->forward_bpdu = forward_bpdu;
     xbridge->has_in_band = has_in_band;
-    xbridge->has_netflow = has_netflow;
     xbridge->frag = frag;
     xbridge->miss_rule = miss_rule;
     xbridge->no_packet_in_rule = no_packet_in_rule;
@@ -509,8 +514,10 @@ xlate_ofport_remove(struct ofport_dpif *ofport)
  * respectively), populates 'flow' with the result of odp_flow_key_to_flow().
  * Optionally, if nonnull, populates 'fitnessp' with the fitness of 'flow' as
  * returned by odp_flow_key_to_flow().  Also, optionally populates 'ofproto'
- * with the ofproto_dpif, and 'odp_in_port' with the datapath in_port, that
- * 'packet' ingressed.
+ * with the ofproto_dpif, 'odp_in_port' with the datapath in_port, that
+ * 'packet' ingressed, and 'ipfix', 'sflow', and 'netflow' with the appropriate
+ * handles for those protocols if they're enabled.  Caller is responsible for
+ * unrefing them.
  *
  * If 'ofproto' is nonnull, requires 'flow''s in_port to exist.  Otherwise sets
  * 'flow''s in_port to OFPP_NONE.
@@ -532,7 +539,9 @@ int
 xlate_receive(const struct dpif_backer *backer, struct ofpbuf *packet,
               const struct nlattr *key, size_t key_len,
               struct flow *flow, enum odp_key_fitness *fitnessp,
-              struct ofproto_dpif **ofproto, odp_port_t *odp_in_port)
+              struct ofproto_dpif **ofproto, struct dpif_ipfix **ipfix,
+              struct dpif_sflow **sflow, struct netflow **netflow,
+              odp_port_t *odp_in_port)
 {
     enum odp_key_fitness fitness;
     const struct xport *xport;
@@ -586,6 +595,18 @@ xlate_receive(const struct dpif_backer *backer, struct ofpbuf *packet,
         *ofproto = xport->xbridge->ofproto;
     }
 
+    if (ipfix) {
+        *ipfix = dpif_ipfix_ref(xport->xbridge->ipfix);
+    }
+
+    if (sflow) {
+        *sflow = dpif_sflow_ref(xport->xbridge->sflow);
+    }
+
+    if (netflow) {
+        *netflow = netflow_ref(xport->xbridge->netflow);
+    }
+
 exit:
     if (fitnessp) {
         *fitnessp = fitness;
@@ -1718,6 +1739,9 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
         if (ctx->xin->resubmit_stats) {
             netdev_vport_inc_tx(xport->netdev, ctx->xin->resubmit_stats);
             netdev_vport_inc_rx(peer->netdev, ctx->xin->resubmit_stats);
+            if (peer->bfd) {
+                bfd_account_rx(peer->bfd, ctx->xin->resubmit_stats);
+            }
         }
 
         return;
@@ -2902,44 +2926,6 @@ xlate_out_copy(struct xlate_out *dst, const struct xlate_out *src)
     ofpbuf_put(&dst->odp_actions, src->odp_actions.data,
                src->odp_actions.size);
 }
-
-/* Returns a reference to the sflow handled associated with ofproto, or NULL if
- * there is none.  The caller is responsible for decrementing the results ref
- * count with dpif_sflow_unref(). */
-struct dpif_sflow *
-xlate_get_sflow(const struct ofproto_dpif *ofproto)
-{
-    struct dpif_sflow *sflow = NULL;
-    struct xbridge *xbridge;
-
-    ovs_rwlock_rdlock(&xlate_rwlock);
-    xbridge = xbridge_lookup(ofproto);
-    if (xbridge) {
-        sflow = dpif_sflow_ref(xbridge->sflow);
-    }
-    ovs_rwlock_unlock(&xlate_rwlock);
-
-    return sflow;
-}
-
-/* Returns a reference to the ipfix handled associated with ofproto, or NULL if
- * there is none.  The caller is responsible for decrementing the results ref
- * count with dpif_ipfix_unref(). */
-struct dpif_ipfix *
-xlate_get_ipfix(const struct ofproto_dpif *ofproto)
-{
-    struct dpif_ipfix *ipfix = NULL;
-    struct xbridge *xbridge;
-
-    ovs_rwlock_rdlock(&xlate_rwlock);
-    xbridge = xbridge_lookup(ofproto);
-    if (xbridge) {
-        ipfix = dpif_ipfix_ref(xbridge->ipfix);
-    }
-    ovs_rwlock_unlock(&xlate_rwlock);
-
-    return ipfix;
-}
 \f
 static struct skb_priority_to_dscp *
 get_skb_priority(const struct xport *xport, uint32_t skb_priority)
@@ -3077,7 +3063,7 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out *xout)
     wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
 
     tnl_may_send = tnl_xlate_init(&ctx.base_flow, flow, wc);
-    if (ctx.xbridge->has_netflow) {
+    if (ctx.xbridge->netflow) {
         netflow_mask_wc(flow, wc);
     }
 
@@ -3200,8 +3186,7 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out *xout)
 
     /* Clear the metadata and register wildcard masks, because we won't
      * use non-header fields as part of the cache. */
-    memset(&wc->masks.metadata, 0, sizeof wc->masks.metadata);
-    memset(&wc->masks.regs, 0, sizeof wc->masks.regs);
+    flow_wildcards_clear_non_packet_fields(wc);
 
 out:
     rule_actions_unref(actions);