From: David Ahern <dsah...@gmail.com> Add nexthop selection to fib_result and update FIB_RES macros to use it. Right now, fib_nh in fib_result will point to a nexthop within a fib_info. Later, fib_nh can point to data with a nexthop.
Signed-off-by: David Ahern <dsah...@gmail.com> --- include/net/ip_fib.h | 21 +++++++++------------ net/core/filter.c | 2 +- net/ipv4/fib_frontend.c | 4 ++-- net/ipv4/fib_semantics.c | 4 ++-- net/ipv4/fib_trie.c | 4 ++-- net/ipv4/route.c | 18 +++++++++--------- 6 files changed, 25 insertions(+), 28 deletions(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index ce9b92485064..0b40c59b8a5f 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -141,6 +141,7 @@ struct fib_result { unsigned char type; unsigned char scope; u32 tclassid; + struct fib_nh *nh; struct fib_info *fi; struct fib_table *table; struct hlist_head *fa_head; @@ -161,11 +162,7 @@ struct fib_result_nl { int err; }; -#ifdef CONFIG_IP_ROUTE_MULTIPATH -#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) -#else /* CONFIG_IP_ROUTE_MULTIPATH */ -#define FIB_RES_NH(res) ((res).fi->fib_nh[0]) -#endif /* CONFIG_IP_ROUTE_MULTIPATH */ +#define FIB_RES_NH(res) ((res).nh) #ifdef CONFIG_IP_MULTIPLE_TABLES #define FIB_TABLE_HASHSZ 256 @@ -177,13 +174,13 @@ __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh, unsigned char scope); #define FIB_RES_SADDR(net, res) \ - ((FIB_RES_NH(res).nh_saddr_genid == \ + ((FIB_RES_NH(res)->nh_saddr_genid == \ atomic_read(&(net)->ipv4.dev_addr_genid)) ? \ - FIB_RES_NH(res).nh_saddr : \ - fib_info_update_nh_saddr((net), &FIB_RES_NH(res), (res).fi->fib_scope)) -#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) -#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev) -#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif) + FIB_RES_NH(res)->nh_saddr : \ + fib_info_update_nh_saddr((net), FIB_RES_NH(res), (res).fi->fib_scope)) +#define FIB_RES_GW(res) (FIB_RES_NH(res)->nh_gw) +#define FIB_RES_DEV(res) (FIB_RES_NH(res)->nh_dev) +#define FIB_RES_OIF(res) (FIB_RES_NH(res)->nh_oif) #define FIB_RES_PREFSRC(net, res) ((res).fi->fib_prefsrc ? : \ FIB_RES_SADDR(net, res)) @@ -422,7 +419,7 @@ static inline void fib_combine_itag(u32 *itag, const struct fib_result *res) #ifdef CONFIG_IP_MULTIPLE_TABLES u32 rtag; #endif - *itag = FIB_RES_NH(*res).nh_tclassid<<16; + *itag = FIB_RES_NH(*res)->nh_tclassid << 16; #ifdef CONFIG_IP_MULTIPLE_TABLES rtag = res->tclassid; if (*itag == 0) diff --git a/net/core/filter.c b/net/core/filter.c index c25eb36f1320..0ba4c477415d 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4311,7 +4311,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params, return BPF_FIB_LKUP_RET_FRAG_NEEDED; } - nh = &res.fi->fib_nh[res.nh_sel]; + nh = res.nh; /* do not handle lwt encaps right now */ if (nh->nh_lwtstate) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index b0910d8c8bd4..2f9bf1ec2678 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -380,7 +380,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, dev_match = true; #endif if (dev_match) { - ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; + ret = FIB_RES_NH(res)->nh_scope >= RT_SCOPE_HOST; return ret; } if (no_addr) @@ -392,7 +392,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, ret = 0; if (fib_lookup(net, &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE) == 0) { if (res.type == RTN_UNICAST) - ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; + ret = FIB_RES_NH(res)->nh_scope >= RT_SCOPE_HOST; } return ret; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 0d792666821a..53e38ecfdd58 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -1728,7 +1728,7 @@ void fib_select_multipath(struct fib_result *res, int hash) if (!fib_good_nh(nh)) continue; if (!first) { - res->nh_sel = nhsel; + res->nh = &fi->fib_nh[nhsel]; first = true; } } @@ -1736,7 +1736,7 @@ void fib_select_multipath(struct fib_result *res, int hash) if (hash > atomic_read(&nh->nh_upper_bound)) continue; - res->nh_sel = nhsel; + res->nh = &fi->fib_nh[nhsel]; return; } endfor_nexthops(fi); } diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 5bc0c89e81e4..51e7b38f3a7b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1468,7 +1468,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, if (fi->fib_flags & RTNH_F_DEAD) continue; for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { - const struct fib_nh *nh = &fi->fib_nh[nhsel]; + struct fib_nh *nh = &fi->fib_nh[nhsel]; struct in_device *in_dev = __in_dev_get_rcu(nh->nh_dev); if (nh->nh_flags & RTNH_F_DEAD) @@ -1489,7 +1489,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, res->prefix = htonl(n->key); res->prefixlen = KEYLENGTH - fa->fa_slen; - res->nh_sel = nhsel; + res->nh = nh; res->type = fa->fa_type; res->scope = fi->fib_scope; res->fi = fi; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b678466da451..1297c7c934a8 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -776,7 +776,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow neigh_event_send(n, NULL); } else { if (fib_lookup(net, fl4, &res, 0) == 0) { - struct fib_nh *nh = &FIB_RES_NH(res); + struct fib_nh *nh = FIB_RES_NH(res); update_or_create_fnhe(nh, fl4->daddr, new_gw, 0, false, @@ -1021,7 +1021,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) rcu_read_lock(); if (fib_lookup(dev_net(dst->dev), fl4, &res, 0) == 0) { - struct fib_nh *nh = &FIB_RES_NH(res); + struct fib_nh *nh = FIB_RES_NH(res); update_or_create_fnhe(nh, fl4->daddr, 0, mtu, lock, jiffies + ip_rt_mtu_expires); @@ -1350,7 +1350,7 @@ static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr) u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr) { struct fib_info *fi = res->fi; - struct fib_nh *nh = &fi->fib_nh[res->nh_sel]; + struct fib_nh *nh = res->nh; struct net_device *dev = nh->nh_dev; u32 mtu = 0; @@ -1527,7 +1527,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, bool cached = false; if (fi) { - struct fib_nh *nh = &FIB_RES_NH(*res); + struct fib_nh *nh = FIB_RES_NH(*res); if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) { rt->rt_gateway = nh->nh_gw; @@ -1744,12 +1744,12 @@ static int __mkroute_input(struct sk_buff *skb, } } - fnhe = find_exception(&FIB_RES_NH(*res), daddr); + fnhe = find_exception(FIB_RES_NH(*res), daddr); if (do_cache) { if (fnhe) rth = rcu_dereference(fnhe->fnhe_rth_input); else - rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input); + rth = rcu_dereference(FIB_RES_NH(*res)->nh_rth_input); if (rt_cache_valid(rth)) { skb_dst_set_noref(skb, &rth->dst); goto out; @@ -2039,7 +2039,7 @@ out: return err; do_cache = false; if (res->fi) { if (!itag) { - rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input); + rth = rcu_dereference(FIB_RES_NH(*res)->nh_rth_input); if (rt_cache_valid(rth)) { skb_dst_set_noref(skb, &rth->dst); err = 0; @@ -2069,7 +2069,7 @@ out: return err; } if (do_cache) { - struct fib_nh *nh = &FIB_RES_NH(*res); + struct fib_nh *nh = FIB_RES_NH(*res); rth->dst.lwtstate = lwtstate_get(nh->nh_lwtstate); if (lwtunnel_input_redirect(rth->dst.lwtstate)) { @@ -2249,7 +2249,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, do_cache &= fi != NULL; if (fi) { struct rtable __rcu **prth; - struct fib_nh *nh = &FIB_RES_NH(*res); + struct fib_nh *nh = FIB_RES_NH(*res); fnhe = find_exception(nh, fl4->daddr); if (!do_cache) -- 2.11.0