+ /*
+ * unset the persistence when attaching to existing
+ * interface
+ */
+ if (args->tap_flags & TAP_FLAG_ATTACH)
+ {
+ _IOCTL (tfd, TUNSETPERSIST, (void *) (uintptr_t) 0);
+ tap_log_dbg (vif, "TUNSETPERSIST: unset");
+ }
+
+ /* set the persistence */
+ if (args->tap_flags & TAP_FLAG_PERSIST)
+ {
+ _IOCTL (tfd, TUNSETPERSIST, (void *) (uintptr_t) 1);
+ tap_log_dbg (vif, "TUNSETPERSIST: set");
+
+ /* verify persistence is set, read the flags */
+ _IOCTL (tfd, TUNGETIFF, (void *) &get_ifr);
+ tap_log_dbg (vif, "TUNGETIFF: flags 0x%lx", get_ifr.ifr_flags);
+ if ((get_ifr.ifr_flags & IFF_PERSIST) == 0)
+ {
+ args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
+ args->error = clib_error_return (0, "persistence not supported");
+ goto error;
+ }
+ }
+
+ tap_log_dbg (vif, "TUNSETVNETHDRSZ: fd %d vnet_hdr_sz %u", tfd, hdrsz);
+ _IOCTL (tfd, TUNSETVNETHDRSZ, &hdrsz);
+
+ i = INT_MAX;
+ tap_log_dbg (vif, "TUNSETSNDBUF: fd %d sndbuf %d", tfd, i);
+ _IOCTL (tfd, TUNSETSNDBUF, &i);
+
+ tap_log_dbg (vif, "TUNSETOFFLOAD: fd %d offload 0x%lx", tfd, offload);
+ _IOCTL (tfd, TUNSETOFFLOAD, offload);
+
+ /* open vhost-net fd for each queue pair and set ownership */
+ for (i = 0; i < num_q_pairs; i++)
+ {
+ if ((vfd = open ("/dev/vhost-net", O_RDWR | O_NONBLOCK)) < 0)
+ {
+ args->rv = VNET_API_ERROR_SYSCALL_ERROR_1;
+ args->error = clib_error_return_unix (0, "open '/dev/vhost-net'");
+ goto error;
+ }
+ vec_add1 (vif->vhost_fds, vfd);
+ virtio_log_debug (vif, "open vhost-net fd %d qpair %u", vfd, i);
+ _IOCTL (vfd, VHOST_SET_OWNER, 0);
+ virtio_log_debug (vif, "VHOST_SET_OWNER: fd %u", vfd);
+ }
+
+ _IOCTL (vif->vhost_fds[0], VHOST_GET_FEATURES, &vif->remote_features);
+ virtio_log_debug (vif, "VHOST_GET_FEATURES: features 0x%lx",
+ vif->remote_features);