diff options
Diffstat (limited to 'drivers/net/tun.c')
| -rw-r--r-- | drivers/net/tun.c | 118 | 
1 files changed, 34 insertions, 84 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 650c937ed56b..07476c6510f2 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -75,35 +75,6 @@  static void tun_default_link_ksettings(struct net_device *dev,  				       struct ethtool_link_ksettings *cmd); -/* Uncomment to enable debugging */ -/* #define TUN_DEBUG 1 */ - -#ifdef TUN_DEBUG -static int debug; - -#define tun_debug(level, tun, fmt, args...)			\ -do {								\ -	if (tun->debug)						\ -		netdev_printk(level, tun->dev, fmt, ##args);	\ -} while (0) -#define DBG1(level, fmt, args...)				\ -do {								\ -	if (debug == 2)						\ -		printk(level fmt, ##args);			\ -} while (0) -#else -#define tun_debug(level, tun, fmt, args...)			\ -do {								\ -	if (0)							\ -		netdev_printk(level, tun->dev, fmt, ##args);	\ -} while (0) -#define DBG1(level, fmt, args...)				\ -do {								\ -	if (0)							\ -		printk(level fmt, ##args);			\ -} while (0) -#endif -  #define TUN_RX_PAD (NET_IP_ALIGN + NET_SKB_PAD)  /* TUN device flags */ @@ -225,9 +196,7 @@ struct tun_struct {  	struct sock_fprog	fprog;  	/* protected by rtnl lock */  	bool			filter_attached; -#ifdef TUN_DEBUG -	int debug; -#endif +	u32			msg_enable;  	spinlock_t lock;  	struct hlist_head flows[TUN_NUM_FLOW_ENTRIES];  	struct timer_list flow_gc_timer; @@ -423,8 +392,9 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun,  	struct tun_flow_entry *e = kmalloc(sizeof(*e), GFP_ATOMIC);  	if (e) { -		tun_debug(KERN_INFO, tun, "create flow: hash %u index %u\n", -			  rxhash, queue_index); +		netif_info(tun, tx_queued, tun->dev, +			   "create flow: hash %u index %u\n", +			   rxhash, queue_index);  		e->updated = jiffies;  		e->rxhash = rxhash;  		e->rps_rxhash = 0; @@ -438,8 +408,8 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun,  static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e)  { -	tun_debug(KERN_INFO, tun, "delete flow: hash %u index %u\n", -		  e->rxhash, e->queue_index); +	netif_info(tun, tx_queued, tun->dev, "delete flow: hash %u index %u\n", +		   e->rxhash, e->queue_index);  	hlist_del_rcu(&e->hash_link);  	kfree_rcu(e, rcu);  	--tun->flow_count; @@ -485,8 +455,6 @@ static void tun_flow_cleanup(struct timer_list *t)  	unsigned long count = 0;  	int i; -	tun_debug(KERN_INFO, tun, "tun_flow_cleanup\n"); -  	spin_lock(&tun->lock);  	for (i = 0; i < TUN_NUM_FLOW_ENTRIES; i++) {  		struct tun_flow_entry *e; @@ -546,8 +514,7 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,  	rcu_read_unlock();  } -/** - * Save the hash received in the stack receive path and update the +/* Save the hash received in the stack receive path and update the   * flow_hash table accordingly.   */  static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) @@ -1076,9 +1043,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)  	if (!rcu_dereference(tun->steering_prog))  		tun_automq_xmit(tun, skb); -	tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); - -	BUG_ON(!tfile); +	netif_info(tun, tx_queued, tun->dev, "%s %d\n", __func__, skb->len);  	/* Drop if the filter does not like it.  	 * This is a noop if the filter is disabled. @@ -1435,8 +1400,6 @@ static __poll_t tun_chr_poll(struct file *file, poll_table *wait)  	sk = tfile->socket.sk; -	tun_debug(KERN_INFO, tun, "tun_chr_poll\n"); -  	poll_wait(file, sk_sleep(sk), wait);  	if (!ptr_ring_empty(&tfile->tx_ring)) @@ -1715,8 +1678,12 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,  			alloc_frag->offset += buflen;  		}  		err = tun_xdp_act(tun, xdp_prog, &xdp, act); -		if (err < 0) -			goto err_xdp; +		if (err < 0) { +			if (act == XDP_REDIRECT || act == XDP_TX) +				put_page(alloc_frag->page); +			goto out; +		} +  		if (err == XDP_REDIRECT)  			xdp_do_flush();  		if (err != XDP_PASS) @@ -1730,8 +1697,6 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,  	return __tun_build_skb(tfile, alloc_frag, buf, buflen, len, pad); -err_xdp: -	put_page(alloc_frag->page);  out:  	rcu_read_unlock();  	local_bh_enable(); @@ -2207,8 +2172,6 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,  	ssize_t ret;  	int err; -	tun_debug(KERN_INFO, tun, "tun_do_read\n"); -  	if (!iov_iter_count(to)) {  		tun_ptr_free(ptr);  		return 0; @@ -2853,8 +2816,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)  	netif_carrier_on(tun->dev); -	tun_debug(KERN_INFO, tun, "tun_set_iff\n"); -  	/* Make sure persistent devices do not get stuck in  	 * xoff state.  	 */ @@ -2885,8 +2846,6 @@ err_free_dev:  static void tun_get_iff(struct tun_struct *tun, struct ifreq *ifr)  { -	tun_debug(KERN_INFO, tun, "tun_get_iff\n"); -  	strcpy(ifr->ifr_name, tun->dev->name);  	ifr->ifr_flags = tun_flags(tun); @@ -3110,7 +3069,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,  	if (!tun)  		goto unlock; -	tun_debug(KERN_INFO, tun, "tun_chr_ioctl cmd %u\n", cmd); +	netif_info(tun, drv, tun->dev, "tun_chr_ioctl cmd %u\n", cmd);  	net = dev_net(tun->dev);  	ret = 0; @@ -3131,8 +3090,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,  		/* Disable/Enable checksum */  		/* [unimplemented] */ -		tun_debug(KERN_INFO, tun, "ignored: set checksum %s\n", -			  arg ? "disabled" : "enabled"); +		netif_info(tun, drv, tun->dev, "ignored: set checksum %s\n", +			   arg ? "disabled" : "enabled");  		break;  	case TUNSETPERSIST: @@ -3150,8 +3109,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,  			do_notify = true;  		} -		tun_debug(KERN_INFO, tun, "persist %s\n", -			  arg ? "enabled" : "disabled"); +		netif_info(tun, drv, tun->dev, "persist %s\n", +			   arg ? "enabled" : "disabled");  		break;  	case TUNSETOWNER: @@ -3163,8 +3122,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,  		}  		tun->owner = owner;  		do_notify = true; -		tun_debug(KERN_INFO, tun, "owner set to %u\n", -			  from_kuid(&init_user_ns, tun->owner)); +		netif_info(tun, drv, tun->dev, "owner set to %u\n", +			   from_kuid(&init_user_ns, tun->owner));  		break;  	case TUNSETGROUP: @@ -3176,29 +3135,28 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,  		}  		tun->group = group;  		do_notify = true; -		tun_debug(KERN_INFO, tun, "group set to %u\n", -			  from_kgid(&init_user_ns, tun->group)); +		netif_info(tun, drv, tun->dev, "group set to %u\n", +			   from_kgid(&init_user_ns, tun->group));  		break;  	case TUNSETLINK:  		/* Only allow setting the type when the interface is down */  		if (tun->dev->flags & IFF_UP) { -			tun_debug(KERN_INFO, tun, -				  "Linktype set failed because interface is up\n"); +			netif_info(tun, drv, tun->dev, +				   "Linktype set failed because interface is up\n");  			ret = -EBUSY;  		} else {  			tun->dev->type = (int) arg; -			tun_debug(KERN_INFO, tun, "linktype set to %d\n", -				  tun->dev->type); +			netif_info(tun, drv, tun->dev, "linktype set to %d\n", +				   tun->dev->type);  			ret = 0;  		}  		break; -#ifdef TUN_DEBUG  	case TUNSETDEBUG: -		tun->debug = arg; +		tun->msg_enable = (u32)arg;  		break; -#endif +  	case TUNSETOFFLOAD:  		ret = set_offload(tun, arg);  		break; @@ -3221,9 +3179,6 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,  	case SIOCSIFHWADDR:  		/* Set hw address */ -		tun_debug(KERN_DEBUG, tun, "set hw address: %pM\n", -			  ifr.ifr_hwaddr.sa_data); -  		ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr, NULL);  		break; @@ -3418,8 +3373,6 @@ static int tun_chr_open(struct inode *inode, struct file * file)  	struct net *net = current->nsproxy->net_ns;  	struct tun_file *tfile; -	DBG1(KERN_INFO, "tunX: tun_chr_open\n"); -  	tfile = (struct tun_file *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,  					    &tun_proto, 0);  	if (!tfile) @@ -3559,20 +3512,16 @@ static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info  static u32 tun_get_msglevel(struct net_device *dev)  { -#ifdef TUN_DEBUG  	struct tun_struct *tun = netdev_priv(dev); -	return tun->debug; -#else -	return -EOPNOTSUPP; -#endif + +	return tun->msg_enable;  }  static void tun_set_msglevel(struct net_device *dev, u32 value)  { -#ifdef TUN_DEBUG  	struct tun_struct *tun = netdev_priv(dev); -	tun->debug = value; -#endif + +	tun->msg_enable = value;  }  static int tun_get_coalesce(struct net_device *dev, @@ -3599,6 +3548,7 @@ static int tun_set_coalesce(struct net_device *dev,  }  static const struct ethtool_ops tun_ethtool_ops = { +	.supported_coalesce_params = ETHTOOL_COALESCE_RX_MAX_FRAMES,  	.get_drvinfo	= tun_get_drvinfo,  	.get_msglevel	= tun_get_msglevel,  	.set_msglevel	= tun_set_msglevel,  |