[ovs-dev] [RFC v2 2/4] netdev-offload: Use dpif type instead of class.

Ilya Maximets i.maximets at ovn.org
Fri Nov 15 20:13:47 UTC 2019


There is no real difference between the 'class' and 'type' in the
context of common lookup operations inside netdev-offload module
because it only checks the value of pointers without using the
value itself.  However, 'type' has some meaning and can be used by
offload provides on the initialization phase to check if this type
of Flow API in pair with the netdev type could be used in particular
datapath type.  For example, this is needed to check if Linux flow
API could be used for current tunneling vport because it could be
used only if tunneling vport belongs to system datapath, i.e. has
backing linux interface.

This is needed to unblock tunneling offloads in userspace datapath
with DPDK flow API.

Signed-off-by: Ilya Maximets <i.maximets at ovn.org>
---
 lib/dpif-netlink.c            | 23 +++++++++-------
 lib/dpif.c                    | 21 ++++++++-------
 lib/netdev-offload-tc.c       |  4 +--
 lib/netdev-offload.c          | 51 +++++++++++++++++------------------
 lib/netdev-offload.h          | 16 +++++------
 ofproto/ofproto-dpif-upcall.c |  5 ++--
 6 files changed, 61 insertions(+), 59 deletions(-)

diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index d1f9b81db..55e07c361 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -1072,6 +1072,7 @@ dpif_netlink_port_get_pid(const struct dpif *dpif_, odp_port_t port_no)
 static int
 dpif_netlink_flow_flush(struct dpif *dpif_)
 {
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif_));
     const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
     struct dpif_netlink_flow flow;
 
@@ -1080,7 +1081,7 @@ dpif_netlink_flow_flush(struct dpif *dpif_)
     flow.dp_ifindex = dpif->dp_ifindex;
 
     if (netdev_is_flow_api_enabled()) {
-        netdev_ports_flow_flush(dpif_->dpif_class);
+        netdev_ports_flow_flush(dpif_type_str);
     }
 
     return dpif_netlink_flow_transact(&flow, NULL, NULL);
@@ -1397,7 +1398,7 @@ start_netdev_dump(const struct dpif *dpif_,
     ovs_mutex_lock(&dump->netdev_lock);
     dump->netdev_current_dump = 0;
     dump->netdev_dumps
-        = netdev_ports_flow_dump_create(dpif_->dpif_class,
+        = netdev_ports_flow_dump_create(dpif_normalize_type(dpif_type(dpif_)),
                                         &dump->netdev_dumps_num);
     ovs_mutex_unlock(&dump->netdev_lock);
 }
@@ -1945,6 +1946,7 @@ dpif_netlink_operate__(struct dpif_netlink *dpif,
 static int
 parse_flow_get(struct dpif_netlink *dpif, struct dpif_flow_get *get)
 {
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(&dpif->dpif));
     struct dpif_flow *dpif_flow = get->flow;
     struct match match;
     struct nlattr *actions;
@@ -1959,8 +1961,8 @@ parse_flow_get(struct dpif_netlink *dpif, struct dpif_flow_get *get)
     int err;
 
     ofpbuf_use_stack(&buf, &act_buf, sizeof act_buf);
-    err = netdev_ports_flow_get(dpif->dpif.dpif_class, &match,
-                                &actions, get->ufid, &stats, &attrs, &buf);
+    err = netdev_ports_flow_get(dpif_type_str, &match, &actions, get->ufid,
+                                &stats, &attrs, &buf);
     if (err) {
         return err;
     }
@@ -1985,8 +1987,8 @@ parse_flow_get(struct dpif_netlink *dpif, struct dpif_flow_get *get)
 static int
 parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
 {
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(&dpif->dpif));
     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
-    const struct dpif_class *dpif_class = dpif->dpif.dpif_class;
     struct match match;
     odp_port_t in_port;
     const struct nlattr *nla;
@@ -2008,7 +2010,7 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
     }
 
     in_port = match.flow.in_port.odp_port;
-    dev = netdev_ports_get(in_port, dpif_class);
+    dev = netdev_ports_get(in_port, dpif_type_str);
     if (!dev) {
         return EOPNOTSUPP;
     }
@@ -2021,7 +2023,7 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
             odp_port_t out_port;
 
             out_port = nl_attr_get_odp_port(nla);
-            outdev = netdev_ports_get(out_port, dpif_class);
+            outdev = netdev_ports_get(out_port, dpif_type_str);
             if (!outdev) {
                 err = EOPNOTSUPP;
                 goto out;
@@ -2037,7 +2039,6 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
         }
     }
 
