diff options
| -rw-r--r-- | include/net/ip6_route.h | 18 | ||||
| -rw-r--r-- | net/ipv6/fib6_rules.c | 11 | ||||
| -rw-r--r-- | net/ipv6/route.c | 11 |
3 files changed, 22 insertions, 18 deletions
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 4a808de7c0f6..68f67836e146 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h | |||
| @@ -37,6 +37,24 @@ struct route_info { | |||
| 37 | #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 | 37 | #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 |
| 38 | #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 | 38 | #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 |
| 39 | 39 | ||
| 40 | /* | ||
| 41 | * rt6_srcprefs2flags() and rt6_flags2srcprefs() translate | ||
| 42 | * between IPV6_ADDR_PREFERENCES socket option values | ||
| 43 | * IPV6_PREFER_SRC_TMP = 0x1 | ||
| 44 | * IPV6_PREFER_SRC_PUBLIC = 0x2 | ||
| 45 | * IPV6_PREFER_SRC_COA = 0x4 | ||
| 46 | * and above RT6_LOOKUP_F_SRCPREF_xxx flags. | ||
| 47 | */ | ||
| 48 | static inline int rt6_srcprefs2flags(unsigned int srcprefs) | ||
| 49 | { | ||
| 50 | /* No need to bitmask because srcprefs have only 3 bits. */ | ||
| 51 | return srcprefs << 3; | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline unsigned int rt6_flags2srcprefs(int flags) | ||
| 55 | { | ||
| 56 | return (flags >> 3) & 7; | ||
| 57 | } | ||
| 40 | 58 | ||
| 41 | extern void ip6_route_input(struct sk_buff *skb); | 59 | extern void ip6_route_input(struct sk_buff *skb); |
| 42 | 60 | ||
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 551882b9dfd6..5e463c43fcc2 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
| @@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
| 84 | if ((rule->flags & FIB_RULE_FIND_SADDR) && | 84 | if ((rule->flags & FIB_RULE_FIND_SADDR) && |
| 85 | r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { | 85 | r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { |
| 86 | struct in6_addr saddr; | 86 | struct in6_addr saddr; |
| 87 | unsigned int srcprefs = 0; | ||
| 88 | |||
| 89 | if (flags & RT6_LOOKUP_F_SRCPREF_TMP) | ||
| 90 | srcprefs |= IPV6_PREFER_SRC_TMP; | ||
| 91 | if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC) | ||
| 92 | srcprefs |= IPV6_PREFER_SRC_PUBLIC; | ||
| 93 | if (flags & RT6_LOOKUP_F_SRCPREF_COA) | ||
| 94 | srcprefs |= IPV6_PREFER_SRC_COA; | ||
| 95 | 87 | ||
| 96 | if (ipv6_dev_get_saddr(net, | 88 | if (ipv6_dev_get_saddr(net, |
| 97 | ip6_dst_idev(&rt->u.dst)->dev, | 89 | ip6_dst_idev(&rt->u.dst)->dev, |
| 98 | &flp->fl6_dst, srcprefs, | 90 | &flp->fl6_dst, |
| 91 | rt6_flags2srcprefs(flags), | ||
| 99 | &saddr)) | 92 | &saddr)) |
| 100 | goto again; | 93 | goto again; |
| 101 | if (!ipv6_prefix_equal(&saddr, &r->src.addr, | 94 | if (!ipv6_prefix_equal(&saddr, &r->src.addr, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b08879e97f22..52cd3eff31dc 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -819,15 +819,8 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, | |||
| 819 | 819 | ||
| 820 | if (!ipv6_addr_any(&fl->fl6_src)) | 820 | if (!ipv6_addr_any(&fl->fl6_src)) |
| 821 | flags |= RT6_LOOKUP_F_HAS_SADDR; | 821 | flags |= RT6_LOOKUP_F_HAS_SADDR; |
| 822 | else if (sk) { | 822 | else if (sk) |
| 823 | unsigned int prefs = inet6_sk(sk)->srcprefs; | 823 | flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); |
| 824 | if (prefs & IPV6_PREFER_SRC_TMP) | ||
| 825 | flags |= RT6_LOOKUP_F_SRCPREF_TMP; | ||
| 826 | if (prefs & IPV6_PREFER_SRC_PUBLIC) | ||
| 827 | flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC; | ||
| 828 | if (prefs & IPV6_PREFER_SRC_COA) | ||
| 829 | flags |= RT6_LOOKUP_F_SRCPREF_COA; | ||
| 830 | } | ||
| 831 | 824 | ||
| 832 | return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); | 825 | return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); |
| 833 | } | 826 | } |
