Commit 22441cfa authored by Pedro Ribeiro's avatar Pedro Ribeiro Committed by David S. Miller

IPV6: Fix default gateway criteria wrt. HIGH/LOW preference radv option

Problem observed:
               In IPv6, in the presence of multiple routers candidates to
               default gateway in one segment, each sending a different
               value of preference, the Linux hosts connected to the
               segment weren't selecting the right one in all the
               combinations possible of LOW/MEDIUM/HIGH preference.

This patch changes two files:
include/linux/icmpv6.h
               Get the "router_pref" bitfield in the right place
               (as RFC4191 says), named the bit left with this fix as
               "home_agent" (RFC3775 say that's his function)

net/ipv6/ndisc.c
               Corrects the binary logic behind the updating of the
               router preference in the flags of the routing table

Result:
               With this two fixes applied, the default route used by
               the system was to consistent with the rules mentioned
               in RFC4191 in case of changes in the value of preference
               in router advertisements
Signed-off-by: default avatarPedro Ribeiro <pribeiro@net.ipl.pt>
Acked-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent deb28d9b
...@@ -40,16 +40,18 @@ struct icmp6hdr { ...@@ -40,16 +40,18 @@ struct icmp6hdr {
struct icmpv6_nd_ra { struct icmpv6_nd_ra {
__u8 hop_limit; __u8 hop_limit;
#if defined(__LITTLE_ENDIAN_BITFIELD) #if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 reserved:4, __u8 reserved:3,
router_pref:2, router_pref:2,
home_agent:1,
other:1, other:1,
managed:1; managed:1;
#elif defined(__BIG_ENDIAN_BITFIELD) #elif defined(__BIG_ENDIAN_BITFIELD)
__u8 managed:1, __u8 managed:1,
other:1, other:1,
home_agent:1,
router_pref:2, router_pref:2,
reserved:4; reserved:3;
#else #else
#error "Please fix <asm/byteorder.h>" #error "Please fix <asm/byteorder.h>"
#endif #endif
......
...@@ -1199,7 +1199,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) ...@@ -1199,7 +1199,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
} }
neigh->flags |= NTF_ROUTER; neigh->flags |= NTF_ROUTER;
} else if (rt) { } else if (rt) {
rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
} }
if (rt) if (rt)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment