All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC net-next iproute2 0/2] Add support for operating raw sockest via diag interface
@ 2016-10-26 19:30 Cyrill Gorcunov
  2016-10-26 19:30 ` [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply Cyrill Gorcunov
  2016-10-26 19:30 ` [RFC net-next iproute2 2/2] ss: Add inet raw sockets information gathering via netlink diag interface Cyrill Gorcunov
  0 siblings, 2 replies; 6+ messages in thread
From: Cyrill Gorcunov @ 2016-10-26 19:30 UTC (permalink / raw)
  To: netdev
  Cc: Stephen Hemminger, Eric Dumazet, David Ahern, Andrey Vagin,
	Cyrill Gorcunov

The diag interface for raw sockets is now in linux-net-next
http://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=432490f9d455fb842d70219f22d9d2c812371676
so here is early patches for misc/ss

While "showing" action works as expected, I see some weird effects on
"kill" socket actions. In particular I've a test program which binds
sockets to veth interface

	# ip link add dev vm1 type veth peer name vm2

        setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, "vm1", 3);
        setsockopt(sk6, SOL_SOCKET, SO_BINDTODEVICE, "vm1", 3);
        setsockopt(skc, SOL_SOCKET, SO_BINDTODEVICE, "vm1", 3);
        setsockopt(sk6, SOL_SOCKET, SO_BINDTODEVICE, "vm1", 3);
        setsockopt(skicmp, SOL_SOCKET, SO_BINDTODEVICE, "vm1", 3);

so the output shows

[root@pcs7 iproute2]# ./misc/ss -A raw
State      Recv-Q Send-Q                                Local Address:Port                                                 Peer Address:Port                
UNCONN     0      0                                             *%vm1:icmp                                                            *:*                    
UNCONN     0      0                                                 *:ipproto-255                                                     *:*                    
UNCONN     0      0                                             *%vm1:ipproto-255                                                     *:*                    
UNCONN     0      0                                    127.0.0.10%vm1:ipproto-255                                                     *:*                    
UNCONN     0      0                                                :::ipv6-icmp                                                      :::*                    
UNCONN     0      0                                                :::ipv6-icmp                                                      :::*                    
ESTAB      0      0                                               ::1:ipproto-255                                                   ::1:ipproto-9091         
UNCONN     0      0                                           ::1%vm1:ipproto-255                                                    :::*                    
[root@pcs7 iproute2]# 

But when I start killing sockets

[root@pcs7 iproute2]# ./misc/ss -aKw 'dev == vm1'
State      Recv-Q Send-Q                                Local Address:Port                                                 Peer Address:Port                
UNCONN     0      0                                             *%vm1:ipproto-255                                                     *:*                    
UNCONN     0      0                                    127.0.0.10%vm1:ipproto-255                                                     *:*                    
UNCONN     0      0                                           ::1%vm1:ipproto-255                                                    :::*                    
[root@pcs7 iproute2]# 
[root@pcs7 iproute2]# ./misc/ss -aKw 'dev == vm1'
State      Recv-Q Send-Q                                Local Address:Port                                                 Peer Address:Port                
UNCONN     0      0                                    127.0.0.10%vm1:ipproto-255                                                     *:*                    
[root@pcs7 iproute2]# ./misc/ss -aKw 'dev == vm1'
State      Recv-Q Send-Q                                Local Address:Port                                                 Peer Address:Port                
UNCONN     0      0                                             *%vm1:icmp                                                            *:*                    
[root@pcs7 iproute2]# ./misc/ss -aKw 'dev == vm1'
State      Recv-Q Send-Q                                Local Address:Port                                                 Peer Address:Port                
[root@pcs7 iproute2]# 

It doesn't do all this in one pass, so I suspect I miss something in second patch?
Please take a look, once time permit.

Cyrill Gorcunov (2):
  libnetlink: Add test for error code returned from netlink reply
  ss: Add inet raw sockets information gathering via netlink diag
    interface

 include/linux/inet_diag.h | 15 +++++++++++++++
 lib/libnetlink.c          | 21 +++++++++++++++++++++
 misc/ss.c                 | 20 ++++++++++++++++++--
 3 files changed, 54 insertions(+), 2 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply
  2016-10-26 19:30 [RFC net-next iproute2 0/2] Add support for operating raw sockest via diag interface Cyrill Gorcunov
