ipv6: fib: Provide offload indication using nexthop flags
authorIdo Schimmel <idosch@mellanox.com>
Tue, 15 Aug 2017 07:09:49 +0000 (09:09 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Aug 2017 00:05:03 +0000 (17:05 -0700)
IPv6 routes currently lack nexthop flags as in IPv4. This has several
implications.

In the forwarding path, it requires us to check the carrier state of the
nexthop device and potentially ignore a linkdown route, instead of
checking for RTNH_F_LINKDOWN.

It also requires capable drivers to use the user facing IPv6-specific
route flags to provide offload indication, instead of using the nexthop
flags as in IPv4.

Add nexthop flags to IPv6 routes in the 40 bytes hole and use it to
provide offload indication instead of the RTF_OFFLOAD flag, which is
removed while it's still not part of any official kernel release.

In the near future we would like to use the field for the
RTNH_F_{LINKDOWN,DEAD} flags, but this change is more involved and might
not be ready in time for the current cycle.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Acked-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
include/net/ip6_fib.h
include/uapi/linux/ipv6_route.h
net/ipv6/route.c

index 16676fffbf7051a6dcff5ca15db3524ee233151b..4895d5b8942b465a0c79e35260fccb6373c193cf 100644 (file)
@@ -2397,7 +2397,7 @@ mlxsw_sp_fib6_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry)
 
        if (fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL) {
                list_first_entry(&fib6_entry->rt6_list, struct mlxsw_sp_rt6,
-                                list)->rt->rt6i_flags |= RTF_OFFLOAD;
+                                list)->rt->rt6i_nh_flags |= RTNH_F_OFFLOAD;
                return;
        }
 
@@ -2407,9 +2407,9 @@ mlxsw_sp_fib6_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry)
 
                nh = mlxsw_sp_rt6_nexthop(nh_grp, mlxsw_sp_rt6);
                if (nh && nh->offloaded)
-                       mlxsw_sp_rt6->rt->rt6i_flags |= RTF_OFFLOAD;
+                       mlxsw_sp_rt6->rt->rt6i_nh_flags |= RTNH_F_OFFLOAD;
                else
-                       mlxsw_sp_rt6->rt->rt6i_flags &= ~RTF_OFFLOAD;
+                       mlxsw_sp_rt6->rt->rt6i_nh_flags &= ~RTNH_F_OFFLOAD;
        }
 }
 
@@ -2424,7 +2424,7 @@ mlxsw_sp_fib6_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry)
        list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
                struct rt6_info *rt = mlxsw_sp_rt6->rt;
 
-               rt->rt6i_flags &= ~RTF_OFFLOAD;
+               rt->rt6i_nh_flags &= ~RTNH_F_OFFLOAD;
        }
 }
 
index 1d790ea40ea7828e8eda44ca614fdc7528946fee..71c1646298ae369e29f266d9e3b079635f22b95e 100644 (file)
@@ -120,6 +120,8 @@ struct rt6_info {
 
        atomic_t                        rt6i_ref;
 
+       unsigned int                    rt6i_nh_flags;
+
        /* These are in a separate cache line. */
        struct rt6key                   rt6i_dst ____cacheline_aligned_in_smp;
        u32                             rt6i_flags;
index 33e2a5732bd1594349d2d43f9f79b37dd9eca1c7..d496c02e14bc44327fd3ab6c3faad0c1d7ac1e12 100644 (file)
@@ -35,7 +35,6 @@
 #define RTF_PREF(pref) ((pref) << 27)
 #define RTF_PREF_MASK  0x18000000
 
-#define RTF_OFFLOAD    0x20000000      /* offloaded route              */
 #define RTF_PCPU       0x40000000      /* read-only: can not be set by user */
 #define RTF_LOCAL      0x80000000
 
index 035762fed07db7c2859acf76fe1a991944d90154..6793135d49dbf3f28aa59f93a0ca09aa98648e9a 100644 (file)
@@ -1820,11 +1820,6 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
                goto out;
        }
 
-       if (cfg->fc_flags & RTF_OFFLOAD) {
-               NL_SET_ERR_MSG(extack, "Userspace can not set RTF_OFFLOAD");
-               goto out;
-       }
-
        if (cfg->fc_dst_len > 128) {
                NL_SET_ERR_MSG(extack, "Invalid prefix length");
                goto out;
@@ -3335,7 +3330,7 @@ static int rt6_nexthop_info(struct sk_buff *skb, struct rt6_info *rt,
                        goto nla_put_failure;
        }
 
-       if (rt->rt6i_flags & RTF_OFFLOAD)
+       if (rt->rt6i_nh_flags & RTNH_F_OFFLOAD)
                *flags |= RTNH_F_OFFLOAD;
 
        /* not needed for multipath encoding b/c it has a rtnexthop struct */