struct dpif_linux_port_state {
struct nl_dump dump;
+ unsigned long *port_bitmap; /* Ports in the datapath. */
+ bool complete; /* Dump completed without error. */
};
static int
struct ofpbuf *buf;
*statep = state = xmalloc(sizeof *state);
+ state->port_bitmap = bitmap_allocate(LRU_MAX_PORTS);
+ state->complete = false;
dpif_linux_vport_init(&request);
request.cmd = ODP_DP_CMD_GET;
int error;
if (!nl_dump_next(&state->dump, &buf)) {
+ state->complete = true;
return EOF;
}
return error;
}
+ if (vport.port_no < LRU_MAX_PORTS) {
+ bitmap_set1(state->port_bitmap, vport.port_no);
+ }
+
dpif_port->name = (char *) vport.name;
dpif_port->type = (char *) netdev_vport_get_netdev_type(&vport);
dpif_port->port_no = vport.port_no;
}
static int
-dpif_linux_port_dump_done(const struct dpif *dpif OVS_UNUSED, void *state_)
+dpif_linux_port_dump_done(const struct dpif *dpif_, void *state_)
{
+ struct dpif_linux *dpif = dpif_linux_cast(dpif_);
struct dpif_linux_port_state *state = state_;
int error = nl_dump_done(&state->dump);
+
+ if (state->complete) {
+ uint16_t i;
+
+ for (i = 0; i < LRU_MAX_PORTS; i++) {
+ if (!bitmap_is_set(state->port_bitmap, i)) {
+ dpif_linux_push_port(dpif, i);
+ }
+ }
+ }
+
+ free(state->port_bitmap);
free(state);
return error;
}