rtnetlink interface state monitoring problems.

9 messages, 5 authors, 2002-10-24 · open the first message on its own page

rtnetlink interface state monitoring problems.

From: David Woodhouse <dwmw2@infradead.org>
Date: 2002-10-21 11:11:59

I'm playing with userspace applications which want to monitor the status of 
IrDA and Bluetooth devices. Rather than polling for the interface state 
(this is a handheld device and polling wastes CPU and battery), I want to 
use netlink. 

I have two problems:

 1. I appear to need CAP_NET_ADMIN to bind to the netlink groups which give
	me this  information. I can poll for it just fine, but need 
	elevated privs to be notified. Why is this, and is there a workaround?

 2. Even root doesn't get notification of state changes for Bluetooth
	interfaces, because they're not treated as 'normal' network devices
	like IrDA devices are. I can see the logic behind that -- by why
	is it done differently from IrDA? Is there a way to get notification
	of BT interface state changes?


--
dwmw2

Re: rtnetlink interface state monitoring problems.

From: jamal <hidden>
Date: 2002-10-21 13:05:43


On Mon, 21 Oct 2002, David Woodhouse wrote:
I'm playing with userspace applications which want to monitor the status of
IrDA and Bluetooth devices. Rather than polling for the interface state
(this is a handheld device and polling wastes CPU and battery), I want to
use netlink.

I have two problems:

 1. I appear to need CAP_NET_ADMIN to bind to the netlink groups which give
	me this  information. I can poll for it just fine, but need
	elevated privs to be notified. Why is this, and is there a workaround?
Alexey should be able to give you a better comment.
If you can get the status via ioctl there should be no reason why you
shouldnt get it via netlink. The change maybe a little involved
(look at:net/netlink/af_netlink.c::netlink_bind()) since
there are some valid reasons to block non-admin from receiving certain
messages. I think the LSM people may have been trying to do this, cant
remember details.
 2. Even root doesn't get notification of state changes for Bluetooth
	interfaces, because they're not treated as 'normal' network devices
	like IrDA devices are. I can see the logic behind that -- by why
	is it done differently from IrDA? Is there a way to get notification
	of BT interface state changes?
I cant see anything on netlink and irda; i am also not very familiar with
either IrDA or Bluetooth.
Regardless,  you dont need to be a net device to use netlink. Its a
messaging system and you can use it both within the kernel as well as
kernel<->userspace. If you get stuck writting the interface ping me
privately.

cheers,
jamal

Re: rtnetlink interface state monitoring problems.

From: James Morris <hidden>
Date: 2002-10-21 13:40:31

On Mon, 21 Oct 2002, David Woodhouse wrote:
 1. I appear to need CAP_NET_ADMIN to bind to the netlink groups which give
	me this  information. I can poll for it just fine, but need 
	elevated privs to be notified. Why is this, and is there a workaround?
Andi Kleen implemented a simple and effective workaround this for 2.4
which has gone into the tree (see netlink_set_nonroot() in rtnetlink.c).  

Another more complicated solution was partially developed for 2.5, but is
unlikely to make it in by Halloween.


- James
-- 
James Morris
[off-list ref]

Re: rtnetlink interface state monitoring problems.

From: James Morris <hidden>
Date: 2002-10-21 13:42:07

On Mon, 21 Oct 2002, James Morris wrote:
Andi Kleen implemented a simple and effective workaround this for 2.4
which has gone into the tree (see netlink_set_nonroot() in rtnetlink.c).  
Forgot to add that it might be possible to get Andi's solution into 2.6.


- James
-- 
James Morris
[off-list ref]

Re: rtnetlink interface state monitoring problems.

From: David S. Miller <hidden>
Date: 2002-10-21 16:50:27

On Mon, 2002-10-21 at 06:48, James Morris wrote:
Forgot to add that it might be possible to get Andi's solution into 2.6.
Send me the patch for 2.5.x

It not being there is by accident, usually when I make a 2.4.x
patch I do 2.5.x in parallel.

Re: rtnetlink interface state monitoring problems.

