Netdev List
 help / color / mirror / Atom feed
* [PATCH] ipv6: address issue in __ip6_append_data
From: Madalin Bucur @ 2015-02-13 15:30 UTC (permalink / raw)
  To: netdev, vyasevich; +Cc: davem, Madalin Bucur

Hello,

I think I've found a problem that allows generic IPv6 traffic to be
sent by the stack with CHECKSUM_PARTIAL to a netdevice that declares
NETIF_F_IPV6_CSUM. The NETIF_F_IPV6_CSUM flag is based on the
NETIF_F_IPV6_CSUM_BIT that is described as referring only to TCP and
UDP but in my test ICMPv6 frames with CHECKSUM_PARTIAL are seen:

NETIF_F_IPV6_CSUM_BIT,          /* Can checksum TCP/UDP over IPV6 */

I've traced the issue to a recent commit that includes this check:

	rt->dst.dev->features & NETIF_F_V6_CSUM

The problem with this is that NETIF_F_V6_CSUM is more than one bit:

#define NETIF_F_V6_CSUM         (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)

Thus the above check should be either:

	(rt->dst.dev->features & NETIF_F_V6_CSUM) == NETIF_F_V6_CSUM

or probably should use NETIF_F_HW_CSUM only:

	rt->dst.dev->features & NETIF_F_HW_CSUM

The mentioned commit is 32dce968dd987adfb0c00946d78dad9154f64759

> Author: Vlad Yasevich <vyasevich@gmail.com>
> Date:   Sat Jan 31 10:40:18 2015 -0500
>
>	ipv6: Allow for partial checksums on non-ufo packets
>
>	Currntly, if we are not doing UFO on the packet, all UDP
>	packets will start with CHECKSUM_NONE and thus perform full
>	checksum computations in software even if device support
>	IPv6 checksum offloading.

>	Let's start start with CHECKSUM_PARTIAL if the device
>	supports it and we are sending only a single packet at
>	or below mtu size.

>	Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
>	Signed-off-by: David S. Miller <davem@davemloft.net>

Reverting this commit solved the issue, then the changes below were
validated as well. The problem was evidentiated by running ping6
but it should be visible with any IPv6 payload that it is not UDP
nor TCP.

Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com>
---
 net/ipv6/ip6_output.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index d33df4c..7177f63 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1275,7 +1275,7 @@ emsgsize:
 	 */
 	if (!skb &&
 	    length + fragheaderlen < mtu &&
-	    rt->dst.dev->features & NETIF_F_V6_CSUM &&
+	    (rt->dst.dev->features & NETIF_F_V6_CSUM) == NETIF_F_V6_CSUM &&
 	    !exthdrlen)
 		csummode = CHECKSUM_PARTIAL;
 	/*
-- 
1.7.11.7

^ permalink raw reply related

* Question on Bonding driver
From: Murali Karicheri @ 2015-02-13 17:11 UTC (permalink / raw)
  To: netdev, WingMan Kwok

Hi,

I am working to enable bonding driver on my hardware and trying to 
understand this.

I am using the alb mode. I create a bond interface with 2 ethernet 
interfaces. First one is the basic question about net driver itself and 
second is about bonding.

1. Each ethernet interface has a MAC address. The hardware has MAC 
filter and the driver fills the net_device's dev_addr with its MAC 
address before calling register_netdev() API. When the net core calls 
ndo_start(), is the low level driver responsible for setting up its MAC 
address in the MAC filter of the hardware or low level driver will be 
told to do so by upper layer. Or is it required to set it up as part of 
ndo_set_rx_mode() or ndo_set_mac_address()?

2. In the case of bonding, the bond interface MAC address is copied from 
the active slave's MAC address. Also it updates the dev_addr in the 
netdev struct of each of the slave with its own MAC address. So I 
assume, the device/NIC now needs to accept packets to its original MAC 
address as well the bond's MAC address. This is especially more 
important for the slave's that are not active slave as it can be target 
of packets from Peers as part of rlb. So for the slave that is not 
active slave, MAC filter needs to include its original hw address as 
well unless the slave is put to promiscuous mode. So I am trying to 
figure out how this is expected to work? All slaves put to promiscuous 
mode or MAC filter updated by slave driver to include MAC addresses it 
is expected to filter on (bond MAC address and its own MAC address)

-- 
Murali Karicheri
Linux Kernel, Texas Instruments

^ permalink raw reply

* RE: [E1000-devel] [PATCH 1/3] ixgbe, ixgbevf: Add new mbox API to enable MC promiscuous mode
From: Skidmore, Donald C @ 2015-02-13 17:26 UTC (permalink / raw)
  To: Hiroshi Shimamoto, Kirsher, Jeffrey T, vyasevic@redhat.com
  Cc: Alexander Duyck, Bjørn Mork,
	e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org,
	Choi, Sy Jong, linux-kernel@vger.kernel.org, David Laight,
	Hayato Momma
In-Reply-To: <7F861DC0615E0C47A872E6F3C5FCDDBD05E2E9CE@BPXM14GP.gisp.nec.co.jp>



> -----Original Message-----
> From: Hiroshi Shimamoto [mailto:h-shimamoto@ct.jp.nec.com]
> Sent: Thursday, February 12, 2015 8:45 PM
> To: Skidmore, Donald C; Kirsher, Jeffrey T
> Cc: Alexander Duyck; Bjørn Mork; e1000-devel@lists.sourceforge.net;
> netdev@vger.kernel.org; Choi, Sy Jong; linux-kernel@vger.kernel.org; David
> Laight; Hayato Momma
> Subject: RE: [E1000-devel] [PATCH 1/3] ixgbe, ixgbevf: Add new mbox API to
> enable MC promiscuous mode
> 
> > > > -----Original Message-----
> > > > From: Hiroshi Shimamoto [mailto:h-shimamoto@ct.jp.nec.com]
> > > > Sent: Monday, February 09, 2015 6:29 PM
> > > > To: Kirsher, Jeffrey T
> > > > Cc: Alexander Duyck; Skidmore, Donald C; Bjørn Mork; e1000-
> > > > devel@lists.sourceforge.net; netdev@vger.kernel.org; Choi, Sy
> > > > Jong; linux- kernel@vger.kernel.org; David Laight; Hayato Momma
> > > > Subject: RE: [E1000-devel] [PATCH 1/3] ixgbe, ixgbevf: Add new
> > > > mbox API to enable MC promiscuous mode
> > > >
> > > > > > > > Can you please fix up your patches based on my tree:
> > > > > > > > git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/que
> > > > > > > > ue.git
> > > > > > >
> > > > > > > Yes. I haven't noticed your tree.
> > > > > > > Will resend patches against it.
> > > > > > >
> > > > > >
> > > > > > I encountered an issue with your tree, the commit id is below.
> > > > > >
> > > > > > $ git log | head
> > > > > > commit e6f1649780f8f5a87299bf6af04453f93d1e3d5e
> > > > > > Author: Rasmus Villemoes <linux@rasmusvillemoes.dk>
> > > > > > Date:   Fri Jan 23 20:43:14 2015 -0800
> > > > > >
> > > > > >     ethernet: fm10k: Actually drop 4 bits
> > > > > >
> > > > > >     The comment explains the intention, but vid has type u16. Before
> the
> > > > > >     inner shift, it is promoted to int, which has plenty of space for all
> > > > > >     vid's bits, so nothing is dropped. Use a simple mask instead.
> > > > > >
> > > > > >
> > > > > > I use the kernel from your tree in both host and guest.
> > > > > >
> > > > > > Assign an IPv6 for VF in guest.
> > > > > > # ip -6 addr add 2001:db8::18:1/64 dev ens0
> > > > > >
> > > > > > Send ping packet from other server to the VM.
> > > > > > # ping6  2001:db8::18:1 -I eth0
> > > > > >
> > > > > > The following message was shown.
> > > > > > ixgbevf 0000:00:08.0: partial checksum but l4 proto=3a!
> > > > > >
> > > > > > If I did the same operation in the host, I saw the same error
> > > > > > message in
> > > > host too.
> > > > > > ixgbe 0000:2d:00.0: partial checksum but l4 proto=3a!
> > > > > >
> > > > > > Do you have any idea about that?
> > > > >
> > > > > Ah, sorry about that, try this tree again:
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/queue.git
> > > > >
> > > > > That patch was dropped for favor of a patch that Matthew Vick
> > > > > put together (and recently got pushed upstream).  So my queue no
> > > > > longer has that patch in the queue, since it got dropped.
> > > >
> > > > I still see the same error, the head id is the below
> > > >
> > > > $ git log | head
> > > > commit a072afb0b45904022b76deef3b770ee9a93cb13a
> > > > Author: Nicholas Krause <xerofoify@gmail.com>
> > > > Date:   Mon Feb 9 00:27:00 2015 -0800
> > > >
> > > >     igb: Remove outdated fix me comment in the
> > > > function,gb_acquire_swfw_sync_i210
> > > >
> > > >
> > > > thanks,
> > > > Hiroshi
> > >
> > > I'm having our validation see if they can recreate the same issue
> > > internally.  When they get back to me I'll let you
> > know
> > > what we found.
> >
> > We did bisect, and the below looks the culprit;
> >
> > 32dce968dd987adfb0c00946d78dad9154f64759 is the first bad commit
> > commit 32dce968dd987adfb0c00946d78dad9154f64759
> > Author: Vlad Yasevich <vyasevich@gmail.com>
> > Date:   Sat Jan 31 10:40:18 2015 -0500
> >
> >     ipv6: Allow for partial checksums on non-ufo packets
> >
> >     Currntly, if we are not doing UFO on the packet, all UDP
> >     packets will start with CHECKSUM_NONE and thus perform full
> >     checksum computations in software even if device support
> >     IPv6 checksum offloading.
> >
> >     Let's start start with CHECKSUM_PARTIAL if the device
> >     supports it and we are sending only a single packet at
> >     or below mtu size.
> >
> >     Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
> >     Signed-off-by: David S. Miller <davem@davemloft.net>
> >
> > :040000 040000 4437eaf7e944f5a6136ebf668a256fee688fda3d
> fade8da998d35c8da97a15f0556949ad371e5347 M      net
> 
> When I reverted the commit, the issue was solved.
> 
> thanks,
> Hiroshi

I believe the issue is that this patch (32dce968dd98 - ipv6: Allow for partial checksums on non-ufo packets) is that it now sets CHECKSUM_PARTIAL on all IPv6 packets including ICMPv6 ones.  Our HW (82599) only supports checksum offload on TCP/UDP (NETIF_F_IPV6_CSUM) so we get hung up on the skb's protocol and the fact that it is CHECKSUM_PARTIAL.

Another thing that confuses me is the feature test in this patch.  It checks (rt->dst.dev->features & NETIF_F_V6_CSUM) but NETIF_F_V6_CSUM is a two bit field?  

#define NETIF_F_V6_CSUM         (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)

So the test would succeed if either bit was high, that doesn't seem right.  I cc'd the author so maybe he could clue us in.

Thanks,
-Don Skidmore <donald.c.skidmore@intel.com>



^ permalink raw reply

* Re: [PATCH 1/3] ixgbe, ixgbevf: Add new mbox API to enable MC promiscuous mode
From: Vlad Yasevich @ 2015-02-13 17:34 UTC (permalink / raw)
  To: Skidmore, Donald C, Hiroshi Shimamoto, Kirsher, Jeffrey T
  Cc: e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org,
	Choi, Sy Jong, linux-kernel@vger.kernel.org, David Laight,
	Hayato Momma, Bjørn Mork
In-Reply-To: <F6FB0E698C9B3143BDF729DF22286646912A1A50@ORSMSX110.amr.corp.intel.com>

On 02/13/2015 12:26 PM, Skidmore, Donald C wrote:
> 
> 
>> -----Original Message-----
>> From: Hiroshi Shimamoto [mailto:h-shimamoto@ct.jp.nec.com]
>> Sent: Thursday, February 12, 2015 8:45 PM
>> To: Skidmore, Donald C; Kirsher, Jeffrey T
>> Cc: Alexander Duyck; Bjørn Mork; e1000-devel@lists.sourceforge.net;
>> netdev@vger.kernel.org; Choi, Sy Jong; linux-kernel@vger.kernel.org; David
>> Laight; Hayato Momma
>> Subject: RE: [E1000-devel] [PATCH 1/3] ixgbe, ixgbevf: Add new mbox API to
>> enable MC promiscuous mode
>>
>>>>> -----Original Message-----
>>>>> From: Hiroshi Shimamoto [mailto:h-shimamoto@ct.jp.nec.com]
>>>>> Sent: Monday, February 09, 2015 6:29 PM
>>>>> To: Kirsher, Jeffrey T
>>>>> Cc: Alexander Duyck; Skidmore, Donald C; Bjørn Mork; e1000-
>>>>> devel@lists.sourceforge.net; netdev@vger.kernel.org; Choi, Sy
>>>>> Jong; linux- kernel@vger.kernel.org; David Laight; Hayato Momma
>>>>> Subject: RE: [E1000-devel] [PATCH 1/3] ixgbe, ixgbevf: Add new
>>>>> mbox API to enable MC promiscuous mode
>>>>>
>>>>>>>>> Can you please fix up your patches based on my tree:
>>>>>>>>> git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/que
>>>>>>>>> ue.git
>>>>>>>>
>>>>>>>> Yes. I haven't noticed your tree.
>>>>>>>> Will resend patches against it.
>>>>>>>>
>>>>>>>
>>>>>>> I encountered an issue with your tree, the commit id is below.
>>>>>>>
>>>>>>> $ git log | head
>>>>>>> commit e6f1649780f8f5a87299bf6af04453f93d1e3d5e
>>>>>>> Author: Rasmus Villemoes <linux@rasmusvillemoes.dk>
>>>>>>> Date:   Fri Jan 23 20:43:14 2015 -0800
>>>>>>>
>>>>>>>     ethernet: fm10k: Actually drop 4 bits
>>>>>>>
>>>>>>>     The comment explains the intention, but vid has type u16. Before
>> the
>>>>>>>     inner shift, it is promoted to int, which has plenty of space for all
>>>>>>>     vid's bits, so nothing is dropped. Use a simple mask instead.
>>>>>>>
>>>>>>>
>>>>>>> I use the kernel from your tree in both host and guest.
>>>>>>>
>>>>>>> Assign an IPv6 for VF in guest.
>>>>>>> # ip -6 addr add 2001:db8::18:1/64 dev ens0
>>>>>>>
>>>>>>> Send ping packet from other server to the VM.
>>>>>>> # ping6  2001:db8::18:1 -I eth0
>>>>>>>
>>>>>>> The following message was shown.
>>>>>>> ixgbevf 0000:00:08.0: partial checksum but l4 proto=3a!
>>>>>>>
>>>>>>> If I did the same operation in the host, I saw the same error
>>>>>>> message in
>>>>> host too.
>>>>>>> ixgbe 0000:2d:00.0: partial checksum but l4 proto=3a!
>>>>>>>
>>>>>>> Do you have any idea about that?
>>>>>>
>>>>>> Ah, sorry about that, try this tree again:
>>>>>> git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/queue.git
>>>>>>
>>>>>> That patch was dropped for favor of a patch that Matthew Vick
>>>>>> put together (and recently got pushed upstream).  So my queue no
>>>>>> longer has that patch in the queue, since it got dropped.
>>>>>
>>>>> I still see the same error, the head id is the below
>>>>>
>>>>> $ git log | head
>>>>> commit a072afb0b45904022b76deef3b770ee9a93cb13a
>>>>> Author: Nicholas Krause <xerofoify@gmail.com>
>>>>> Date:   Mon Feb 9 00:27:00 2015 -0800
>>>>>
>>>>>     igb: Remove outdated fix me comment in the
>>>>> function,gb_acquire_swfw_sync_i210
>>>>>
>>>>>
>>>>> thanks,
>>>>> Hiroshi
>>>>
>>>> I'm having our validation see if they can recreate the same issue
>>>> internally.  When they get back to me I'll let you
>>> know
>>>> what we found.
>>>
>>> We did bisect, and the below looks the culprit;
>>>
>>> 32dce968dd987adfb0c00946d78dad9154f64759 is the first bad commit
>>> commit 32dce968dd987adfb0c00946d78dad9154f64759
>>> Author: Vlad Yasevich <vyasevich@gmail.com>
>>> Date:   Sat Jan 31 10:40:18 2015 -0500
>>>
>>>     ipv6: Allow for partial checksums on non-ufo packets
>>>
>>>     Currntly, if we are not doing UFO on the packet, all UDP
>>>     packets will start with CHECKSUM_NONE and thus perform full
>>>     checksum computations in software even if device support
>>>     IPv6 checksum offloading.
>>>
>>>     Let's start start with CHECKSUM_PARTIAL if the device
>>>     supports it and we are sending only a single packet at
>>>     or below mtu size.
>>>
>>>     Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
>>>     Signed-off-by: David S. Miller <davem@davemloft.net>
>>>
>>> :040000 040000 4437eaf7e944f5a6136ebf668a256fee688fda3d
>> fade8da998d35c8da97a15f0556949ad371e5347 M      net
>>
>> When I reverted the commit, the issue was solved.
>>
>> thanks,
>> Hiroshi
> 
> I believe the issue is that this patch (32dce968dd98 - ipv6: Allow for partial checksums on non-ufo packets) is that it now sets CHECKSUM_PARTIAL on all IPv6 packets including ICMPv6 ones.  Our HW (82599) only supports checksum offload on TCP/UDP (NETIF_F_IPV6_CSUM) so we get hung up on the skb's protocol and the fact that it is CHECKSUM_PARTIAL.
> 
> Another thing that confuses me is the feature test in this patch.  It checks (rt->dst.dev->features & NETIF_F_V6_CSUM) but NETIF_F_V6_CSUM is a two bit field?  
> 
> #define NETIF_F_V6_CSUM         (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
> 
> So the test would succeed if either bit was high, that doesn't seem right.  I cc'd the author so maybe he could clue us in.

This has been addressed by:
commit bf250a1fa769f2eb8fc7a4e28b3b523e9cb67eef
Author: Vlad Yasevich <vyasevich@gmail.com>
Date:   Tue Feb 10 11:37:29 2015 -0500

    ipv6: Partial checksum only UDP packets


As far the 2 bit issue, GEN_CSUM (HW_SUM) and IPV6_CSUM can not coexist at the same time.
See netdev_fix_features().

-vlad

> 
> Thanks,
> -Don Skidmore <donald.c.skidmore@intel.com>
> 
> 


------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
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] bridge: make it possible for packets to traverse the bridge withour hitting netfilter
From: Imre Palik @ 2015-02-13 17:45 UTC (permalink / raw)
  To: Florian Westphal
  Cc: David Miller, bridge, stephen, netdev, linux-kernel, imrep,
	aliguori
In-Reply-To: <20150213163703.GC15141@breakpoint.cc>

On 02/13/15 17:37, Florian Westphal wrote:
> Imre Palik <imrep.amz@gmail.com> wrote:
>> On 02/11/15 23:29, David Miller wrote:
>>> If I apply this, someone is going to try to submit a patch for every
>>> damn protocol layer to add a stupid hack like this.
>>
>> Actually this is one of those patches.  There is already a "stupid hack like this" for iptables and arptables.  (Implemented before git history, and giving me 10% speedup.  Many thanks, whoever did it.)
>>
>> I also searched various LKML archives, and it seems the existing "stupid hacks" for iptables and arptables haven't resulted in any related patch submission in the last ten years.  (Or my google-fu is weak.)
>>
>> Moreover, I cannot imagine any other reasonable on/off switch for bridge-netfilter than these three.  Of course, my imagination might be lacking there.
> 
> Why do you load the bridge netfilter module if you don't want it?
> Loading it registers the internal hooks for the call-ip(6)tables and
> sabotage hooks with NF_BRIDGE protocol so most of the NF_HOOK(NF_BRIDGE, ...
> calls become active.
> 

The trouble is that there are some bridges (with low traffic) where I need netfilter, and some other bridges (carrying lots of traffic), where I don't.  Being able to set things up on a per bridge basis is a powerful thing.

I only implemented the global switch because the iptables and arptables support also have one.  If this is what bugs people here, I can remove it, and resubmit.

^ permalink raw reply

* Re: [PATCH net-next 2/3] ipv4: Use binary search to choose tcp PMTU probe_size
From: John Heffner @ 2015-02-13 17:52 UTC (permalink / raw)
  To: Fan Du; +Cc: David Miller, Netdev, fengyuleidian0615
In-Reply-To: <1423815405-32644-3-git-send-email-fan.du@intel.com>

On Fri, Feb 13, 2015 at 3:16 AM, Fan Du <fan.du@intel.com> wrote:
> Current probe_size is chosen by doubling mss_cache,
> the initial mss base is 512 Bytes, as a result the
> converged probe_size will only be 1024 Bytes, there
> is still big gap between 1024 and common 1500 bytes
> of mtu.
>
> Use binary search to choose probe_size in a fine
> granularity manner, an optimal mss will be found
> to boost performance as its maxmium.
>
> Test env:
> Docker instance with vxlan encapuslation(82599EB)
> iperf -c 10.0.0.24  -t 60
>
> before this patch:
> 1.26 Gbits/sec
>
> After this patch: increase 26%
> 1.59 Gbits/sec
>
> Signed-off-by: Fan Du <fan.du@intel.com>

Thanks for looking into making mtu probing better.  Improving the
search strategy is commendable.  One high level comment though is that
there's some cost associated with probing and diminishing returns the
smaller the interval (search_high - search_low), so there should be
some threshold below which further probing is deemed no longer useful.

Aside from that, some things in this patch don't look right to me.
Comments inline below.


> ---
>  include/net/inet_connection_sock.h |    3 +++
>  net/ipv4/tcp_input.c               |    5 ++++-
>  net/ipv4/tcp_output.c              |   12 +++++++++---
>  net/ipv4/tcp_timer.c               |    2 +-
>  4 files changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
> index 5976bde..3d0932e 100644
> --- a/include/net/inet_connection_sock.h
> +++ b/include/net/inet_connection_sock.h
> @@ -124,6 +124,9 @@ struct inet_connection_sock {
>                 int               search_high;
>                 int               search_low;
>
> +               int               search_high_sav;
> +               int               search_low_sav;
> +
>                 /* Information on the current probe. */
>                 int               probe_size;
>         } icsk_mtup;


