//Implement the code to release the tap devices here static int turbotap_release(struct socket *sock) { struct turbotap_sock_fd *turbotap_sf = find_interface_from_sock(sock); // need to decide which interface if (!turbotap_sf) return -1; printk(KERN_INFO "Release Socket %d\n", turbotap_sf->tun_fd); if(turbotap_sf->tun_file->f_op->release) turbotap_sf->tun_file->f_op->release(NULL,turbotap_sf->tun_file); interface_free(turbotap_sf); return 0; }
static void iface_update_cb(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old) { struct interface *iface; if (node_old) { iface = container_of(node_old, struct interface, node); interface_free(iface); } if (node_new) { iface = container_of(node_new, struct interface, node); interface_start(iface); } }
static void interface_free_func(void** state) { void* malloc_pool = malloc(POOL_SIZE); init_memory_pool(POOL_SIZE, malloc_pool, 0); size_t first_size = get_used_size(malloc_pool); IPv4Interface* interface = interface_alloc(malloc_pool); size_t comp_size = get_used_size(malloc_pool); assert_int_not_equal(comp_size, first_size); interface_free(interface, malloc_pool); comp_size = get_used_size(malloc_pool); assert_int_equal(comp_size, first_size); destroy_memory_pool(malloc_pool); free(malloc_pool); malloc_pool = NULL; }
/* * It is main IOCTL routine which handles all ioctl related to turbotap. * This function is registered to do all HACKs. It is the main culprit * as it oprhans the PF_PACKET socket and also set the pointers to call * the tun functions tun_sendmsg and tun_recvmsg for send and receive. */ static long turbotap_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct socket *tun_sock; struct turbotap_sock_fd *turbotap_sf; struct socket *turbotap_sock; struct file *tun_file; int ret; if (cmd == TUNGETSOCKFD) { void __user *argp = (void __user *)arg; int tun_fd = -1; if (copy_from_user(&tun_fd, argp, sizeof (int))) return -EFAULT; printk(KERN_DEBUG "tun fd value %d\n", tun_fd); /* * Allocate the new interface */ turbotap_sf = interface_alloc(); if (IS_ERR(turbotap_sf)) return PTR_ERR(turbotap_sf); /* * Get the tun sock using tun fd, user is responsible for * providing it. */ tun_file = fget(tun_fd); if (!tun_file) return -EBADF; tun_sock = tun_get_socket(tun_file); if (IS_ERR(tun_sock)) { ret = -ENOTSOCK; goto err; } else { turbotap_sf->tun_sock = tun_sock; turbotap_sf->tun_file = tun_file; turbotap_sf->tun_fd = tun_fd; printk(KERN_DEBUG "Successfully get the tun socket\n"); } /* * Create a new socket and return the fd to that socket */ ret = turbotap_socket_create(&turbotap_sock); if (ret < 0) goto err; if (!turbotap_sock) { ret = -1; goto err; } turbotap_sf->turbotap_sock = turbotap_sock; turbotap_sf->turbotap_fd = ret; /* * HACK: * It is ugly but there is no choice to over power on PF_PACKETs. * Here it kicks out the PF_PACKET's ops which becomes orphan * and set pointer to new ops. */ if (turbotap_sf->tun_sock->ops->sendmsg && turbotap_sf->tun_sock->ops->recvmsg) { /* * put the module for PF_PACKET as we are hacking its * ops to use them internally :-) */ module_put(turbotap_sf->turbotap_sock->ops->owner); turbotap_sf->turbotap_sock->ops = &turbotap_socket_ops; printk(KERN_DEBUG "set pointer to new ops\n"); // get the module for new owner which is THIS_MODULE :D if (!try_module_get(turbotap_sf->turbotap_sock->ops->owner)) printk(KERN_ERR "Error in getting module\n"); printk(KERN_INFO "IOCTL Successful\n"); } else { printk(KERN_ERR "Fail to set pointer to new ops\n"); ret = -1; goto err; } } else { printk(KERN_ERR "IOCTL fail\n"); return -1; } return ret; err: interface_free(turbotap_sf); return ret; }