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;
{
struct dp_netdev_flow *flow;
- assert(key->reserved == 0);
HMAP_FOR_EACH_WITH_HASH (flow, struct dp_netdev_flow, node,
flow_hash(key, 0), &dp->flow_table) {
if (flow_equal(&flow->key, key)) {
case ODPAT_SET_DL_DST:
case ODPAT_SET_NW_SRC:
case ODPAT_SET_NW_DST:
+ case ODPAT_SET_NW_TOS:
case ODPAT_SET_TP_SRC:
case ODPAT_SET_TP_DST:
*mutates = true;
flow = xcalloc(1, sizeof *flow);
flow->key = odp_flow->key;
- flow->key.reserved = 0;
error = set_flow_actions(flow, odp_flow);
if (error) {
}
}
+static void
+dp_netdev_set_nw_tos(struct ofpbuf *packet, flow_t *key,
+ const struct odp_action_nw_tos *a)
+{
+ if (key->dl_type == htons(ETH_TYPE_IP)) {
+ struct ip_header *nh = packet->l3;
+ uint8_t *field = &nh->ip_tos;
+
+ /* We only set the lower 6 bits. */
+ uint8_t new = (a->nw_tos & 0x3f) | (nh->ip_tos & 0xc0);
+
+ nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t)*field),
+ htons((uint16_t)a->nw_tos));
+ *field = new;
+ }
+}
+
static void
dp_netdev_set_tp_port(struct ofpbuf *packet, flow_t *key,
const struct odp_action_tp_port *a)
dp_netdev_set_nw_addr(packet, key, &a->nw_addr);
break;
+ case ODPAT_SET_NW_TOS:
+ dp_netdev_set_nw_tos(packet, key, &a->nw_tos);
+ break;
+
case ODPAT_SET_TP_SRC:
case ODPAT_SET_TP_DST:
dp_netdev_set_tp_port(packet, key, &a->tp_port);