Netlink and IPv6

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A while ago I sent a message to this list pointing out that IPv6 NetLink
messages have incorrect information in the pid and protocol fields.  I'm
including a patch that addresses these issues for route additions and
deletions.  The patch is against stock 2.4.20.

The patch adds rtmsg_pid and rtmsg_protocol fields to struct in6_rtmsg.
Additionally, it adds an rt6i_protocol field to struct rt6_info.  Finally,
it adds a pid parameter to many of the functions in the IPv6 route add/
delete callpath.

I would like these problems to be fixed.  If there are any changes
that I can make to the patches to help get them applied, or if an
entirely different route should be taken, please, let me know.

mrr

diff -ru --exclude-from=/home/mrr/exclude linux-2.4.20.orig/include/linux/ipv6_route.h linux-2.4.20/include/linux/ipv6_route.h
--- linux-2.4.20.orig/include/linux/ipv6_route.h	Thu Aug 27 22:33:08 1998
+++ linux-2.4.20/include/linux/ipv6_route.h	Mon Mar 24 16:52:52 2003
@@ -46,6 +46,8 @@
 	unsigned long		rtmsg_info;
         __u32			rtmsg_flags;
 	int			rtmsg_ifindex;
+	__u32			rtmsg_pid;
+	unsigned char		rtmsg_protocol;
 };
 
 #define RTMSG_NEWDEVICE		0x11
diff -ru --exclude-from=/home/mrr/exclude linux-2.4.20.orig/include/net/ip6_fib.h linux-2.4.20/include/net/ip6_fib.h
--- linux-2.4.20.orig/include/net/ip6_fib.h	Mon Dec 11 16:30:48 2000
+++ linux-2.4.20/include/net/ip6_fib.h	Mon Mar 24 17:06:09 2003
@@ -80,6 +80,8 @@
 
 	struct rt6key			rt6i_dst;
 	struct rt6key			rt6i_src;
+
+	unsigned char			rt6i_protocol;
 };
 
 struct fib6_walker_t
@@ -168,11 +170,12 @@
 extern int			fib6_walk_continue(struct fib6_walker_t *w);
 
 extern int			fib6_add(struct fib6_node *root,
-					 struct rt6_info *rt);
+					 struct rt6_info *rt, u32 pid);
 
-extern int			fib6_del(struct rt6_info *rt);
+extern int			fib6_del(struct rt6_info *rt, u32 pid);
 
-extern void			inet6_rt_notify(int event, struct rt6_info *rt);
+extern void			inet6_rt_notify(int event, struct rt6_info *rt,
+					u32 pid);
 
 extern void			fib6_run_gc(unsigned long dummy);
 
diff -ru --exclude-from=/home/mrr/exclude linux-2.4.20.orig/include/net/ip6_route.h linux-2.4.20/include/net/ip6_route.h
--- linux-2.4.20.orig/include/net/ip6_route.h	Mon Dec 11 16:30:48 2000
+++ linux-2.4.20/include/net/ip6_route.h	Mon Mar 24 17:06:09 2003
@@ -37,7 +37,7 @@
 extern int			ipv6_route_ioctl(unsigned int cmd, void *arg);
 
 extern int			ip6_route_add(struct in6_rtmsg *rtmsg);
-extern int			ip6_del_rt(struct rt6_info *);
+extern int			ip6_del_rt(struct rt6_info *, u32 pid);
 
 extern int			ip6_rt_addr_add(struct in6_addr *addr,
 						struct net_device *dev);
diff -ru --exclude-from=/home/mrr/exclude linux-2.4.20.orig/net/ipv6/addrconf.c linux-2.4.20/net/ipv6/addrconf.c
--- linux-2.4.20.orig/net/ipv6/addrconf.c	Thu Nov 28 18:53:15 2002
+++ linux-2.4.20/net/ipv6/addrconf.c	Mon Mar 24 16:51:59 2003
@@ -870,7 +870,7 @@
 	if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
 		if (rt->rt6i_flags&RTF_EXPIRES) {
 			if (pinfo->onlink == 0 || valid_lft == 0) {
-				ip6_del_rt(rt);
+				ip6_del_rt(rt, 0);
 				rt = NULL;
 			} else {
 				rt->rt6i_expires = rt_expires;
diff -ru --exclude-from=/home/mrr/exclude linux-2.4.20.orig/net/ipv6/ip6_fib.c linux-2.4.20/net/ipv6/ip6_fib.c
--- linux-2.4.20.orig/net/ipv6/ip6_fib.c	Thu Nov 28 18:53:15 2002
+++ linux-2.4.20/net/ipv6/ip6_fib.c	Mon Mar 24 16:53:51 2003
@@ -423,7 +423,7 @@
  *	Insert routing information in a node.
  */
 
-static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt)
+static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, u32 pid)
 {
 	struct rt6_info *iter = NULL;
 	struct rt6_info **ins;
@@ -481,7 +481,7 @@
 	*ins = rt;
 	rt->rt6i_node = fn;
 	atomic_inc(&rt->rt6i_ref);
-	inet6_rt_notify(RTM_NEWROUTE, rt);
+	inet6_rt_notify(RTM_NEWROUTE, rt, pid);
 	rt6_stats.fib_rt_entries++;
 
 	if ((fn->fn_flags & RTN_RTINFO) == 0) {
@@ -505,7 +505,7 @@
  *	with source addr info in sub-trees
  */
 
-int fib6_add(struct fib6_node *root, struct rt6_info *rt)
+int fib6_add(struct fib6_node *root, struct rt6_info *rt, u32 pid)
 {
 	struct fib6_node *fn;
 	int err = -ENOMEM;
@@ -578,7 +578,7 @@
 	}
 #endif
 
-	err = fib6_add_rt2node(fn, rt);
+	err = fib6_add_rt2node(fn, rt, pid);
 
 	if (err == 0) {
 		fib6_start_gc(rt);
@@ -886,7 +886,7 @@
 	}
 }
 
-static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp)
+static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, u32 pid)
 {
 	struct fib6_walker_t *w;
 	struct rt6_info *rt = *rtp;
@@ -941,11 +941,11 @@
 		if (atomic_read(&rt->rt6i_ref) != 1) BUG();
 	}
 
-	inet6_rt_notify(RTM_DELROUTE, rt);
+	inet6_rt_notify(RTM_DELROUTE, rt, pid);
 	rt6_release(rt);
 }
 
-int fib6_del(struct rt6_info *rt)
+int fib6_del(struct rt6_info *rt, u32 pid)
 {
 	struct fib6_node *fn = rt->rt6i_node;
 	struct rt6_info **rtp;
@@ -970,7 +970,7 @@
 
 	for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) {
 		if (*rtp == rt) {
-			fib6_del_route(fn, rtp);
+			fib6_del_route(fn, rtp, pid);
 			return 0;
 		}
 	}
@@ -1099,7 +1099,7 @@
 		res = c->func(rt, c->arg);
 		if (res < 0) {
 			w->leaf = rt;
-			res = fib6_del(rt);
+			res = fib6_del(rt, 0);
 			if (res) {
 #if RT6_DEBUG >= 2
 				printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
diff -ru --exclude-from=/home/mrr/exclude linux-2.4.20.orig/net/ipv6/ndisc.c linux-2.4.20/net/ipv6/ndisc.c
--- linux-2.4.20.orig/net/ipv6/ndisc.c	Thu Nov 28 18:53:15 2002
+++ linux-2.4.20/net/ipv6/ndisc.c	Mon Mar 24 16:52:08 2003
@@ -642,7 +642,7 @@
 	rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
 
 	if (rt && lifetime == 0) {
-		ip6_del_rt(rt);
+		ip6_del_rt(rt, 0);
 		rt = NULL;
 	}
 
@@ -1235,7 +1235,7 @@
 					struct rt6_info *rt;
 					rt = rt6_get_dflt_router(saddr, skb->dev);
 					if (rt) {
-						ip6_del_rt(rt);
+						ip6_del_rt(rt, 0);
 					}
 				}
 			} else {
diff -ru --exclude-from=/home/mrr/exclude linux-2.4.20.orig/net/ipv6/route.c linux-2.4.20/net/ipv6/route.c
--- linux-2.4.20.orig/net/ipv6/route.c	Thu Nov 28 18:53:15 2002
+++ linux-2.4.20/net/ipv6/route.c	Mon Mar 24 17:07:29 2003
@@ -261,12 +261,12 @@
    be destroyed.
  */
 
-static int rt6_ins(struct rt6_info *rt)
+static int rt6_ins(struct rt6_info *rt, u32 pid)
 {
 	int err;
 
 	write_lock_bh(&rt6_lock);
-	err = fib6_add(&ip6_routing_table, rt);
+	err = fib6_add(&ip6_routing_table, rt, pid);
 	write_unlock_bh(&rt6_lock);
 
 	return err;
@@ -309,7 +309,7 @@
 
 		dst_clone(&rt->u.dst);
 
-		err = rt6_ins(rt);
+		err = rt6_ins(rt, 0);
 		if (err == 0)
 			return rt;
 
@@ -555,7 +555,7 @@
 
 	if (rt) {
 		if (rt->rt6i_flags & RTF_CACHE)
-			ip6_del_rt(rt);
+			ip6_del_rt(rt, 0);
 		else
 			dst_release(dst);
 	}
@@ -669,6 +669,7 @@
 
 	rt->u.dst.obsolete = -1;
 	rt->rt6i_expires = rtmsg->rtmsg_info;
+	rt->rt6i_protocol = rtmsg->rtmsg_protocol;
 
 	addr_type = ipv6_addr_type(&rtmsg->rtmsg_dst);
 
@@ -793,7 +794,7 @@
 	if (rt->u.dst.advmss > 65535-20)
 		rt->u.dst.advmss = 65535;
 	rt->u.dst.dev = dev;
-	return rt6_ins(rt);
+	return rt6_ins(rt, rtmsg->rtmsg_pid);
 
 out:
 	if (dev)
@@ -802,7 +803,7 @@
 	return err;
 }
 
-int ip6_del_rt(struct rt6_info *rt)
+int ip6_del_rt(struct rt6_info *rt, u32 pid)
 {
 	int err;
 
@@ -814,7 +815,7 @@
 
 	dst_release(&rt->u.dst);
 
-	err = fib6_del(rt);
+	err = fib6_del(rt, pid);
 	write_unlock_bh(&rt6_lock);
 
 	return err;
@@ -847,7 +848,7 @@
 			dst_clone(&rt->u.dst);
 			read_unlock_bh(&rt6_lock);
 
-			return ip6_del_rt(rt);
+			return ip6_del_rt(rt, rtmsg->rtmsg_pid);
 		}
 	}
 	read_unlock_bh(&rt6_lock);
@@ -949,11 +950,11 @@
 		rt->u.dst.advmss = 65535;
 	nrt->rt6i_hoplimit = ipv6_get_hoplimit(neigh->dev);
 
-	if (rt6_ins(nrt))
+	if (rt6_ins(nrt, 0))
 		goto out;
 
 	if (rt->rt6i_flags&RTF_CACHE) {
-		ip6_del_rt(rt);
+		ip6_del_rt(rt, 0);
 		return;
 	}
 
@@ -1039,7 +1040,7 @@
 		dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires);
 		nrt->rt6i_flags |= RTF_DYNAMIC|RTF_CACHE|RTF_EXPIRES;
 		nrt->u.dst.pmtu = pmtu;
-		rt6_ins(nrt);
+		rt6_ins(nrt, 0);
 	}
 
 out:
@@ -1138,7 +1139,7 @@
 
 			read_unlock_bh(&rt6_lock);
 
-			ip6_del_rt(rt);
+			ip6_del_rt(rt, 0);
 
 			goto restart;
 		}
@@ -1224,7 +1225,7 @@
 
 	ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
 	rt->rt6i_dst.plen = 128;
-	rt6_ins(rt);
+	rt6_ins(rt, 0);
 
 	return 0;
 }
@@ -1241,7 +1242,7 @@
 	rt = rt6_lookup(addr, NULL, loopback_dev.ifindex, 1);
 	if (rt) {
 		if (rt->rt6i_dst.plen == 128)
-			err = ip6_del_rt(rt);
+			err = ip6_del_rt(rt, 0);
 		else
 			dst_release(&rt->u.dst);
 	}
@@ -1357,7 +1358,7 @@
 
 	nrt->rt6i_flags |= RTF_CACHE;
 	dst_clone(&nrt->u.dst);
-	err = rt6_ins(nrt);
+	err = rt6_ins(nrt, 0);
 	if (err)
 		nrt->u.dst.error = err;
 	return nrt;
@@ -1442,6 +1443,7 @@
 	rtmsg->rtmsg_dst_len = r->rtm_dst_len;
 	rtmsg->rtmsg_src_len = r->rtm_src_len;
 	rtmsg->rtmsg_flags = RTF_UP;
+	rtmsg->rtmsg_protocol = r->rtm_protocol;
 	if (r->rtm_type == RTN_UNREACHABLE)
 		rtmsg->rtmsg_flags |= RTF_REJECT;
 
@@ -1481,6 +1483,7 @@
 
 	if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
 		return -EINVAL;
+	rtmsg.rtmsg_pid = nlh->nlmsg_pid;
 	return ip6_route_del(&rtmsg);
 }
 
@@ -1491,6 +1494,7 @@
 
 	if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
 		return -EINVAL;
+	rtmsg.rtmsg_pid = nlh->nlmsg_pid;
 	return ip6_route_add(&rtmsg);
 }
 
@@ -1526,7 +1530,7 @@
 		rtm->rtm_type = RTN_UNICAST;
 	rtm->rtm_flags = 0;
 	rtm->rtm_scope = RT_SCOPE_UNIVERSE;
-	rtm->rtm_protocol = RTPROT_BOOT;
+	rtm->rtm_protocol = rt->rt6i_protocol;
 	if (rt->rt6i_flags&RTF_DYNAMIC)
 		rtm->rtm_protocol = RTPROT_REDIRECT;
 	else if (rt->rt6i_flags&(RTF_ADDRCONF|RTF_ALLONLINK))
@@ -1747,7 +1751,7 @@
 	return 0;
 }
 
-void inet6_rt_notify(int event, struct rt6_info *rt)
+void inet6_rt_notify(int event, struct rt6_info *rt, u32 pid)
 {
 	struct sk_buff *skb;
 	int size = NLMSG_SPACE(sizeof(struct rtmsg)+256);
@@ -1757,7 +1761,7 @@
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS);
 		return;
 	}
-	if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0) < 0) {
+	if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, 0) < 0) {
 		kfree_skb(skb);
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL);
 		return;
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux