}
static int
-dpif_linux_port_query__(const struct dpif *dpif, struct odp_port *port)
+dpif_linux_port_query__(const struct dpif *dpif, uint32_t port_no,
+ const char *port_name, struct dpif_port *dpif_port)
{
- int error = do_ioctl(dpif, ODP_VPORT_QUERY, port);
- if (!error) {
- translate_vport_type_to_netdev_type(port);
+ struct odp_port odp_port;
+ int error;
+
+ memset(&odp_port, 0, sizeof odp_port);
+ odp_port.port = port_no;
+ strncpy(odp_port.devname, port_name, sizeof odp_port.devname);
+
+ error = do_ioctl(dpif, ODP_VPORT_QUERY, &odp_port);
+ if (error) {
+ return error;
+ } else if (odp_port.dp_idx != dpif_linux_cast(dpif)->minor) {
+ /* A vport named 'port_name' exists but in some other datapath. */
+ return ENOENT;
+ } else {
+ translate_vport_type_to_netdev_type(&odp_port);
+ dpif_port->name = xstrdup(odp_port.devname);
+ dpif_port->type = xstrdup(odp_port.type);
+ dpif_port->port_no = odp_port.port;
+ return 0;
}
- return error;
}
static int
dpif_linux_port_query_by_number(const struct dpif *dpif, uint16_t port_no,
- struct odp_port *port)
+ struct dpif_port *dpif_port)
{
- memset(port, 0, sizeof *port);
- port->port = port_no;
- return dpif_linux_port_query__(dpif, port);
+ return dpif_linux_port_query__(dpif, port_no, "", dpif_port);
}
static int
-dpif_linux_port_query_by_name(const struct dpif *dpif_, const char *devname,
- struct odp_port *port)
+dpif_linux_port_query_by_name(const struct dpif *dpif, const char *devname,
+ struct dpif_port *dpif_port)
{
- struct dpif_linux *dpif = dpif_linux_cast(dpif_);
- int error;
-
- memset(port, 0, sizeof *port);
- strncpy(port->devname, devname, sizeof port->devname);
- error = dpif_linux_port_query__(dpif_, port);
- if (!error && port->dp_idx != dpif->minor) {
- /* A vport named 'devname' exists but in some other datapath. */
- error = ENOENT;
- }
- return error;
+ return dpif_linux_port_query__(dpif, 0, devname, dpif_port);
}
static int
static int
dpif_linux_port_dump_start(const struct dpif *dpif OVS_UNUSED, void **statep)
{
- *statep = xzalloc(sizeof(struct odp_vport_dump));
+ *statep = xzalloc(sizeof(struct odp_port));
return 0;
}
static int
dpif_linux_port_dump_next(const struct dpif *dpif, void *state,
- struct odp_port *port)
+ struct dpif_port *dpif_port)
{
- struct odp_vport_dump *dump = state;
+ struct odp_port *odp_port = state;
+ struct odp_vport_dump dump;
int error;
- dump->port = port;
- error = do_ioctl(dpif, ODP_VPORT_DUMP, dump);
+ dump.port = odp_port;
+ dump.port_no = odp_port->port;
+ error = do_ioctl(dpif, ODP_VPORT_DUMP, &dump);
if (error) {
return error;
- } else if (port->devname[0] == '\0') {
+ } else if (odp_port->devname[0] == '\0') {
return EOF;
} else {
- dump->port_no = port->port + 1;
- translate_vport_type_to_netdev_type(port);
+ translate_vport_type_to_netdev_type(odp_port);
+ dpif_port->name = odp_port->devname;
+ dpif_port->type = odp_port->type;
+ dpif_port->port_no = odp_port->port;
+ odp_port->port++;
return 0;
}
}
}
static void
-answer_port_query(const struct dp_netdev_port *port, struct odp_port *odp_port)
+answer_port_query(const struct dp_netdev_port *port,
+ struct dpif_port *dpif_port)
{
- memset(odp_port, 0, sizeof *odp_port);
- ovs_strlcpy(odp_port->devname, netdev_get_name(port->netdev),
- sizeof odp_port->devname);
- odp_port->port = port->port_no;
- strcpy(odp_port->type, port->internal ? "internal" : "system");
+ dpif_port->name = xstrdup(netdev_get_name(port->netdev));
+ dpif_port->type = xstrdup(port->internal ? "internal" : "system");
+ dpif_port->port_no = port->port_no;
}
static int
dpif_netdev_port_query_by_number(const struct dpif *dpif, uint16_t port_no,
- struct odp_port *odp_port)
+ struct dpif_port *dpif_port)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
struct dp_netdev_port *port;
error = get_port_by_number(dp, port_no, &port);
if (!error) {
- answer_port_query(port, odp_port);
+ answer_port_query(port, dpif_port);
}
return error;
}
static int
dpif_netdev_port_query_by_name(const struct dpif *dpif, const char *devname,
- struct odp_port *odp_port)
+ struct dpif_port *dpif_port)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
struct dp_netdev_port *port;
error = get_port_by_name(dp, devname, &port);
if (!error) {
- answer_port_query(port, odp_port);
+ answer_port_query(port, dpif_port);
}
return error;
}
struct dp_netdev_port_state {
uint32_t port_no;
+ char *name;
};
static int
static int
dpif_netdev_port_dump_next(const struct dpif *dpif, void *state_,
- struct odp_port *odp_port)
+ struct dpif_port *dpif_port)
{
struct dp_netdev_port_state *state = state_;
struct dp_netdev *dp = get_dp_netdev(dpif);
for (port_no = state->port_no; port_no < MAX_PORTS; port_no++) {
struct dp_netdev_port *port = dp->ports[port_no];
if (port) {
- answer_port_query(port, odp_port);
+ free(state->name);
+ state->name = xstrdup(netdev_get_name(port->netdev));
+ dpif_port->name = state->name;
+ dpif_port->type = port->internal ? "internal" : "system";
+ dpif_port->port_no = port->port_no;
state->port_no = port_no + 1;
return 0;
}
}
static int
-dpif_netdev_port_dump_done(const struct dpif *dpif OVS_UNUSED, void *state)
+dpif_netdev_port_dump_done(const struct dpif *dpif OVS_UNUSED, void *state_)
{
+ struct dp_netdev_port_state *state = state_;
+ free(state->name);
free(state);
return 0;
}
int (*port_del)(struct dpif *dpif, uint16_t port_no);
/* Queries 'dpif' for a port with the given 'port_no' or 'devname'. Stores
- * information about the port into '*port' if successful. */
+ * information about the port into '*port' if successful.
+ *
+ * The caller takes ownership of data in 'port' and must free it with
+ * dpif_port_destroy() when it is no longer needed. */
int (*port_query_by_number)(const struct dpif *dpif, uint16_t port_no,
- struct odp_port *port);
+ struct dpif_port *port);
int (*port_query_by_name)(const struct dpif *dpif, const char *devname,
- struct odp_port *port);
+ struct dpif_port *port);
/* Attempts to begin dumping the ports in a dpif. On success, returns 0
* and initializes '*statep' with any data needed for iteration. On
/* Attempts to retrieve another port from 'dpif' for 'state', which was
* initialized by a successful call to the 'port_dump_start' function for
- * 'dpif'. On success, stores a new odp_port into 'port' and returns 0.
+ * 'dpif'. On success, stores a new dpif_port into 'port' and returns 0.
* Returns EOF if the end of the port table has been reached, or a positive
* errno value on error. This function will not be called again once it
* returns nonzero once for a given iteration (but the 'port_dump_done'
- * function will be called afterward). */
+ * function will be called afterward).
+ *
+ * The dpif provider retains ownership of the data stored in 'port'. It
+ * must remain valid until at least the next call to 'port_dump_next' or
+ * 'port_dump_done' for 'state'. */
int (*port_dump_next)(const struct dpif *dpif, void *state,
- struct odp_port *port);
+ struct dpif_port *port);
/* Releases resources from 'dpif' for 'state', which was initialized by a
* successful call to the 'port_dump_start' function for 'dpif'. */
/*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return error;
}
+/* Makes a deep copy of 'src' into 'dst'. */
+void
+dpif_port_clone(struct dpif_port *dst, const struct dpif_port *src)
+{
+ dst->name = xstrdup(src->name);
+ dst->type = xstrdup(src->type);
+ dst->port_no = src->port_no;
+}
+
+/* Frees memory allocated to members of 'dpif_port'.
+ *
+ * Do not call this function on a dpif_port obtained from
+ * dpif_port_dump_next(): that function retains ownership of the data in the
+ * dpif_port. */
+void
+dpif_port_destroy(struct dpif_port *dpif_port)
+{
+ free(dpif_port->name);
+ free(dpif_port->type);
+}
+
/* Looks up port number 'port_no' in 'dpif'. On success, returns 0 and
* initializes '*port' appropriately; on failure, returns a positive errno
- * value. */
+ * value.
+ *
+ * The caller owns the data in 'port' and must free it with
+ * dpif_port_destroy() when it is no longer needed. */
int
dpif_port_query_by_number(const struct dpif *dpif, uint16_t port_no,
- struct odp_port *port)
+ struct dpif_port *port)
{
int error = dpif->dpif_class->port_query_by_number(dpif, port_no, port);
if (!error) {
VLOG_DBG_RL(&dpmsg_rl, "%s: port %"PRIu16" is device %s",
- dpif_name(dpif), port_no, port->devname);
+ dpif_name(dpif), port_no, port->name);
} else {
memset(port, 0, sizeof *port);
VLOG_WARN_RL(&error_rl, "%s: failed to query port %"PRIu16": %s",
/* Looks up port named 'devname' in 'dpif'. On success, returns 0 and
* initializes '*port' appropriately; on failure, returns a positive errno
- * value. */
+ * value.
+ *
+ * The caller owns the data in 'port' and must free it with
+ * dpif_port_destroy() when it is no longer needed. */
int
dpif_port_query_by_name(const struct dpif *dpif, const char *devname,
- struct odp_port *port)
+ struct dpif_port *port)
{
int error = dpif->dpif_class->port_query_by_name(dpif, devname, port);
if (!error) {
VLOG_DBG_RL(&dpmsg_rl, "%s: device %s is on port %"PRIu16,
- dpif_name(dpif), devname, port->port);
+ dpif_name(dpif), devname, port->port_no);
} else {
memset(port, 0, sizeof *port);
dpif_port_get_name(struct dpif *dpif, uint16_t port_no,
char *name, size_t name_size)
{
- struct odp_port port;
+ struct dpif_port port;
int error;
assert(name_size > 0);
error = dpif_port_query_by_number(dpif, port_no, &port);
if (!error) {
- ovs_strlcpy(name, port.devname, name_size);
+ ovs_strlcpy(name, port.name, name_size);
+ dpif_port_destroy(&port);
} else {
*name = '\0';
}
}
/* Attempts to retrieve another port from 'dump', which must have been
- * initialized with dpif_port_dump_start(). On success, stores a new odp_port
+ * initialized with dpif_port_dump_start(). On success, stores a new dpif_port
* into 'port' and returns true. On failure, returns false.
*
* Failure might indicate an actual error or merely that the last port has been
* dumped. An error status for the entire dump operation is provided when it
- * is completed by calling dpif_port_dump_done(). */
+ * is completed by calling dpif_port_dump_done().
+ *
+ * The dpif owns the data stored in 'port'. It will remain valid until at
+ * least the next time 'dump' is passed to dpif_port_dump_next() or
+ * dpif_port_dump_done(). */
bool
-dpif_port_dump_next(struct dpif_port_dump *dump, struct odp_port *port)
+dpif_port_dump_next(struct dpif_port_dump *dump, struct dpif_port *port)
{
const struct dpif *dpif = dump->dpif;
/*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
int dpif_port_add(struct dpif *, struct netdev *, uint16_t *port_nop);
int dpif_port_del(struct dpif *, uint16_t port_no);
+
+/* A port within a datapath.
+ *
+ * 'name' and 'type' are suitable for passing to netdev_open(). */
+struct dpif_port {
+ char *name; /* Network device name, e.g. "eth0". */
+ char *type; /* Network device type, e.g. "system". */
+ uint32_t port_no; /* Port number within datapath. */
+};
+void dpif_port_clone(struct dpif_port *, const struct dpif_port *);
+void dpif_port_destroy(struct dpif_port *);
int dpif_port_query_by_number(const struct dpif *, uint16_t port_no,
- struct odp_port *);
+ struct dpif_port *);
int dpif_port_query_by_name(const struct dpif *, const char *devname,
- struct odp_port *);
+ struct dpif_port *);
int dpif_port_get_name(struct dpif *, uint16_t port_no,
char *name, size_t name_size);
void *state;
};
void dpif_port_dump_start(struct dpif_port_dump *, const struct dpif *);
-bool dpif_port_dump_next(struct dpif_port_dump *, struct odp_port *);
+bool dpif_port_dump_next(struct dpif_port_dump *, struct dpif_port *);
int dpif_port_dump_done(struct dpif_port_dump *);
-/* Iterates through each ODP_PORT in DPIF, using DUMP as state.
+/* Iterates through each DPIF_PORT in DPIF, using DUMP as state.
*
* Arguments all have pointer type.
*
* If you break out of the loop, then you need to free the dump structure by
* hand using dpif_port_dump_done(). */
-#define DPIF_PORT_FOR_EACH(ODP_PORT, DUMP, DPIF) \
+#define DPIF_PORT_FOR_EACH(DPIF_PORT, DUMP, DPIF) \
for (dpif_port_dump_start(DUMP, DPIF); \
- (dpif_port_dump_next(DUMP, ODP_PORT) \
+ (dpif_port_dump_next(DUMP, DPIF_PORT) \
? true \
: (dpif_port_dump_done(DUMP), false)); \
)
struct shash_node *node;
struct shash devnames;
struct ofport *ofport;
- struct odp_port odp_port;
+ struct dpif_port dpif_port;
COVERAGE_INC(ofproto_reinit_ports);
HMAP_FOR_EACH (ofport, hmap_node, &p->ports) {
shash_add_once (&devnames, ofport->opp.name, NULL);
}
- DPIF_PORT_FOR_EACH (&odp_port, &dump, p->dpif) {
- shash_add_once (&devnames, odp_port.devname, NULL);
+ DPIF_PORT_FOR_EACH (&dpif_port, &dump, p->dpif) {
+ shash_add_once (&devnames, dpif_port.name, NULL);
}
SHASH_FOR_EACH (node, &devnames) {
}
static struct ofport *
-make_ofport(const struct odp_port *odp_port)
+make_ofport(const struct dpif_port *dpif_port)
{
struct netdev_options netdev_options;
enum netdev_flags flags;
int error;
memset(&netdev_options, 0, sizeof netdev_options);
- netdev_options.name = odp_port->devname;
- netdev_options.type = odp_port->type;
+ netdev_options.name = dpif_port->name;
+ netdev_options.type = dpif_port->type;
netdev_options.ethertype = NETDEV_ETH_TYPE_NONE;
error = netdev_open(&netdev_options, &netdev);
if (error) {
VLOG_WARN_RL(&rl, "ignoring port %s (%"PRIu16") because netdev %s "
"cannot be opened (%s)",
- odp_port->devname, odp_port->port,
- odp_port->devname, strerror(error));
+ dpif_port->name, dpif_port->port_no,
+ dpif_port->name, strerror(error));
return NULL;
}
ofport = xmalloc(sizeof *ofport);
ofport->netdev = netdev;
- ofport->odp_port = odp_port->port;
- ofport->opp.port_no = odp_port_to_ofp_port(odp_port->port);
+ ofport->odp_port = dpif_port->port_no;
+ ofport->opp.port_no = odp_port_to_ofp_port(dpif_port->port_no);
netdev_get_etheraddr(netdev, ofport->opp.hw_addr);
- memcpy(ofport->opp.name, odp_port->devname,
- MIN(sizeof ofport->opp.name, sizeof odp_port->devname));
- ofport->opp.name[sizeof ofport->opp.name - 1] = '\0';
+ ovs_strlcpy(ofport->opp.name, dpif_port->name, sizeof ofport->opp.name);
netdev_get_flags(netdev, &flags);
ofport->opp.config = flags & NETDEV_UP ? 0 : OFPPC_PORT_DOWN;
}
static bool
-ofport_conflicts(const struct ofproto *p, const struct odp_port *odp_port)
+ofport_conflicts(const struct ofproto *p, const struct dpif_port *dpif_port)
{
- if (get_port(p, odp_port->port)) {
+ if (get_port(p, dpif_port->port_no)) {
VLOG_WARN_RL(&rl, "ignoring duplicate port %"PRIu16" in datapath",
- odp_port->port);
+ dpif_port->port_no);
return true;
- } else if (shash_find(&p->port_by_name, odp_port->devname)) {
+ } else if (shash_find(&p->port_by_name, dpif_port->name)) {
VLOG_WARN_RL(&rl, "ignoring duplicate device %s in datapath",
- odp_port->devname);
+ dpif_port->name);
return true;
} else {
return false;
static void
update_port(struct ofproto *p, const char *devname)
{
- struct odp_port odp_port;
+ struct dpif_port dpif_port;
struct ofport *old_ofport;
struct ofport *new_ofport;
int error;
COVERAGE_INC(ofproto_update_port);
/* Query the datapath for port information. */
- error = dpif_port_query_by_name(p->dpif, devname, &odp_port);
+ error = dpif_port_query_by_name(p->dpif, devname, &dpif_port);
/* Find the old ofport. */
old_ofport = shash_find_data(&p->port_by_name, devname);
* reliably but more portably by comparing the old port's MAC
* against the new port's MAC. However, this code isn't that smart
* and always sends an OFPPR_MODIFY (XXX). */
- old_ofport = get_port(p, odp_port.port);
+ old_ofport = get_port(p, dpif_port.port_no);
}
} else if (error != ENOENT && error != ENODEV) {
VLOG_WARN_RL(&rl, "dpif_port_query_by_name returned unexpected error "
"%s", strerror(error));
- return;
+ goto exit;
}
/* Create a new ofport. */
- new_ofport = !error ? make_ofport(&odp_port) : NULL;
+ new_ofport = !error ? make_ofport(&dpif_port) : NULL;
/* Eliminate a few pathological cases. */
if (!old_ofport && !new_ofport) {
- return;
+ goto exit;
} else if (old_ofport && new_ofport) {
/* Most of the 'config' bits are OpenFlow soft state, but
* OFPPC_PORT_DOWN is maintained by the kernel. So transfer the
if (ofport_equal(old_ofport, new_ofport)) {
/* False alarm--no change. */
ofport_free(new_ofport);
- return;
+ goto exit;
}
}
: !new_ofport ? OFPPR_DELETE
: OFPPR_MODIFY));
ofport_free(old_ofport);
+
+exit:
+ dpif_port_destroy(&dpif_port);
}
static int
init_ports(struct ofproto *p)
{
struct dpif_port_dump dump;
- struct odp_port odp_port;
+ struct dpif_port dpif_port;
- DPIF_PORT_FOR_EACH (&odp_port, &dump, p->dpif) {
- if (!ofport_conflicts(p, &odp_port)) {
- struct ofport *ofport = make_ofport(&odp_port);
+ DPIF_PORT_FOR_EACH (&dpif_port, &dump, p->dpif) {
+ if (!ofport_conflicts(p, &dpif_port)) {
+ struct ofport *ofport = make_ofport(&dpif_port);
if (ofport) {
ofport_install(p, ofport);
}
static bool
get_port_number(struct dpif *dpif, const char *name, uint16_t *port)
{
- struct odp_port odp_port;
+ struct dpif_port dpif_port;
- if (!dpif_port_query_by_name(dpif, name, &odp_port)) {
- *port = odp_port.port;
+ if (!dpif_port_query_by_name(dpif, name, &dpif_port)) {
+ *port = dpif_port.port_no;
+ dpif_port_destroy(&dpif_port);
return true;
} else {
ovs_error(0, "no port named %s", name);
show_dpif(struct dpif *dpif)
{
struct dpif_port_dump dump;
- struct odp_port odp_port;
+ struct dpif_port dpif_port;
struct odp_stats stats;
printf("%s:\n", dpif_name(dpif));
printf("\tqueues: max-miss:%"PRIu16", max-action:%"PRIu16"\n",
stats.max_miss_queue, stats.max_action_queue);
}
- DPIF_PORT_FOR_EACH (&odp_port, &dump, dpif) {
- printf("\tport %u: %s", odp_port.port, odp_port.devname);
+ DPIF_PORT_FOR_EACH (&dpif_port, &dump, dpif) {
+ printf("\tport %u: %s", dpif_port.port_no, dpif_port.name);
- if (strcmp(odp_port.type, "system")) {
+ if (strcmp(dpif_port.type, "system")) {
struct netdev_options netdev_options;
struct netdev *netdev;
int error;
- printf (" (%s", odp_port.type);
+ printf (" (%s", dpif_port.type);
- netdev_options.name = odp_port.devname;
- netdev_options.type = odp_port.type;
+ netdev_options.name = dpif_port.name;
+ netdev_options.type = dpif_port.type;
netdev_options.args = NULL;
netdev_options.ethertype = NETDEV_ETH_TYPE_NONE;
error = netdev_open(&netdev_options, &netdev);
LIST_FOR_EACH (br, node, &all_bridges) {
struct dpif_port_dump dump;
struct shash want_ifaces;
- struct odp_port odp_port;
+ struct dpif_port dpif_port;
bridge_get_all_ifaces(br, &want_ifaces);
- DPIF_PORT_FOR_EACH (&odp_port, &dump, br->dpif) {
- if (!shash_find(&want_ifaces, odp_port.devname)
- && strcmp(odp_port.devname, br->name)) {
- int retval = dpif_port_del(br->dpif, odp_port.port);
+ DPIF_PORT_FOR_EACH (&dpif_port, &dump, br->dpif) {
+ if (!shash_find(&want_ifaces, dpif_port.name)
+ && strcmp(dpif_port.name, br->name)) {
+ int retval = dpif_port_del(br->dpif, dpif_port.port_no);
if (retval) {
VLOG_ERR("failed to remove %s interface from %s: %s",
- odp_port.devname, dpif_name(br->dpif),
+ dpif_port.name, dpif_name(br->dpif),
strerror(retval));
}
}
shash_destroy(&want_ifaces);
}
LIST_FOR_EACH (br, node, &all_bridges) {
- struct dpif_port {
- char *type; /* Network device type, e.g. "system". */
- uint32_t port_no; /* Port number within datapath. */
- };
struct shash cur_ifaces, want_ifaces;
struct dpif_port_dump dump;
- struct odp_port odp_port;
+ struct dpif_port dpif_port;
/* Get the set of interfaces currently in this datapath. */
shash_init(&cur_ifaces);
- DPIF_PORT_FOR_EACH (&odp_port, &dump, br->dpif) {
+ DPIF_PORT_FOR_EACH (&dpif_port, &dump, br->dpif) {
struct dpif_port *port_info = xmalloc(sizeof *port_info);
- port_info->port_no = odp_port.port;
- port_info->type = xstrdup(odp_port.type);
- shash_add(&cur_ifaces, odp_port.devname, port_info);
+ dpif_port_clone(port_info, &dpif_port);
+ shash_add(&cur_ifaces, dpif_port.name, port_info);
}
/* Get the set of interfaces we want on this datapath. */
SHASH_FOR_EACH (node, &cur_ifaces) {
struct dpif_port *port_info = node->data;
- free(port_info->type);
+ dpif_port_destroy(port_info);
free(port_info);
}
shash_destroy(&cur_ifaces);
bridge_fetch_dp_ifaces(struct bridge *br)
{
struct dpif_port_dump dump;
- struct odp_port odp_port;
+ struct dpif_port dpif_port;
size_t i, j;
/* Reset all interface numbers. */
}
hmap_clear(&br->ifaces);
- DPIF_PORT_FOR_EACH (&odp_port, &dump, br->dpif) {
- struct iface *iface = iface_lookup(br, odp_port.devname);
+ DPIF_PORT_FOR_EACH (&dpif_port, &dump, br->dpif) {
+ struct iface *iface = iface_lookup(br, dpif_port.name);
if (iface) {
if (iface->dp_ifidx >= 0) {
VLOG_WARN("%s reported interface %s twice",
- dpif_name(br->dpif), odp_port.devname);
- } else if (iface_from_dp_ifidx(br, odp_port.port)) {
+ dpif_name(br->dpif), dpif_port.name);
+ } else if (iface_from_dp_ifidx(br, dpif_port.port_no)) {
VLOG_WARN("%s reported interface %"PRIu16" twice",
- dpif_name(br->dpif), odp_port.port);
+ dpif_name(br->dpif), dpif_port.port_no);
} else {
- iface->dp_ifidx = odp_port.port;
+ iface->dp_ifidx = dpif_port.port_no;
hmap_insert(&br->ifaces, &iface->dp_ifidx_node,
hash_int(iface->dp_ifidx, 0));
}