if (!internal) {
error = netdev_open(devname, NETDEV_ETH_TYPE_ANY, &netdev);
} else {
- char *tapname = xasprintf("tap:%s", devname);
- error = netdev_open(tapname, NETDEV_ETH_TYPE_ANY, &netdev);
- free(tapname);
+ error = netdev_create(devname, "tap", NULL);
+ if (!error) {
+ error = netdev_open(devname, NETDEV_ETH_TYPE_ANY, &netdev);
+ if (error) {
+ netdev_destroy(devname);
+ }
+ }
}
if (error) {
return error;
do_del_port(struct dp_netdev *dp, uint16_t port_no)
{
struct dp_netdev_port *port;
+ char *name;
int error;
error = get_port_by_number(dp, port_no, &port);
dp->n_ports--;
dp->serial++;
+ name = xstrdup(netdev_get_name(port->netdev));
netdev_close(port->netdev);
+ if (port->internal) {
+ netdev_destroy(name);
+ }
+ free(name);
free(port);
return 0;
}
static void
-answer_flow_query(const struct dp_netdev_flow *flow,
+answer_flow_query(struct dp_netdev_flow *flow, uint32_t query_flags,
struct odp_flow *odp_flow)
{
if (flow) {
n * sizeof *odp_flow->actions);
odp_flow->n_actions = flow->n_actions;
}
+
+ if (query_flags & ODPFF_ZERO_TCP_FLAGS) {
+ flow->tcp_ctl = 0;
+ }
+
} else {
odp_flow->stats.error = ENOENT;
}
for (i = 0; i < n; i++) {
struct odp_flow *odp_flow = &flows[i];
- answer_flow_query(dp_netdev_lookup_flow(dp, &odp_flow->key), odp_flow);
+ answer_flow_query(dp_netdev_lookup_flow(dp, &odp_flow->key),
+ odp_flow->flags, odp_flow);
}
return 0;
}
flow = dp_netdev_lookup_flow(dp, &odp_flow->key);
if (flow) {
- answer_flow_query(flow, odp_flow);
+ answer_flow_query(flow, 0, odp_flow);
dp_netdev_free_flow(dp, flow);
return 0;
} else {
if (i >= n) {
break;
}
- answer_flow_query(flow, &flows[i++]);
+ answer_flow_query(flow, 0, &flows[i++]);
}
return hmap_count(&dp->flow_table);
}