if ((rule->flags & FIB_RULE_FIND_SADDR) &&
r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) {
struct in6_addr saddr;
- if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
- &flp->fl6_dst, &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,
+ ip6_dst_idev(&rt->u.dst)->dev,
+ &flp->fl6_dst, srcprefs,
+ &saddr))
goto again;
if (!ipv6_prefix_equal(&saddr, &r->src.addr,
r->src.plen))
};
static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
+ struct fib_rule_hdr *frh,
struct nlattr **tb)
{
int err = -EINVAL;
- struct net *net = skb->sk->sk_net;
+ struct net *net = sock_net(skb->sk);
struct fib6_rule *rule6 = (struct fib6_rule *) rule;
if (rule->action == FR_ACT_TO_TBL) {
}
static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
- struct nlmsghdr *nlh, struct fib_rule_hdr *frh)
+ struct fib_rule_hdr *frh)
{
struct fib6_rule *rule6 = (struct fib6_rule *) rule;
void fib6_rules_cleanup(void)
{
- return unregister_pernet_subsys(&fib6_rules_net_ops);
+ unregister_pernet_subsys(&fib6_rules_net_ops);
}