What are these for?  They're assigned but not used.


> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index 8fdd27b..20b28e9 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -2613,7 +2613,10 @@ static void tcp_mtup_probe_success(struct sock *sk)
>         tp->snd_cwnd_stamp = tcp_time_stamp;
>         tp->snd_ssthresh = tcp_current_ssthresh(sk);
>
> -       icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size;
> +       if (icsk->icsk_mtup.search_low == icsk->icsk_mtup.probe_size)
> +               icsk->icsk_mtup.search_low = icsk->icsk_mtup.search_high;
> +       else
> +               icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size;
>         icsk->icsk_mtup.probe_size = 0;
>         tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
>  }

It would be cleaner to handle this in tcp_mtu_probe, in deciding
whether to issue a probe, than to change the semantics of search_high
and search_low.  Issuing a probe where probe_size == search_low seems
like the wrong thing to do.


> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index a2a796c..0a60deb 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -1349,10 +1349,13 @@ void tcp_mtup_init(struct sock *sk)
>         struct inet_connection_sock *icsk = inet_csk(sk);
>         struct net *net = sock_net(sk);
>
> -       icsk->icsk_mtup.enabled = net->ipv4.sysctl_tcp_mtu_probing > 1;
> +       icsk->icsk_mtup.enabled = net->ipv4.sysctl_tcp_mtu_probing;
>         icsk->icsk_mtup.search_high = tp->rx_opt.mss_clamp + sizeof(struct tcphdr) +
>                                icsk->icsk_af_ops->net_header_len;
>         icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, net->ipv4.sysctl_tcp_base_mss);
> +
> +       icsk->icsk_mtup.search_high_sav = icsk->icsk_mtup.search_high;
> +       icsk->icsk_mtup.search_low_sav = icsk->icsk_mtup.search_low;
>         icsk->icsk_mtup.probe_size = 0;
>  }
>  EXPORT_SYMBOL(tcp_mtup_init);

You're changing the meaning of sysctl_tcp_mtu_probing.  I don't think
that's what you want.  From Documentation/networking/ip-sysctl.txt:

tcp_mtu_probing - INTEGER
Controls TCP Packetization-Layer Path MTU Discovery.  Takes three
values:
 0 - Disabled
 1 - Disabled by default, enabled when an ICMP black hole detected
 2 - Always enabled, use initial MSS of tcp_base_mss.



> diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
> index 0732b78..9d1cfe0 100644
> --- a/net/ipv4/tcp_timer.c
> +++ b/net/ipv4/tcp_timer.c
> @@ -113,7 +113,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
>                         struct tcp_sock *tp = tcp_sk(sk);
>                         int mss;
>
> -                       mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1;
> +                       mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low);
>                         mss = min(net->ipv4.sysctl_tcp_base_mss, mss);
>                         mss = max(mss, 68 - tp->tcp_header_len);
>                         icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);

Why did you change this?  I think this breaks black hole detection.

Thanks,
  -John

^ permalink raw reply

* e any as
From: Dorine Kaszinski @ 2015-02-13 18:01 UTC (permalink / raw)
  To: See Pankhurst

 since been corrupted into our familiar "filibuster," is said to have been originally a corruption, being nothing more than the French method of pronouncing the word "

^ permalink raw reply

* Re: [PATCH RFC v5 net-next 4/6] virtio-net: add basic interrupt coalescing support
From: Cornelia Huck @ 2015-02-13 18:19 UTC (permalink / raw)
  To: Rusty Russell
  Cc: pagupta, Pawel Moll, Michael S. Tsirkin, netdev, linux-kernel,
	virtualization
In-Reply-To: <874mqqbk12.fsf@rustcorp.com.au>

On Fri, 13 Feb 2015 13:22:09 +1030
Rusty Russell <rusty@rustcorp.com.au> wrote:

> "Michael S. Tsirkin" <mst@redhat.com> writes:
> > On Tue, Feb 10, 2015 at 12:02:37PM +1030, Rusty Russell wrote:
> >> Jason Wang <jasowang@redhat.com> writes:
> >> > This patch enables the interrupt coalescing setting through ethtool.
> >> 
> >> The problem is that there's nothing network specific about interrupt
> >> coalescing.  I can see other devices wanting exactly the same thing,
> >> which means we'd deprecate this in the next virtio standard.
> >> 
> >> I think the right answer is to extend like we did with
> >> vring_used_event(), eg:
> >> 
> >> 1) Add a new feature VIRTIO_F_RING_COALESCE.
> >> 2) Add another a 32-bit field after vring_used_event(), eg:
> >>         #define vring_used_delay(vr) (*(u32 *)((vr)->avail->ring[(vr)->num + 2]))
> >> 
> >> This loses the ability to coalesce by number of frames, but we can still
> >> do number of sg entries, as we do now with used_event, and we could
> >> change virtqueue_enable_cb_delayed() to take a precise number if we
> >> wanted.
> >
> > But do we expect delay to be update dynamically?
> > If not, why not stick it in config space?
> 
> Hmm, we could update it dynamically (and will, in the case of ethtool).
> But it won't be common, so we could append a field to
> virtio_pci_common_cfg for PCI.
> 
> I think MMIO and CCW would be easy to extend too, but CC'd to check.

If this is a simple extension of the config space, it should just work
for ccw (the Linux guest driver currently uses 0x100 as max config
space size, which I grabbed from pci at the time I wrote it).

But looking at this virtio_pci_common_cfg stuff, it seems to contain a
lot of things that are handled via ccws on virtio-ccw (like number of
queues or device status). Having an extra ccw just for changing this
delay value seems like overkill.

On the basic topic of interrupt coalescing: With adapter interrupts,
virtio-ccw already has some kind of coalescing: The summary indicator
is set just once and an interrupt is made pending, then individual
queue indicators are switched on and no further interrupt is generated
if the summary indicator has not been cleared by the guest yet. I'm not
sure how it would be different if an individual queue indicator is
switched on later. Chances are that the guest code processing the
indicators has not even yet processed to that individual indicator, so
it wouldn't matter if it was set delayed. It is probably something that
has to be tried out.

^ permalink raw reply

* Re: If bridge have no sub-interfaces, it's status may be still with 'RUNNING'
From: Stephen Hemminger @ 2015-02-13 18:30 UTC (permalink / raw)
  To: yzhu1; +Cc: netdev, Wu, Kuaikuai, Tao, Yue
In-Reply-To: <54DDCA99.4040401@windriver.com>

On Fri, 13 Feb 2015 17:57:45 +0800
yzhu1 <Yanjun.Zhu@windriver.com> wrote:

> Hi, all
> 
> I made this test on ubuntu 14.04 with kernel 3,19-rc7:
> 
> 1. brctl addbr br0
> 
> 2. ifconfig br0 up
> 
> 3. ifconfig br0 (br0's status is with 'RUNNING')
> 
> 4. brctl addif br0 eth0
> 
> 5. brctl delif br0 eth0
> 
> 6. ifconfig br0 (br0's status is without 'RUNNING')
> 
> When there is no sub-interface, the flag "RUNNING" is missing after the 
> last sub-interface is removed.
> 
> As such, should we keep "RUNNING" flag after the last sub-interface is 
> removed?

This is intentional. If there are no active ports in bridge, then
we want to tell applications that packets will go nowhere.

^ permalink raw reply

* Re: [PATCH] bridge: make it possible for packets to traverse the bridge withour hitting netfilter
From: Florian Westphal @ 2015-02-13 19:03 UTC (permalink / raw)
  To: Imre Palik
  Cc: Florian Westphal, David Miller, bridge, stephen, netdev,
	linux-kernel, imrep, aliguori
In-Reply-To: <54DE3851.7000206@gmail.com>

Imre Palik <imrep.amz@gmail.com> wrote:
> The trouble is that there are some bridges (with low traffic) where I need netfilter, and some other bridges (carrying lots of traffic), where I don't.  Being able to set things up on a per bridge basis is a powerful thing.
> 
> I only implemented the global switch because the iptables and arptables support also have one.  If this is what bugs people here, I can remove it, and resubmit.

I see.  But I agree with David, accepting such patch would pave way
for all kinds of ugly hacks.

It seems that technically the best solution would be to allow attaching
filter rules to devices, but alas, netfilter doesn't support that.

Alternatively, you patch *might* be ok iff you can get rid of the extra
userspace-visible configuration knobs, we already have way too many of
these.

You'll also have to figure out how to avoid any run-time dependency on
br_netfilter module from the bridge core.

If you can do this, you might be able to get similar effect as your patch
by replacing

NF_HOOK with NF_HOOK_COND(..., !(br->flags & NO_NETFILTER))

or something like this.

I don't know how invasive this would be, though.

^ permalink raw reply

* Re: VLAN creation may lead to deadlock.
From: Cong Wang @ 2015-02-13 19:54 UTC (permalink / raw)
  To: Ignacy Gawedzki, netdev
In-Reply-To: <20150213120217.GA6198@zenon.in.qult.net>

On Fri, Feb 13, 2015 at 4:02 AM, Ignacy Gawedzki
<ignacy.gawedzki@green-communications.fr> wrote:
> Hi,
>
> I stumbled upon the following annoying situation: supposing eth0 is some
> interface that is currently DOWN, the following command
>
>   ip link add link eth0 name eth0.1 up type vlan id 1
>
> never returns and the kernel printks the following lines every few seconds
>
>   unregister_netdevice: waiting for eth0.1 to become free. Usage count = 2
>
> I understand that the kernel should prevent me from creating a VLAN interface
> that's initially up when loose-binding is off and the master interface is down
> (and indeed there is absolutely no problem when loose-binding is on), but the
> unregistering of the currently-being-registered device should not block like
> that.  It appears there are too few dev_puts compared to dev_holds in there.

Good catch! It looks like we forgot to call unregister_vlan_dev(),
I am cooking a patch.

^ permalink raw reply

* [PATCH iproute2 0/7] ss: Unify socket info output to common funcs
From: Vadim Kochan @ 2015-02-13 20:13 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan

From: Vadim Kochan <vadim4j@gmail.com>

Split tcpstat struct into sockstat & tcpstat, old sockstat renamed
to sksummary.

Refactored printing socket info to common funcs.

Also fixed wrong setting tcp ato value.

Vadim Kochan (7):
  ss: Split tcpstap struct to sockstat & tcpstat
  ss: Replace pktstat struct by new sockstat struct
  ss: Replace unixstat struct by new sockstat struct
  ss: Unify state socket output:netid, state, rq, wq
  ss: Unify details info output:ino,uid,sk
  ss: Unify socket address output by one generic func
  ss: Fixed wrong tcp ato value from netlink

 include/utils.h |   2 +
 lib/utils.c     |   6 +
 misc/ss.c       | 539 +++++++++++++++++++++++++++++---------------------------
 3 files changed, 290 insertions(+), 257 deletions(-)

-- 
2.2.2

^ permalink raw reply

* [PATCH iproute2 1/7] ss: Split tcpstap struct to sockstat & tcpstat
From: Vadim Kochan @ 2015-02-13 20:13 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1423858444-10158-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 154 +++++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 86 insertions(+), 68 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 0a6a65e..7e11fc0 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -690,16 +690,7 @@ static const char *sstate_namel[] = {
 	[SS_CLOSING] = "closing",
 };
 
-struct dctcpstat
-{
-	unsigned int	ce_state;
-	unsigned int	alpha;
-	unsigned int	ab_ecn;
-	unsigned int	ab_tot;
-	bool		enabled;
-};
-
-struct tcpstat
+struct sockstat
 {
 	inet_prefix	    local;
 	inet_prefix	    remote;
@@ -712,6 +703,20 @@ struct tcpstat
 	int		    refcnt;
 	unsigned int	    iface;
 	unsigned long long  sk;
+};
+
+struct dctcpstat
+{
+	unsigned int	ce_state;
+	unsigned int	alpha;
+	unsigned int	ab_ecn;
+	unsigned int	ab_tot;
+	bool		enabled;
+};
+
+struct tcpstat
+{
+	struct sockstat	    ss;
 	int		    timer;
 	int		    timeout;
 	int		    probes;
@@ -999,7 +1004,7 @@ static int unix_match(const inet_prefix *a, const inet_prefix *p)
 	return !fnmatch(pattern, addr, 0);
 }
 
-static int run_ssfilter(struct ssfilter *f, struct tcpstat *s)
+static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
 {
 	switch (f->type) {
 		case SSF_S_AUTO:
@@ -1484,7 +1489,7 @@ static char *proto_name(int protocol)
 	return "???";
 }
 
-static void inet_stats_print(struct tcpstat *s, int protocol)
+static void inet_stats_print(struct sockstat *s, int protocol)
 {
 	char *buf = NULL;
 
@@ -1498,17 +1503,6 @@ static void inet_stats_print(struct tcpstat *s, int protocol)
 	formatted_print(&s->local, s->lport, s->iface);
 	formatted_print(&s->remote, s->rport, 0);
 
-	if (show_options) {
-		if (s->timer) {
-			if (s->timer > 4)
-				s->timer = 5;
-			printf(" timer:(%s,%s,%d)",
-			       tmr_name[s->timer],
-			       print_ms_timer(s->timeout),
-			       s->retrans);
-		}
-	}
-
 	if (show_proc_ctx || show_sock_ctx) {
 		if (find_entry(s->ino, &buf,
 				(show_proc_ctx & show_sock_ctx) ?
@@ -1524,7 +1518,8 @@ static void inet_stats_print(struct tcpstat *s, int protocol)
 	}
 }
 
-static int proc_parse_inet_addr(char *loc, char *rem, int family, struct tcpstat *s)
+static int proc_parse_inet_addr(char *loc, char *rem, int family, struct
+		sockstat *s)
 {
 	s->local.family = s->remote.family = family;
 	if (family == AF_INET) {
@@ -1655,7 +1650,7 @@ static void tcp_stats_print(struct tcpstat *s)
 		printf(" retrans:%u/%u", s->retrans, s->retrans_total);
 	if (s->lost)
 		printf(" lost:%u", s->lost);
-	if (s->sacked && s->state != SS_LISTEN)
+	if (s->sacked && s->ss.state != SS_LISTEN)
 		printf(" sacked:%u", s->sacked);
 	if (s->fackets)
 		printf(" fackets:%u", s->fackets);
@@ -1667,6 +1662,18 @@ static void tcp_stats_print(struct tcpstat *s)
 		printf(" rcv_space:%d", s->rcv_space);
 }
 
+static void tcp_timer_print(struct tcpstat *s)
+{
+	if (s->timer) {
+		if (s->timer > 4)
+			s->timer = 5;
+		printf(" timer:(%s,%s,%d)",
+				tmr_name[s->timer],
+				print_ms_timer(s->timeout),
+				s->retrans);
+	}
+}
+
 static int tcp_show_line(char *line, const struct filter *f, int family)
 {
 	int rto = 0, ato = 0;
@@ -1683,17 +1690,17 @@ static int tcp_show_line(char *line, const struct filter *f, int family)
 	if (!(f->states & (1 << state)))
 		return 0;
 
-	proc_parse_inet_addr(loc, rem, family, &s);
+	proc_parse_inet_addr(loc, rem, family, &s.ss);
 
-	if (f->f && run_ssfilter(f->f, &s) == 0)
+	if (f->f && run_ssfilter(f->f, &s.ss) == 0)
 		return 0;
 
 	opt[0] = 0;
 	n = sscanf(data, "%x %x:%x %x:%x %x %d %d %u %d %llx %d %d %d %d %d %[^\n]\n",
-		   &s.state, &s.wq, &s.rq,
-		   &s.timer, &s.timeout, &s.retrans, &s.uid, &s.probes, &s.ino,
-		   &s.refcnt, &s.sk, &rto, &ato, &s.qack,
-		   &s.cwnd, &s.ssthresh, opt);
+		   &s.ss.state, &s.ss.wq, &s.ss.rq,
+		   &s.timer, &s.timeout, &s.retrans, &s.ss.uid, &s.probes,
+		   &s.ss.ino, &s.ss.refcnt, &s.ss.sk, &rto, &ato, &s.qack, &s.cwnd,
+		   &s.ssthresh, opt);
 
 	if (n < 17)
 		opt[0] = 0;
@@ -1713,13 +1720,16 @@ static int tcp_show_line(char *line, const struct filter *f, int family)
 	s.ssthresh  = s.ssthresh == -1 ? 0 : s.ssthresh;
 	s.rto	    = s.rto != 3 * hz  ? s.rto / hz : 0;
 
-	inet_stats_print(&s, IPPROTO_TCP);
+	inet_stats_print(&s.ss, IPPROTO_TCP);
+
+	if (show_options)
+		tcp_timer_print(&s);
 
 	if (show_details) {
-		if (s.uid)
-			printf(" uid:%u", (unsigned)s.uid);
-		printf(" ino:%u", s.ino);
-		printf(" sk:%llx", s.sk);
+		if (s.ss.uid)
+			printf(" uid:%u", (unsigned)s.ss.uid);
+		printf(" ino:%u", s.ss.ino);
+		printf(" sk:%llx", s.ss.sk);
 		if (opt[0])
 			printf(" opt:\"%s\"", opt);
 	}
@@ -1804,6 +1814,8 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
 	double rtt = 0;
 	struct tcpstat s = {};
 
+	s.ss.state = r->idiag_state;
+
 	print_skmeminfo(tb, INET_DIAG_SKMEMINFO);
 
 	if (tb[INET_DIAG_INFO]) {
@@ -1913,7 +1925,7 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
 {
 	struct rtattr * tb[INET_DIAG_MAX+1];
 	struct inet_diag_msg *r = NLMSG_DATA(nlh);
-	struct tcpstat s = {};
+	struct sockstat s = {};
 
 	parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr*)(r+1),
 		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
@@ -1924,9 +1936,6 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
 	s.rport = ntohs(r->id.idiag_dport);
 	s.wq = r->idiag_wqueue;
 	s.rq = r->idiag_rqueue;
-	s.timer = r->idiag_timer;
-	s.timeout = r->idiag_expires;
-	s.retrans = r->idiag_retrans;
 	s.ino = r->idiag_inode;
 	s.uid = r->idiag_uid;
 	s.iface = r->id.idiag_if;
@@ -1945,6 +1954,15 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
 
 	inet_stats_print(&s, protocol);
 
+	if (show_options) {
+		struct tcpstat t = {};
+
+		t.timer = r->idiag_timer;
+		t.timeout = r->idiag_expires;
+		t.retrans = r->idiag_retrans;
+		tcp_timer_print(&t);
+	}
+
 	if (show_details) {
 		if (r->idiag_uid)
 			printf(" uid:%u", (unsigned)r->idiag_uid);
@@ -2286,7 +2304,7 @@ outerr:
 
 static int dgram_show_line(char *line, const struct filter *f, int family)
 {
-	struct tcpstat s = {};
+	struct sockstat s = {};
 	char *loc, *rem, *data;
 	char opt[256];
 	int n;
@@ -2483,15 +2501,15 @@ static void unix_stats_print(struct unixstat *list, struct filter *f)
 		}
 
 		if (f->f) {
-			struct tcpstat tst;
-			tst.local.family = AF_UNIX;
-			tst.remote.family = AF_UNIX;
-			memcpy(tst.local.data, &s->name, sizeof(s->name));
+			struct sockstat st;
+			st.local.family = AF_UNIX;
+			st.remote.family = AF_UNIX;
+			memcpy(st.local.data, &s->name, sizeof(s->name));
 			if (strcmp(peer, "*") == 0)
-				memset(tst.remote.data, 0, sizeof(peer));
+				memset(st.remote.data, 0, sizeof(peer));
 			else
-				memcpy(tst.remote.data, &peer, sizeof(peer));
-			if (run_ssfilter(f->f, &tst) == 0)
+				memcpy(st.remote.data, &peer, sizeof(peer));
+			if (run_ssfilter(f->f, &st) == 0)
 				continue;
 		}
 
@@ -2716,14 +2734,14 @@ static int packet_stats_print(struct pktstat *s, const struct filter *f)
 	char *buf = NULL;
 
 	if (f->f) {
-		struct tcpstat tst;
-		tst.local.family = AF_PACKET;
-		tst.remote.family = AF_PACKET;
-		tst.rport = 0;
-		tst.lport = s->iface;
-		tst.local.data[0] = s->prot;
-		tst.remote.data[0] = 0;
-		if (run_ssfilter(f->f, &tst) == 0)
+		struct sockstat st;
+		st.local.family = AF_PACKET;
+		st.remote.family = AF_PACKET;
+		st.rport = 0;
+		st.lport = s->iface;
+		st.local.data[0] = s->prot;
+		st.remote.data[0] = 0;
+		if (run_ssfilter(f->f, &st) == 0)
 			return 1;
 	}
 
@@ -2899,14 +2917,14 @@ static void netlink_show_one(struct filter *f,
 	SPRINT_BUF(prot_name);
 
 	if (f->f) {
-		struct tcpstat tst;
-		tst.local.family = AF_NETLINK;
-		tst.remote.family = AF_NETLINK;
-		tst.rport = -1;
-		tst.lport = pid;
-		tst.local.data[0] = prot;
-		tst.remote.data[0] = 0;
-		if (run_ssfilter(f->f, &tst) == 0)
+		struct sockstat st;
+		st.local.family = AF_NETLINK;
+		st.remote.family = AF_NETLINK;
+		st.rport = -1;
+		st.lport = pid;
+		st.local.data[0] = prot;
+		st.remote.data[0] = 0;
+		if (run_ssfilter(f->f, &st) == 0)
 			return;
 	}
 
@@ -3117,7 +3135,7 @@ static int get_snmp_int(char *proto, char *key, int *result)
 
 /* Get stats from sockstat */
 
-struct sockstat
+struct ssummary
 {
 	int socks;
 	int tcp_mem;
@@ -3136,7 +3154,7 @@ struct sockstat
 	int frag6_mem;
 };
 
-static void get_sockstat_line(char *line, struct sockstat *s)
+static void get_sockstat_line(char *line, struct ssummary *s)
 {
 	char id[256], rem[256];
 
@@ -3165,7 +3183,7 @@ static void get_sockstat_line(char *line, struct sockstat *s)
 		       &s->tcp_orphans, &s->tcp_tws, &s->tcp_total, &s->tcp_mem);
 }
 
-static int get_sockstat(struct sockstat *s)
+static int get_sockstat(struct ssummary *s)
 {
 	char buf[256];
 	FILE *fp;
@@ -3189,7 +3207,7 @@ static int get_sockstat(struct sockstat *s)
 
 static int print_summary(void)
 {
-	struct sockstat s;
+	struct ssummary s;
 	struct snmpstat sn;
 
 	if (get_sockstat(&s) < 0)
-- 
2.2.2

^ permalink raw reply related

* [PATCH iproute2 2/7] ss: Replace pktstat struct by new sockstat struct
From: Vadim Kochan @ 2015-02-13 20:13 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1423858444-10158-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 33 ++++++++++++---------------------
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 7e11fc0..f033892 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -692,6 +692,8 @@ static const char *sstate_namel[] = {
 
 struct sockstat
 {
+	uint8_t		    type;
+	uint16_t	    prot;
 	inet_prefix	    local;
 	inet_prefix	    remote;
 	int		    lport;
@@ -2719,29 +2721,18 @@ static int unix_show(struct filter *f)
 	return 0;
 }
 
-struct pktstat {
-	uint8_t  type;
-	uint16_t prot;
-	uint32_t iface;
-	int state;
-	uint32_t rq;
-	uid_t uid;
-	ino_t ino;
-};
-
-static int packet_stats_print(struct pktstat *s, const struct filter *f)
+static int packet_stats_print(struct sockstat *s, const struct filter *f)
 {
 	char *buf = NULL;
 
 	if (f->f) {
-		struct sockstat st;
-		st.local.family = AF_PACKET;
-		st.remote.family = AF_PACKET;
-		st.rport = 0;
-		st.lport = s->iface;
-		st.local.data[0] = s->prot;
-		st.remote.data[0] = 0;
-		if (run_ssfilter(f->f, &st) == 0)
+		s->local.family = AF_PACKET;
+		s->remote.family = AF_PACKET;
+		s->rport = 0;
+		s->lport = s->iface;
+		s->local.data[0] = s->prot;
+		s->remote.data[0] = 0;
+		if (run_ssfilter(f->f, s) == 0)
 			return 1;
 	}
 
@@ -2790,7 +2781,7 @@ static int packet_show_sock(const struct sockaddr_nl *addr,
 	const struct filter *f = arg;
 	struct packet_diag_msg *r = NLMSG_DATA(nlh);
 	struct rtattr *tb[PACKET_DIAG_MAX+1];
-	struct pktstat stat = {};
+	struct sockstat stat = {};
 
 	parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr*)(r+1),
 		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
@@ -2859,7 +2850,7 @@ static int packet_show_netlink(struct filter *f)
 static int packet_show_line(char *buf, const struct filter *f, int fam)
 {
 	unsigned long long sk;
-	struct pktstat stat = {};
+	struct sockstat stat = {};
 	int type, prot, iface, state, rq, uid, ino;
 
 	sscanf(buf, "%llx %*d %d %x %d %d %u %u %u",
-- 
2.2.2

^ permalink raw reply related

* [PATCH iproute2 3/7] ss: Replace unixstat struct by new sockstat struct
From: Vadim Kochan @ 2015-02-13 20:14 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1423858444-10158-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 141 +++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 75 insertions(+), 66 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index f033892..54f2e21 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -660,6 +660,18 @@ static int get_slabstat(struct slabstat *s)
 	return 0;
 }
 
+static inline void sock_addr_set_str(inet_prefix *prefix, char **ptr)
+{
+    memcpy(prefix->data, ptr, sizeof(char *));
+}
+
+static inline char *sock_addr_get_str(const inet_prefix *prefix)
+{
+    char *tmp ;
+    memcpy(&tmp, prefix->data, sizeof(char *));
+    return tmp;
+}
+
 static const char *sstate_name[] = {
 	"UNKNOWN",
 	[SS_ESTABLISHED] = "ESTAB",
@@ -692,7 +704,8 @@ static const char *sstate_namel[] = {
 
 struct sockstat
 {
-	uint8_t		    type;
+	struct sockstat	   *next;
+	unsigned int	    type;
 	uint16_t	    prot;
 	inet_prefix	    local;
 	inet_prefix	    remote;
@@ -996,9 +1009,9 @@ static int inet2_addr_match(const inet_prefix *a, const inet_prefix *p,
 
 static int unix_match(const inet_prefix *a, const inet_prefix *p)
 {
-	char *addr, *pattern;
-	memcpy(&addr, a->data, sizeof(addr));
-	memcpy(&pattern, p->data, sizeof(pattern));
+	char *addr = sock_addr_get_str(a);
+	char *pattern = sock_addr_get_str(p);
+
 	if (pattern == NULL)
 		return 1;
 	if (addr == NULL)
@@ -1014,8 +1027,7 @@ static int run_ssfilter(struct ssfilter *f, struct sockstat *s)
                 static int low, high=65535;
 
 		if (s->local.family == AF_UNIX) {
-			char *p;
-			memcpy(&p, s->local.data, sizeof(p));
+			char *p = sock_addr_get_str(&s->local);
 			return p == NULL || (p[0] == '@' && strlen(p) == 6 &&
 					     strspn(p+1, "0123456789abcdef") == 5);
 		}
@@ -1338,7 +1350,7 @@ void *parse_hostcond(char *addr)
 			addr+=5;
 		p = strdup(addr);
 		a.addr.bitlen = 8*strlen(p);
-		memcpy(a.addr.data, &p, sizeof(p));
+		sock_addr_set_str(&a.addr, &p);
 		fam = AF_UNIX;
 		goto out;
 	}
@@ -2415,31 +2427,21 @@ outerr:
 	} while (0);
 }
 
-struct unixstat
-{
-	struct unixstat *next;
-	int ino;
-	int peer;
-	char *peer_name;
-	int rq;
-	int wq;
-	int state;
-	int type;
-	char *name;
-};
-
 int unix_state_map[] = { SS_CLOSE, SS_SYN_SENT,
 			 SS_ESTABLISHED, SS_CLOSING };
 
-#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct unixstat))
+#define MAX_UNIX_REMEMBER (1024*1024/sizeof(struct sockstat))
 
-static void unix_list_free(struct unixstat *list)
+static void unix_list_free(struct sockstat *list)
 {
 	while (list) {
-		struct unixstat *s = list;
+		struct sockstat *s = list;
+		char *name = sock_addr_get_str(&s->local);
+
 		list = list->next;
-		if (s->name)
-			free(s->name);
+
+		if (name)
+			free(name);
 		free(s);
 	}
 }
@@ -2463,7 +2465,7 @@ static const char *unix_netid_name(int type)
 	return netid;
 }
 
-static bool unix_type_skip(struct unixstat *s, struct filter *f)
+static bool unix_type_skip(struct sockstat *s, struct filter *f)
 {
 	if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
 		return true;
@@ -2474,44 +2476,49 @@ static bool unix_type_skip(struct unixstat *s, struct filter *f)
 	return false;
 }
 
-static void unix_stats_print(struct unixstat *list, struct filter *f)
+static bool unix_use_proc(void)
+{
+	return getenv("PROC_NET_UNIX") || getenv("PROC_ROOT");
+}
+
+static void unix_stats_print(struct sockstat *list, struct filter *f)
 {
-	struct unixstat *s;
-	char *peer;
+	struct sockstat *s;
+	char *local, *peer;
+	bool use_proc = unix_use_proc();
 
 	for (s = list; s; s = s->next) {
-		if (!(f->states & (1<<s->state)))
+		if (!(f->states & (1 << s->state)))
 			continue;
 		if (unix_type_skip(s, f))
 			continue;
 
-		peer = "*";
-		if (s->peer_name)
-			peer = s->peer_name;
+		local = sock_addr_get_str(&s->local);
+		peer  = "*";
+
+		if (s->rport && use_proc) {
+			struct sockstat *p;
 
-		if (s->peer && !s->peer_name) {
-			struct unixstat *p;
 			for (p = list; p; p = p->next) {
-				if (s->peer == p->ino)
+				if (s->rport == p->lport)
 					break;
 			}
+
 			if (!p) {
 				peer = "?";
 			} else {
-				peer = p->name ? : "*";
+				peer = sock_addr_get_str(&p->local);
+				peer = peer ? : "*";
 			}
 		}
 
 		if (f->f) {
-			struct sockstat st;
-			st.local.family = AF_UNIX;
-			st.remote.family = AF_UNIX;
-			memcpy(st.local.data, &s->name, sizeof(s->name));
 			if (strcmp(peer, "*") == 0)
-				memset(st.remote.data, 0, sizeof(peer));
+				memset(s->remote.data, 0, sizeof(char *));
 			else
-				memcpy(st.remote.data, &peer, sizeof(peer));
-			if (run_ssfilter(f->f, &st) == 0)
+				sock_addr_set_str(&s->remote, &peer);
+
+			if (run_ssfilter(f->f, s) == 0)
 				continue;
 		}
 
@@ -2522,8 +2529,8 @@ static void unix_stats_print(struct unixstat *list, struct filter *f)
 			printf("%-*s ", state_width, sstate_name[s->state]);
 		printf("%-6d %-6d ", s->rq, s->wq);
 		printf("%*s %-*d %*s %-*d",
-		       addr_width, s->name ? : "*", serv_width, s->ino,
-		       addr_width, peer, serv_width, s->peer);
+		       addr_width, local ? : "*", serv_width,
+		       s->lport, addr_width, peer, serv_width, s->rport);
 		char *buf = NULL;
 
 		if (show_proc_ctx || show_sock_ctx) {
@@ -2549,15 +2556,16 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 	struct filter *f = (struct filter *)arg;
 	struct unix_diag_msg *r = NLMSG_DATA(nlh);
 	struct rtattr *tb[UNIX_DIAG_MAX+1];
-	char name[128];
-	struct unixstat stat = { .name = "*" , .peer_name = "*" };
+	char *name = NULL;
+	struct sockstat stat = {};
 
 	parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
 		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
 	stat.type  = r->udiag_type;
 	stat.state = r->udiag_state;
-	stat.ino   = r->udiag_ino;
+	stat.ino   = stat.lport = r->udiag_ino;
+	stat.local.family = stat.remote.family = AF_UNIX;
 
 	if (unix_type_skip(&stat, f))
 		return 0;
@@ -2570,14 +2578,15 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 	if (tb[UNIX_DIAG_NAME]) {
 		int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
 
+		name = malloc(len + 1);
 		memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len);
 		name[len] = '\0';
 		if (name[0] == '\0')
 			name[0] = '@';
-		stat.name = &name[0];
+		sock_addr_set_str(&stat.local, &name);
 	}
 	if (tb[UNIX_DIAG_PEER])
-		stat.peer = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
+		stat.rport = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
 
 	unix_stats_print(&stat, f);
 
@@ -2594,6 +2603,9 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
 	}
 	if (show_mem || show_details)
 		printf("\n");
+
+	if (name)
+		free(name);
 	return 0;
 }
 
@@ -2640,13 +2652,12 @@ static int unix_show(struct filter *f)
 	char name[128];
 	int  newformat = 0;
 	int  cnt;
-	struct unixstat *list = NULL;
+	struct sockstat *list = NULL;
 
 	if (!filter_af_get(f, AF_UNIX))
 		return 0;
 
-	if (!getenv("PROC_NET_UNIX") && !getenv("PROC_ROOT")
-	    && unix_show_netlink(f) == 0)
+	if (!unix_use_proc() && unix_show_netlink(f) == 0)
 		return 0;
 
 	if ((fp = net_unix_open()) == NULL)
@@ -2658,31 +2669,30 @@ static int unix_show(struct filter *f)
 	cnt = 0;
 
 	while (fgets(buf, sizeof(buf)-1, fp)) {
-		struct unixstat *u, **insp;
+		struct sockstat *u, **insp;
 		int flags;
 
 		if (!(u = malloc(sizeof(*u))))
 			break;
-		u->name = NULL;
-		u->peer_name = NULL;
 
 		if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
-			   &u->peer, &u->rq, &u->wq, &flags, &u->type,
+			   &u->rport, &u->rq, &u->wq, &flags, &u->type,
 			   &u->state, &u->ino, name) < 8)
 			name[0] = 0;
 
-		if (flags&(1<<16)) {
+		u->lport = u->ino;
+		u->local.family = u->remote.family = AF_UNIX;
+
+		if (flags & (1 << 16)) {
 			u->state = SS_LISTEN;
 		} else {
 			u->state = unix_state_map[u->state-1];
-			if (u->type == SOCK_DGRAM &&
-			    u->state == SS_CLOSE &&
-			    u->peer)
+			if (u->type == SOCK_DGRAM && u->state == SS_CLOSE && u->rport)
 				u->state = SS_ESTABLISHED;
 		}
 
 		if (!newformat) {
-			u->peer = 0;
+			u->rport = 0;
 			u->rq = 0;
 			u->wq = 0;
 		}
@@ -2699,9 +2709,8 @@ static int unix_show(struct filter *f)
 		*insp = u;
 
 		if (name[0]) {
-			if ((u->name = malloc(strlen(name)+1)) == NULL)
-				break;
-			strcpy(u->name, name);
+			char *tmp = strdup(name);
+			sock_addr_set_str(&u->local, &tmp);
 		}
 		if (++cnt > MAX_UNIX_REMEMBER) {
 			unix_stats_print(list, f);
-- 
2.2.2

^ permalink raw reply related

* [PATCH iproute2 4/7] ss: Unify state socket output:netid, state, rq, wq
From: Vadim Kochan @ 2015-02-13 20:14 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1423858444-10158-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 61 ++++++++++++++++++++++++++++---------------------------------
 1 file changed, 28 insertions(+), 33 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 54f2e21..305ab38 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -765,6 +765,16 @@ struct tcpstat
 	struct dctcpstat    *dctcp;
 };
 
+static void sock_state_print(struct sockstat *s, const char *sock_name)
+{
+	if (netid_width)
+		printf("%-*s ", netid_width, sock_name);
+	if (state_width)
+		printf("%-*s ", state_width, sstate_name[s->state]);
+
+	printf("%-6d %-6d ", s->rq, s->wq);
+}
+
 static const char *tmr_name[] = {
 	"off",
 	"on",
@@ -1507,12 +1517,7 @@ static void inet_stats_print(struct sockstat *s, int protocol)
 {
 	char *buf = NULL;
 
-	if (netid_width)
-		printf("%-*s ", netid_width, proto_name(protocol));
-	if (state_width)
-		printf("%-*s ", state_width, sstate_name[s->state]);
-
-	printf("%-6d %-6d ", s->rq, s->wq);
+	sock_state_print(s, proto_name(protocol));
 
 	formatted_print(&s->local, s->lport, s->iface);
 	formatted_print(&s->remote, s->rport, 0);
@@ -2522,12 +2527,8 @@ static void unix_stats_print(struct sockstat *list, struct filter *f)
 				continue;
 		}
 
-		if (netid_width)
-			printf("%-*s ", netid_width,
-			       unix_netid_name(s->type));
-		if (state_width)
-			printf("%-*s ", state_width, sstate_name[s->state]);
-		printf("%-6d %-6d ", s->rq, s->wq);
+		sock_state_print(s, unix_netid_name(s->type));
+
 		printf("%*s %-*d %*s %-*d",
 		       addr_width, local ? : "*", serv_width,
 		       s->lport, addr_width, peer, serv_width, s->rport);
@@ -2737,21 +2738,13 @@ static int packet_stats_print(struct sockstat *s, const struct filter *f)
 	if (f->f) {
 		s->local.family = AF_PACKET;
 		s->remote.family = AF_PACKET;
-		s->rport = 0;
-		s->lport = s->iface;
 		s->local.data[0] = s->prot;
-		s->remote.data[0] = 0;
 		if (run_ssfilter(f->f, s) == 0)
 			return 1;
 	}
 
-	if (netid_width)
-		printf("%-*s ", netid_width,
-				s->type == SOCK_RAW ? "p_raw" : "p_dgr");
-	if (state_width)
-		printf("%-*s ", state_width, "UNCONN");
+	sock_state_print(s, s->type == SOCK_RAW ? "p_raw" : "p_dgr");
 
-	printf("%-6d %-6d ", s->rq, 0);
 	if (s->prot == 3) {
 		printf("%*s:", addr_width, "*");
 	} else {
@@ -2799,9 +2792,10 @@ static int packet_show_sock(const struct sockaddr_nl *addr,
 	if (!tb[PACKET_DIAG_MEMINFO])
 		return -1;
 
-	stat.type = r->pdiag_type;
-	stat.prot = r->pdiag_num;
-	stat.ino = r->pdiag_ino;
+	stat.type   = r->pdiag_type;
+	stat.prot   = r->pdiag_num;
+	stat.ino    = r->pdiag_ino;
+	stat.state  = SS_CLOSE;
 
 	if (tb[PACKET_DIAG_MEMINFO]) {
 		__u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]);
@@ -2810,7 +2804,7 @@ static int packet_show_sock(const struct sockaddr_nl *addr,
 
 	if (tb[PACKET_DIAG_INFO]) {
 		struct packet_diag_info *pinfo = RTA_DATA(tb[PACKET_DIAG_INFO]);
-		stat.iface = pinfo->pdi_index;
+		stat.lport = stat.iface = pinfo->pdi_index;
 	}
 
 	if (packet_stats_print(&stat, f))
@@ -2874,11 +2868,13 @@ static int packet_show_line(char *buf, const struct filter *f, int fam)
 
 	stat.type  = type;
 	stat.prot  = prot;
-	stat.iface = iface;
+	stat.lport = stat.iface = iface;
 	stat.state = state;
 	stat.rq    = rq;
 	stat.uid   = uid;
 	stat.ino   = ino;
+	stat.state = SS_CLOSE;
+
 	if (packet_stats_print(&stat, f))
 		return 0;
 
@@ -2914,25 +2910,24 @@ static void netlink_show_one(struct filter *f,
 				int rq, int wq,
 				unsigned long long sk, unsigned long long cb)
 {
+	struct sockstat st;
 	SPRINT_BUF(prot_name);
 
+	st.state = SS_CLOSE;
+	st.rq	 = rq;
+	st.wq	 = wq;
+
 	if (f->f) {
-		struct sockstat st;
 		st.local.family = AF_NETLINK;
 		st.remote.family = AF_NETLINK;
 		st.rport = -1;
 		st.lport = pid;
 		st.local.data[0] = prot;
-		st.remote.data[0] = 0;
 		if (run_ssfilter(f->f, &st) == 0)
 			return;
 	}
 
-	if (netid_width)
-		printf("%-*s ", netid_width, "nl");
-	if (state_width)
-		printf("%-*s ", state_width, "UNCONN");
-	printf("%-6d %-6d ", rq, wq);
+	sock_state_print(&st, "nl");
 
 	if (resolve_services) {
 		printf("%*s:", addr_width, nl_proto_n2a(prot, prot_name,
-- 
2.2.2

^ permalink raw reply related

* [PATCH iproute2 5/7] ss: Unify details info output:ino,uid,sk
From: Vadim Kochan @ 2015-02-13 20:14 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1423858444-10158-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 78 ++++++++++++++++++++++++++++-----------------------------------
 1 file changed, 35 insertions(+), 43 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 305ab38..905cec9 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -672,6 +672,11 @@ static inline char *sock_addr_get_str(const inet_prefix *prefix)
     return tmp;
 }
 
+static unsigned long cookie_sk_get(uint32_t *cookie)
+{
+	return (((unsigned long)cookie[1] << 31) << 1) | cookie[0];
+}
+
 static const char *sstate_name[] = {
 	"UNKNOWN",
 	[SS_ESTABLISHED] = "ESTAB",
@@ -775,6 +780,15 @@ static void sock_state_print(struct sockstat *s, const char *sock_name)
 	printf("%-6d %-6d ", s->rq, s->wq);
 }
 
+static void sock_details_print(struct sockstat *s)
+{
+	if (s->uid)
+		printf(" uid:%u", s->uid);
+
+	printf(" ino:%u", s->ino);
+	printf(" sk:%llx", s->sk);
+}
+
 static const char *tmr_name[] = {
 	"off",
 	"on",
@@ -1745,10 +1759,7 @@ static int tcp_show_line(char *line, const struct filter *f, int family)
 		tcp_timer_print(&s);
 
 	if (show_details) {
-		if (s.ss.uid)
-			printf(" uid:%u", (unsigned)s.ss.uid);
-		printf(" ino:%u", s.ss.ino);
-		printf(" sk:%llx", s.ss.sk);
+		sock_details_print(&s.ss);
 		if (opt[0])
 			printf(" opt:\"%s\"", opt);
 	}
@@ -1949,15 +1960,16 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
 	parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr*)(r+1),
 		     nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
 
-	s.state = r->idiag_state;
-	s.local.family = s.remote.family = r->idiag_family;
-	s.lport = ntohs(r->id.idiag_sport);
-	s.rport = ntohs(r->id.idiag_dport);
-	s.wq = r->idiag_wqueue;
-	s.rq = r->idiag_rqueue;
-	s.ino = r->idiag_inode;
-	s.uid = r->idiag_uid;
-	s.iface = r->id.idiag_if;
+	s.state		= r->idiag_state;
+	s.local.family  = s.remote.family = r->idiag_family;
+	s.lport		= ntohs(r->id.idiag_sport);
+	s.rport		= ntohs(r->id.idiag_dport);
+	s.wq		= r->idiag_wqueue;
+	s.rq		= r->idiag_rqueue;
+	s.ino		= r->idiag_inode;
+	s.uid		= r->idiag_uid;
+	s.iface		= r->id.idiag_if;
+	s.sk		= cookie_sk_get(&r->id.idiag_cookie[0]);
 
 	if (s.local.family == AF_INET) {
 		s.local.bytelen = s.remote.bytelen = 4;
@@ -1983,13 +1995,7 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
 	}
 
 	if (show_details) {
-		if (r->idiag_uid)
-			printf(" uid:%u", (unsigned)r->idiag_uid);
-		printf(" ino:%u", r->idiag_inode);
-		printf(" sk:");
-		if (r->id.idiag_cookie[1] != 0)
-			printf("%08x", r->id.idiag_cookie[1]);
-		printf("%08x", r->id.idiag_cookie[0]);
+		sock_details_print(&s);
 		if (tb[INET_DIAG_SHUTDOWN]) {
 			unsigned char mask;
 			mask = *(__u8 *)RTA_DATA(tb[INET_DIAG_SHUTDOWN]);
@@ -2351,14 +2357,8 @@ static int dgram_show_line(char *line, const struct filter *f, int family)
 
 	inet_stats_print(&s, IPPROTO_UDP);
 
-	if (show_details) {
-		if (s.uid)
-			printf(" uid=%u", (unsigned)s.uid);
-		printf(" ino=%u", s.ino);
-		printf(" sk=%llx", s.sk);
-		if (opt[0])
-			printf(" opt:\"%s\"", opt);
-	}
+	if (show_details && opt[0])
+		printf(" opt:\"%s\"", opt);
 
 	printf("\n");
 	return 0;
@@ -2774,6 +2774,9 @@ static int packet_stats_print(struct sockstat *s, const struct filter *f)
 		}
 	}
 
+	if (show_details)
+		sock_details_print(s);
+
 	return 0;
 }
 
@@ -2796,6 +2799,7 @@ static int packet_show_sock(const struct sockaddr_nl *addr,
 	stat.prot   = r->pdiag_num;
 	stat.ino    = r->pdiag_ino;
 	stat.state  = SS_CLOSE;
+	stat.sk	    = cookie_sk_get(&r->pdiag_cookie[0]);
 
 	if (tb[PACKET_DIAG_MEMINFO]) {
 		__u32 *skmeminfo = RTA_DATA(tb[PACKET_DIAG_MEMINFO]);
@@ -2807,21 +2811,12 @@ static int packet_show_sock(const struct sockaddr_nl *addr,
 		stat.lport = stat.iface = pinfo->pdi_index;
 	}
 
+	if (tb[PACKET_DIAG_UID])
+		stat.uid = *(__u32 *)RTA_DATA(tb[PACKET_DIAG_UID]);
+
 	if (packet_stats_print(&stat, f))
 		return 0;
 
-	if (show_details) {
-		__u32 uid = 0;
-
-		if (tb[PACKET_DIAG_UID])
-			uid = *(__u32 *)RTA_DATA(tb[PACKET_DIAG_UID]);
-
-		printf(" ino=%u uid=%u sk=", r->pdiag_ino, uid);
-		if (r->pdiag_cookie[1] != 0)
-			printf("%08x", r->pdiag_cookie[1]);
-		printf("%08x", r->pdiag_cookie[0]);
-	}
-
 	if (show_bpf && tb[PACKET_DIAG_FILTER]) {
 		struct sock_filter *fil =
 		       RTA_DATA(tb[PACKET_DIAG_FILTER]);
@@ -2878,9 +2873,6 @@ static int packet_show_line(char *buf, const struct filter *f, int fam)
 	if (packet_stats_print(&stat, f))
 		return 0;
 
-	if (show_details) {
-		printf(" ino=%u uid=%u sk=%llx", ino, uid, sk);
-	}
 	printf("\n");
 	return 0;
 }
-- 
2.2.2

^ permalink raw reply related

* [PATCH iproute2 6/7] ss: Unify socket address output by one generic func
From: Vadim Kochan @ 2015-02-13 20:14 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1423858444-10158-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 include/utils.h |   2 +
 lib/utils.c     |   6 +++
 misc/ss.c       | 124 ++++++++++++++++++++++++++++++++------------------------
 3 files changed, 80 insertions(+), 52 deletions(-)

diff --git a/include/utils.h b/include/utils.h
index 3da2283..fec9ef4 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -167,4 +167,6 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
 extern int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
 		bool show_label);
 
+char *int_to_str(int val, char *buf);
+
 #endif /* __UTILS_H__ */
diff --git a/lib/utils.c b/lib/utils.c
index efebe18..e2b05bc 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -906,3 +906,9 @@ int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
 
 	return netns_foreach(on_netns, &nsf);
 }
+
+char *int_to_str(int val, char *buf)
+{
+	sprintf(buf, "%d", val);
+	return buf;
+}
diff --git a/misc/ss.c b/misc/ss.c
index 905cec9..9cf0055 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -789,6 +789,24 @@ static void sock_details_print(struct sockstat *s)
 	printf(" sk:%llx", s->sk);
 }
 
+static void sock_addr_print_width(int addr_len, const char *addr, char *delim,
+		int port_len, const char *port, const char *ifname)
+{
+	if (ifname) {
+		printf("%*s%%%s%s%-*s ", addr_len, addr, ifname, delim,
+				port_len, port);
+	}
+	else {
+		printf("%*s%s%-*s ", addr_len, addr, delim, port_len, port);
+	}
+}
+
+static void sock_addr_print(const char *addr, char *delim, const char *port,
+		const char *ifname)
+{
+	sock_addr_print_width(addr_width, addr, delim, serv_width, port, ifname);
+}
+
 static const char *tmr_name[] = {
 	"off",
 	"on",
@@ -971,13 +989,12 @@ static const char *resolve_service(int port)
 	return buf;
 }
 
-static void formatted_print(const inet_prefix *a, int port, unsigned int ifindex)
+static void inet_addr_print(const inet_prefix *a, int port, unsigned int ifindex)
 {
 	char buf[1024];
 	const char *ap = buf;
-	int est_len;
-
-	est_len = addr_width;
+	int est_len = addr_width;
+	const char *ifname = NULL;
 
 	if (a->family == AF_INET) {
 		if (a->data[0] == 0) {
@@ -994,14 +1011,14 @@ static void formatted_print(const inet_prefix *a, int port, unsigned int ifindex
 		else
 			est_len = addr_width + ((est_len-addr_width+3)/4)*4;
 	}
+
 	if (ifindex) {
-		const char *ifname = ll_index_to_name(ifindex);
-		const int len = strlen(ifname) + 1;  /* +1 for percent char */
+		ifname   = ll_index_to_name(ifindex);
+		est_len -= strlen(ifname) + 1;  /* +1 for percent char */
+	}
 
-		printf("%*s%%%s:%-*s ", est_len - len, ap, ifname, serv_width,
-		       resolve_service(port));
-	} else
-		printf("%*s:%-*s ", est_len, ap, serv_width, resolve_service(port));
+	sock_addr_print_width(est_len, ap, ":", serv_width, resolve_service(port),
+			ifname);
 }
 
 struct aafilter
@@ -1533,8 +1550,8 @@ static void inet_stats_print(struct sockstat *s, int protocol)
 
 	sock_state_print(s, proto_name(protocol));
 
-	formatted_print(&s->local, s->lport, s->iface);
-	formatted_print(&s->remote, s->rport, 0);
+	inet_addr_print(&s->local, s->lport, s->iface);
+	inet_addr_print(&s->remote, s->rport, 0);
 
 	if (show_proc_ctx || show_sock_ctx) {
 		if (find_entry(s->ino, &buf,
@@ -2490,7 +2507,9 @@ static void unix_stats_print(struct sockstat *list, struct filter *f)
 {
 	struct sockstat *s;
 	char *local, *peer;
+	char *ctx_buf = NULL;
 	bool use_proc = unix_use_proc();
+	char port_name[30] = {};
 
 	for (s = list; s; s = s->next) {
 		if (!(f->states & (1 << s->state)))
@@ -2529,22 +2548,22 @@ static void unix_stats_print(struct sockstat *list, struct filter *f)
 
 		sock_state_print(s, unix_netid_name(s->type));
 
-		printf("%*s %-*d %*s %-*d",
-		       addr_width, local ? : "*", serv_width,
-		       s->lport, addr_width, peer, serv_width, s->rport);
-		char *buf = NULL;
+		sock_addr_print(local ?: "*", " ",
+				int_to_str(s->lport, port_name), NULL);
+		sock_addr_print(peer, " ", int_to_str(s->rport, port_name),
+				NULL);
 
 		if (show_proc_ctx || show_sock_ctx) {
-			if (find_entry(s->ino, &buf,
+			if (find_entry(s->ino, &ctx_buf,
 					(show_proc_ctx & show_sock_ctx) ?
 					PROC_SOCK_CTX : PROC_CTX) > 0) {
-				printf(" users:(%s)", buf);
-				free(buf);
+				printf(" users:(%s)", ctx_buf);
+				free(ctx_buf);
 			}
 		} else if (show_users) {
-			if (find_entry(s->ino, &buf, USERS) > 0) {
-				printf(" users:(%s)", buf);
-				free(buf);
+			if (find_entry(s->ino, &ctx_buf, USERS) > 0) {
+				printf(" users:(%s)", ctx_buf);
+				free(ctx_buf);
 			}
 		}
 		printf("\n");
@@ -2734,6 +2753,8 @@ static int unix_show(struct filter *f)
 static int packet_stats_print(struct sockstat *s, const struct filter *f)
 {
 	char *buf = NULL;
+	const char *addr, *port;
+	char ll_name[16];
 
 	if (f->f) {
 		s->local.family = AF_PACKET;
@@ -2745,20 +2766,18 @@ static int packet_stats_print(struct sockstat *s, const struct filter *f)
 
 	sock_state_print(s, s->type == SOCK_RAW ? "p_raw" : "p_dgr");
 
-	if (s->prot == 3) {
-		printf("%*s:", addr_width, "*");
-	} else {
-		char tb[16];
-		printf("%*s:", addr_width,
-				ll_proto_n2a(htons(s->prot), tb, sizeof(tb)));
-	}
-	if (s->iface == 0) {
-		printf("%-*s ", serv_width, "*");
-	} else {
-		printf("%-*s ", serv_width, xll_index_to_name(s->iface));
-	}
+	if (s->prot == 3)
+		addr = "*";
+	else
+		addr = ll_proto_n2a(htons(s->prot), ll_name, sizeof(ll_name));
+
+	if (s->iface == 0)
+		port = "*";
+	else
+		port = xll_index_to_name(s->iface);
 
-	printf("%*s*%-*s", addr_width, "", serv_width, "");
+	sock_addr_print(addr, ":", port, NULL);
+	sock_addr_print("", "*", "", NULL);
 
 	if (show_proc_ctx || show_sock_ctx) {
 		if (find_entry(s->ino, &buf,
@@ -2903,7 +2922,9 @@ static void netlink_show_one(struct filter *f,
 				unsigned long long sk, unsigned long long cb)
 {
 	struct sockstat st;
-	SPRINT_BUF(prot_name);
+	SPRINT_BUF(prot_buf) = {};
+	const char *prot_name;
+	char procname[64] = {};
 
 	st.state = SS_CLOSE;
 	st.rq	 = rq;
@@ -2921,46 +2942,45 @@ static void netlink_show_one(struct filter *f,
 
 	sock_state_print(&st, "nl");
 
-	if (resolve_services) {
-		printf("%*s:", addr_width, nl_proto_n2a(prot, prot_name,
-					sizeof(prot_name)));
-	} else {
-		printf("%*d:", addr_width, prot);
-	}
+	if (resolve_services)
+		prot_name = nl_proto_n2a(prot, prot_buf, sizeof(prot_buf));
+	else
+		prot_name = int_to_str(prot, prot_buf);
 
 	if (pid == -1) {
-		printf("%-*s ", serv_width, "*");
+		procname[0] = '*';
 	} else if (resolve_services) {
 		int done = 0;
 		if (!pid) {
 			done = 1;
-			printf("%-*s ", serv_width, "kernel");
+			strncpy(procname, "kernel", 6);
 		} else if (pid > 0) {
-			char procname[64];
 			FILE *fp;
 			sprintf(procname, "%s/%d/stat",
 				getenv("PROC_ROOT") ? : "/proc", pid);
 			if ((fp = fopen(procname, "r")) != NULL) {
 				if (fscanf(fp, "%*d (%[^)])", procname) == 1) {
 					sprintf(procname+strlen(procname), "/%d", pid);
-					printf("%-*s ", serv_width, procname);
 					done = 1;
 				}
 				fclose(fp);
 			}
 		}
 		if (!done)
-			printf("%-*d ", serv_width, pid);
+			int_to_str(pid, procname);
 	} else {
-		printf("%-*d ", serv_width, pid);
+		int_to_str(pid, procname);
 	}
 
+	sock_addr_print(prot_name, ":", procname, NULL);
+
 	if (state == NETLINK_CONNECTED) {
-		printf("%*d:%-*d",
-		       addr_width, dst_group, serv_width, dst_pid);
+		char dst_group_buf[30];
+		char dst_pid_buf[30];
+		sock_addr_print(int_to_str(dst_group, dst_group_buf), ":",
+				int_to_str(dst_pid, dst_pid_buf), NULL);
 	} else {
-		printf("%*s*%-*s",
-		       addr_width, "", serv_width, "");
+		sock_addr_print("", "*", "", NULL);
 	}
 
 	char *pid_context = NULL;
-- 
2.2.2

^ permalink raw reply related

* [PATCH iproute2 7/7] ss: Fixed wrong tcp ato value from netlink
From: Vadim Kochan @ 2015-02-13 20:14 UTC (permalink / raw)
  To: netdev; +Cc: Vadim Kochan
In-Reply-To: <1423858444-10158-1-git-send-email-vadim4j@gmail.com>

From: Vadim Kochan <vadim4j@gmail.com>

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
---
 misc/ss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/misc/ss.c b/misc/ss.c
index 9cf0055..69794ea 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -1903,7 +1903,7 @@ static void tcp_show_info(const struct nlmsghdr *nlh, struct inet_diag_msg *r,
 		s.backoff	 = info->tcpi_backoff;
 		s.rtt		 = (double)info->tcpi_rtt / 1000;
 		s.rttvar	 = (double)info->tcpi_rttvar / 1000;
-		s.ato		 = (double)info->tcpi_rttvar / 1000;
+		s.ato		 = (double)info->tcpi_ato / 1000;
 		s.mss		 = info->tcpi_snd_mss;
 		s.rcv_space	 = info->tcpi_rcv_space;
 		s.rcv_rtt	 = (double)info->tcpi_rcv_rtt / 1000;
-- 
2.2.2

^ permalink raw reply related

* [PATCH] net: phy: micrel: disable NAND-tree for KSZ8021,KSZ8031,KSZ8051,KSZ8081
From: Sylvain Rochet @ 2015-02-13 20:35 UTC (permalink / raw)
  To: Florian Fainelli, netdev, linux-kernel, Nicolas Ferre,
	Alexandre Belloni, voice.shen, josh.wu, ludovic.desroches,
	Boris Brezillon
  Cc: Sylvain Rochet

NAND-tree is used to check wiring between MAC and PHY using NAND gates
on the PHY side, hence the name.

NAND-tree initial status is latched at reset by probing the IRQ pin.
However some devices are sharing the PHY IRQ pin with other peripherals
such as Atmel SAMA5D[34]x-EK boards when using the optional TM7000
display module, therefore they are switching the PHY in NAND-tree test
mode depending on the current IRQ line status at reset.

This patch ensure PHY is not in NAND-tree test mode for all Micrel PHYs
using IRQ line as a NAND-tree toggle mode at reset.

Signed-off-by: Sylvain Rochet <sylvain.rochet@finsecur.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
 drivers/net/phy/micrel.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 3ad8ca7..1190fd8 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -32,6 +32,7 @@
 /* Operation Mode Strap Override */
 #define MII_KSZPHY_OMSO				0x16
 #define KSZPHY_OMSO_B_CAST_OFF			BIT(9)
+#define KSZPHY_OMSO_NAND_TREE_ON		BIT(5)
 #define KSZPHY_OMSO_RMII_OVERRIDE		BIT(1)
 #define KSZPHY_OMSO_MII_OVERRIDE		BIT(0)
 
@@ -76,6 +77,7 @@ struct kszphy_type {
 	u32 led_mode_reg;
 	u16 interrupt_level_mask;
 	bool has_broadcast_disable;
+	bool has_nand_tree_disable;
 	bool has_rmii_ref_clk_sel;
 };
 
@@ -89,6 +91,7 @@ struct kszphy_priv {
 static const struct kszphy_type ksz8021_type = {
 	.led_mode_reg		= MII_KSZPHY_CTRL_2,
 	.has_broadcast_disable	= true,
+	.has_nand_tree_disable	= true,
 	.has_rmii_ref_clk_sel	= true,
 };
 
@@ -98,11 +101,13 @@ static const struct kszphy_type ksz8041_type = {
 
 static const struct kszphy_type ksz8051_type = {
 	.led_mode_reg		= MII_KSZPHY_CTRL_2,
+	.has_nand_tree_disable	= true,
 };
 
 static const struct kszphy_type ksz8081_type = {
 	.led_mode_reg		= MII_KSZPHY_CTRL_2,
 	.has_broadcast_disable	= true,
+	.has_nand_tree_disable	= true,
 	.has_rmii_ref_clk_sel	= true,
 };
 
@@ -231,6 +236,26 @@ out:
 	return ret;
 }
 
+static int kszphy_nand_tree_disable(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = phy_read(phydev, MII_KSZPHY_OMSO);
+	if (ret < 0)
+		goto out;
+
+	if (!(ret & KSZPHY_OMSO_NAND_TREE_ON))
+		return 0;
+
+	ret = phy_write(phydev, MII_KSZPHY_OMSO,
+			ret & ~KSZPHY_OMSO_NAND_TREE_ON);
+out:
+	if (ret)
+		dev_err(&phydev->dev, "failed to disable NAND tree mode\n");
+
+	return ret;
+}
+
 static int kszphy_config_init(struct phy_device *phydev)
 {
 	struct kszphy_priv *priv = phydev->priv;
@@ -245,6 +270,9 @@ static int kszphy_config_init(struct phy_device *phydev)
 	if (type->has_broadcast_disable)
 		kszphy_broadcast_disable(phydev);
 
+	if (type->has_nand_tree_disable)
+		kszphy_nand_tree_disable(phydev);
+
 	if (priv->rmii_ref_clk_sel) {
 		ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
 		if (ret) {
-- 
2.1.4

^ permalink raw reply related

* [PATCH] rhashtable: use rht_obj() consistently
From: Johannes Berg @ 2015-02-13 20:42 UTC (permalink / raw)
  To: netdev; +Cc: Thomas Graf, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Looking at the RHT code I found two places where this was
done manually rather than using the rht_obj() helper, use
that instead.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 lib/rhashtable.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 6c3c723e902b..a8ea16093839 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -457,7 +457,7 @@ void *rhashtable_lookup(const struct rhashtable *ht, const void *key)
 		if (memcmp(rht_obj(ht, he) + ht->p.key_offset, key,
 			   ht->p.key_len))
 			continue;
-		return (void *) he - ht->p.head_offset;
+		return rht_obj(ht, he);
 	}
 
 	return NULL;
@@ -491,7 +491,7 @@ void *rhashtable_lookup_compare(const struct rhashtable *ht, u32 hash,
 	rht_for_each_rcu(he, tbl->buckets[hash], ht) {
 		if (!compare(rht_obj(ht, he), arg))
 			continue;
-		return (void *) he - ht->p.head_offset;
+		return rht_obj(ht, he);
 	}
 
 	return NULL;
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH] rhashtable: use rht_obj() consistently
From: Thomas Graf @ 2015-02-13 20:58 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev, Johannes Berg
In-Reply-To: <1423860161-20875-1-git-send-email-johannes@sipsolutions.net>

On 02/13/15 at 09:42pm, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> Looking at the RHT code I found two places where this was
> done manually rather than using the rht_obj() helper, use
> that instead.
> 
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>

Acked-by: Thomas Graf <tgraf@suug.ch>

^ permalink raw reply

* Re: [PATCH 1/1] tun: change speed from 10M to dynamically configured
From: Francois Romieu @ 2015-02-13 21:28 UTC (permalink / raw)
  To: Zhu Yanjun
  Cc: netdev, mst, jasowang, viro, davem, sergei.shtylyov,
	jonathon.reinhart
In-Reply-To: <1423808353-8722-2-git-send-email-Yanjun.Zhu@windriver.com>

Zhu Yanjun <Yanjun.Zhu@windriver.com> :
> The default speed of normal nic is 1000M while the default speed
> of tun is 10M. Now the default speed of tun is changed to 1000M.
> And there are 3 options: 10M, 100M and 1000M to the speed of tun.
> The command "ethtool -s tun0 speed 10/100/1000" can configure the
> speed of tun dynamically.

You don't explain why this patch is needed.

Why should tun_set_settings filter speed this way/at all ?

There's no reason to pollute uapi .h file.

-- 
Ueimor

^ permalink raw reply

* Re: [PATCH 1/1] tun: change speed from 10M to dynamically configured
From: Rick Jones @ 2015-02-13 21:32 UTC (permalink / raw)
  To: Francois Romieu, Zhu Yanjun
  Cc: netdev, mst, jasowang, viro, davem, sergei.shtylyov,
	jonathon.reinhart
In-Reply-To: <20150213212830.GA29912@electric-eye.fr.zoreil.com>

It is perhaps as much a bug in the monitoring tools as anything else, 
but I have come across (versions of) software - such as collectl I think 
- which when presented with counters indicating a data rate higher than 
the reported link rate of the interface get somewhat cranky.

rick jones

^ permalink raw reply

* Re: [PATCH] rhashtable: use rht_obj() consistently
From: Thomas Graf @ 2015-02-13 21:42 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev, Johannes Berg
In-Reply-To: <20150213205853.GA18659@casper.infradead.org>

On 02/13/15 at 08:58pm, Thomas Graf wrote:
> On 02/13/15 at 09:42pm, Johannes Berg wrote:
> > From: Johannes Berg <johannes.berg@intel.com>
> > 
> > Looking at the RHT code I found two places where this was
> > done manually rather than using the rht_obj() helper, use
> > that instead.
> > 
> > Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> 
> Acked-by: Thomas Graf <tgraf@suug.ch>

Actually, this is already "fixed" in net-next.

^ 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