Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] netfilter: xt_condition: add security capability support
From: Luciano Coelho @ 2010-08-23 18:45 UTC (permalink / raw)
  To: ext Jan Engelhardt
  Cc: ext Changli Gao, kaber@trash.net, netfilter-devel@vger.kernel.org,
	netdev@vger.kernel.org, James Morris,
	linux-security-module@vger.kernel.org
In-Reply-To: <alpine.LNX.2.01.1008231628010.21000@obet.zrqbmnf.qr>

On Mon, 2010-08-23 at 16:34 +0200, ext Jan Engelhardt wrote:
> On Monday 2010-08-23 15:42, Luciano Coelho wrote:
> >> >  /* Defaults, these can be overridden on the module command-line. */
> >> >  static unsigned int condition_list_perms = S_IRUGO | S_IWUSR;
> >> >  static unsigned int condition_uid_perms = 0;
> >> >  static unsigned int condition_gid_perms = 0;
> >> > +static unsigned int condition_capabilities = CAP_NET_ADMIN;
> >> >
> >> It is strange that we set security policy in this way. Maybe the
> >> permission of the proc file is enough in this case.
> >
> >Yes, that is another way to do it.  But in our device we use security
> >capabilities more extensively than normal file permissions.  That's why
> >we need this.
> >
> >If this is too restrictive (ie. having CAP_NET_ADMIN) for most users, we
> >could change the default value to no capabilities needed.  Then we can
> >set CAP_NET_ADMIN when loading the module.
> 
> But it looks as strange as the Yama code attempt.

What is so strange about it? Is it because it's possible to set the
capability requirement from modprobe arguments? The capability check
already exists in at least in nfnetlink, where it checks for received
messages for the CAP_NET_ADMIN capability.  Is it strange because we're
checking for the capability when someone tries to write to a file?


>  This is the one time 
> where I would personally be looking into SELinux, or perhaps SMACK if 
> the former is too complex, to whether _t'ing off procfs is possible.

Yeah, but it's not up to me to decide this.  We have one entire team
dedicated to figuring out how to ensure "security" in our device.  It
was that team who advised us to protect this file by checking for
CAP_NET_ADMIN.


-- 
Cheers,
Luca.


^ permalink raw reply

* Re: [PATCH] Fix deadlock between boomerang_interrupt and boomerang_start_tx in 3c59x
From: Neil Horman @ 2010-08-23 18:32 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, klassert
In-Reply-To: <20100811.231334.39172883.davem@davemloft.net>

On Wed, Aug 11, 2010 at 11:13:34PM -0700, David Miller wrote:
> From: Neil Horman <nhorman@tuxdriver.com>
> Date: Wed, 11 Aug 2010 11:00:18 -0400
> 
> > @@ -2133,6 +2134,15 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
> >  			   dev->name, vp->cur_tx);
> >  	}
> >  
> > +	/*
> > +	 * We can't allow a recursion from our interrupt handler back into the
> > +	 * tx routine, as they take the same spin lock, and that causes
> > +	 * deadlock.  Just return NETDEV_TX_BUSY and let the stack try again in
> > +	 * a bit
> > +	 */
> > +	if (vp->handling_irq)
> > +		return NETDEV_TX_BUSY;
> > +
> >  	if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
> >  		if (vortex_debug > 0)
> >  			pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n",
> 
> This is just as racy as your previous patch :-)
> 
> You don't hold vp->lock so right after testing this another cpu can
> enter the interrupt handler, take the lock, and set vp->handling_irq
> to '1'.
> 
> This is becomming hopeless, you can't synchronize the state without
> holding the same lock which is giving us trouble in the first place.
> 
> Maybe just toss the pr_*() statements from the interrupt handler.
> 
> This driver is old enough that the easiest to verify fix is probably
> the best one to make.
> 
> 


Dave, any further thoughts here?  Is the explination regarding the lack of
lock-race satisfactory, or would you rather we just pull all the pr_* calls from
the interrupt handler?

Neil


^ permalink raw reply

* Re: [PATCH net-next 1/3] drivers/net/ixgbe/ixgbe_main.c: Checkpatch cleanups
From: Jeff Kirsher @ 2010-08-23 18:24 UTC (permalink / raw)
  To: David Miller
  Cc: e1000-devel, netdev, bruce.w.allan, jesse.brandeburg,
	linux-kernel, john.ronciak, joe
In-Reply-To: <20100822.203404.242143197.davem@davemloft.net>

On Sun, Aug 22, 2010 at 20:34, David Miller <davem@davemloft.net> wrote:
>
> I'll let the Intel folks integrate these 3 patches.
>
> Thanks Joe.
> --

Thanks Joe, I have added the patches to my queue.

-- 
Cheers,
Jeff

------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm) Developer Program
Be part of this innovative community and reach millions of netbook users 
worldwide. Take advantage of special opportunities to increase revenue and 
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply

* Re: [PATCH net-next-2.6] net: copy_rtnl_link_stats64() simplification
From: Eric Dumazet @ 2010-08-23 18:17 UTC (permalink / raw)
  To: Joe Perches; +Cc: David Miller, netdev, Ben Hutchings
In-Reply-To: <1282585624.1879.103.camel@Joe-Laptop>

Le lundi 23 août 2010 à 10:47 -0700, Joe Perches a écrit :
> On Mon, 2010-08-23 at 19:14 +0200, Eric Dumazet wrote:
> > No need to use a temporary struct rtnl_link_stats64 variable,
> > just copy the source to skb buffer.
> > 
> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> Maybe it's better to use the same argument style as copy_rtnl_link_stats
> 
>  net/core/rtnetlink.c |   36 ++++--------------------------------
>  1 files changed, 4 insertions(+), 32 deletions(-)
> 
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index f78d821..f8781db 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -610,38 +610,10 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
>  	a->tx_compressed = b->tx_compressed;
>  }
>  
> -static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
> +static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *a,
> +				   const struct rtnl_link_stats64 *b)
>  {



Nope, we have no quarantee of v being aligned on a u64

If you tell compiler first argument is a pointer to rtnl_link_stats64,
it might use 64bit stores and trap.




^ permalink raw reply

* Re: [PATCH net-next-2.6] net: copy_rtnl_link_stats64() simplification
From: Ben Hutchings @ 2010-08-23 18:14 UTC (permalink / raw)
  To: Joe Perches; +Cc: Eric Dumazet, David Miller, netdev
In-Reply-To: <1282585624.1879.103.camel@Joe-Laptop>

On Mon, 2010-08-23 at 10:47 -0700, Joe Perches wrote:
> On Mon, 2010-08-23 at 19:14 +0200, Eric Dumazet wrote:
> > No need to use a temporary struct rtnl_link_stats64 variable,
> > just copy the source to skb buffer.
> > 
> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> Maybe it's better to use the same argument style as copy_rtnl_link_stats
[...]

I believe the destination pointer is typed as void * because it may not
be naturally aligned for u64.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH] xps-mq: Transmit Packet Steering for multiqueue
From: Stephen Hemminger @ 2010-08-23 17:59 UTC (permalink / raw)
  To: Tom Herbert; +Cc: davem, netdev, eric.dumazet
In-Reply-To: <alpine.DEB.1.00.1008222233530.31382@pokey.mtv.corp.google.com>

On Sun, 22 Aug 2010 22:39:57 -0700 (PDT)
Tom Herbert <therbert@google.com> wrote:

