diff options
author | David Ahern <dsahern@gmail.com> | 2019-04-16 17:36:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-18 02:10:47 -0400 |
commit | effda4dd97e878ab83336bec7411cc41b5cc6d37 (patch) | |
tree | 7091d54945d28a89581e4b49aebe816c817340af /net/ipv6/fib6_rules.c | |
parent | 8ff2e5b26cb84b1b0f502c0b7a3c62e4c4d86acc (diff) |
ipv6: Pass fib6_result to fib lookups
Change fib6_lookup and fib6_table_lookup to take a fib6_result and set
f6i and nh rather than returning a fib6_info. For now both always
return 0.
A later patch set can make these more like the IPv4 counterparts and
return EINVAL, EACCESS, etc based on fib6_type.
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/fib6_rules.c')
-rw-r--r-- | net/ipv6/fib6_rules.c | 34 |
1 files changed, 13 insertions, 21 deletions
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index f590446595d8..ab5ac643bae8 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -61,16 +61,16 @@ unsigned int fib6_rules_seq_read(struct net *net) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /* called with rcu lock held; no reference taken on fib6_info */ | 63 | /* called with rcu lock held; no reference taken on fib6_info */ |
64 | struct fib6_info *fib6_lookup(struct net *net, int oif, struct flowi6 *fl6, | 64 | int fib6_lookup(struct net *net, int oif, struct flowi6 *fl6, |
65 | int flags) | 65 | struct fib6_result *res, int flags) |
66 | { | 66 | { |
67 | struct fib6_info *f6i; | ||
68 | int err; | 67 | int err; |
69 | 68 | ||
70 | if (net->ipv6.fib6_has_custom_rules) { | 69 | if (net->ipv6.fib6_has_custom_rules) { |
71 | struct fib_lookup_arg arg = { | 70 | struct fib_lookup_arg arg = { |
72 | .lookup_ptr = fib6_table_lookup, | 71 | .lookup_ptr = fib6_table_lookup, |
73 | .lookup_data = &oif, | 72 | .lookup_data = &oif, |
73 | .result = res, | ||
74 | .flags = FIB_LOOKUP_NOREF, | 74 | .flags = FIB_LOOKUP_NOREF, |
75 | }; | 75 | }; |
76 | 76 | ||
@@ -78,19 +78,15 @@ struct fib6_info *fib6_lookup(struct net *net, int oif, struct flowi6 *fl6, | |||
78 | 78 | ||
79 | err = fib_rules_lookup(net->ipv6.fib6_rules_ops, | 79 | err = fib_rules_lookup(net->ipv6.fib6_rules_ops, |
80 | flowi6_to_flowi(fl6), flags, &arg); | 80 | flowi6_to_flowi(fl6), flags, &arg); |
81 | if (err) | ||
82 | return ERR_PTR(err); | ||
83 | |||
84 | f6i = arg.result ? : net->ipv6.fib6_null_entry; | ||
85 | } else { | 81 | } else { |
86 | f6i = fib6_table_lookup(net, net->ipv6.fib6_local_tbl, | 82 | err = fib6_table_lookup(net, net->ipv6.fib6_local_tbl, oif, |
87 | oif, fl6, flags); | 83 | fl6, res, flags); |
88 | if (!f6i || f6i == net->ipv6.fib6_null_entry) | 84 | if (err || res->f6i == net->ipv6.fib6_null_entry) |
89 | f6i = fib6_table_lookup(net, net->ipv6.fib6_main_tbl, | 85 | err = fib6_table_lookup(net, net->ipv6.fib6_main_tbl, |
90 | oif, fl6, flags); | 86 | oif, fl6, res, flags); |
91 | } | 87 | } |
92 | 88 | ||
93 | return f6i; | 89 | return err; |
94 | } | 90 | } |
95 | 91 | ||
96 | struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, | 92 | struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, |
@@ -157,10 +153,10 @@ static int fib6_rule_saddr(struct net *net, struct fib_rule *rule, int flags, | |||
157 | static int fib6_rule_action_alt(struct fib_rule *rule, struct flowi *flp, | 153 | static int fib6_rule_action_alt(struct fib_rule *rule, struct flowi *flp, |
158 | int flags, struct fib_lookup_arg *arg) | 154 | int flags, struct fib_lookup_arg *arg) |
159 | { | 155 | { |
156 | struct fib6_result *res = arg->result; | ||
160 | struct flowi6 *flp6 = &flp->u.ip6; | 157 | struct flowi6 *flp6 = &flp->u.ip6; |
161 | struct net *net = rule->fr_net; | 158 | struct net *net = rule->fr_net; |
162 | struct fib6_table *table; | 159 | struct fib6_table *table; |
163 | struct fib6_info *f6i; | ||
164 | int err = -EAGAIN, *oif; | 160 | int err = -EAGAIN, *oif; |
165 | u32 tb_id; | 161 | u32 tb_id; |
166 | 162 | ||
@@ -182,14 +178,10 @@ static int fib6_rule_action_alt(struct fib_rule *rule, struct flowi *flp, | |||
182 | return -EAGAIN; | 178 | return -EAGAIN; |
183 | 179 | ||
184 | oif = (int *)arg->lookup_data; | 180 | oif = (int *)arg->lookup_data; |
185 | f6i = fib6_table_lookup(net, table, *oif, flp6, flags); | 181 | err = fib6_table_lookup(net, table, *oif, flp6, res, flags); |
186 | if (f6i != net->ipv6.fib6_null_entry) { | 182 | if (!err && res->f6i != net->ipv6.fib6_null_entry) |
187 | err = fib6_rule_saddr(net, rule, flags, flp6, | 183 | err = fib6_rule_saddr(net, rule, flags, flp6, |
188 | fib6_info_nh_dev(f6i)); | 184 | res->nh->fib_nh_dev); |
189 | |||
190 | if (likely(!err)) | ||
191 | arg->result = f6i; | ||
192 | } | ||
193 | 185 | ||
194 | return err; | 186 | return err; |
195 | } | 187 | } |