X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-linux.c;h=75bfc45872fa787c9ce495b1c57bdf6897e7755e;hb=de6c85b0a2e61105d288c23b718f6599761c2a2e;hp=62f69174406812db7e40810b555052825dab1102;hpb=aecfb4af7e87a78dfec44db1fa82c4463a7f8309;p=openvswitch diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 62f69174..75bfc458 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -200,7 +200,7 @@ struct dpif_linux { bool change_error; /* Port number allocation. */ - uint16_t alloc_port_no; + uint32_t alloc_port_no; }; static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5); @@ -219,7 +219,7 @@ static int dpif_linux_init(void); static void open_dpif(const struct dpif_linux_dp *, struct dpif **); static bool dpif_linux_nln_parse(struct ofpbuf *, void *); static void dpif_linux_port_changed(const void *vport, void *dpif); -static uint32_t dpif_linux_port_get_pid(const struct dpif *, uint16_t port_no); +static uint32_t dpif_linux_port_get_pid(const struct dpif *, uint32_t port_no); static void dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *, struct ofpbuf *); @@ -392,7 +392,7 @@ dpif_linux_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats) static int dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, - uint16_t *port_nop) + uint32_t *port_nop) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); const char *name = netdev_get_name(netdev); @@ -424,11 +424,13 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, netdev_linux_ethtool_set_flag(netdev, ETH_FLAG_LRO, "LRO", false); } - /* Loop until we find a port that isn't used. */ + /* Unless a specific port was requested, loop until we find a port + * that isn't used. */ do { uint32_t upcall_pid; - request.port_no = ++dpif->alloc_port_no; + request.port_no = *port_nop != UINT32_MAX ? *port_nop + : ++dpif->alloc_port_no; upcall_pid = dpif_linux_port_get_pid(dpif_, request.port_no); request.upcall_pid = &upcall_pid; error = dpif_linux_vport_transact(&request, &reply, &buf); @@ -441,17 +443,20 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev, /* Older datapath has lower limit. */ max_ports = dpif->alloc_port_no; dpif->alloc_port_no = 0; + } else if (error == EBUSY && *port_nop != UINT32_MAX) { + VLOG_INFO("%s: requested port %"PRIu32" is in use", + dpif_name(dpif_), *port_nop); } ofpbuf_delete(buf); - } while ((i++ < max_ports) + } while ((*port_nop == UINT32_MAX) && (i++ < max_ports) && (error == EBUSY || error == EFBIG)); return error; } static int -dpif_linux_port_del(struct dpif *dpif_, uint16_t port_no) +dpif_linux_port_del(struct dpif *dpif_, uint32_t port_no) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); struct dpif_linux_vport vport; @@ -487,7 +492,7 @@ dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no, /* A query by name reported that 'port_name' is in some datapath * other than 'dpif', but the caller wants to know about 'dpif'. */ error = ENODEV; - } else { + } else if (dpif_port) { dpif_port->name = xstrdup(reply.name); dpif_port->type = xstrdup(netdev_vport_get_netdev_type(&reply)); dpif_port->port_no = reply.port_no; @@ -498,7 +503,7 @@ dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no, } static int -dpif_linux_port_query_by_number(const struct dpif *dpif, uint16_t port_no, +dpif_linux_port_query_by_number(const struct dpif *dpif, uint32_t port_no, struct dpif_port *dpif_port) { return dpif_linux_port_query__(dpif, port_no, NULL, dpif_port); @@ -518,7 +523,7 @@ dpif_linux_get_max_ports(const struct dpif *dpif OVS_UNUSED) } static uint32_t -dpif_linux_port_get_pid(const struct dpif *dpif_, uint16_t port_no) +dpif_linux_port_get_pid(const struct dpif *dpif_, uint32_t port_no) { struct dpif_linux *dpif = dpif_linux_cast(dpif_); @@ -527,7 +532,7 @@ dpif_linux_port_get_pid(const struct dpif *dpif_, uint16_t port_no) } else { int idx; - idx = (port_no != UINT16_MAX + idx = (port_no != UINT32_MAX ? 1 + (port_no & (N_CHANNELS - 2)) : 0); return nl_sock_pid(dpif->channels[idx].sock); @@ -590,8 +595,8 @@ dpif_linux_port_dump_next(const struct dpif *dpif OVS_UNUSED, void *state_, return error; } - dpif_port->name = (char *) vport.name; - dpif_port->type = (char *) netdev_vport_get_netdev_type(&vport); + dpif_port->name = CONST_CAST(char *, vport.name); + dpif_port->type = CONST_CAST(char *, netdev_vport_get_netdev_type(&vport)); dpif_port->port_no = vport.port_no; return 0; } @@ -663,7 +668,7 @@ dpif_linux_flow_get(const struct dpif *dpif_, dpif_linux_flow_get_stats(&reply, stats); } if (actionsp) { - buf->data = (void *) reply.actions; + buf->data = CONST_CAST(struct nlattr *, reply.actions); buf->size = reply.actions_len; *actionsp = buf; } else { @@ -968,24 +973,38 @@ dpif_linux_operate__(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops) switch (op->type) { case DPIF_OP_FLOW_PUT: put = &op->u.flow_put; - if (!op->error && put->stats) { - struct dpif_linux_flow reply; - - op->error = dpif_linux_flow_from_ofpbuf(&reply, txn->reply); + if (put->stats) { if (!op->error) { - dpif_linux_flow_get_stats(&reply, put->stats); + struct dpif_linux_flow reply; + + op->error = dpif_linux_flow_from_ofpbuf(&reply, + txn->reply); + if (!op->error) { + dpif_linux_flow_get_stats(&reply, put->stats); + } + } + + if (op->error) { + memset(put->stats, 0, sizeof *put->stats); } } break; case DPIF_OP_FLOW_DEL: del = &op->u.flow_del; - if (!op->error && del->stats) { - struct dpif_linux_flow reply; - - op->error = dpif_linux_flow_from_ofpbuf(&reply, txn->reply); + if (del->stats) { if (!op->error) { - dpif_linux_flow_get_stats(&reply, del->stats); + struct dpif_linux_flow reply; + + op->error = dpif_linux_flow_from_ofpbuf(&reply, + txn->reply); + if (!op->error) { + dpif_linux_flow_get_stats(&reply, del->stats); + } + } + + if (op->error) { + memset(del->stats, 0, sizeof *del->stats); } } break; @@ -1150,9 +1169,11 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall, memset(upcall, 0, sizeof *upcall); upcall->type = type; upcall->packet = buf; - upcall->packet->data = (void *) nl_attr_get(a[OVS_PACKET_ATTR_PACKET]); + upcall->packet->data = CONST_CAST(struct nlattr *, + nl_attr_get(a[OVS_PACKET_ATTR_PACKET])); upcall->packet->size = nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]); - upcall->key = (void *) nl_attr_get(a[OVS_PACKET_ATTR_KEY]); + upcall->key = CONST_CAST(struct nlattr *, + nl_attr_get(a[OVS_PACKET_ATTR_KEY])); upcall->key_len = nl_attr_get_size(a[OVS_PACKET_ATTR_KEY]); upcall->userdata = (a[OVS_PACKET_ATTR_USERDATA] ? nl_attr_get_u64(a[OVS_PACKET_ATTR_USERDATA]) @@ -1378,10 +1399,10 @@ dpif_linux_vport_send(int dp_ifindex, uint32_t port_no, uint64_t action; ofpbuf_use_const(&packet, data, size); - flow_extract(&packet, 0, htonll(0), 0, &flow); + flow_extract(&packet, 0, NULL, 0, &flow); ofpbuf_use_stack(&key, &keybuf, sizeof keybuf); - odp_flow_key_from_flow(&key, &flow); + odp_flow_key_from_flow(&key, &flow, OVSP_NONE); ofpbuf_use_stack(&actions, &action, sizeof action); nl_msg_put_u32(&actions, OVS_ACTION_ATTR_OUTPUT, port_no); @@ -1981,7 +2002,7 @@ report_loss(struct dpif *dpif_, struct dpif_channel *ch) } ds_chomp(&s, ','); - VLOG_ERR("%s: lost packet on channel %td%s", - dpif_name(dpif_), ch - dpif->channels, ds_cstr(&s)); + VLOG_WARN("%s: lost packet on channel %td%s", + dpif_name(dpif_), ch - dpif->channels, ds_cstr(&s)); ds_destroy(&s); }