[ovs-dev] [PATCH v2 09/15] ofproto-dpif-xlate: Expose xlate cache.

Jarno Rajahalme jarno at ovn.org
Mon Aug 22 23:31:35 UTC 2016


Later patches will need to create xlate cache entries from different
modules.  This patch refactors the xlate cache code in preparation
without any functional changes, so that the changes are clearly
visible in the following patches.

Signed-off-by: Jarno Rajahalme <jarno at ovn.org>
---
 ofproto/ofproto-dpif-xlate.c | 269 ++++++++++++++++---------------------------
 ofproto/ofproto-dpif-xlate.h |  80 ++++++++++++-
 2 files changed, 180 insertions(+), 169 deletions(-)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 893c033..2e89845 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -448,83 +448,6 @@ struct skb_priority_to_dscp {
     uint8_t dscp;               /* DSCP bits to mark outgoing traffic with. */
 };
 
-enum xc_type {
-    XC_RULE,
-    XC_BOND,
-    XC_NETDEV,
-    XC_NETFLOW,
-    XC_MIRROR,
-    XC_LEARN,
-    XC_NORMAL,
-    XC_FIN_TIMEOUT,
-    XC_GROUP,
-    XC_TNL_NEIGH,
-};
-
-/* xlate_cache entries hold enough information to perform the side effects of
- * xlate_actions() for a rule, without needing to perform rule translation
- * from scratch. The primary usage of these is to submit statistics to objects
- * that a flow relates to, although they may be used for other effects as well
- * (for instance, refreshing hard timeouts for learned flows). */
-struct xc_entry {
-    enum xc_type type;
-    union {
-        struct rule_dpif *rule;
-        struct {
-            struct netdev *tx;
-            struct netdev *rx;
-            struct bfd *bfd;
-        } dev;
-        struct {
-            struct netflow *netflow;
-            struct flow *flow;
-            ofp_port_t iface;
-        } nf;
-        struct {
-            struct mbridge *mbridge;
-            mirror_mask_t mirrors;
-        } mirror;
-        struct {
-            struct bond *bond;
-            struct flow *flow;
-            uint16_t vid;
-        } bond;
-        struct {
-            struct ofproto_dpif *ofproto;
-            struct ofputil_flow_mod *fm;
-            struct ofpbuf *ofpacts;
-        } learn;
-        struct {
-            struct ofproto_dpif *ofproto;
-            struct flow *flow;
-            int vlan;
-        } normal;
-        struct {
-            struct rule_dpif *rule;
-            uint16_t idle;
-            uint16_t hard;
-        } fin;
-        struct {
-            struct group_dpif *group;
-            struct ofputil_bucket *bucket;
-        } group;
-        struct {
-            char br_name[IFNAMSIZ];
-            struct in6_addr d_ipv6;
-        } tnl_neigh_cache;
-    } u;
-};
-
-#define XC_ENTRY_FOR_EACH(ENTRY, ENTRIES, XCACHE)               \
-    ENTRIES = XCACHE->entries;                                  \
-    for (ENTRY = ofpbuf_try_pull(&ENTRIES, sizeof *ENTRY);      \
-         ENTRY;                                                 \
-         ENTRY = ofpbuf_try_pull(&ENTRIES, sizeof *ENTRY))
-
-struct xlate_cache {
-    struct ofpbuf entries;
-};
-
 /* Xlate config contains hash maps of all bridges, bundles and ports.
  * Xcfgp contains the pointer to the current xlate configuration.
  * When the main thread needs to change the configuration, it copies xcfgp to
@@ -578,8 +501,6 @@ static size_t count_skb_priorities(const struct xport *);
 static bool dscp_from_skb_priority(const struct xport *, uint32_t skb_priority,
                                    uint8_t *dscp);
 
-static struct xc_entry *xlate_cache_add_entry(struct xlate_cache *xc,
-                                              enum xc_type type);
 static void xlate_xbridge_init(struct xlate_cfg *, struct xbridge *);
 static void xlate_xbundle_init(struct xlate_cfg *, struct xbundle *);
 static void xlate_xport_init(struct xlate_cfg *, struct xport *);
@@ -5776,7 +5697,7 @@ xlate_cache_new(void)
     return xcache;
 }
 
-static struct xc_entry *
+struct xc_entry *
 xlate_cache_add_entry(struct xlate_cache *xcache, enum xc_type type)
 {
     struct xc_entry *entry;
@@ -5825,61 +5746,68 @@ xlate_cache_normal(struct ofproto_dpif *ofproto, struct flow *flow, int vlan)
 
 /* Push stats and perform side effects of flow translation. */
 void
-xlate_push_stats(struct xlate_cache *xcache,
-                 const struct dpif_flow_stats *stats)
+xlate_push_stats_entry(struct xc_entry *entry,
+                       const struct dpif_flow_stats *stats)
 {
-    struct xc_entry *entry;
-    struct ofpbuf entries = xcache->entries;
     struct eth_addr dmac;
 
+    switch (entry->type) {
+    case XC_RULE:
+        rule_dpif_credit_stats(entry->u.rule, stats);
+        break;
+    case XC_BOND:
+        bond_account(entry->u.bond.bond, entry->u.bond.flow,
+                     entry->u.bond.vid, stats->n_bytes);
+        break;
+    case XC_NETDEV:
+        xlate_cache_netdev(entry, stats);
+        break;
+    case XC_NETFLOW:
+        netflow_flow_update(entry->u.nf.netflow, entry->u.nf.flow,
+                            entry->u.nf.iface, stats);
+        break;
+    case XC_MIRROR:
+        mirror_update_stats(entry->u.mirror.mbridge,
+                            entry->u.mirror.mirrors,
+                            stats->n_packets, stats->n_bytes);
+        break;
+    case XC_LEARN:
+        ofproto_dpif_flow_mod(entry->u.learn.ofproto, entry->u.learn.fm);
+        break;
+    case XC_NORMAL:
+        xlate_cache_normal(entry->u.normal.ofproto, entry->u.normal.flow,
+                           entry->u.normal.vlan);
+        break;
+    case XC_FIN_TIMEOUT:
+        xlate_fin_timeout__(entry->u.fin.rule, stats->tcp_flags,
+                            entry->u.fin.idle, entry->u.fin.hard);
+        break;
+    case XC_GROUP:
+        group_dpif_credit_stats(entry->u.group.group, entry->u.group.bucket,
+                                stats);
+        break;
+    case XC_TNL_NEIGH:
+        /* Lookup neighbor to avoid timeout. */
+        tnl_neigh_lookup(entry->u.tnl_neigh_cache.br_name,
+                         &entry->u.tnl_neigh_cache.d_ipv6, &dmac);
+        break;
+    default:
+        OVS_NOT_REACHED();
+    }
+}
+
+void
+xlate_push_stats(struct xlate_cache *xcache,
+                 const struct dpif_flow_stats *stats)
+{
     if (!stats->n_packets) {
         return;
     }
 
-    XC_ENTRY_FOR_EACH (entry, entries, xcache) {
-        switch (entry->type) {
-        case XC_RULE:
-            rule_dpif_credit_stats(entry->u.rule, stats);
-            break;
-        case XC_BOND:
-            bond_account(entry->u.bond.bond, entry->u.bond.flow,
-                         entry->u.bond.vid, stats->n_bytes);
-            break;
-        case XC_NETDEV:
-            xlate_cache_netdev(entry, stats);
-            break;
-        case XC_NETFLOW:
-            netflow_flow_update(entry->u.nf.netflow, entry->u.nf.flow,
-                                entry->u.nf.iface, stats);
-            break;
-        case XC_MIRROR:
-            mirror_update_stats(entry->u.mirror.mbridge,
-                                entry->u.mirror.mirrors,
-                                stats->n_packets, stats->n_bytes);
-            break;
-        case XC_LEARN:
-            ofproto_dpif_flow_mod(entry->u.learn.ofproto, entry->u.learn.fm);
-            break;
-        case XC_NORMAL:
-            xlate_cache_normal(entry->u.normal.ofproto, entry->u.normal.flow,
-                               entry->u.normal.vlan);
-            break;
-        case XC_FIN_TIMEOUT:
-            xlate_fin_timeout__(entry->u.fin.rule, stats->tcp_flags,
-                                entry->u.fin.idle, entry->u.fin.hard);
-            break;
-        case XC_GROUP:
-            group_dpif_credit_stats(entry->u.group.group, entry->u.group.bucket,
-                                    stats);
-            break;
-        case XC_TNL_NEIGH:
-            /* Lookup neighbor to avoid timeout. */
-            tnl_neigh_lookup(entry->u.tnl_neigh_cache.br_name,
-                             &entry->u.tnl_neigh_cache.d_ipv6, &dmac);
-            break;
-        default:
-            OVS_NOT_REACHED();
-        }
+    struct xc_entry *entry;
+    struct ofpbuf entries = xcache->entries;
+    XC_ENTRY_FOR_EACH (entry, &entries) {
+        xlate_push_stats_entry(entry, stats);
     }
 }
 
@@ -5906,52 +5834,57 @@ xlate_cache_clear_netflow(struct netflow *netflow, struct flow *flow)
 }
 
 void
-xlate_cache_clear(struct xlate_cache *xcache)
+xlate_cache_clear_entry(struct xc_entry *entry)
 {
-    struct xc_entry *entry;
-    struct ofpbuf entries;
+    switch (entry->type) {
+    case XC_RULE:
+        rule_dpif_unref(entry->u.rule);
+        break;
+    case XC_BOND:
+        free(entry->u.bond.flow);
+        bond_unref(entry->u.bond.bond);
+        break;
+    case XC_NETDEV:
+        xlate_dev_unref(entry);
+        break;
+    case XC_NETFLOW:
+        xlate_cache_clear_netflow(entry->u.nf.netflow, entry->u.nf.flow);
+        break;
+    case XC_MIRROR:
+        mbridge_unref(entry->u.mirror.mbridge);
+        break;
+    case XC_LEARN:
+        free(entry->u.learn.fm);
+        ofpbuf_delete(entry->u.learn.ofpacts);
+        break;
+    case XC_NORMAL:
+        free(entry->u.normal.flow);
+        break;
+    case XC_FIN_TIMEOUT:
+        /* 'u.fin.rule' is always already held as a XC_RULE, which
+         * has already released it's reference above. */
+        break;
+    case XC_GROUP:
+        group_dpif_unref(entry->u.group.group);
+        break;
+    case XC_TNL_NEIGH:
+        break;
+    default:
+        OVS_NOT_REACHED();
+    }
+}
 
