Commit 0c9a2ac1 authored by YOSHIFUJI Hideaki / 吉藤英明's avatar YOSHIFUJI Hideaki / 吉藤英明 Committed by David S. Miller

ipv6: Optmize translation between IPV6_PREFER_SRC_xxx and RT6_LOOKUP_F_xxx.

IPV6_PREFER_SRC_xxx definitions:
| #define IPV6_PREFER_SRC_TMP             0x0001
| #define IPV6_PREFER_SRC_PUBLIC          0x0002
| #define IPV6_PREFER_SRC_COA             0x0004

RT6_LOOKUP_F_xxx definitions:
| #define RT6_LOOKUP_F_SRCPREF_TMP        0x00000008
| #define RT6_LOOKUP_F_SRCPREF_PUBLIC     0x00000010
| #define RT6_LOOKUP_F_SRCPREF_COA        0x00000020

So, we can translate between these two groups by shift operation
instead of multiple 'if's.
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 25dc27d1
...@@ -37,6 +37,24 @@ struct route_info { ...@@ -37,6 +37,24 @@ struct route_info {
#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010
#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020
/*
* rt6_srcprefs2flags() and rt6_flags2srcprefs() translate
* between IPV6_ADDR_PREFERENCES socket option values
* IPV6_PREFER_SRC_TMP = 0x1
* IPV6_PREFER_SRC_PUBLIC = 0x2
* IPV6_PREFER_SRC_COA = 0x4
* and above RT6_LOOKUP_F_SRCPREF_xxx flags.
*/
static inline int rt6_srcprefs2flags(unsigned int srcprefs)
{
/* No need to bitmask because srcprefs have only 3 bits. */
return srcprefs << 3;
}
static inline unsigned int rt6_flags2srcprefs(int flags)
{
return (flags >> 3) & 7;
}
extern void ip6_route_input(struct sk_buff *skb); extern void ip6_route_input(struct sk_buff *skb);
......
...@@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, ...@@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
if ((rule->flags & FIB_RULE_FIND_SADDR) && if ((rule->flags & FIB_RULE_FIND_SADDR) &&
r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
struct in6_addr saddr; struct in6_addr saddr;
unsigned int srcprefs = 0;
if (flags & RT6_LOOKUP_F_SRCPREF_TMP)
srcprefs |= IPV6_PREFER_SRC_TMP;
if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC)
srcprefs |= IPV6_PREFER_SRC_PUBLIC;
if (flags & RT6_LOOKUP_F_SRCPREF_COA)
srcprefs |= IPV6_PREFER_SRC_COA;
if (ipv6_dev_get_saddr(net, if (ipv6_dev_get_saddr(net,
ip6_dst_idev(&rt->u.dst)->dev, ip6_dst_idev(&rt->u.dst)->dev,
&flp->fl6_dst, srcprefs, &flp->fl6_dst,
rt6_flags2srcprefs(flags),
&saddr)) &saddr))
goto again; goto again;
if (!ipv6_prefix_equal(&saddr, &r->src.addr, if (!ipv6_prefix_equal(&saddr, &r->src.addr,
......
...@@ -819,15 +819,8 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, ...@@ -819,15 +819,8 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
if (!ipv6_addr_any(&fl->fl6_src)) if (!ipv6_addr_any(&fl->fl6_src))
flags |= RT6_LOOKUP_F_HAS_SADDR; flags |= RT6_LOOKUP_F_HAS_SADDR;
else if (sk) { else if (sk)
unsigned int prefs = inet6_sk(sk)->srcprefs; flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs);
if (prefs & IPV6_PREFER_SRC_TMP)
flags |= RT6_LOOKUP_F_SRCPREF_TMP;
if (prefs & IPV6_PREFER_SRC_PUBLIC)
flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC;
if (prefs & IPV6_PREFER_SRC_COA)
flags |= RT6_LOOKUP_F_SRCPREF_COA;
}
return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output);
} }
......
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