+
+cleanup:
+ free(ofname);
+ free(ifname);
+ close(ifd);
+ close(ofd);
+ return error;
+}
+
+static int
+netdev_pltap_sync_flags(struct netdev_dev_pltap *dev)
+{
+ int error = 0;
+ char *msg = NULL, *reply = NULL;
+ const size_t reply_size = 1024;
+ enum netdev_flags flags = 0;
+
+
+ if (dev->fd < 0 || !dev->finalized) {
+ /* pretend we have synchronized, we will do it later */
+ sync_needed(dev);
+ return 0;
+ }
+
+ error = get_flags(dev, &flags);
+ if (error) {
+ VLOG_ERR("get_flags(%s): %s", dev->real_name, strerror(error));
+ goto cleanup;
+ }
+ VLOG_DBG("sync_flags(%s): current: %s %s",
+ dev->real_name,
+ (flags & NETDEV_UP ? "UP" : "-"),
+ (flags & NETDEV_PROMISC ? "PROMISC" : "-"));
+
+ if ((dev->flags & NETDEV_PROMISC) ^ (flags & NETDEV_PROMISC)) {
+ msg = xasprintf("%s\n%s",
+ dev->real_name,
+ (dev->flags & NETDEV_PROMISC ? "" : "-\n"));
+ reply = (char*)xmalloc(reply_size);
+ if (!msg || !reply) {
+ VLOG_ERR("Out of memory\n");
+ error = ENOMEM;
+ goto cleanup;
+ }
+ error = vsys_transaction("promisc", msg, reply, reply_size);
+ if (error) {
+ dev->error = reply;
+ reply = NULL; /* prevent free of reply msg */
+ goto cleanup;
+ }
+ netdev_pltap_update_seq(dev);
+ }
+
+cleanup:
+
+ sync_done(dev);
+ free(msg);
+ free(reply);
+
+ return error;
+}
+
+static int
+netdev_pltap_create_finalize(struct netdev_dev_pltap *dev)
+{
+ int error = 0;
+ char *msg = NULL, *reply = NULL;
+ const size_t reply_size = 1024;
+
+ if (dev->finalized)
+ return 0;
+ if (!dev->valid_local_ip || !dev->valid_local_netmask)
+ return 0;
+
+ msg = xasprintf("%s\n"IP_FMT"\n%d\n",
+ dev->real_name,
+ IP_ARGS(&dev->local_addr.sin_addr),
+ dev->local_netmask);
+ reply = (char*)xmalloc(reply_size);
+ if (!msg || !reply) {
+ VLOG_ERR("Out of memory");
+ error = ENOMEM;
+ goto cleanup;
+ }
+ error = vsys_transaction("vif_up", msg, reply, reply_size);
+ if (error) {
+ dev->error = reply;
+ reply = NULL; /* prevent free of reply msg */
+ goto cleanup;
+ }