-    info.dpif_class = dpif_class;
     info.tp_dst_port = dst_port;
     info.tunnel_csum_on = csum_on;
     err = netdev_flow_put(dev, &match,
@@ -2135,8 +2136,10 @@ try_send_to_netdev(struct dpif_netlink *dpif, struct dpif_op *op)
         }
 
         log_flow_del_message(&dpif->dpif, &this_module, del, 0);
-        err = netdev_ports_flow_del(dpif->dpif.dpif_class, del->ufid,
-                                    del->stats);
+        err = netdev_ports_flow_del(
+                                dpif_normalize_type(dpif_type(&dpif->dpif)),
+                                del->ufid,
+                                del->stats);
         break;
     }
     case DPIF_OP_FLOW_GET: {
diff --git a/lib/dpif.c b/lib/dpif.c
index c88b2106f..22d5f3ea6 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -347,6 +347,7 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp)
     error = registered_class->dpif_class->open(registered_class->dpif_class,
                                                name, create, &dpif);
     if (!error) {
+        const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
         struct dpif_port_dump port_dump;
         struct dpif_port dpif_port;
 
@@ -363,7 +364,7 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp)
             err = netdev_open(dpif_port.name, dpif_port.type, &netdev);
 
             if (!err) {
-                netdev_ports_insert(netdev, dpif->dpif_class, &dpif_port);
+                netdev_ports_insert(netdev, dpif_type_str, &dpif_port);
                 netdev_close(netdev);
             } else {
                 VLOG_WARN("could not open netdev %s type %s: %s",
@@ -427,14 +428,15 @@ dpif_create_and_open(const char *name, const char *type, struct dpif **dpifp)
 
 static void
 dpif_remove_netdev_ports(struct dpif *dpif) {
-        struct dpif_port_dump port_dump;
-        struct dpif_port dpif_port;
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
+    struct dpif_port_dump port_dump;
+    struct dpif_port dpif_port;
 
-        DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
-            if (!dpif_is_tap_port(dpif_port.type)) {
-                netdev_ports_remove(dpif_port.port_no, dpif->dpif_class);
-            }
+    DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
+        if (!dpif_is_tap_port(dpif_port.type)) {
+            netdev_ports_remove(dpif_port.port_no, dpif_type_str);
         }
+    }
 }
 
 /* Closes and frees the connection to 'dpif'.  Does not destroy the datapath
@@ -588,12 +590,13 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, odp_port_t *port_nop)
 
         if (!dpif_is_tap_port(netdev_get_type(netdev))) {
 
+            const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
             struct dpif_port dpif_port;
 
             dpif_port.type = CONST_CAST(char *, netdev_get_type(netdev));
             dpif_port.name = CONST_CAST(char *, netdev_name);
             dpif_port.port_no = port_no;
-            netdev_ports_insert(netdev, dpif->dpif_class, &dpif_port);
+            netdev_ports_insert(netdev, dpif_type_str, &dpif_port);
         }
     } else {
         VLOG_WARN_RL(&error_rl, "%s: failed to add %s as port: %s",
@@ -625,7 +628,7 @@ dpif_port_del(struct dpif *dpif, odp_port_t port_no, bool local_delete)
         }
     }
 
-    netdev_ports_remove(port_no, dpif->dpif_class);
+    netdev_ports_remove(port_no, dpif_normalize_type(dpif_type(dpif)));
     return error;
 }
 
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 1adbb325b..dee82aa9a 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -1368,8 +1368,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
         action = &flower.actions[flower.action_count];
         if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) {
             odp_port_t port = nl_attr_get_odp_port(nla);
-            struct netdev *outdev = netdev_ports_get(port, info->dpif_class);
-
+            struct netdev *outdev = netdev_ports_get(
+                                        port, netdev_get_dpif_type(netdev));
             action->out.ifindex_out = netdev_get_ifindex(outdev);
             action->out.ingress = is_internal_port(netdev_get_type(outdev));
             action->type = TC_ACT_OUTPUT;
diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
index ae01acda6..00fb083fc 100644
--- a/lib/netdev-offload.c
+++ b/lib/netdev-offload.c
@@ -370,11 +370,10 @@ static struct hmap ifindex_to_port OVS_GUARDED_BY(netdev_hmap_rwlock)
     = HMAP_INITIALIZER(&ifindex_to_port);
 
 struct port_to_netdev_data {
-    struct hmap_node portno_node; /* By (dpif_class, dpif_port.port_no). */
-    struct hmap_node ifindex_node; /* By (dpif_class, ifindex). */
+    struct hmap_node portno_node; /* By (dpif_type, dpif_port.port_no). */
+    struct hmap_node ifindex_node; /* By (dpif_type, ifindex). */
     struct netdev *netdev;
     struct dpif_port dpif_port;
-    const struct dpif_class *dpif_class;
     int ifindex;
 };
 
@@ -410,13 +409,13 @@ netdev_is_flow_api_enabled(void)
 }
 
 void
-netdev_ports_flow_flush(const struct dpif_class *dpif_class)
+netdev_ports_flow_flush(const char *dpif_type)
 {
     struct port_to_netdev_data *data;
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class) {
+        if (netdev_get_dpif_type(data->netdev) == dpif_type) {
             netdev_flow_flush(data->netdev);
         }
     }
@@ -424,7 +423,7 @@ netdev_ports_flow_flush(const struct dpif_class *dpif_class)
 }
 
 struct netdev_flow_dump **
-netdev_ports_flow_dump_create(const struct dpif_class *dpif_class, int *ports)
+netdev_ports_flow_dump_create(const char *dpif_type, int *ports)
 {
     struct port_to_netdev_data *data;
     struct netdev_flow_dump **dumps;
@@ -433,7 +432,7 @@ netdev_ports_flow_dump_create(const struct dpif_class *dpif_class, int *ports)
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class) {
+        if (netdev_get_dpif_type(data->netdev) == dpif_type) {
             count++;
         }
     }
@@ -441,7 +440,7 @@ netdev_ports_flow_dump_create(const struct dpif_class *dpif_class, int *ports)
     dumps = count ? xzalloc(sizeof *dumps * count) : NULL;
 
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class) {
+        if (netdev_get_dpif_type(data->netdev) == dpif_type) {
             if (netdev_flow_dump_create(data->netdev, &dumps[i])) {
                 continue;
             }
@@ -457,15 +456,14 @@ netdev_ports_flow_dump_create(const struct dpif_class *dpif_class, int *ports)
 }
 
 int
-netdev_ports_flow_del(const struct dpif_class *dpif_class,
-                      const ovs_u128 *ufid,
+netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid,
                       struct dpif_flow_stats *stats)
 {
     struct port_to_netdev_data *data;
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class
+        if (netdev_get_dpif_type(data->netdev) == dpif_type
             && !netdev_flow_del(data->netdev, ufid, stats)) {
             ovs_rwlock_unlock(&netdev_hmap_rwlock);
             return 0;
@@ -477,7 +475,7 @@ netdev_ports_flow_del(const struct dpif_class *dpif_class,
 }
 
 int
-netdev_ports_flow_get(const struct dpif_class *dpif_class, struct match *match,
+netdev_ports_flow_get(const char *dpif_type, struct match *match,
                       struct nlattr **actions, const ovs_u128 *ufid,
                       struct dpif_flow_stats *stats,
                       struct dpif_flow_attrs *attrs, struct ofpbuf *buf)
@@ -486,7 +484,7 @@ netdev_ports_flow_get(const struct dpif_class *dpif_class, struct match *match,
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
     HMAP_FOR_EACH (data, portno_node, &port_to_netdev) {
-        if (data->dpif_class == dpif_class
+        if (netdev_get_dpif_type(data->netdev) == dpif_type
             && !netdev_flow_get(data->netdev, match, actions,
                                 ufid, stats, attrs, buf)) {
             ovs_rwlock_unlock(&netdev_hmap_rwlock);
@@ -498,21 +496,21 @@ netdev_ports_flow_get(const struct dpif_class *dpif_class, struct match *match,
 }
 
 static uint32_t
-netdev_ports_hash(odp_port_t port, const struct dpif_class *dpif_class)
+netdev_ports_hash(odp_port_t port, const char *dpif_type)
 {
-    return hash_int(odp_to_u32(port), hash_pointer(dpif_class, 0));
+    return hash_int(odp_to_u32(port), hash_pointer(dpif_type, 0));
 }
 
 static struct port_to_netdev_data *
-netdev_ports_lookup(odp_port_t port_no, const struct dpif_class *dpif_class)
+netdev_ports_lookup(odp_port_t port_no, const char *dpif_type)
     OVS_REQ_RDLOCK(netdev_hmap_rwlock)
 {
     struct port_to_netdev_data *data;
 
     HMAP_FOR_EACH_WITH_HASH (data, portno_node,
-                             netdev_ports_hash(port_no, dpif_class),
+                             netdev_ports_hash(port_no, dpif_type),
                              &port_to_netdev) {
-        if (data->dpif_class == dpif_class
+        if (netdev_get_dpif_type(data->netdev) == dpif_type
             && data->dpif_port.port_no == port_no) {
             return data;
         }
@@ -521,7 +519,7 @@ netdev_ports_lookup(odp_port_t port_no, const struct dpif_class *dpif_class)
 }
 
 int
-netdev_ports_insert(struct netdev *netdev, const struct dpif_class *dpif_class,
+netdev_ports_insert(struct netdev *netdev, const char *dpif_type,
                     struct dpif_port *dpif_port)
 {
     struct port_to_netdev_data *data;
@@ -532,19 +530,20 @@ netdev_ports_insert(struct netdev *netdev, const struct dpif_class *dpif_class,
     }
 
     ovs_rwlock_wrlock(&netdev_hmap_rwlock);
-    if (netdev_ports_lookup(dpif_port->port_no, dpif_class)) {
+    if (netdev_ports_lookup(dpif_port->port_no, dpif_type)) {
         ovs_rwlock_unlock(&netdev_hmap_rwlock);
         return EEXIST;
     }
 
     data = xzalloc(sizeof *data);
     data->netdev = netdev_ref(netdev);
-    data->dpif_class = dpif_class;
     dpif_port_clone(&data->dpif_port, dpif_port);
     data->ifindex = ifindex;
 
+    netdev_set_dpif_type(netdev, dpif_type);
+
     hmap_insert(&port_to_netdev, &data->portno_node,
-                netdev_ports_hash(dpif_port->port_no, dpif_class));
+                netdev_ports_hash(dpif_port->port_no, dpif_type));
     hmap_insert(&ifindex_to_port, &data->ifindex_node, ifindex);
     ovs_rwlock_unlock(&netdev_hmap_rwlock);
 
@@ -554,13 +553,13 @@ netdev_ports_insert(struct netdev *netdev, const struct dpif_class *dpif_class,
 }
 
 struct netdev *
-netdev_ports_get(odp_port_t port_no, const struct dpif_class *dpif_class)
+netdev_ports_get(odp_port_t port_no, const char *dpif_type)
 {
     struct port_to_netdev_data *data;
     struct netdev *ret = NULL;
 
     ovs_rwlock_rdlock(&netdev_hmap_rwlock);
-    data = netdev_ports_lookup(port_no, dpif_class);
+    data = netdev_ports_lookup(port_no, dpif_type);
     if (data) {
         ret = netdev_ref(data->netdev);
     }
@@ -570,13 +569,13 @@ netdev_ports_get(odp_port_t port_no, const struct dpif_class *dpif_class)
 }
 
 int
-netdev_ports_remove(odp_port_t port_no, const struct dpif_class *dpif_class)
+netdev_ports_remove(odp_port_t port_no, const char *dpif_type)
 {
     struct port_to_netdev_data *data;
     int ret = ENOENT;
 
     ovs_rwlock_wrlock(&netdev_hmap_rwlock);
-    data = netdev_ports_lookup(port_no, dpif_class);
+    data = netdev_ports_lookup(port_no, dpif_type);
     if (data) {
         dpif_port_destroy(&data->dpif_port);
         netdev_close(data->netdev); /* unref and possibly close */
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index 97a500647..c04845644 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -62,7 +62,6 @@ struct netdev_flow_dump {
 
 /* Flow offloading. */
 struct offload_info {
-    const struct dpif_class *dpif_class;
     ovs_be16 tp_dst_port; /* Destination port for tunnel in SET action */
     uint8_t tunnel_csum_on; /* Tunnel header with checksum */
 
@@ -98,21 +97,20 @@ bool netdev_is_flow_api_enabled(void);
 void netdev_set_flow_api_enabled(const struct smap *ovs_other_config);
 bool netdev_is_offload_rebalance_policy_enabled(void);
 
-struct dpif_class;
 struct dpif_port;
-int netdev_ports_insert(struct netdev *, const struct dpif_class *,
+int netdev_ports_insert(struct netdev *, const char *dpif_type,
                         struct dpif_port *);
-struct netdev *netdev_ports_get(odp_port_t port, const struct dpif_class *);
-int netdev_ports_remove(odp_port_t port, const struct dpif_class *);
+struct netdev *netdev_ports_get(odp_port_t port, const char *dpif_type);
+int netdev_ports_remove(odp_port_t port, const char *dpif_type);
 odp_port_t netdev_ifindex_to_odp_port(int ifindex);
 
 struct netdev_flow_dump **netdev_ports_flow_dump_create(
-                                        const struct dpif_class *,
+                                        const char *dpif_type,
                                         int *ports);
-void netdev_ports_flow_flush(const struct dpif_class *);
-int netdev_ports_flow_del(const struct dpif_class *, const ovs_u128 *ufid,
+void netdev_ports_flow_flush(const char *dpif_type);
+int netdev_ports_flow_del(const char *dpif_type, const ovs_u128 *ufid,
                           struct dpif_flow_stats *stats);
-int netdev_ports_flow_get(const struct dpif_class *, struct match *match,
+int netdev_ports_flow_get(const char *dpif_type, struct match *match,
                           struct nlattr **actions,
                           const ovs_u128 *ufid,
                           struct dpif_flow_stats *stats,
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 657aa7f79..221bb3505 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -2505,8 +2505,7 @@ ukey_netdev_unref(struct udpif_key *ukey)
 static void
 ukey_to_flow_netdev(struct udpif *udpif, struct udpif_key *ukey)
 {
-    const struct dpif *dpif = udpif->dpif;
-    const struct dpif_class *dpif_class = dpif->dpif_class;
+    const char *dpif_type_str = dpif_normalize_type(dpif_type(udpif->dpif));
     const struct nlattr *k;
     unsigned int left;
 
@@ -2519,7 +2518,7 @@ ukey_to_flow_netdev(struct udpif *udpif, struct udpif_key *ukey)
 
         if (type == OVS_KEY_ATTR_IN_PORT) {
             ukey->in_netdev = netdev_ports_get(nl_attr_get_odp_port(k),
-                                               dpif_class);
+                                               dpif_type_str);
         } else if (type == OVS_KEY_ATTR_TUNNEL) {
             struct flow_tnl tnl;
             enum odp_key_fitness res;
-- 
2.17.1



More information about the dev mailing list