> This patch implements transmit packet steering (XPS) for multiqueue
> devices.  XPS selects a transmit queue during packet transmission based
> on configuration.  This is done by mapping the CPU transmitting the
> packet to a queue.  This is the transmit side analogue to RPS-- where
> RPS is selecting a CPU based on receive queue, XPS selects a queue
> based on the CPU (previously there was an XPS patch from Eric
> Dumazet, but that might more appropriately be called transmit completion
> steering).
> 
> Each transmit queue can be associated with a number of CPUs which will
> used the queue to send packets.  This is configured as a CPU mask on a
> per queue basis in:
> 
> /sys/class/net/eth<n>/queues/tx-<n>/xps_cpus
> 
> The mappings are stored per device in an inverted data structure that
> maps CPUs to queues.  In the netdevice structure this is an array of
> num_possible_cpu structures where each array entry contains a bit map
> of queues which that CPU can use.
> 
> We also allow the mapping of a socket to queue to be modified, for
> instance if a thread is scheduled on a different CPU the desired queue
> for transmitting packets would likely change.  To maintain in order
> packet transmission a flag (ooo_okay) has been added to the sk_buf
> structure.  If a transport layer sets this flag on a packet, the
> transmit queue can be changed for this socket.  Presumably, the
> transport would set this is there was no possbility of creating ooo
> packets (for instance there are no packets in flight for the socket).
> This patch includes the modification in TCP output for setting this
> flag.
> 
> The benefits of XPS are improved locality in the per queue data
> strutures.  Also, transmit completions are more likely to be done
> nearer to the sending thread so this should promote locality back 
> to the socket (e.g. UDP).  The benefits of XPS are dependent on
> cache hierarchy, application load, and other factors.  XPS would
> nominally be configured so that a queue would only be shared by CPUs
> which are sharing a cache, the degenerative configuration woud be that
> each CPU has it's own queue.
> 
> Below are some benchmark results which show the potential benfit of
> this patch.  The netperf test has 500 instances of netperf TCP_RR test
> with 1 byte req. and resp.
> 
> bnx2x on 16 core AMD
>    XPS (16 queues, 1 TX queue per CPU)	1015K at 99% CPU
>    No XPS (16 queues)			1127K at 98% CPU
> 
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 46c36ff..0ff6c9f 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -497,6 +497,12 @@ struct netdev_queue {
>  	struct Qdisc		*qdisc;
>  	unsigned long		state;
>  	struct Qdisc		*qdisc_sleeping;
> +#ifdef CONFIG_RPS
> +	struct kobject		kobj;
> +	struct netdev_queue	*first;
> +	atomic_t		count;
> +#endif
> +
>  /*
>   * write mostly part
>   */
> @@ -524,6 +530,22 @@ struct rps_map {
>  #define RPS_MAP_SIZE(_num) (sizeof(struct rps_map) + (_num * sizeof(u16)))
>  
>  /*
> + * This structure holds an XPS map which can be of variable length.  queues
> + * is an array of num_possible_cpus entries, where each entry is a mask of
> + * queues for that CPU (up to num_tx_queues bits for device).
> + */
> +struct xps_map {
> +	struct rcu_head rcu;
> +	unsigned long queues[0];
> +};
> +
> +#define QUEUE_MASK_SIZE(dev) (BITS_TO_LONGS(dev->num_tx_queues))
> +#define XPS_MAP_SIZE(dev) (sizeof(struct xps_map) + (num_possible_cpus() * \
> +    QUEUE_MASK_SIZE(dev) * sizeof(unsigned long)))
> +#define XPS_ENTRY(map, offset, dev) \
> +    (&map->queues[offset * QUEUE_MASK_SIZE(dev)])
> +
> +/*
>   * The rps_dev_flow structure contains the mapping of a flow to a CPU and the
>   * tail pointer for that CPU's input queue at the time of last enqueue.
>   */
> @@ -978,6 +1000,9 @@ struct net_device {
>  	void			*rx_handler_data;
>  
>  	struct netdev_queue	*_tx ____cacheline_aligned_in_smp;
> +#ifdef CONFIG_RPS
> +	struct xps_map		*xps_maps;
> +#endif
>  
>  	/* Number of TX queues allocated at alloc_netdev_mq() time  */
>  	unsigned int		num_tx_queues;
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index f067c95..146df6f 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -381,6 +381,7 @@ struct sk_buff {
>  #else
>  	__u8			deliver_no_wcard:1;
>  #endif
> +	__u8			ooo_okay:1;
>  	kmemcheck_bitfield_end(flags2);
>  
>  	/* 0/14 bit hole */
> diff --git a/net/core/dev.c b/net/core/dev.c
> index da584f5..d23f9c4 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2054,6 +2054,60 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index)
>  	return queue_index;
>  }
>  
> +static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb,
> +				int queue_index)
> +{
> +	struct xps_map *maps;
> +	int cpu = smp_processor_id();
> +	u32 hash;
> +	unsigned long *queues;
> +	int weight, select;
> +
> +	rcu_read_lock();
> +	maps = rcu_dereference(dev->xps_maps);
> +
> +	if (!maps) {
> +		rcu_read_unlock();
> +		return queue_index;
> +	}
> +
> +	queues = XPS_ENTRY(maps, cpu, dev);
> +
> +	if (queue_index >= 0) {
> +		if (test_bit(queue_index, queues)) {
> +			rcu_read_unlock();
> +			return queue_index;
> +		}
> +	}
> +
> +	weight = bitmap_weight(queues, dev->real_num_tx_queues);
> +	switch (weight) {
> +	case 0:
> +		break;
> +	case 1:
> +		queue_index =
> +		    find_first_bit(queues, dev->real_num_tx_queues);
> +		break;
> +	default:
> +		if (skb->sk && skb->sk->sk_hash)
> +			hash = skb->sk->sk_hash;
> +		else
> +			hash = (__force u16) skb->protocol ^ skb->rxhash;
> +		hash = jhash_1word(hash, hashrnd);
> +
> +		select = ((u64) hash * weight) >> 32;
> +		queue_index =
> +		    find_first_bit(queues, dev->real_num_tx_queues);
> +		while (select--)
> +			queue_index = find_next_bit(queues,
> +			    dev->real_num_tx_queues, queue_index);
> +		break;
> +	}
> +
> +	rcu_read_unlock();
> +	return queue_index;
> +}
> +
>  static struct netdev_queue *dev_pick_tx(struct net_device *dev,
>  					struct sk_buff *skb)
>  {
> @@ -2061,23 +2115,30 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
>  	struct sock *sk = skb->sk;
>  
>  	queue_index = sk_tx_queue_get(sk);
> -	if (queue_index < 0) {
> +
> +	if (queue_index < 0 || (skb->ooo_okay && dev->real_num_tx_queues > 1)) {
>  		const struct net_device_ops *ops = dev->netdev_ops;
> +		int old_index = queue_index;
>  
>  		if (ops->ndo_select_queue) {
>  			queue_index = ops->ndo_select_queue(dev, skb);
>  			queue_index = dev_cap_txqueue(dev, queue_index);
>  		} else {
> -			queue_index = 0;
> -			if (dev->real_num_tx_queues > 1)
> -				queue_index = skb_tx_hash(dev, skb);
> +			if (dev->real_num_tx_queues > 1) {
> +				queue_index = get_xps_queue(dev,
> +				    skb, queue_index);
> +				if (queue_index < 0)
> +					queue_index = skb_tx_hash(dev, skb);
> +			} else
> +				queue_index = 0;
> +		}
>  
> -			if (sk) {
> -				struct dst_entry *dst = rcu_dereference_check(sk->sk_dst_cache, 1);
> +		if ((queue_index != old_index) && sk) {
> +			struct dst_entry *dst =
> +			    rcu_dereference_check(sk->sk_dst_cache, 1);
>  
> -				if (dst && skb_dst(skb) == dst)
> -					sk_tx_queue_set(sk, queue_index);
> -			}
> +			if (dst && skb_dst(skb) == dst)
> +				sk_tx_queue_set(sk, queue_index);
>  		}
>  	}
>  
> @@ -5429,6 +5490,15 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
>  	}
>  
>  #ifdef CONFIG_RPS
> +	atomic_set(&tx->count, queue_count);
> +
> +	/*
> +	 * Set a pointer to first element in the array which holds the
> +	 * reference count.
> +	 */
> +	for (i = 0; i < queue_count; i++)
> +		tx[i].first = tx;
> +
>  	rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
>  	if (!rx) {
>  		printk(KERN_ERR "alloc_netdev: Unable to allocate "
> @@ -5506,7 +5576,9 @@ void free_netdev(struct net_device *dev)
>  
>  	release_net(dev_net(dev));
>  
> +#ifndef CONFIG_RPS
>  	kfree(dev->_tx);
> +#endif
>  
>  	/* Flush device addresses */
>  	dev_addr_flush(dev);
> diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> index af4dfba..661c481 100644
> --- a/net/core/net-sysfs.c
> +++ b/net/core/net-sysfs.c
> @@ -742,34 +742,295 @@ static int rx_queue_add_kobject(struct net_device *net, int index)
>  	return error;
>  }
>  
> -static int rx_queue_register_kobjects(struct net_device *net)
> +/*
> + * netdev_queue sysfs structures and functions.
> + */
> +struct netdev_queue_attribute {
> +	struct attribute attr;
> +	ssize_t (*show)(struct netdev_queue *queue,
> +	    struct netdev_queue_attribute *attr, char *buf);
> +	ssize_t (*store)(struct netdev_queue *queue,
> +	    struct netdev_queue_attribute *attr, const char *buf, size_t len);
> +};
> +#define to_netdev_queue_attr(_attr) container_of(_attr,		\
> +    struct netdev_queue_attribute, attr)
> +
> +#define to_netdev_queue(obj) container_of(obj, struct netdev_queue, kobj)
> +
> +static ssize_t netdev_queue_attr_show(struct kobject *kobj,
> +				      struct attribute *attr, char *buf)
> +{
> +	struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr);
> +	struct netdev_queue *queue = to_netdev_queue(kobj);
> +
> +	if (!attribute->show)
> +		return -EIO;
> +
> +	return attribute->show(queue, attribute, buf);
> +}
> +
> +static ssize_t netdev_queue_attr_store(struct kobject *kobj,
> +				       struct attribute *attr,
> +				       const char *buf, size_t count)
> +{
> +	struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr);
> +	struct netdev_queue *queue = to_netdev_queue(kobj);
> +
> +	if (!attribute->store)
> +		return -EIO;
> +
> +	return attribute->store(queue, attribute, buf, count);
> +}
> +
> +static struct sysfs_ops netdev_queue_sysfs_ops = {
> +	.show = netdev_queue_attr_show,
> +	.store = netdev_queue_attr_store,
> +};
> +
> +static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue)
>  {
> +	struct net_device *dev = queue->dev;
> +	int i;
> +
> +	for (i = 0; i < dev->num_tx_queues; i++)
> +		if (queue == &dev->_tx[i])
> +			break;
> +
> +	BUG_ON(i >= dev->num_tx_queues);
> +
> +	return i;
> +}
> +
> +static ssize_t show_xps_map(struct netdev_queue *queue,
> +			    struct netdev_queue_attribute *attribute, char *buf)
> +{
> +	struct net_device *dev = queue->dev;
> +	struct xps_map *maps;
> +	cpumask_var_t mask;
> +	unsigned long *qmask, index;
> +	size_t len = 0;
>  	int i;
> +	unsigned int qmask_size = QUEUE_MASK_SIZE(dev);
> +
> +	if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
> +		return -ENOMEM;
> +
> +	index = get_netdev_queue_index(queue);
> +
> +	rcu_read_lock();
> +	maps = rcu_dereference(dev->xps_maps);
> +	if (maps) {
> +		qmask = maps->queues;
> +		for (i = 0; i < num_possible_cpus(); i++) {
> +			if (test_bit(index, qmask))
> +				cpumask_set_cpu(i, mask);
> +			qmask += qmask_size;
> +		}
> +	}
> +	len += cpumask_scnprintf(buf + len, PAGE_SIZE, mask);
> +	if (PAGE_SIZE - len < 3) {
> +		rcu_read_unlock();
> +		free_cpumask_var(mask);
> +		return -EINVAL;
> +	}
> +	rcu_read_unlock();
> +
> +	free_cpumask_var(mask);
> +	len += sprintf(buf + len, "\n");
> +	return len;
> +}
> +
> +static void xps_map_release(struct rcu_head *rcu)
> +{
> +	struct xps_map *map = container_of(rcu, struct xps_map, rcu);
> +
> +	kfree(map);
> +}
> +
> +static DEFINE_MUTEX(xps_map_lock);
> +
> +static ssize_t store_xps_map(struct netdev_queue *queue,
> +		      struct netdev_queue_attribute *attribute,
> +		      const char *buf, size_t len)
> +{
> +	struct net_device *dev = queue->dev;
> +	struct xps_map *maps;
> +	cpumask_var_t mask;
> +	int err, i, nonempty = 0;
> +	unsigned long *qmask, index;
> +	unsigned int qmask_size = QUEUE_MASK_SIZE(dev);
> +
> +	if (!capable(CAP_NET_ADMIN))
> +		return -EPERM;
> +
> +	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
> +		return -ENOMEM;
> +
> +	err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
> +	if (err) {
> +		free_cpumask_var(mask);
> +		return err;
> +	}
> +
> +	mutex_lock(&xps_map_lock);
> +
> +	maps = dev->xps_maps;
> +	if (!maps) {
> +		if (!cpumask_weight(mask)) {
> +			mutex_unlock(&xps_map_lock);
> +			free_cpumask_var(mask);
> +			return 0;
> +		}
> +		maps = kzalloc(XPS_MAP_SIZE(dev), GFP_KERNEL);
> +		if (!maps) {
> +			mutex_unlock(&xps_map_lock);
> +			free_cpumask_var(mask);
> +			return -ENOMEM;
> +		}
> +		rcu_assign_pointer(dev->xps_maps, maps);
> +	}
> +
> +	index = get_netdev_queue_index(queue);
> +
> +	qmask = maps->queues;
> +	for (i = 0; i < num_possible_cpus(); i++) {
> +		if (cpu_isset(i, *mask) && cpu_online(i)) {
> +			set_bit(index, qmask);
> +			nonempty = 1;
> +		} else
> +			clear_bit(index, qmask);
> +		if (!nonempty &&
> +		    bitmap_weight(qmask, dev->real_num_tx_queues))
> +			nonempty = 1;
> +		qmask += qmask_size;
> +	}
> +
> +	if (!nonempty) {
> +		rcu_assign_pointer(dev->xps_maps, NULL);
> +		call_rcu(&maps->rcu, xps_map_release);
> +	}
> +
> +	mutex_unlock(&xps_map_lock);
> +
> +	free_cpumask_var(mask);
> +	return len;
> +}
> +
> +static struct netdev_queue_attribute xps_cpus_attribute =
> +    __ATTR(xps_cpus, S_IRUGO | S_IWUSR, show_xps_map, store_xps_map);
> +
> +static struct attribute *netdev_queue_default_attrs[] = {
> +	&xps_cpus_attribute.attr,
> +	NULL
> +};
> +
> +static void netdev_queue_release(struct kobject *kobj)
> +{
> +	struct netdev_queue *queue = to_netdev_queue(kobj);
> +	struct net_device *dev = queue->dev;
> +	struct netdev_queue *first = queue->first;
> +	struct xps_map *maps;
> +	unsigned long *qmask, index;
> +	int i, nonempty = 0;
> +	unsigned int qmask_size = QUEUE_MASK_SIZE(dev);
> +
> +	index = get_netdev_queue_index(queue);
> +
> +	mutex_lock(&xps_map_lock);
> +
> +	maps = dev->xps_maps;
> +
> +	if (maps) {
> +		qmask = maps->queues;
> +		for (i = 0; i < num_possible_cpus(); i++) {
> +			clear_bit(index, qmask);
> +			if (!nonempty &&
> +			    bitmap_weight(qmask, dev->real_num_tx_queues))
> +				nonempty = 1;
> +			qmask += qmask_size;
> +		}
> +
> +		if (!nonempty) {
> +			rcu_assign_pointer(dev->xps_maps, NULL);
> +			call_rcu(&maps->rcu, xps_map_release);
> +		}
> +	}
> +	mutex_unlock(&xps_map_lock);
> +
> +	if (atomic_dec_and_test(&first->count)) {
> +		kfree(first);
> +		dev_put(dev);
> +	}
> +}
> +
> +static struct kobj_type netdev_queue_ktype = {
> +	.sysfs_ops = &netdev_queue_sysfs_ops,
> +	.release = netdev_queue_release,
> +	.default_attrs = netdev_queue_default_attrs,
> +};
> +
> +static int netdev_queue_add_kobject(struct net_device *net, int index)
> +{
> +	struct netdev_queue *queue = net->_tx + index;
> +	struct kobject *kobj = &queue->kobj;
> +	int error = 0;
> +
> +	kobj->kset = net->queues_kset;
> +	error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL,
> +	    "tx-%u", index);
> +	if (error) {
> +		kobject_put(kobj);
> +		return error;
> +	}
> +
> +	kobject_uevent(kobj, KOBJ_ADD);
> +
> +	return error;
> +}
> +
> +static int register_queue_kobjects(struct net_device *net)
> +{
> +	int rx = 0, tx = 0;
>  	int error = 0;
>  
>  	net->queues_kset = kset_create_and_add("queues",
>  	    NULL, &net->dev.kobj);
>  	if (!net->queues_kset)
>  		return -ENOMEM;
> -	for (i = 0; i < net->num_rx_queues; i++) {
> -		error = rx_queue_add_kobject(net, i);
> +
> +	for (rx = 0; rx < net->num_rx_queues; rx++) {
> +		error = rx_queue_add_kobject(net, rx);
>  		if (error)
> -			break;
> +			goto error;
>  	}
>  
> -	if (error)
> -		while (--i >= 0)
> -			kobject_put(&net->_rx[i].kobj);
> +	for (tx = 0; tx < net->num_tx_queues; tx++) {
> +		error = netdev_queue_add_kobject(net, tx);
> +		if (error)
> +			goto error;
> +	}
> +	dev_hold(net);
> +
> +	return error;
> +
> +error:
> +	while (--rx >= 0)
> +		kobject_put(&net->_rx[rx].kobj);
> +
> +	while (--tx >= 0)
> +		kobject_put(&net->_tx[tx].kobj);
>  
>  	return error;
>  }
>  
> -static void rx_queue_remove_kobjects(struct net_device *net)
> +static void remove_queue_kobjects(struct net_device *net)
>  {
>  	int i;
>  
>  	for (i = 0; i < net->num_rx_queues; i++)
>  		kobject_put(&net->_rx[i].kobj);
> +	for (i = 0; i < net->num_tx_queues; i++)
> +		kobject_put(&net->_tx[i].kobj);
>  	kset_unregister(net->queues_kset);
>  }
>  #endif /* CONFIG_RPS */
> @@ -871,7 +1132,7 @@ void netdev_unregister_kobject(struct net_device * net)
>  	kobject_get(&dev->kobj);
>  
>  #ifdef CONFIG_RPS
> -	rx_queue_remove_kobjects(net);
> +	remove_queue_kobjects(net);
>  #endif
>  
>  	device_del(dev);
> @@ -912,7 +1173,7 @@ int netdev_register_kobject(struct net_device *net)
>  		return error;
>  
>  #ifdef CONFIG_RPS
> -	error = rx_queue_register_kobjects(net);
> +	error = register_queue_kobjects(net);
>  	if (error) {
>  		device_del(dev);
>  		return error;
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index de3bd84..80c1928 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -828,8 +828,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
>  							   &md5);
>  	tcp_header_size = tcp_options_size + sizeof(struct tcphdr);
>  
> -	if (tcp_packets_in_flight(tp) == 0)
> +	if (tcp_packets_in_flight(tp) == 0) {
>  		tcp_ca_event(sk, CA_EVENT_TX_START);
> +		skb->ooo_okay = 1;
> +	}
>  
>  	skb_push(skb, tcp_header_size);
>  	skb_reset_transport_header(skb);

Why don't we do this in the normal transmit processing.
There is already so much policy mechanism filters/actions/qdisc that
doing it in higher level is fighting against these.



-- 

^ permalink raw reply

* Re: [PATCH] xps-mq: Transmit Packet Steering for multiqueue
From: Ben Hutchings @ 2010-08-23 17:50 UTC (permalink / raw)
  To: Tom Herbert; +Cc: davem, netdev, eric.dumazet
In-Reply-To: <AANLkTinST5zaS0NtBjrzyLbsg=w_EVsHE3DCDcrmQNc6@mail.gmail.com>

On Mon, 2010-08-23 at 10:30 -0700, Tom Herbert wrote:
> 
> 
> On Mon, Aug 23, 2010 at 10:09 AM, Ben Hutchings
> <bhutchings@solarflare.com> wrote:
>         On Sun, 2010-08-22 at 22:39 -0700, Tom Herbert wrote:
>         [...]
>         > Each transmit queue can be associated with a number of CPUs
>         which will
>         > used the queue to send packets.  This is configured as a CPU
>         mask on a
>         > per queue basis in:
>         >
>         > /sys/class/net/eth<n>/queues/tx-<n>/xps_cpus
>         >
>         > The mappings are stored per device in an inverted data
>         structure that
>         > maps CPUs to queues.  In the netdevice structure this is an
>         array of
>         > num_possible_cpu structures where each array entry contains
>         a bit map
>         > of queues which that CPU can use.
>         
>         [...]
>         
>         The mapping of TX queue to CPU should match the affinity of
>         the
>         completion IRQ for that queue.  It should not be a separate
>         setting.
>         
>         
>         
> That implies one possible configuration, but there are others.  For
> instance, there may be fewer queues than CPUs in which case a TX queue
> would be used by more than just the CPU handling the IRQ.

The affinity of IRQs is not restricted to a single CPU either, but I
take your point.

The IRQ affinity and the mapping of sender to queue do at least need to
be coordinated, and I think that continuing to add independent knobs for
CPU affinity of closely-related objects makes it too hard for
administrators to get this right.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH net-next-2.6] net: copy_rtnl_link_stats64() simplification
From: Joe Perches @ 2010-08-23 17:47 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, Ben Hutchings
In-Reply-To: <1282583676.2486.525.camel@edumazet-laptop>

