@@ -101,12 +101,9 @@ static bool should_log_flow_message(const struct vlog_module *module,
struct seq *tnl_conf_seq;
static bool
-dpif_is_internal_port(const char *type)
+dpif_is_tap_port(const char *type)
{
- /* For userspace datapath, tap devices are the equivalent
- * of internal devices in the kernel datapath, so both
- * these types are 'internal' devices. */
- return !strcmp(type, "internal") || !strcmp(type, "tap");
+ return !strcmp(type, "tap");
}
static void
@@ -359,7 +356,7 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp)
struct netdev *netdev;
int err;
- if (dpif_is_internal_port(dpif_port.type)) {
+ if (dpif_is_tap_port(dpif_port.type)) {
continue;
}
@@ -434,7 +431,7 @@ dpif_remove_netdev_ports(struct dpif *dpif) {
struct dpif_port dpif_port;
DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
- if (!dpif_is_internal_port(dpif_port.type)) {
+ if (!dpif_is_tap_port(dpif_port.type)) {
netdev_ports_remove(dpif_port.port_no, dpif->dpif_class);
}
}
@@ -582,7 +579,7 @@ dpif_port_add(struct dpif *dpif, struct netdev *netdev, odp_port_t *port_nop)
VLOG_DBG_RL(&dpmsg_rl, "%s: added %s as port %"PRIu32,
dpif_name(dpif), netdev_name, port_no);
- if (!dpif_is_internal_port(netdev_get_type(netdev))) {
+ if (!dpif_is_tap_port(netdev_get_type(netdev))) {
struct dpif_port dpif_port;
@@ -3339,6 +3339,7 @@ const struct netdev_class netdev_tap_class = {
const struct netdev_class netdev_internal_class = {
NETDEV_LINUX_CLASS_COMMON,
+ LINUX_FLOW_OFFLOAD_API,
.type = "internal",
.construct = netdev_linux_construct,
.get_stats = netdev_internal_get_stats,
@@ -185,11 +185,12 @@ del_ufid_tc_mapping(const ovs_u128 *ufid)
/* Wrapper function to delete filter and ufid tc mapping */
static int
del_filter_and_ufid_mapping(int ifindex, int prio, int handle,
- uint32_t block_id, const ovs_u128 *ufid)
+ uint32_t block_id, const ovs_u128 *ufid,
+ bool egress)
{
int err;
- err = tc_del_filter(ifindex, prio, handle, block_id, false);
+ err = tc_del_filter(ifindex, prio, handle, block_id, egress);
del_ufid_tc_mapping(ufid);
return err;
@@ -346,6 +347,7 @@ get_block_id_from_netdev(struct netdev *netdev)
int
netdev_tc_flow_flush(struct netdev *netdev)
{
+ bool egress = is_internal_port(netdev_get_type(netdev));
int ifindex = netdev_get_ifindex(netdev);
uint32_t block_id = 0;
@@ -357,13 +359,14 @@ netdev_tc_flow_flush(struct netdev *netdev)
block_id = get_block_id_from_netdev(netdev);
- return tc_flush(ifindex, block_id, false);
+ return tc_flush(ifindex, block_id, egress);
}
int
netdev_tc_flow_dump_create(struct netdev *netdev,
struct netdev_flow_dump **dump_out)
{
+ bool egress = is_internal_port(netdev_get_type(netdev));
struct netdev_flow_dump *dump;
uint32_t block_id = 0;
int ifindex;
@@ -379,7 +382,7 @@ netdev_tc_flow_dump_create(struct netdev *netdev,
dump = xzalloc(sizeof *dump);
dump->nl_dump = xzalloc(sizeof *dump->nl_dump);
dump->netdev = netdev_ref(netdev);
- tc_dump_flower_start(ifindex, dump->nl_dump, block_id, false);
+ tc_dump_flower_start(ifindex, dump->nl_dump, block_id, egress);
*dump_out = dump;
@@ -1080,6 +1083,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
struct dpif_flow_stats *stats OVS_UNUSED)
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
+ bool egress = is_internal_port(netdev_get_type(netdev));
struct tc_flower flower;
const struct flow *key = &match->flow;
struct flow *mask = &match->wc.masks;
@@ -1342,7 +1346,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
handle = get_ufid_tc_mapping(ufid, &prio, NULL);
if (handle && prio) {
VLOG_DBG_RL(&rl, "updating old handle: %d prio: %d", handle, prio);
- del_filter_and_ufid_mapping(ifindex, prio, handle, block_id, ufid);
+ del_filter_and_ufid_mapping(ifindex, prio, handle, block_id, ufid,
+ egress);
}
if (!prio) {
@@ -1356,7 +1361,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
flower.act_cookie.data = ufid;
flower.act_cookie.len = sizeof *ufid;
- err = tc_replace_flower(ifindex, prio, handle, &flower, block_id, false);
+ err = tc_replace_flower(ifindex, prio, handle, &flower, block_id, egress);
if (!err) {
add_ufid_tc_mapping(ufid, flower.prio, flower.handle, netdev, ifindex);
}
@@ -1380,6 +1385,7 @@ netdev_tc_flow_get(struct netdev *netdev OVS_UNUSED,
odp_port_t in_port;
int prio = 0;
int ifindex;
+ bool egress;
int handle;
int err;
@@ -1388,6 +1394,7 @@ netdev_tc_flow_get(struct netdev *netdev OVS_UNUSED,
return ENOENT;
}
+ egress = is_internal_port(netdev_get_type(netdev));
ifindex = netdev_get_ifindex(dev);
if (ifindex < 0) {
VLOG_ERR_RL(&error_rl, "flow_get: failed to get ifindex for %s: %s",
@@ -1399,7 +1406,7 @@ netdev_tc_flow_get(struct netdev *netdev OVS_UNUSED,
block_id = get_block_id_from_netdev(dev);
VLOG_DBG_RL(&rl, "flow get (dev %s prio %d handle %d block_id %d)",
netdev_get_name(dev), prio, handle, block_id);
- err = tc_get_flower(ifindex, prio, handle, &flower, block_id, false);
+ err = tc_get_flower(ifindex, prio, handle, &flower, block_id, egress);
netdev_close(dev);
if (err) {
VLOG_ERR_RL(&error_rl, "flow get failed (dev %s prio %d handle %d): %s",
@@ -1426,6 +1433,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED,
struct netdev *dev;
int prio = 0;
int ifindex;
+ bool egress;
int handle;
int error;
@@ -1434,6 +1442,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED,
return ENOENT;
}
+ egress = is_internal_port(netdev_get_type(netdev));
ifindex = netdev_get_ifindex(dev);
if (ifindex < 0) {
VLOG_ERR_RL(&error_rl, "flow_del: failed to get ifindex for %s: %s",
@@ -1446,14 +1455,15 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED,
if (stats) {
memset(stats, 0, sizeof *stats);
- if (!tc_get_flower(ifindex, prio, handle, &flower, block_id, false)) {
+ if (!tc_get_flower(ifindex, prio, handle, &flower, block_id, egress)) {
stats->n_packets = get_32aligned_u64(&flower.stats.n_packets);
stats->n_bytes = get_32aligned_u64(&flower.stats.n_bytes);
stats->used = flower.lastused;
}
}
- error = del_filter_and_ufid_mapping(ifindex, prio, handle, block_id, ufid);
+ error = del_filter_and_ufid_mapping(ifindex, prio, handle, block_id, ufid,
+ egress);
netdev_close(dev);
@@ -1525,6 +1535,7 @@ netdev_tc_init_flow_api(struct netdev *netdev)
{
static struct ovsthread_once multi_mask_once = OVSTHREAD_ONCE_INITIALIZER;
static struct ovsthread_once block_once = OVSTHREAD_ONCE_INITIALIZER;
+ bool egress = is_internal_port(netdev_get_type(netdev));
uint32_t block_id = 0;
int ifindex;
int error;
@@ -1550,7 +1561,7 @@ netdev_tc_init_flow_api(struct netdev *netdev)
}
block_id = get_block_id_from_netdev(netdev);
- error = tc_add_del_qdisc(ifindex, true, block_id, false);
+ error = tc_add_del_qdisc(ifindex, true, block_id, egress);
if (error && error != EEXIST) {
VLOG_ERR("failed adding ingress qdisc required for offloading: %s",