@@ -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: {
@@ -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;
}
@@ -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;
@@ -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 */
@@ -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,
@@ -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;
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@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(-)