On Mon, 2010-08-23 at 19:14 +0200, Eric Dumazet wrote:
> No need to use a temporary struct rtnl_link_stats64 variable,
> just copy the source to skb buffer.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Maybe it's better to use the same argument style as copy_rtnl_link_stats

 net/core/rtnetlink.c |   36 ++++--------------------------------
 1 files changed, 4 insertions(+), 32 deletions(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f78d821..f8781db 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -610,38 +610,10 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
 	a->tx_compressed = b->tx_compressed;
 }
 
-static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
+static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *a,
+				   const struct rtnl_link_stats64 *b)
 {
-	struct rtnl_link_stats64 a;
-
-	a.rx_packets = b->rx_packets;
-	a.tx_packets = b->tx_packets;
-	a.rx_bytes = b->rx_bytes;
-	a.tx_bytes = b->tx_bytes;
-	a.rx_errors = b->rx_errors;
-	a.tx_errors = b->tx_errors;
-	a.rx_dropped = b->rx_dropped;
-	a.tx_dropped = b->tx_dropped;
-
-	a.multicast = b->multicast;
-	a.collisions = b->collisions;
-
-	a.rx_length_errors = b->rx_length_errors;
-	a.rx_over_errors = b->rx_over_errors;
-	a.rx_crc_errors = b->rx_crc_errors;
-	a.rx_frame_errors = b->rx_frame_errors;
-	a.rx_fifo_errors = b->rx_fifo_errors;
-	a.rx_missed_errors = b->rx_missed_errors;
-
-	a.tx_aborted_errors = b->tx_aborted_errors;
-	a.tx_carrier_errors = b->tx_carrier_errors;
-	a.tx_fifo_errors = b->tx_fifo_errors;
-	a.tx_heartbeat_errors = b->tx_heartbeat_errors;
-	a.tx_window_errors = b->tx_window_errors;
-
-	a.rx_compressed = b->rx_compressed;
-	a.tx_compressed = b->tx_compressed;
-	memcpy(v, &a, sizeof(a));
+	memcpy(a, b, sizeof(*b));
 }
 
 /* All VF info */



^ permalink raw reply related

* Re: [PATCH] iproute2: add 64bit support to ifstat
From: Stephen Hemminger @ 2010-08-23 17:33 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Ben Hutchings, David Miller, netdev
In-Reply-To: <1282582464.2486.479.camel@edumazet-laptop>

On Mon, 23 Aug 2010 18:54:24 +0200
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Le lundi 23 août 2010 à 09:17 -0700, Stephen Hemminger a écrit :
> > On Mon, 23 Aug 2010 16:43:23 +0100
> > Ben Hutchings <bhutchings@solarflare.com> wrote:
> > 
> > > On Mon, 2010-08-23 at 08:32 -0700, Stephen Hemminger wrote:
> > > > This commit broke iproute2 build:
> > > > 
> > > > commit be1f3c2c027cc5ad735df6a45a542ed1db7ec48b
> > > > Author: Ben Hutchings <bhutchings@solarflare.com>
> > > > Date:   Tue Jun 8 07:19:54 2010 +0000
> > > > 
> > > >     net: Enable 64-bit net device statistics on 32-bit architectures
> > > >     
> > > >     Use struct rtnl_link_stats64 as the statistics structure.
> > > > 
> > > > Iproute2 uses a the kernel exported headers, and the structure
> > > > net_device_stats which is part of the netlink IFLA_STATS message
> > > > was no longer exposed.
> > > [...]
> > > 
> > > This is not true; the kernel uses struct rtnl_link_stats for IFLA_STATS.
> > > AFAICS the only reference to struct net_device_stats in iproute2 is:
> > > 
> > > misc/ifstat.c:51:#define MAXS (sizeof(struct net_device_stats)/sizeof(unsigned long))
> > > 
> > > This should be changed to refer to the structure that is actually used.
> > 
> > Ok.
> 
> Stephen,
> 
> Here is a patch to ifstat on top of your last one.
> 
> I guess nobody tried it on a 64bit platform...
> 
> Thanks
> 
> iproute2: add 64bit support to ifstat
> 
> ifstat assumes IFLA_STATS fields are "unsigned long"
> 
> ifstat can use 64bit stats if available (IFLA_STATS64)
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> ---
> 
> diff --git a/misc/ifstat.c b/misc/ifstat.c
> index 5cf2e01..c649ee2 100644
> --- a/misc/ifstat.c
> +++ b/misc/ifstat.c
> @@ -49,7 +49,7 @@ int npatterns;
>  char info_source[128];
>  int source_mismatch;
>  
> -#define MAXS (sizeof(struct rtnl_link_stats)/sizeof(unsigned long))
> +#define MAXS (sizeof(struct rtnl_link_stats)/sizeof(__u32))
>  
>  struct ifstat_ent
>  {
> @@ -58,7 +58,7 @@ struct ifstat_ent
>  	int			ifindex;
>  	unsigned long long	val[MAXS];
>  	double			rate[MAXS];
> -	unsigned long		ival[MAXS];
> +	__u32			ival[MAXS];
>  };
>  
>  struct ifstat_ent *kern_db;
> @@ -108,8 +108,12 @@ static int get_nlmsg(const struct sockaddr_nl *who,
>  	n->name = strdup(RTA_DATA(tb[IFLA_IFNAME]));
>  	memcpy(&n->ival, RTA_DATA(tb[IFLA_STATS]), sizeof(n->ival));
>  	memset(&n->rate, 0, sizeof(n->rate));
> -	for (i=0; i<MAXS; i++)
> -		n->val[i] = n->ival[i];
> +	if (tb[IFLA_STATS64])
> +		memcpy(&n->val, RTA_DATA(tb[IFLA_STATS64]), sizeof(n->val));
> +	else
> +		for (i = 0; i < MAXS; i++)
> +			n->val[i] = n->ival[i];
> +
>  	n->next = kern_db;
>  	kern_db = n;
>  	return 0;
> 
> 

I think this breaks the wraparound detection code in this command.


-- 

^ permalink raw reply

* Re: [PATCH net-next-2.6] net: copy_rtnl_link_stats64() simplification
From: Ben Hutchings @ 2010-08-23 17:21 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1282583676.2486.525.camel@edumazet-laptop>

On Mon, 2010-08-23 at 19:14 +0200, Eric Dumazet wrote:
> No need to use a temporary struct rtnl_link_stats64 variable,
> just copy the source to skb buffer.

Yes, this makes sense.

The reason I didn't do this initially was that I was concerned about
possible tearing of asynchronously-updated stats.  Since you made
dev_get_stats() copy into a caller-provided buffer, this is no longer a
concern.

For what it's worth:

> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* [PATCH v2] driver core: platform_bus: allow runtime override of dev_pm_ops
From: Kevin Hilman @ 2010-08-23 17:18 UTC (permalink / raw)
  To: linux-kernel
  Cc: Grant Likely, Magnus Damm, Kevin Hilman, Greg Kroah-Hartman,
	Uwe Kleine-König, Paul Mundt, Magnus Damm, Eric Miao, netdev

Currently, the platform_bus allows customization of several of the
busses dev_pm_ops methods by using weak symbols so that platform code
can override them.  The weak-symbol approach is not scalable when
wanting to support multiple platforms in a single kernel binary.

Instead, provide __init methods for platform code to customize the
dev_pm_ops methods at runtime.

NOTE: after these dynamic methods are merged, the weak symbols should
      be removed from drivers/base/platform.c.  AFAIK, this will only
      affect SH and sh-mobile which should be converted to use this
      runtime approach instead of the weak symbols.  After SH &
      sh-mobile are converted, the weak symobols could be removed.

Tested on OMAP3.

Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 drivers/base/platform.c         |   35 +++++++++++++++++++++++++++++++++++
 include/linux/platform_device.h |    3 +++
 2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c6c933f..e40a773 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -976,6 +976,41 @@ struct bus_type platform_bus_type = {
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
 
+/**
+ * platform_bus_get_pm_ops: return pointer to busses dev_pm_ops
+ *
+ * This function can be used by platform code to get the current
+ * set of dev_pm_ops functions used by the platform_bus_type.
+ */
+const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
+{
+	return platform_bus_type.pm;
+}
+
+/**
+ * platform_bus_set_pm_ops: update dev_pm_ops for the platform_bus_type
+ *
+ * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
+ *
+ * Platform code can override the dev_pm_ops methods of
+ * platform_bus_type by using this function.  It is expected that
+ * platform code will first do a platform_bus_get_pm_ops(), then
+ * kmemdup it, then customize selected methods and pass a pointer to
+ * the new struct dev_pm_ops to this function.
+ *
+ * Since platform-specific code is customizing methods for *all*
+ * devices (not just platform-specific devices) it is expected that
+ * any custom overrides of these functions will keep existing behavior
+ * and simply extend it.  For example, any customization of the
+ * runtime PM methods should continue to call the pm_generic_*
+ * functions as the default ones do in addition to the
+ * platform-specific behavior.
+ */
+void __init platform_bus_set_pm_ops(struct dev_pm_ops *pm)
+{
+	platform_bus_type.pm = pm;
+}
+
 int __init platform_bus_init(void)
 {
 	int error;
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index d7ecad0..cd55d39 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr
 					struct resource *res, unsigned int n_res,
 					const void *data, size_t size);
 
+extern const struct dev_pm_ops * __init platform_bus_get_pm_ops(void);
+extern void __init platform_bus_set_pm_ops(struct dev_pm_ops *pm);
+
 /* early platform driver interface */
 struct early_platform_driver {
 	const char *class_str;
-- 
1.7.2.1

^ permalink raw reply related

* [PATCH net-next-2.6] net: copy_rtnl_link_stats64() simplification
From: Eric Dumazet @ 2010-08-23 17:14 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Ben Hutchings

No need to use a temporary struct rtnl_link_stats64 variable,
just copy the source to skb buffer.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 net/core/rtnetlink.c |   31 +------------------------------
 1 file changed, 1 insertion(+), 30 deletions(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f78d821..b2a718d 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -612,36 +612,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
 
 static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
 {
-	struct rtnl_link_stats64 a;
-
-	a.rx_packets = b->rx_packets;
-	a.tx_packets = b->tx_packets;
-	a.rx_bytes = b->rx_bytes;
-	a.tx_bytes = b->tx_bytes;
-	a.rx_errors = b->rx_errors;
-	a.tx_errors = b->tx_errors;
-	a.rx_dropped = b->rx_dropped;
-	a.tx_dropped = b->tx_dropped;
-
-	a.multicast = b->multicast;
-	a.collisions = b->collisions;
-
-	a.rx_length_errors = b->rx_length_errors;
-	a.rx_over_errors = b->rx_over_errors;
-	a.rx_crc_errors = b->rx_crc_errors;
-	a.rx_frame_errors = b->rx_frame_errors;
-	a.rx_fifo_errors = b->rx_fifo_errors;
-	a.rx_missed_errors = b->rx_missed_errors;
-
-	a.tx_aborted_errors = b->tx_aborted_errors;
-	a.tx_carrier_errors = b->tx_carrier_errors;
-	a.tx_fifo_errors = b->tx_fifo_errors;
-	a.tx_heartbeat_errors = b->tx_heartbeat_errors;
-	a.tx_window_errors = b->tx_window_errors;
-
-	a.rx_compressed = b->rx_compressed;
-	a.tx_compressed = b->tx_compressed;
-	memcpy(v, &a, sizeof(a));
+	memcpy(v, b, sizeof(*b));
 }
 
 /* All VF info */



^ permalink raw reply related

* Re: [PATCH] xps-mq: Transmit Packet Steering for multiqueue
From: Ben Hutchings @ 2010-08-23 17:09 UTC (permalink / raw)
  To: Tom Herbert; +Cc: davem, netdev, eric.dumazet
In-Reply-To: <alpine.DEB.1.00.1008222233530.31382@pokey.mtv.corp.google.com>

On Sun, 2010-08-22 at 22:39 -0700, Tom Herbert wrote:
[...]
> Each transmit queue can be associated with a number of CPUs which will
> used the queue to send packets.  This is configured as a CPU mask on a
> per queue basis in:
> 
> /sys/class/net/eth<n>/queues/tx-<n>/xps_cpus
> 
> The mappings are stored per device in an inverted data structure that
> maps CPUs to queues.  In the netdevice structure this is an array of
> num_possible_cpu structures where each array entry contains a bit map
> of queues which that CPU can use.
[...]

The mapping of TX queue to CPU should match the affinity of the
completion IRQ for that queue.  It should not be a separate setting.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH 1/1] posix clocks: introduce syscall for clock tuning.
From: Roland McGrath @ 2010-08-23 16:57 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Matthew Wilcox, Richard Cochran, john stultz, linux-api, netdev,
	linux-kernel
In-Reply-To: <201008231646.00357.arnd@arndb.de>

EOPNOTSUPP is also called ENOTSUP in userland.  ENOTSUP is the appropriate
POSIX errno code for a situation such as a clock type that cannot be used
in a certain call (like setting when you can only read it, etc.).


Thanks,
Roland

^ permalink raw reply

* [PATCH] iproute2: add 64bit support to ifstat
From: Eric Dumazet @ 2010-08-23 16:54 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Ben Hutchings, David Miller, netdev
In-Reply-To: <20100823091750.2bf87605@nehalam>

Le lundi 23 août 2010 à 09:17 -0700, Stephen Hemminger a écrit :
> On Mon, 23 Aug 2010 16:43:23 +0100
> Ben Hutchings <bhutchings@solarflare.com> wrote:
> 
> > On Mon, 2010-08-23 at 08:32 -0700, Stephen Hemminger wrote:
> > > This commit broke iproute2 build:
> > > 
> > > commit be1f3c2c027cc5ad735df6a45a542ed1db7ec48b
> > > Author: Ben Hutchings <bhutchings@solarflare.com>
> > > Date:   Tue Jun 8 07:19:54 2010 +0000
> > > 
> > >     net: Enable 64-bit net device statistics on 32-bit architectures
> > >     
> > >     Use struct rtnl_link_stats64 as the statistics structure.
> > > 
> > > Iproute2 uses a the kernel exported headers, and the structure
> > > net_device_stats which is part of the netlink IFLA_STATS message
> > > was no longer exposed.
> > [...]
> > 
> > This is not true; the kernel uses struct rtnl_link_stats for IFLA_STATS.
> > AFAICS the only reference to struct net_device_stats in iproute2 is:
> > 
> > misc/ifstat.c:51:#define MAXS (sizeof(struct net_device_stats)/sizeof(unsigned long))
> > 
> > This should be changed to refer to the structure that is actually used.
> 
> Ok.

Stephen,

Here is a patch to ifstat on top of your last one.

I guess nobody tried it on a 64bit platform...

Thanks

iproute2: add 64bit support to ifstat

ifstat assumes IFLA_STATS fields are "unsigned long"

ifstat can use 64bit stats if available (IFLA_STATS64)

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---

diff --git a/misc/ifstat.c b/misc/ifstat.c
index 5cf2e01..c649ee2 100644
--- a/misc/ifstat.c
+++ b/misc/ifstat.c
@@ -49,7 +49,7 @@ int npatterns;
 char info_source[128];
 int source_mismatch;
 
-#define MAXS (sizeof(struct rtnl_link_stats)/sizeof(unsigned long))
+#define MAXS (sizeof(struct rtnl_link_stats)/sizeof(__u32))
 
 struct ifstat_ent
 {
@@ -58,7 +58,7 @@ struct ifstat_ent
 	int			ifindex;
 	unsigned long long	val[MAXS];
 	double			rate[MAXS];
-	unsigned long		ival[MAXS];
+	__u32			ival[MAXS];
 };
 
 struct ifstat_ent *kern_db;
@@ -108,8 +108,12 @@ static int get_nlmsg(const struct sockaddr_nl *who,
 	n->name = strdup(RTA_DATA(tb[IFLA_IFNAME]));
 	memcpy(&n->ival, RTA_DATA(tb[IFLA_STATS]), sizeof(n->ival));
 	memset(&n->rate, 0, sizeof(n->rate));
-	for (i=0; i<MAXS; i++)
-		n->val[i] = n->ival[i];
+	if (tb[IFLA_STATS64])
+		memcpy(&n->val, RTA_DATA(tb[IFLA_STATS64]), sizeof(n->val));
+	else
+		for (i = 0; i < MAXS; i++)
+			n->val[i] = n->ival[i];
+
 	n->next = kern_db;
 	kern_db = n;
 	return 0;



^ permalink raw reply related

* Re: netfilter/iptables stopped logging 2.6.35-rc
From: auto595907 @ 2010-08-23 16:29 UTC (permalink / raw)
  To: maciej.rutecki; +Cc: netdev, linux-kernel

>I created a Bugzilla entry at
>https://bugzilla.kernel.org/show_bug.cgi?id=16423
>for your bug report, please add your address to the CC list in
>there, thanks!
>
>--
>Maciej Rutecki
>http://www.maciek.unixy.pl


this patch fixes the bug above
(http://marc.info/?l=netfilter-devel&m=128116762801769&w=2)


thanks. 

(forgot the subject last time, sorry)

^ permalink raw reply

* Re: [PATCH] netdev: re-expose net_device_stats to user headers
From: Stephen Hemminger @ 2010-08-23 16:17 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: David Miller, netdev
In-Reply-To: <1282578203.2267.27.camel@achroite.uk.solarflarecom.com>

On Mon, 23 Aug 2010 16:43:23 +0100
Ben Hutchings <bhutchings@solarflare.com> wrote:

> On Mon, 2010-08-23 at 08:32 -0700, Stephen Hemminger wrote:
> > This commit broke iproute2 build:
> > 
> > commit be1f3c2c027cc5ad735df6a45a542ed1db7ec48b
> > Author: Ben Hutchings <bhutchings@solarflare.com>
> > Date:   Tue Jun 8 07:19:54 2010 +0000
> > 
> >     net: Enable 64-bit net device statistics on 32-bit architectures
> >     
> >     Use struct rtnl_link_stats64 as the statistics structure.
> > 
> > Iproute2 uses a the kernel exported headers, and the structure
> > net_device_stats which is part of the netlink IFLA_STATS message
> > was no longer exposed.
> [...]
> 
> This is not true; the kernel uses struct rtnl_link_stats for IFLA_STATS.
> AFAICS the only reference to struct net_device_stats in iproute2 is:
> 
> misc/ifstat.c:51:#define MAXS (sizeof(struct net_device_stats)/sizeof(unsigned long))
> 
> This should be changed to refer to the structure that is actually used.

Ok.

^ permalink raw reply

* Re: [PATCH] netdev: re-expose net_device_stats to user headers
From: Ben Hutchings @ 2010-08-23 15:43 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20100823083258.0777e83d@nehalam>

On Mon, 2010-08-23 at 08:32 -0700, Stephen Hemminger wrote:
> This commit broke iproute2 build:
> 
> commit be1f3c2c027cc5ad735df6a45a542ed1db7ec48b
> Author: Ben Hutchings <bhutchings@solarflare.com>
> Date:   Tue Jun 8 07:19:54 2010 +0000
> 
>     net: Enable 64-bit net device statistics on 32-bit architectures
>     
>     Use struct rtnl_link_stats64 as the statistics structure.
> 
> Iproute2 uses a the kernel exported headers, and the structure
> net_device_stats which is part of the netlink IFLA_STATS message
> was no longer exposed.
[...]

This is not true; the kernel uses struct rtnl_link_stats for IFLA_STATS.
AFAICS the only reference to struct net_device_stats in iproute2 is:

misc/ifstat.c:51:#define MAXS (sizeof(struct net_device_stats)/sizeof(unsigned long))

This should be changed to refer to the structure that is actually used.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH iproute2] ip: add RTA_MARK support
From: Stephen Hemminger @ 2010-08-23 15:41 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, David Miller
In-Reply-To: <1279705370.2452.45.camel@edumazet-laptop>

On Wed, 21 Jul 2010 11:42:50 +0200
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Adds support for RTA_MARK rt attribute added in linux-2.6.36
> 
> $ ip route get ADDR mark 4
> 192.168.20.110 dev eth1  src 192.168.20.108  mark 4
>     cache  mtu 1500 advmss 1460 hoplimit 64
> 
> $ ip route get 192.168.20.108 from ADDR iif STRING mark 256
> local 192.168.20.108 from 192.168.20.110 dev lo  src 192.168.20.108  mark 0x100
>     cache <local,src-direct>  iif eth1
> 
> $ ip route list cache [ADDR] mark NUMBER
> 
> Hexadecimal output if mark >= 16
> null marks are not displayed.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied

-- 

^ permalink raw reply

* Re: [Patch 1/2] s2io: remove lro parameter
From: Jon Mason @ 2010-08-23 15:41 UTC (permalink / raw)
  To: Cong Wang
  Cc: netdev@vger.kernel.org, bhutchings@solarflare.com,
	Ramkrishna Vepa, sgruszka@redhat.com, davem@davemloft.net
In-Reply-To: <4C72346C.9020606@redhat.com>

On Mon, Aug 23, 2010 at 01:42:20AM -0700, Cong Wang wrote:
> On 08/20/10 16:54, Cong Wang wrote:
> > On 08/18/10 23:36, Jon Mason wrote:
> >> On Wed, Aug 18, 2010 at 12:51:09AM -0700, Amerigo Wang wrote:
> >>>
> >>> As suggested by David, this parameter can die, we can use ethtool
> >>> to turn LRO on/off. Compile tests only.
> >>
> >> Needs some additional removal
> >>
> >> Line 41 and 42 " * lro: Specifies whether to enable Large Receive ..."
> >> As you have removed the modparm
> >>
> >> Line 8286 "if (sp->lro)"
> >> As it will always be on in this instance
> >>
> >>
> >> Also, all references to "sp->lro" can be converted to "(dev->features
> >> & NETIF_F_LRO)", removing an unnecessary variable.
> >>
> >
> > Thanks for pointing these out.
> > I will fix them later.
> >
> 
> Done, please review the patch below.

Looks good to me.  Push it formally, and I'll ack it.

Thanks,
Jon

> 
> Thanks!
> 
> -- 
> 
> Remove "lro" parameter of s2io driver.
> 
> Signed-off-by: WANG Cong <amwang@redhat.com>

> diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
> index 18bc5b7..b3a30ac 100644
> --- a/drivers/net/s2io.c
> +++ b/drivers/net/s2io.c
> @@ -38,8 +38,6 @@
>   * Tx descriptors that can be associated with each corresponding FIFO.
>   * intr_type: This defines the type of interrupt. The values can be 0(INTA),
>   *     2(MSI_X). Default value is '2(MSI_X)'
> - * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
> - *     Possible values '1' for enable '0' for disable. Default is '0'
>   * lro_max_pkts: This parameter defines maximum number of packets can be
>   *     aggregated as a single large packet
>   * napi: This parameter used to enable/disable NAPI (polling Rx)
> @@ -496,8 +494,6 @@ S2IO_PARM_INT(rxsync_frequency, 3);
>  /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
>  S2IO_PARM_INT(intr_type, 2);
>  /* Large receive offload feature */
> -static unsigned int lro_enable = 1;
> -module_param_named(lro, lro_enable, uint, 0);
>  
>  /* Max pkts to be aggregated by LRO at one time. If not specified,
>   * aggregation happens until we hit max IP pkt size(64K)
> @@ -6735,13 +6731,10 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
>  		return -EINVAL;
>  
>  	if (data & ETH_FLAG_LRO) {
> -		if (lro_enable) {
> -			if (!(dev->features & NETIF_F_LRO)) {
> -				dev->features |= NETIF_F_LRO;
> -				changed = 1;
> -			}
> -		} else
> -			rc = -EINVAL;
> +		if (!(dev->features & NETIF_F_LRO)) {
> +			dev->features |= NETIF_F_LRO;
> +			changed = 1;
> +		}
>  	} else if (dev->features & NETIF_F_LRO) {
>  		dev->features &= ~NETIF_F_LRO;
>  		changed = 1;
> @@ -6750,7 +6743,6 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
>  	if (changed && netif_running(dev)) {
>  		s2io_stop_all_tx_queue(sp);
>  		s2io_card_down(sp);
> -		sp->lro = !!(dev->features & NETIF_F_LRO);
>  		rc = s2io_card_up(sp);
>  		if (rc)
>  			s2io_reset(sp);
> @@ -7307,7 +7299,7 @@ static int s2io_card_up(struct s2io_nic *sp)
>  		struct ring_info *ring = &mac_control->rings[i];
>  
>  		ring->mtu = dev->mtu;
> -		ring->lro = sp->lro;
> +		ring->lro = !!(dev->features & NETIF_F_LRO);
>  		ret = fill_rx_buffers(sp, ring, 1);
>  		if (ret) {
>  			DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
> @@ -7341,7 +7333,7 @@ static int s2io_card_up(struct s2io_nic *sp)
>  	/* Setting its receive mode */
>  	s2io_set_multicast(dev);
>  
> -	if (sp->lro) {
> +	if (dev->features & NETIF_F_LRO) {
>  		/* Initialize max aggregatable pkts per session based on MTU */
>  		sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu;
>  		/* Check if we can use (if specified) user provided value */
> @@ -7911,7 +7903,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
>  	else
>  		sp->device_type = XFRAME_I_DEVICE;
>  
> -	sp->lro = lro_enable;
>  
>  	/* Initialize some PCI/PCI-X fields of the NIC. */
>  	s2io_init_pci(sp);
> @@ -8047,8 +8038,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
>  	dev->netdev_ops = &s2io_netdev_ops;
>  	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
>  	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
> -	if (lro_enable)
> -		dev->features |= NETIF_F_LRO;
> +	dev->features |= NETIF_F_LRO;
>  	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
>  	if (sp->high_dma_flag == true)
>  		dev->features |= NETIF_F_HIGHDMA;
> @@ -8283,9 +8273,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
>  			  dev->name);
>  	}
>  
> -	if (sp->lro)
> -		DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
> -			  dev->name);
> +	DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
> +		  dev->name);
>  	if (ufo)
>  		DBG_PRINT(ERR_DBG,
>  			  "%s: UDP Fragmentation Offload(UFO) enabled\n",
> diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
> index 0af0335..26c7884 100644
> --- a/drivers/net/s2io.h
> +++ b/drivers/net/s2io.h
> @@ -971,7 +971,6 @@ struct s2io_nic {
>  
>  	unsigned long	clubbed_frms_cnt;
>  	unsigned long	sending_both;
> -	u8		lro;
>  	u16		lro_max_aggr_per_sess;
>  	volatile unsigned long state;
>  	u64		general_int_mask;


^ permalink raw reply

* [PATCH] netdev: re-expose net_device_stats to user headers
From: Stephen Hemminger @ 2010-08-23 15:32 UTC (permalink / raw)
  To: David Miller; +Cc: Ben Hutchings, netdev

This commit broke iproute2 build:

commit be1f3c2c027cc5ad735df6a45a542ed1db7ec48b
Author: Ben Hutchings <bhutchings@solarflare.com>
Date:   Tue Jun 8 07:19:54 2010 +0000

    net: Enable 64-bit net device statistics on 32-bit architectures
    
    Use struct rtnl_link_stats64 as the statistics structure.

Iproute2 uses a the kernel exported headers, and the structure
net_device_stats which is part of the netlink IFLA_STATS message
was no longer exposed.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
This patch needs to be applied to net-2.6 (2.6.36)
    

--- a/include/linux/netdevice.h	2010-08-23 08:22:17.801906612 -0700
+++ b/include/linux/netdevice.h	2010-08-23 08:25:23.502078638 -0700
@@ -165,6 +165,8 @@ static inline bool dev_xmit_complete(int
 #define MAX_HEADER (LL_MAX_HEADER + 48)
 #endif
 
+#endif  /*  __KERNEL__  */
+
 /*
  *	Old network device statistics. Fields are native words
  *	(unsigned long) so they can be read and written atomically.
@@ -196,9 +198,6 @@ struct net_device_stats {
 	unsigned long	tx_compressed;
 };
 
-#endif  /*  __KERNEL__  */
-
-
 /* Media selection options. */
 enum {
         IF_PORT_UNKNOWN = 0,

^ permalink raw reply

* Re: [PATCH] driver core: platform_bus: allow runtime override of dev_pm_ops
From: Grant Likely @ 2010-08-23 15:30 UTC (permalink / raw)
  To: Grant Likely, Kevin Hilman
  Cc: Magnus Damm, Greg Kroah-Hartman, Uwe Kleine-König,
	Paul Mundt, Magnus Damm, Eric Miao, linux-kernel, netdev
In-Reply-To: <4cb3d19e-ab7a-495f-b48c-70e3ec9f3b9b@email.android.com>



"Grant Likely" <grant.likely@secretlab.ca> wrote:

>
>
>"Kevin Hilman" <khilman@deeprootsystems.com> wrote:
>
>>From: Kevin Hilman <khilman@ti.com>
>>
>>Currently, the platform_bus allows customization of several of the
>>busses dev_pm_ops methods by using weak symbols so that platform code
>>can override them.  The weak-symbol approach is not scalable when
>>wanting to support multiple platforms in a single kernel binary.
>>
>>Instead, provide __init methods for platform code to customize the
>>dev_pm_ops methods at runtime.
>>
>>NOTE: after these dynamic methods are merged, the weak symbols should
>>      be removed from drivers/base/platform.c.  AFAIK, this will only
>>      affect SH and sh-mobile which should be converted to use this
>>      runtime approach instead of the weak symbols.  After SH &
>>      sh-mobile are converted, the weak symobols could be removed.
>>
>>Tested on OMAP3.
>>
>>Cc: Grant Likely <grant.likely@secretlab.ca>
>>Cc: Magnus Damm <magnus.damm@gmail.com>
>>Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
>>---
>> drivers/base/platform.c         |   16 ++++++++++++++++
>> include/linux/platform_device.h |    3 +++
>> 2 files changed, 19 insertions(+), 0 deletions(-)
>>
>>diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>>index c6c933f..a7d8a00 100644
>>--- a/drivers/base/platform.c
>>+++ b/drivers/base/platform.c
>>@@ -976,6 +976,22 @@ struct bus_type platform_bus_type = {
>> };
>> EXPORT_SYMBOL_GPL(platform_bus_type);
>> 
>>+const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
>>+{
>>+	struct bus_type *bus = &platform_bus_type;
>>+
>>+	return bus->pm;
>>+}
>>+
>>+int __init platform_bus_set_pm_ops(struct dev_pm_ops *pm)
>>+{
>>+	struct bus_type *bus = &platform_bus_type;
>>+
>>+	bus->pm = pm;
>>+
>>+	return 0;
>>+}
>>+

Another (minor) note, these can be more concise.  The set open function can have a void return, and bus = &platform_bus_type lines are unnecessary.

g.

>-- 
>Sent from my Android phone with K-9 Mail. Please excuse my brevity.

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.

^ permalink raw reply

* [PATCH] driver core: platform_bus: allow runtime override of dev_pm_ops
From: Kevin Hilman @ 2010-08-23 15:28 UTC (permalink / raw)
  To: linux-kernel
  Cc: Grant Likely, Magnus Damm, Greg Kroah-Hartman,
	Uwe Kleine-König, Paul Mundt, Magnus Damm, Kevin Hilman,
	Eric Miao, netdev

From: Kevin Hilman <khilman@ti.com>

Currently, the platform_bus allows customization of several of the
busses dev_pm_ops methods by using weak symbols so that platform code
can override them.  The weak-symbol approach is not scalable when
wanting to support multiple platforms in a single kernel binary.

Instead, provide __init methods for platform code to customize the
dev_pm_ops methods at runtime.

NOTE: after these dynamic methods are merged, the weak symbols should
      be removed from drivers/base/platform.c.  AFAIK, this will only
      affect SH and sh-mobile which should be converted to use this
      runtime approach instead of the weak symbols.  After SH &
      sh-mobile are converted, the weak symobols could be removed.

Tested on OMAP3.

Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
Apolgies for duplicate mails.  I fat-fingered the LKML list addr the first try.

 drivers/base/platform.c         |   16 ++++++++++++++++
 include/linux/platform_device.h |    3 +++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c6c933f..a7d8a00 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -976,6 +976,22 @@ struct bus_type platform_bus_type = {
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
 
+const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
+{
+	struct bus_type *bus = &platform_bus_type;
+
+	return bus->pm;
+}
+
+int __init platform_bus_set_pm_ops(struct dev_pm_ops *pm)
+{
+	struct bus_type *bus = &platform_bus_type;
+
+	bus->pm = pm;
+
+	return 0;
+}
+
 int __init platform_bus_init(void)
 {
 	int error;
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index d7ecad0..4bce2c9 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -138,6 +138,9 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr
 					struct resource *res, unsigned int n_res,
 					const void *data, size_t size);
 
+extern const struct dev_pm_ops * __init platform_bus_get_pm_ops(void);
+extern int __init platform_bus_set_pm_ops(struct dev_pm_ops *pm);
+
 /* early platform driver interface */
 struct early_platform_driver {
 	const char *class_str;
-- 
1.7.2.1


^ permalink raw reply related

* Re: [iproute2] iproute2:  Fix filtering related to flushing IP addresses.
From: Stephen Hemminger @ 2010-08-23 15:15 UTC (permalink / raw)
  To: Ben Greear; +Cc: netdev
In-Reply-To: <1281978008-6383-1-git-send-email-greearb@candelatech.com>

On Mon, 16 Aug 2010 10:00:08 -0700
Ben Greear <greearb@candelatech.com> wrote:

> The old 'ip addr flush' logic had several flaws:
> 
> * It reversed logic for primary v/s secondary flags
>   (though, it sort of worked right anyway)
> 
> * The code tried to remove secondaries and then primaries,
>   but in practice, it always removed one primary per loop,
>   which not at all efficient.
> 
> * The filter logic in the core would run only the first
>   filter in most cases.
> 
> * If you used '-s -s', the ifa_flags member would be
>   modified, which could make future filters fail
>   to function fine.
> 
> This patch attempts to fix all of these issues.
> 
> Tested-by: Brian Haley <brian.haley@hp.com>
> Signed-off-by: Ben Greear <greearb@candelatech.com>

applied

-- 

^ permalink raw reply

* Re: [PATCH] iproute2: dont filter cached routes on iproute_get
From: Stephen Hemminger @ 2010-08-23 15:15 UTC (permalink / raw)
  To: Ulrich Weber; +Cc: Andreas Henriksson, Fabio Comolli, netdev
In-Reply-To: <20100812090519.GA13769@babylon>

On Thu, 12 Aug 2010 11:05:19 +0200
Ulrich Weber <uweber@astaro.com> wrote:

> iproute_get will return cloned routes for IPv4
> and cloned as well non-cloned routes for IPv6.
> 
> Therefore RTM_F_CLONED flag should not be checked
> for iproute_get routes. Check in print_route will
> always fail because valid values are 0 and 1.
> 
> Signed-off-by: Ulrich Weber <uweber@astaro.com>
> ---
>  ip/iproute.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/ip/iproute.c b/ip/iproute.c
> index 711576e..b43933c 100644
> --- a/ip/iproute.c
> +++ b/ip/iproute.c
> @@ -1286,6 +1286,7 @@ int iproute_get(int argc, char **argv)
>  	memset(&req, 0, sizeof(req));
>  
>  	iproute_reset_filter();
> +	filter.cloned = 2;
>  
>  	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
>  	req.n.nlmsg_flags = NLM_F_REQUEST;

Applied

-- 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox