diff options
author | David Ahern <dsahern@gmail.com> | 2019-04-06 01:30:26 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-09 00:22:40 +0200 |
commit | bdf004677107e3b847c5db09c9fbf8edefa24996 (patch) | |
tree | c0df291ae563fc3a8ea801243a77b77a9334ea61 | |
parent | ipv6: Add neighbor helpers that use the ipv6 stub (diff) | |
download | linux-bdf004677107e3b847c5db09c9fbf8edefa24996.tar.xz linux-bdf004677107e3b847c5db09c9fbf8edefa24996.zip |
net: Replace nhc_has_gw with nhc_gw_family
Allow the gateway in a fib_nh_common to be from a different address
family than the outer fib{6}_nh. To that end, replace nhc_has_gw with
nhc_gw_family and update users of nhc_has_gw to check nhc_gw_family.
Now nhc_family is used to know if the nh_common is part of a fib_nh
or fib6_nh (used for container_of to get to route family specific data),
and nhc_gw_family represents the address family for the gateway.
Signed-off-by: David Ahern <dsahern@gmail.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 4 | ||||
-rw-r--r-- | include/net/ip6_route.h | 2 | ||||
-rw-r--r-- | include/net/ip_fib.h | 7 | ||||
-rw-r--r-- | include/trace/events/fib.h | 4 | ||||
-rw-r--r-- | net/core/filter.c | 4 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 25 | ||||
-rw-r--r-- | net/ipv4/route.c | 5 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_fib.c | 2 | ||||
-rw-r--r-- | net/ipv6/route.c | 18 |
10 files changed, 35 insertions, 38 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 0ba9daa05a52..772aa78cab51 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -4915,7 +4915,7 @@ static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6) static bool mlxsw_sp_fib6_rt_can_mp(const struct fib6_info *rt) { /* RTF_CACHE routes are ignored */ - return !(rt->fib6_flags & RTF_ADDRCONF) && rt->fib6_nh.fib_nh_has_gw; + return !(rt->fib6_flags & RTF_ADDRCONF) && rt->fib6_nh.fib_nh_gw_family; } static struct fib6_info * @@ -5055,7 +5055,7 @@ static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp, static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp, const struct fib6_info *rt) { - return rt->fib6_nh.fib_nh_has_gw || + return rt->fib6_nh.fib_nh_gw_family || mlxsw_sp_nexthop6_ipip_type(mlxsw_sp, rt, NULL); } diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 342180a7285c..5909fc421305 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -69,7 +69,7 @@ static inline bool rt6_need_strict(const struct in6_addr *daddr) static inline bool rt6_qualify_for_ecmp(const struct fib6_info *f6i) { return !(f6i->fib6_flags & (RTF_ADDRCONF|RTF_DYNAMIC)) && - f6i->fib6_nh.fib_nh_has_gw; + f6i->fib6_nh.fib_nh_gw_family; } void ip6_route_input(struct sk_buff *skb); diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 3ce07841dc3b..c68a40435ee0 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -83,8 +83,8 @@ struct fib_nh_common { struct lwtunnel_state *nhc_lwtstate; unsigned char nhc_scope; u8 nhc_family; - u8 nhc_has_gw:1, - unused:7; + u8 nhc_gw_family; + union { __be32 ipv4; struct in6_addr ipv6; @@ -112,8 +112,7 @@ struct fib_nh { #define fib_nh_flags nh_common.nhc_flags #define fib_nh_lws nh_common.nhc_lwtstate #define fib_nh_scope nh_common.nhc_scope -#define fib_nh_family nh_common.nhc_family -#define fib_nh_has_gw nh_common.nhc_has_gw +#define fib_nh_gw_family nh_common.nhc_gw_family #define fib_nh_gw4 nh_common.nhc_gw.ipv4 #define fib_nh_gw6 nh_common.nhc_gw.ipv6 #define fib_nh_weight nh_common.nhc_weight diff --git a/include/trace/events/fib.h b/include/trace/events/fib.h index 7f83b6eafc5c..6f2a4dc35e37 100644 --- a/include/trace/events/fib.h +++ b/include/trace/events/fib.h @@ -69,13 +69,13 @@ TRACE_EVENT(fib_table_lookup, __assign_str(name, dev ? dev->name : "-"); if (nhc) { - if (nhc->nhc_family == AF_INET) { + if (nhc->nhc_gw_family == AF_INET) { p32 = (__be32 *) __entry->gw4; *p32 = nhc->nhc_gw.ipv4; in6 = (struct in6_addr *)__entry->gw6; *in6 = in6_zero; - } else if (nhc->nhc_family == AF_INET6) { + } else if (nhc->nhc_gw_family == AF_INET6) { p32 = (__be32 *) __entry->gw4; *p32 = 0; diff --git a/net/core/filter.c b/net/core/filter.c index 26d9cd785ae2..abd5b6ce031a 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4639,7 +4639,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params, return BPF_FIB_LKUP_RET_UNSUPP_LWT; dev = nhc->nhc_dev; - if (nhc->nhc_has_gw) + if (nhc->nhc_gw_family) params->ipv4_dst = nhc->nhc_gw.ipv4; params->rt_metric = res.fi->fib_priority; @@ -4752,7 +4752,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params, if (f6i->fib6_nh.fib_nh_lws) return BPF_FIB_LKUP_RET_UNSUPP_LWT; - if (f6i->fib6_nh.fib_nh_has_gw) + if (f6i->fib6_nh.fib_nh_gw_family) *dst = f6i->fib6_nh.fib_nh_gw6; dev = f6i->fib6_nh.fib_nh_dev; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 8e0cb1687a74..e11f78c6373f 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -513,7 +513,7 @@ int fib_nh_init(struct net *net, struct fib_nh *nh, nh->fib_nh_oif = cfg->fc_oif; if (cfg->fc_gw) { nh->fib_nh_gw4 = cfg->fc_gw; - nh->fib_nh_has_gw = 1; + nh->fib_nh_gw_family = AF_INET; } nh->fib_nh_flags = cfg->fc_flags; @@ -1238,7 +1238,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, "Route with host scope can not have multiple nexthops"); goto err_inval; } - if (nh->fib_nh_gw4) { + if (nh->fib_nh_gw_family) { NL_SET_ERR_MSG(extack, "Route with host scope can not have a gateway"); goto err_inval; @@ -1341,18 +1341,15 @@ int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nhc, rcu_read_unlock(); } - if (nhc->nhc_has_gw) { - switch (nhc->nhc_family) { - case AF_INET: - if (nla_put_in_addr(skb, RTA_GATEWAY, nhc->nhc_gw.ipv4)) - goto nla_put_failure; - break; - case AF_INET6: - if (nla_put_in6_addr(skb, RTA_GATEWAY, - &nhc->nhc_gw.ipv6) < 0) - goto nla_put_failure; - break; - } + switch (nhc->nhc_gw_family) { + case AF_INET: + if (nla_put_in_addr(skb, RTA_GATEWAY, nhc->nhc_gw.ipv4)) + goto nla_put_failure; + break; + case AF_INET6: + if (nla_put_in6_addr(skb, RTA_GATEWAY, &nhc->nhc_gw.ipv6) < 0) + goto nla_put_failure; + break; } *flags |= (nhc->nhc_flags & RTNH_F_ONLINK); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index f3f2adf630d4..e7338e421796 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1734,8 +1734,9 @@ static int __mkroute_input(struct sk_buff *skb, do_cache = res->fi && !itag; if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && skb->protocol == htons(ETH_P_IP)) { - __be32 gw = nhc->nhc_family == AF_INET ? nhc->nhc_gw.ipv4 : 0; + __be32 gw; + gw = nhc->nhc_gw_family == AF_INET ? nhc->nhc_gw.ipv4 : 0; if (IN_DEV_SHARED_MEDIA(out_dev) || inet_addr_onlink(out_dev, saddr, gw)) IPCB(skb)->flags |= IPSKB_DOREDIRECT; @@ -2284,7 +2285,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, } else { if (unlikely(fl4->flowi4_flags & FLOWI_FLAG_KNOWN_NH && - !(nhc->nhc_has_gw && + !(nhc->nhc_gw_family && nhc->nhc_scope == RT_SCOPE_LINK))) { do_cache = false; goto add; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2e8d1d2d8d3d..340a0f06f974 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2421,7 +2421,7 @@ static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, for_each_fib6_node_rt_rcu(fn) { if (rt->fib6_nh.fib_nh_dev->ifindex != dev->ifindex) continue; - if (no_gw && rt->fib6_nh.fib_nh_has_gw) + if (no_gw && rt->fib6_nh.fib_nh_gw_family) continue; if ((rt->fib6_flags & flags) != flags) continue; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 8c00609a1513..46f54a5bb1f0 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -2304,7 +2304,7 @@ static int ipv6_route_seq_show(struct seq_file *seq, void *v) #else seq_puts(seq, "00000000000000000000000000000000 00 "); #endif - if (rt->fib6_nh.fib_nh_has_gw) { + if (rt->fib6_nh.fib_nh_gw_family) { flags |= RTF_GATEWAY; seq_printf(seq, "%pi6", &rt->fib6_nh.fib_nh_gw6); } else { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 6e89151693d0..69f92d2b780e 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -533,7 +533,7 @@ static void rt6_probe(struct fib6_info *rt) * Router Reachability Probe MUST be rate-limited * to no more than one per minute. */ - if (!rt || !rt->fib6_nh.fib_nh_has_gw) + if (!rt || !rt->fib6_nh.fib_nh_gw_family) return; nh_gw = &rt->fib6_nh.fib_nh_gw6; @@ -595,7 +595,7 @@ static inline enum rt6_nud_state rt6_check_neigh(struct fib6_info *rt) struct neighbour *neigh; if (rt->fib6_flags & RTF_NONEXTHOP || - !rt->fib6_nh.fib_nh_has_gw) + !rt->fib6_nh.fib_nh_gw_family) return RT6_NUD_SUCCEED; rcu_read_lock_bh(); @@ -769,7 +769,7 @@ static struct fib6_info *rt6_select(struct net *net, struct fib6_node *fn, static bool rt6_is_gw_or_nonexthop(const struct fib6_info *rt) { - return (rt->fib6_flags & RTF_NONEXTHOP) || rt->fib6_nh.fib_nh_has_gw; + return (rt->fib6_flags & RTF_NONEXTHOP) || rt->fib6_nh.fib_nh_gw_family; } #ifdef CONFIG_IPV6_ROUTE_INFO @@ -975,7 +975,7 @@ static void ip6_rt_copy_init(struct rt6_info *rt, struct fib6_info *ort) rt->rt6i_dst = ort->fib6_dst; rt->rt6i_idev = dev ? in6_dev_get(dev) : NULL; rt->rt6i_flags = ort->fib6_flags; - if (ort->fib6_nh.fib_nh_has_gw) { + if (ort->fib6_nh.fib_nh_gw_family) { rt->rt6i_gateway = ort->fib6_nh.fib_nh_gw6; rt->rt6i_flags |= RTF_GATEWAY; } @@ -1860,7 +1860,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, rcu_read_unlock(); return rt; } else if (unlikely((fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH) && - !f6i->fib6_nh.fib_nh_has_gw)) { + !f6i->fib6_nh.fib_nh_gw_family)) { /* Create a RTF_CACHE clone which will not be * owned by the fib6 tree. It is for the special case where * the daddr in the skb during the neighbor look-up is different @@ -2430,7 +2430,7 @@ restart: continue; if (rt->fib6_flags & RTF_REJECT) break; - if (!rt->fib6_nh.fib_nh_has_gw) + if (!rt->fib6_nh.fib_nh_gw_family) continue; if (fl6->flowi6_oif != rt->fib6_nh.fib_nh_dev->ifindex) continue; @@ -2964,7 +2964,7 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, goto out; fib6_nh->fib_nh_gw6 = cfg->fc_gateway; - fib6_nh->fib_nh_has_gw = 1; + fib6_nh->fib_nh_gw_family = AF_INET6; } err = -ENODEV; @@ -3476,7 +3476,7 @@ static struct fib6_info *rt6_get_route_info(struct net *net, if (rt->fib6_nh.fib_nh_dev->ifindex != ifindex) continue; if (!(rt->fib6_flags & RTF_ROUTEINFO) || - !rt->fib6_nh.fib_nh_has_gw) + !rt->fib6_nh.fib_nh_gw_family) continue; if (!ipv6_addr_equal(&rt->fib6_nh.fib_nh_gw6, gwaddr)) continue; @@ -3807,7 +3807,7 @@ static int fib6_clean_tohost(struct fib6_info *rt, void *arg) struct in6_addr *gateway = (struct in6_addr *)arg; if (((rt->fib6_flags & RTF_RA_ROUTER) == RTF_RA_ROUTER) && - rt->fib6_nh.fib_nh_has_gw && + rt->fib6_nh.fib_nh_gw_family && ipv6_addr_equal(gateway, &rt->fib6_nh.fib_nh_gw6)) { return -1; } |