/* A port in a netdev-based datapath. */
struct dp_netdev_port {
- int port_no; /* Index into dp_netdev's 'ports'. */
+ odp_port_t port_no; /* Index into dp_netdev's 'ports'. */
struct list node; /* Element in dp_netdev's 'port_list'. */
struct netdev *netdev;
struct netdev_saved_flags *sf;
/* Maximum port MTU seen so far. */
static int max_mtu = ETH_PAYLOAD_MAX;
-static int get_port_by_number(struct dp_netdev *, uint32_t port_no,
+static int get_port_by_number(struct dp_netdev *, odp_port_t port_no,
struct dp_netdev_port **portp);
static int get_port_by_name(struct dp_netdev *, const char *devname,
struct dp_netdev_port **portp);
static void dp_netdev_free(struct dp_netdev *);
static void dp_netdev_flow_flush(struct dp_netdev *);
static int do_add_port(struct dp_netdev *, const char *devname,
- const char *type, uint32_t port_no);
-static int do_del_port(struct dp_netdev *, uint32_t port_no);
+ const char *type, odp_port_t port_no);
+static int do_del_port(struct dp_netdev *, odp_port_t port_no);
static int dpif_netdev_open(const struct dpif_class *, const char *name,
bool create, struct dpif **);
static int dp_netdev_output_userspace(struct dp_netdev *, const struct ofpbuf *,
return &dpif->dpif;
}
-static int
+/* Choose an unused, non-zero port number and return it on success.
+ * Return ODPP_NONE on failure. */
+static odp_port_t
choose_port(struct dp_netdev *dp, const char *name)
{
- int port_no;
+ uint32_t port_no;
if (dp->class != &dpif_netdev_class) {
const char *p;
port_no = start_no + strtol(p, NULL, 10);
if (port_no > 0 && port_no < MAX_PORTS
&& !dp->ports[port_no]) {
- return port_no;
+ return u32_to_odp(port_no);
}
break;
}
for (port_no = 1; port_no < MAX_PORTS; port_no++) {
if (!dp->ports[port_no]) {
- return port_no;
+ return u32_to_odp(port_no);
}
}
- return -1;
+ return ODPP_NONE;
}
static int
hmap_init(&dp->flow_table);
list_init(&dp->port_list);
- error = do_add_port(dp, name, "internal", OVSP_LOCAL);
+ error = do_add_port(dp, name, "internal", ODPP_LOCAL);
if (error) {
dp_netdev_free(dp);
return error;
static int
do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
- uint32_t port_no)
+ odp_port_t port_no)
{
struct netdev_saved_flags *sf;
struct dp_netdev_port *port;
}
list_push_back(&dp->port_list, &port->node);
- dp->ports[port_no] = port;
+ dp->ports[odp_to_u32(port_no)] = port;
dp->serial++;
return 0;
static int
dpif_netdev_port_add(struct dpif *dpif, struct netdev *netdev,
- uint32_t *port_nop)
+ odp_port_t *port_nop)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
const char *dpif_port;
- int port_no;
+ odp_port_t port_no;
dpif_port = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf);
- if (*port_nop != UINT32_MAX) {
- if (*port_nop >= MAX_PORTS) {
+ if (*port_nop != ODPP_NONE) {
+ uint32_t port_idx = odp_to_u32(*port_nop);
+ if (port_idx >= MAX_PORTS) {
return EFBIG;
- } else if (dp->ports[*port_nop]) {
+ } else if (dp->ports[port_idx]) {
return EBUSY;
}
port_no = *port_nop;
} else {
port_no = choose_port(dp, dpif_port);
}
- if (port_no >= 0) {
+ if (port_no != ODPP_NONE) {
*port_nop = port_no;
return do_add_port(dp, dpif_port, netdev_get_type(netdev), port_no);
}
}
static int
-dpif_netdev_port_del(struct dpif *dpif, uint32_t port_no)
+dpif_netdev_port_del(struct dpif *dpif, odp_port_t port_no)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
- return port_no == OVSP_LOCAL ? EINVAL : do_del_port(dp, port_no);
+ return (port_no == ODPP_LOCAL ?
+ EINVAL : do_del_port(dp, port_no));
}
static bool
-is_valid_port_number(uint32_t port_no)
+is_valid_port_number(odp_port_t port_no)
{
- return port_no < MAX_PORTS;
+ return odp_to_u32(port_no) < MAX_PORTS;
}
static int
get_port_by_number(struct dp_netdev *dp,
- uint32_t port_no, struct dp_netdev_port **portp)
+ odp_port_t port_no, struct dp_netdev_port **portp)
{
if (!is_valid_port_number(port_no)) {
*portp = NULL;
return EINVAL;
} else {
- *portp = dp->ports[port_no];
+ *portp = dp->ports[odp_to_u32(port_no)];
return *portp ? 0 : ENOENT;
}
}
}
static int
-do_del_port(struct dp_netdev *dp, uint32_t port_no)
+do_del_port(struct dp_netdev *dp, odp_port_t port_no)
{
struct dp_netdev_port *port;
int error;
}
list_remove(&port->node);
- dp->ports[port->port_no] = NULL;
+ dp->ports[odp_to_u32(port_no)] = NULL;
dp->serial++;
netdev_close(port->netdev);
}
static int
-dpif_netdev_port_query_by_number(const struct dpif *dpif, uint32_t port_no,
+dpif_netdev_port_query_by_number(const struct dpif *dpif, odp_port_t port_no,
struct dpif_port *dpif_port)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
return error;
}
-static int
+static odp_port_t
dpif_netdev_get_max_ports(const struct dpif *dpif OVS_UNUSED)
{
- return MAX_PORTS;
+ return u32_to_odp(MAX_PORTS);
}
static void
}
struct dp_netdev_port_state {
- uint32_t port_no;
+ odp_port_t port_no;
char *name;
};
{
struct dp_netdev_port_state *state = state_;
struct dp_netdev *dp = get_dp_netdev(dpif);
- uint32_t port_no;
+ uint32_t port_idx;
- for (port_no = state->port_no; port_no < MAX_PORTS; port_no++) {
- struct dp_netdev_port *port = dp->ports[port_no];
+ for (port_idx = odp_to_u32(state->port_no);
+ port_idx < MAX_PORTS; port_idx++) {
+ struct dp_netdev_port *port = dp->ports[port_idx];
if (port) {
free(state->name);
state->name = xstrdup(netdev_get_name(port->netdev));
dpif_port->name = state->name;
dpif_port->type = port->type;
dpif_port->port_no = port->port_no;
- state->port_no = port_no + 1;
+ state->port_no = u32_to_odp(port_idx + 1);
return 0;
}
}
return EINVAL;
}
- if (flow->in_port < OFPP_MAX
- ? flow->in_port >= MAX_PORTS
- : flow->in_port != OFPP_LOCAL && flow->in_port != OFPP_NONE) {
+ if (!is_valid_port_number(flow->in_port.odp_port)) {
return EINVAL;
}
struct ofpbuf buf;
ofpbuf_use_stack(&buf, &state->keybuf, sizeof state->keybuf);
- odp_flow_key_from_flow(&buf, &flow->key, flow->key.in_port);
+ odp_flow_key_from_flow(&buf, &flow->key, flow->key.in_port.odp_port);
*key = buf.data;
*key_len = buf.size;
ofpbuf_reserve(©, DP_NETDEV_HEADROOM);
ofpbuf_put(©, execute->packet->data, execute->packet->size);
- flow_extract(©, 0, 0, NULL, -1, &key);
+ flow_extract(©, 0, 0, NULL, NULL, &key);
error = dpif_netdev_flow_from_nlattrs(execute->key, execute->key_len,
&key);
if (!error) {
{
struct dp_netdev_flow *flow;
struct flow key;
+ union flow_in_port in_port_;
if (packet->size < ETH_HEADER_LEN) {
return;
}
- flow_extract(packet, skb_priority, skb_mark, tnl, port->port_no, &key);
+ in_port_.odp_port = port->port_no;
+ flow_extract(packet, skb_priority, skb_mark, tnl, &in_port_, &key);
flow = dp_netdev_lookup_flow(dp, &key);
if (flow) {
dp_netdev_flow_used(flow, packet);
ofpbuf_init(buf, buf_size);
/* Put ODP flow. */
- odp_flow_key_from_flow(buf, flow, flow->in_port);
+ odp_flow_key_from_flow(buf, flow, flow->in_port.odp_port);
upcall->key = buf->data;
upcall->key_len = buf->size;