Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ebacaaa0 authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki Committed by David S. Miller
Browse files

[IPV6]: ROUTE: Add support for Router Preference (RFC4191).

parent 8238dd06
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -40,14 +40,16 @@ struct icmp6hdr {
                struct icmpv6_nd_ra {
			__u8		hop_limit;
#if defined(__LITTLE_ENDIAN_BITFIELD)
			__u8		reserved:6,
			__u8		reserved:4,
					router_pref:2,
					other:1,
					managed:1;

#elif defined(__BIG_ENDIAN_BITFIELD)
			__u8		managed:1,
					other:1,
					reserved:6;
					router_pref:2,
					reserved:4;
#else
#error	"Please fix <asm/byteorder.h>"
#endif
@@ -70,8 +72,13 @@ struct icmp6hdr {
#define icmp6_addrconf_managed	icmp6_dataun.u_nd_ra.managed
#define icmp6_addrconf_other	icmp6_dataun.u_nd_ra.other
#define icmp6_rt_lifetime	icmp6_dataun.u_nd_ra.rt_lifetime
#define icmp6_router_pref	icmp6_dataun.u_nd_ra.router_pref
};

#define ICMPV6_ROUTER_PREF_LOW		0x3
#define ICMPV6_ROUTER_PREF_MEDIUM	0x0
#define ICMPV6_ROUTER_PREF_HIGH		0x1
#define ICMPV6_ROUTER_PREF_INVALID	0x2

#define ICMPV6_DEST_UNREACH		1
#define ICMPV6_PKT_TOOBIG		2
+8 −0
Original line number Diff line number Diff line
@@ -27,8 +27,16 @@
#define RTF_FLOW	0x02000000	/* flow significant route	*/
#define RTF_POLICY	0x04000000	/* policy route			*/

#define RTF_PREF(pref)	((pref) << 27)
#define RTF_PREF_MASK	0x18000000

#define RTF_LOCAL	0x80000000

#ifdef __KERNEL__
#define IPV6_EXTRACT_PREF(flag)	(((flag) & RTF_PREF_MASK) >> 27)
#define IPV6_DECODE_PREF(pref)	((pref) ^ 2)	/* 1:low,2:med,3:high */
#endif

struct in6_rtmsg {
	struct in6_addr		rtmsg_dst;
	struct in6_addr		rtmsg_src;
+2 −1
Original line number Diff line number Diff line
@@ -87,7 +87,8 @@ extern struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
extern struct rt6_info *	rt6_get_dflt_router(struct in6_addr *addr,
						    struct net_device *dev);
extern struct rt6_info *	rt6_add_dflt_router(struct in6_addr *gwaddr,
						    struct net_device *dev);
						    struct net_device *dev,
						    unsigned int pref);

extern void			rt6_purge_dflt_routers(void);

+11 −0
Original line number Diff line number Diff line
@@ -38,6 +38,17 @@ config IPV6_PRIVACY

	  See <file:Documentation/networking/ip-sysctl.txt> for details.

config IPV6_ROUTER_PREF
	bool "IPv6: Router Preference (RFC 4191) support"
	depends on IPV6
	---help---
	  Router Preference is an optional extension to the Router
	  Advertisement message to improve the ability of hosts
	  to pick more appropriate router, especially when the hosts
	  is placed in a multi-homed network.

	  If unsure, say N.

config INET6_AH
	tristate "IPv6: AH transformation"
	depends on IPV6
+11 −1
Original line number Diff line number Diff line
@@ -1023,6 +1023,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
	int lifetime;
	struct ndisc_options ndopts;
	int optlen;
	unsigned int pref = 0;

	__u8 * opt = (__u8 *)(ra_msg + 1);

@@ -1086,6 +1087,13 @@ static void ndisc_router_discovery(struct sk_buff *skb)

	lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime);

#ifdef CONFIG_IPV6_ROUTER_PREF
	pref = ra_msg->icmph.icmp6_router_pref;
	/* 10b is handled as if it were 00b (medium) */
	if (pref == ICMPV6_ROUTER_PREF_INVALID)
		pref = ICMPV6_ROUTER_PREF_MEDIUM;
#endif

	rt = rt6_get_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);

	if (rt)
@@ -1101,7 +1109,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
		ND_PRINTK3(KERN_DEBUG
			   "ICMPv6 RA: adding default router.\n");

		rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
		rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev, pref);
		if (rt == NULL) {
			ND_PRINTK0(KERN_ERR
				   "ICMPv6 RA: %s() failed to add default route.\n",
@@ -1120,6 +1128,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
			return;
		}
		neigh->flags |= NTF_ROUTER;
	} else if (rt) {
		rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
	}

	if (rt)
Loading