+ /* Discard any saved channels that we didn't reuse. */
+ for (i = 0; i < keep_channels_nbits; i++) {
+ if (!bitmap_is_set(keep_channels, i)) {
+ vport_del_channels(dpif, u32_to_odp(i));
+ }
+ }
+ free(keep_channels);
+
+ return retval;
+}
+
+static int
+dpif_linux_recv_set__(struct dpif *dpif_, bool enable)
+{
+ struct dpif_linux *dpif = dpif_linux_cast(dpif_);
+
+ if ((dpif->handlers != NULL) == enable) {
+ return 0;
+ } else if (!enable) {
+ destroy_all_channels(dpif);
+ return 0;
+ } else {
+ return dpif_linux_refresh_channels(dpif_, 1);
+ }
+}
+
+static int
+dpif_linux_recv_set(struct dpif *dpif_, bool enable)
+{
+ struct dpif_linux *dpif = dpif_linux_cast(dpif_);
+ int error;
+
+ fat_rwlock_wrlock(&dpif->upcall_lock);
+ error = dpif_linux_recv_set__(dpif_, enable);
+ fat_rwlock_unlock(&dpif->upcall_lock);
+
+ return error;
+}
+
+static int
+dpif_linux_handlers_set(struct dpif *dpif_, uint32_t n_handlers)
+{
+ struct dpif_linux *dpif = dpif_linux_cast(dpif_);
+ int error = 0;
+
+ fat_rwlock_wrlock(&dpif->upcall_lock);
+ if (dpif->handlers) {
+ error = dpif_linux_refresh_channels(dpif_, n_handlers);
+ }
+ fat_rwlock_unlock(&dpif->upcall_lock);
+
+ return error;