+void
+xlate_cache_clear(struct xlate_cache *xcache)
+{
     if (!xcache) {
         return;
     }
 
-    XC_ENTRY_FOR_EACH (entry, entries, xcache) {
-        switch (entry->type) {
-        case XC_RULE:
-            rule_dpif_unref(entry->u.rule);
-            break;
-        case XC_BOND:
-            free(entry->u.bond.flow);
-            bond_unref(entry->u.bond.bond);
-            break;
-        case XC_NETDEV:
-            xlate_dev_unref(entry);
-            break;
-        case XC_NETFLOW:
-            xlate_cache_clear_netflow(entry->u.nf.netflow, entry->u.nf.flow);
-            break;
-        case XC_MIRROR:
-            mbridge_unref(entry->u.mirror.mbridge);
-            break;
-        case XC_LEARN:
-            free(entry->u.learn.fm);
-            ofpbuf_delete(entry->u.learn.ofpacts);
-            break;
-        case XC_NORMAL:
-            free(entry->u.normal.flow);
-            break;
-        case XC_FIN_TIMEOUT:
-            /* 'u.fin.rule' is always already held as a XC_RULE, which
-             * has already released it's reference above. */
-            break;
-        case XC_GROUP:
-            group_dpif_unref(entry->u.group.group);
-            break;
-        case XC_TNL_NEIGH:
-            break;
-        default:
-            OVS_NOT_REACHED();
-        }
+    struct xc_entry *entry;
+    struct ofpbuf entries = xcache->entries;
+    XC_ENTRY_FOR_EACH (entry, &entries) {
+        xlate_cache_clear_entry(entry);
     }
 
     ofpbuf_clear(&xcache->entries);
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
index 7808a60..776e2ad 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -35,7 +35,82 @@ struct dpif_ipfix;
 struct dpif_sflow;
 struct mac_learning;
 struct mcast_snooping;
-struct xlate_cache;
+
+enum xc_type {
+    XC_RULE,
+    XC_BOND,
+    XC_NETDEV,
+    XC_NETFLOW,
+    XC_MIRROR,
+    XC_LEARN,
+    XC_NORMAL,
+    XC_FIN_TIMEOUT,
+    XC_GROUP,
+    XC_TNL_NEIGH,
+};
+
+/* xlate_cache entries hold enough information to perform the side effects of
+ * xlate_actions() for a rule, without needing to perform rule translation
+ * from scratch. The primary usage of these is to submit statistics to objects
+ * that a flow relates to, although they may be used for other effects as well
+ * (for instance, refreshing hard timeouts for learned flows). */
+struct xc_entry {
+    enum xc_type type;
+    union {
+        struct rule_dpif *rule;
+        struct {
+            struct netdev *tx;
+            struct netdev *rx;
+            struct bfd *bfd;
+        } dev;
+        struct {
+            struct netflow *netflow;
+            struct flow *flow;
+            ofp_port_t iface;
+        } nf;
+        struct {
+            struct mbridge *mbridge;
+            mirror_mask_t mirrors;
+        } mirror;
+        struct {
+            struct bond *bond;
+            struct flow *flow;
+            uint16_t vid;
+        } bond;
+        struct {
+            struct ofproto_dpif *ofproto;
+            struct ofputil_flow_mod *fm;
+            struct ofpbuf *ofpacts;
+        } learn;
+        struct {
+            struct ofproto_dpif *ofproto;
+            struct flow *flow;
+            int vlan;
+        } normal;
+        struct {
+            struct rule_dpif *rule;
+            uint16_t idle;
+            uint16_t hard;
+        } fin;
+        struct {
+            struct group_dpif *group;
+            struct ofputil_bucket *bucket;
+        } group;
+        struct {
+            char br_name[IFNAMSIZ];
+            struct in6_addr d_ipv6;
+        } tnl_neigh_cache;
+    } u;
+};
+
+#define XC_ENTRY_FOR_EACH(ENTRY, ENTRIES)                       \
+    for (ENTRY = ofpbuf_try_pull(ENTRIES, sizeof *ENTRY);       \
+         ENTRY;                                                 \
+         ENTRY = ofpbuf_try_pull(ENTRIES, sizeof *ENTRY))
+
+struct xlate_cache {
+    struct ofpbuf entries;
+};
 
 struct xlate_out {
     enum slow_path_reason slow; /* 0 if fast path may be used. */
@@ -214,7 +289,10 @@ enum ofperr xlate_resume(struct ofproto_dpif *,
 int xlate_send_packet(const struct ofport_dpif *, bool oam, struct dp_packet *);
 
 struct xlate_cache *xlate_cache_new(void);
+struct xc_entry *xlate_cache_add_entry(struct xlate_cache *, enum xc_type);
+void xlate_push_stats_entry(struct xc_entry *, const struct dpif_flow_stats *);
 void xlate_push_stats(struct xlate_cache *, const struct dpif_flow_stats *);
+void xlate_cache_clear_entry(struct xc_entry *);
 void xlate_cache_clear(struct xlate_cache *);
 void xlate_cache_delete(struct xlate_cache *);
 
-- 
2.1.4




More information about the dev mailing list