aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip6_fib.h1
-rw-r--r--net/ipv6/fib6_rules.c15
2 files changed, 12 insertions, 4 deletions
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 5a4a67b38712..40105738e2f6 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -195,6 +195,7 @@ struct fib6_result {
195 struct fib6_info *f6i; 195 struct fib6_info *f6i;
196 u32 fib6_flags; 196 u32 fib6_flags;
197 u8 fib6_type; 197 u8 fib6_type;
198 struct rt6_info *rt6;
198}; 199};
199 200
200#define for_each_fib6_node_rt_rcu(fn) \ 201#define for_each_fib6_node_rt_rcu(fn) \
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index dbedbe655c91..06d1b7763600 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -94,9 +94,11 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
94 int flags, pol_lookup_t lookup) 94 int flags, pol_lookup_t lookup)
95{ 95{
96 if (net->ipv6.fib6_has_custom_rules) { 96 if (net->ipv6.fib6_has_custom_rules) {
97 struct fib6_result res = {};
97 struct fib_lookup_arg arg = { 98 struct fib_lookup_arg arg = {
98 .lookup_ptr = lookup, 99 .lookup_ptr = lookup,
99 .lookup_data = skb, 100 .lookup_data = skb,
101 .result = &res,
100 .flags = FIB_LOOKUP_NOREF, 102 .flags = FIB_LOOKUP_NOREF,
101 }; 103 };
102 104
@@ -106,8 +108,8 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
106 fib_rules_lookup(net->ipv6.fib6_rules_ops, 108 fib_rules_lookup(net->ipv6.fib6_rules_ops,
107 flowi6_to_flowi(fl6), flags, &arg); 109 flowi6_to_flowi(fl6), flags, &arg);
108 110
109 if (arg.result) 111 if (res.rt6)
110 return arg.result; 112 return &res.rt6->dst;
111 } else { 113 } else {
112 struct rt6_info *rt; 114 struct rt6_info *rt;
113 115
@@ -191,6 +193,7 @@ static int fib6_rule_action_alt(struct fib_rule *rule, struct flowi *flp,
191static int __fib6_rule_action(struct fib_rule *rule, struct flowi *flp, 193static int __fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
192 int flags, struct fib_lookup_arg *arg) 194 int flags, struct fib_lookup_arg *arg)
193{ 195{
196 struct fib6_result *res = arg->result;
194 struct flowi6 *flp6 = &flp->u.ip6; 197 struct flowi6 *flp6 = &flp->u.ip6;
195 struct rt6_info *rt = NULL; 198 struct rt6_info *rt = NULL;
196 struct fib6_table *table; 199 struct fib6_table *table;
@@ -245,7 +248,7 @@ again:
245discard_pkt: 248discard_pkt:
246 dst_hold(&rt->dst); 249 dst_hold(&rt->dst);
247out: 250out:
248 arg->result = rt; 251 res->rt6 = rt;
249 return err; 252 return err;
250} 253}
251 254
@@ -260,9 +263,13 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
260 263
261static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) 264static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
262{ 265{
263 struct rt6_info *rt = (struct rt6_info *) arg->result; 266 struct fib6_result *res = arg->result;
267 struct rt6_info *rt = res->rt6;
264 struct net_device *dev = NULL; 268 struct net_device *dev = NULL;
265 269
270 if (!rt)
271 return false;
272
266 if (rt->rt6i_idev) 273 if (rt->rt6i_idev)
267 dev = rt->rt6i_idev->dev; 274 dev = rt->rt6i_idev->dev;
268 275