@ 2016-10-26 19:30 ` Cyrill Gorcunov
  2016-10-27  3:52   ` Stephen Hemminger
  2016-10-26 19:30 ` [RFC net-next iproute2 2/2] ss: Add inet raw sockets information gathering via netlink diag interface Cyrill Gorcunov
  1 sibling, 1 reply; 6+ messages in thread
From: Cyrill Gorcunov @ 2016-10-26 19:30 UTC (permalink / raw)
  To: netdev
  Cc: Stephen Hemminger, Eric Dumazet, David Ahern, Andrey Vagin,
	Cyrill Gorcunov

In case if some diag module is not present in the system,
say the kernel is not modern enough, we simply skip the
error code reported. Instead we should check for data
length in NLMSG_DONE and process unsupported case.

Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
---
 lib/libnetlink.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 2279935..a397c07 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -312,6 +312,27 @@ int rtnl_dump_filter_l(struct rtnl_handle *rth,
 					dump_intr = 1;
 
 				if (h->nlmsg_type == NLMSG_DONE) {
+					int len;
+
+					/*
+					 * The kernel reports if there is
+					 * no inet-diag module present in
+					 * the system via negative length
+					 * as error code.
+					 */
+					if (h->nlmsg_len < NLMSG_LENGTH(sizeof(int))) {
+						fprintf(stderr, "Truncated length reply\n");
+						return -1;
+					}
+					len = *(int *)NLMSG_DATA(h);
+					if (len < 0) {
+						errno = -len;
+						if (errno == ENOENT ||
+						    errno == EOPNOTSUPP)
+							return -1;
+						perror("RTNETLINK answers");
+						return len;
+					}
 					found_done = 1;
 					break; /* process next filter */
 				}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC net-next iproute2 2/2] ss: Add inet raw sockets information gathering via netlink diag interface
  2016-10-26 19:30 [RFC net-next iproute2 0/2] Add support for operating raw sockest via diag interface Cyrill Gorcunov
  2016-10-26 19:30 ` [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply Cyrill Gorcunov
@ 2016-10-26 19:30 ` Cyrill Gorcunov
  1 sibling, 0 replies; 6+ messages in thread
From: Cyrill Gorcunov @ 2016-10-26 19:30 UTC (permalink / raw)
  To: netdev
  Cc: Stephen Hemminger, Eric Dumazet, David Ahern, Andrey Vagin,
	Cyrill Gorcunov

unix, tcp, udp[lite], packet, netlink sockets already support diag
interface for their collection and killing. Now with commit XXX
this facility is implemented for raw sockets.

Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
---
 include/linux/inet_diag.h | 15 +++++++++++++++
 misc/ss.c                 | 20 ++++++++++++++++++--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index f5f5c1b..ac66148 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -43,6 +43,21 @@ struct inet_diag_req_v2 {
 	struct inet_diag_sockid id;
 };
 
+/*
+ * An alias for struct inet_diag_req_v2,
+ * @sdiag_raw_protocol member shadows
+ * @pad explicitly, it is done this way
+ * for backward compatibility sake.
+ */
+struct inet_diag_req_raw {
+	__u8	sdiag_family;
+	__u8	sdiag_protocol;
+	__u8	idiag_ext;
+	__u8	sdiag_raw_protocol;
+	__u32	idiag_states;
+	struct inet_diag_sockid id;
+};
+
 enum {
 	INET_DIAG_REQ_NONE,
 	INET_DIAG_REQ_BYTECODE,
diff --git a/misc/ss.c b/misc/ss.c
index dd77b81..e8c4010 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -724,6 +724,7 @@ struct sockstat {
 	struct sockstat	   *next;
 	unsigned int	    type;
 	uint16_t	    prot;
+	uint16_t	    raw_prot;
 	inet_prefix	    local;
 	inet_prefix	    remote;
 	int		    lport;
@@ -2190,6 +2191,10 @@ static void parse_diag_msg(struct nlmsghdr *nlh, struct sockstat *s)
 	s->mark = 0;
 	if (tb[INET_DIAG_MARK])
 		s->mark = *(__u32 *) RTA_DATA(tb[INET_DIAG_MARK]);
+	if (tb[INET_DIAG_PROTOCOL])
+		s->raw_prot = *(__u8 *)RTA_DATA(tb[INET_DIAG_PROTOCOL]);
+	else
+		s->raw_prot = 0;
 
 	if (s->local.family == AF_INET)
 		s->local.bytelen = s->remote.bytelen = 4;
@@ -2384,7 +2389,7 @@ struct inet_diag_arg {
 	struct rtnl_handle *rth;
 };
 
-static int kill_inet_sock(struct nlmsghdr *h, void *arg)
+static int kill_inet_sock(struct nlmsghdr *h, void *arg, struct sockstat *s)
 {
 	struct inet_diag_msg *d = NLMSG_DATA(h);
 	struct inet_diag_arg *diag_arg = arg;
@@ -2399,6 +2404,13 @@ static int kill_inet_sock(struct nlmsghdr *h, void *arg)
 	req.r.sdiag_protocol = diag_arg->protocol;
 	req.r.id = d->id;
 
+	if (diag_arg->protocol == IPPROTO_RAW) {
+		struct inet_diag_req_raw *raw = (void *)&req.r;
+
+		BUILD_BUG_ON(sizeof(req.r) != sizeof(*raw));
+		raw->sdiag_raw_protocol = s->raw_prot;
+	}
+
 	return rtnl_talk(rth, &req.nlh, NULL, 0);
 }
 
@@ -2418,7 +2430,7 @@ static int show_one_inet_sock(const struct sockaddr_nl *addr,
 	if (diag_arg->f->f && run_ssfilter(diag_arg->f->f, &s) == 0)
 		return 0;
 
-	if (diag_arg->f->kill && kill_inet_sock(h, arg) != 0) {
+	if (diag_arg->f->kill && kill_inet_sock(h, arg, &s) != 0) {
 		if (errno == EOPNOTSUPP || errno == ENOENT) {
 			/* Socket can't be closed, or is already closed. */
 			return 0;
@@ -2715,6 +2727,10 @@ static int raw_show(struct filter *f)
 
 	dg_proto = RAW_PROTO;
 
+	if (!getenv("PROC_NET_RAW") && !getenv("PROC_ROOT") &&
+	    inet_show_netlink(f, NULL, IPPROTO_RAW) == 0)
+		return 0;
+
 	if (f->families&(1<<AF_INET)) {
 		if ((fp = net_raw_open()) == NULL)
 			goto outerr;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply
  2016-10-26 19:30 ` [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply Cyrill Gorcunov
@ 2016-10-27  3:52   ` Stephen Hemminger
  2016-10-27  6:52     ` Cyrill Gorcunov
  0 siblings, 1 reply; 6+ messages in thread
From: Stephen Hemminger @ 2016-10-27  3:52 UTC (permalink / raw)
  To: Cyrill Gorcunov; +Cc: netdev, Eric Dumazet, David Ahern, Andrey Vagin

On Wed, 26 Oct 2016 22:30:07 +0300
Cyrill Gorcunov <gorcunov@gmail.com> wrote:

>  
>  				if (h->nlmsg_type == NLMSG_DONE) {
> +					int len;
> +
> +					/*
> +					 * The kernel reports if there is
> +					 * no inet-diag module present in
> +					 * the system via negative length
> +					 * as error code.
> +					 */
> +					if (h->nlmsg_len < NLMSG_LENGTH(sizeof(int))) {
> +						fprintf(stderr, "Truncated length reply\n");
> +						return -1;
> +					}
> +					len = *(int *)NLMSG_DATA(h);
> +					if (len < 0) {
> +						errno = -len;
> +						if (errno == ENOENT ||
> +						    errno == EOPNOTSUPP)
> +							return -1;
> +						perror("RTNETLINK answers");
> +						return len;
> +					}
>  					found_done = 1;
>  					break; /* process next filter */
>  				

This looks like a mistake in how you implemented the functionality in the kernel.
Despite what it looks like, all netlink request/reply functionality reports
errors in current implementation by returning error to the sendmsg request.

What you added implies that the new kernel api is wrong, or many other usages
are wrong.  Please fix the kernel.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply
  2016-10-27  3:52   ` Stephen Hemminger
@ 2016-10-27  6:52     ` Cyrill Gorcunov
  2016-10-27  8:24       ` Cyrill Gorcunov
  0 siblings, 1 reply; 6+ messages in thread
From: Cyrill Gorcunov @ 2016-10-27  6:52 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Eric Dumazet, David Ahern, Andrey Vagin

On Wed, Oct 26, 2016 at 08:52:56PM -0700, Stephen Hemminger wrote:
> On Wed, 26 Oct 2016 22:30:07 +0300
> Cyrill Gorcunov <gorcunov@gmail.com> wrote:
> 
> >  
> >  				if (h->nlmsg_type == NLMSG_DONE) {
> > +					int len;
> > +
> > +					/*
> > +					 * The kernel reports if there is
> > +					 * no inet-diag module present in
> > +					 * the system via negative length
> > +					 * as error code.
> > +					 */
> > +					if (h->nlmsg_len < NLMSG_LENGTH(sizeof(int))) {
> > +						fprintf(stderr, "Truncated length reply\n");
> > +						return -1;
> > +					}
> > +					len = *(int *)NLMSG_DATA(h);
> > +					if (len < 0) {
> > +						errno = -len;
> > +						if (errno == ENOENT ||
> > +						    errno == EOPNOTSUPP)
> > +							return -1;
> > +						perror("RTNETLINK answers");
> > +						return len;
> > +					}
> >  					found_done = 1;
> >  					break; /* process next filter */
> >  				
> 
> This looks like a mistake in how you implemented the functionality in the kernel.
> Despite what it looks like, all netlink request/reply functionality reports
> errors in current implementation by returning error to the sendmsg request.
> 
> What you added implies that the new kernel api is wrong, or many other usages
> are wrong.  Please fix the kernel.

No. This is not my code. This code has been in kernel for the really long time.
I don't know why you've not been doing such test in libnetlink before.

Actually I've hit this problem accidentaly -- I made a patch 2 from this
set and run it on the machine where kernel was unpatched, ie without
raw-diag module, and I found that we can't figure out if kernel notified
us that some diag module simply not present in the system. And here is
the only way to find it out.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply
  2016-10-27  6:52     ` Cyrill Gorcunov
@ 2016-10-27  8:24       ` Cyrill Gorcunov
  0 siblings, 0 replies; 6+ messages in thread
From: Cyrill Gorcunov @ 2016-10-27  8:24 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, Eric Dumazet, David Ahern, Andrey Vagin

On Thu, Oct 27, 2016 at 09:52:53AM +0300, Cyrill Gorcunov wrote:
...
> > 
> > This looks like a mistake in how you implemented the functionality in the kernel.
> > Despite what it looks like, all netlink request/reply functionality reports
> > errors in current implementation by returning error to the sendmsg request.
> > 
> > What you added implies that the new kernel api is wrong, or many other usages
> > are wrong.  Please fix the kernel.
> 
> No. This is not my code. This code has been in kernel for the really long time.
> I don't know why you've not been doing such test in libnetlink before.
> 
> Actually I've hit this problem accidentaly -- I made a patch 2 from this
> set and run it on the machine where kernel was unpatched, ie without
> raw-diag module, and I found that we can't figure out if kernel notified
> us that some diag module simply not present in the system. And here is
> the only way to find it out.

Also, drop this series for a while, I'll resend new one: the status of
diag should not be tested unconditionally with NLMSG_DONE because the
rtnl_dump_filter_l helper is used not only for diag talks but overall
the iproute2, thus I need to test for status only for specified requests.
And I need to narrow down why not all device bound interfaces are killed
in one pass.

	Cyrill

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-10-27 14:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-26 19:30 [RFC net-next iproute2 0/2] Add support for operating raw sockest via diag interface Cyrill Gorcunov
2016-10-26 19:30 ` [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply Cyrill Gorcunov
2016-10-27  3:52   ` Stephen Hemminger
2016-10-27  6:52     ` Cyrill Gorcunov
2016-10-27  8:24       ` Cyrill Gorcunov
2016-10-26 19:30 ` [RFC net-next iproute2 2/2] ss: Add inet raw sockets information gathering via netlink diag interface Cyrill Gorcunov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.