From: David Woodhouse <dwmw2@infradead.org>
Date: 2002-10-21 18:52:23

hadi@cyberus.ca said:
I cant see anything on netlink and irda; i am also not very familiar
with either IrDA or Bluetooth. Regardless,  you dont need to be a net
device to use netlink. 
IrDA devices are network devices. The core network code sends a RTM_NETLINK 
message when they go up or down. All is well, and once the permission fix 
gets into the kernel I'm using, my irda monitor applet no longer needs to 
poll the state of the interface.

But Bluetooth devices are not network devices, it seems. There exists no 
current mechanism for notifying anyone of state changes. Should we invent a 
new method of notification using netlink, or should Bluetooth interfaces in 
fact be normal network devices just like IrDA devices are?

--
dwmw2

Re: rtnetlink interface state monitoring problems.

From: jamal <hidden>
Date: 2002-10-23 01:00:41


On Mon, 21 Oct 2002, David Woodhouse wrote:
hadi@cyberus.ca said:
quoted
I cant see anything on netlink and irda; i am also not very familiar
with either IrDA or Bluetooth. Regardless,  you dont need to be a net
device to use netlink.
IrDA devices are network devices. The core network code sends a RTM_NETLINK
message when they go up or down. All is well, and once the permission fix
gets into the kernel I'm using, my irda monitor applet no longer needs to
poll the state of the interface.
Ah, ok. I see what you mean - for a moment i thought IrDA was doing
something clever with netlink.
But Bluetooth devices are not network devices, it seems. There exists no
current mechanism for notifying anyone of state changes. Should we invent a
new method of notification using netlink, or should Bluetooth interfaces in
fact be normal network devices just like IrDA devices are?
I think the only time you should go netdev is when it makes sense to run
IP. Is there IP over bluttooth? Then you could take advantage of all the
nice features provided by netdevices (other than being IP devices;->).
If not, it probably time for someone to write a generic notification
scheme via netlink.

cheers,
jamal

Re: rtnetlink interface state monitoring problems.

From: Maksim (Max) Krasnyanskiy <hidden>
Date: 2002-10-23 19:35:33

Hi Jamal,
quoted
But Bluetooth devices are not network devices, it seems. There exists no
current mechanism for notifying anyone of state changes. Should we invent a
new method of notification using netlink, or should Bluetooth interfaces in
fact be normal network devices just like IrDA devices are?
I think the only time you should go netdev is when it makes sense to run IP. 
Totally agree.
Is there IP over bluttooth? 
Yep. It's called BNEP (Bluetooth Network Encapsulation Protocol) which is bascially
an Ethernet emulation. That thing is the netdev of course.
Then you could take advantage of all the nice features provided by netdevices (other 
than being IP devices;->).
If not, it probably time for someone to write a generic notification
scheme via netlink.
Might be interesting.

Max

[PATCH] Re: rtnetlink interface state monitoring problems.

From: James Morris <hidden>
Date: 2002-10-24 03:41:36

On 21 Oct 2002, David S. Miller wrote:
On Mon, 2002-10-21 at 06:48, James Morris wrote:
quoted
Forgot to add that it might be possible to get Andi's solution into 2.6.
Send me the patch for 2.5.x
Patch below, for 2.5.44.

- James
-- 
James Morris
[off-list ref]

diff -urN -X dontdiff linux-2.5.44.orig/include/linux/netlink.h linux-2.5.44.w1/include/linux/netlink.h
--- linux-2.5.44.orig/include/linux/netlink.h	Fri Aug  2 07:16:34 2002
+++ linux-2.5.44.w1/include/linux/netlink.h	Thu Oct 24 13:24:33 2002
@@ -162,6 +162,10 @@
 			      int (*done)(struct netlink_callback*));
 
 
+#define NL_NONROOT_RECV 0x1
+#define NL_NONROOT_SEND 0x2
+extern void netlink_set_nonroot(int protocol, unsigned flag);
+
 #endif /* __KERNEL__ */
 
 #endif	/* __LINUX_NETLINK_H */
diff -urN -X dontdiff linux-2.5.44.orig/net/core/rtnetlink.c linux-2.5.44.w1/net/core/rtnetlink.c
--- linux-2.5.44.orig/net/core/rtnetlink.c	Fri Aug  2 07:17:32 2002
+++ linux-2.5.44.w1/net/core/rtnetlink.c	Thu Oct 24 13:25:35 2002
@@ -523,6 +523,7 @@
 	rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv);
 	if (rtnl == NULL)
 		panic("rtnetlink_init: cannot initialize rtnetlink\n");
+	netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
 	register_netdevice_notifier(&rtnetlink_dev_notifier);
 	rtnetlink_links[PF_UNSPEC] = link_rtnetlink_table;
 	rtnetlink_links[PF_PACKET] = link_rtnetlink_table;
diff -urN -X dontdiff linux-2.5.44.orig/net/netlink/af_netlink.c linux-2.5.44.w1/net/netlink/af_netlink.c
--- linux-2.5.44.orig/net/netlink/af_netlink.c	Wed Oct 16 17:45:49 2002
+++ linux-2.5.44.w1/net/netlink/af_netlink.c	Thu Oct 24 13:28:58 2002
@@ -69,6 +69,7 @@
 
 static struct sock *nl_table[MAX_LINKS];
 static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
+static unsigned nl_nonroot[MAX_LINKS];
 
 #ifdef NL_EMULATE_DEV
 static struct socket *netlink_kernel[MAX_LINKS];
@@ -317,6 +318,11 @@
 	return 0;
 }
 
+static inline int netlink_capable(struct socket *sock, unsigned flag) 
+{ 
+	return (nl_nonroot[sock->sk->protocol] & flag) || capable(CAP_NET_ADMIN);
+} 
+
 static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 {
 	struct sock *sk = sock->sk;
@@ -328,7 +334,7 @@
 		return -EINVAL;
 
 	/* Only superuser is allowed to listen multicasts */
-	if (nladdr->nl_groups && !capable(CAP_NET_ADMIN))
+	if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_RECV))
 		return -EPERM;
 
 	if (nlk->pid) {
@@ -368,7 +374,7 @@
 		return -EINVAL;
 
 	/* Only superuser is allowed to send multicasts */
-	if (nladdr->nl_groups && !capable(CAP_NET_ADMIN))
+	if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_SEND))
 		return -EPERM;
 
 	if (!nlk->pid)
@@ -590,7 +596,7 @@
 			return -EINVAL;
 		dst_pid = addr->nl_pid;
 		dst_groups = addr->nl_groups;
-		if (dst_groups && !capable(CAP_NET_ADMIN))
+		if (dst_groups && !netlink_capable(sock, NL_NONROOT_SEND))
 			return -EPERM;
 	} else {
 		dst_pid = nlk->dst_pid;
@@ -743,6 +749,12 @@
 	return sk;
 }
 
+void netlink_set_nonroot(int protocol, unsigned flags)
+{ 
+	if ((unsigned)protocol < MAX_LINKS) 
+		nl_nonroot[protocol] = flags;
+} 
+
 static void netlink_destroy_callback(struct netlink_callback *cb)
 {
 	if (cb->skb)
diff -urN -X dontdiff linux-2.5.44.orig/net/netsyms.c linux-2.5.44.w1/net/netsyms.c
--- linux-2.5.44.orig/net/netsyms.c	Sat Oct 19 19:57:49 2002
+++ linux-2.5.44.w1/net/netsyms.c	Thu Oct 24 13:29:22 2002
@@ -411,6 +411,7 @@
 EXPORT_SYMBOL(netlink_kernel_create);
 EXPORT_SYMBOL(netlink_dump_start);
 EXPORT_SYMBOL(netlink_ack);
+EXPORT_SYMBOL(netlink_set_nonroot);
 EXPORT_SYMBOL(netlink_register_notifier);
 EXPORT_SYMBOL(netlink_unregister_notifier);
 #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help