Skip to content

Commit

Permalink
Merge branch 'flexible-array-for-ip-tunnel-options'
Browse files Browse the repository at this point in the history
Gal Pressman says:

====================
Flexible array for ip tunnel options

Remove the hidden assumption that options are allocated at the end of
the struct, and teach the compiler about them using a flexible array.

First patch is converting hard-coded 'info + 1' to use ip_tunnel_info()
helper.
Second patch adds the 'options' flexible array and changes the helper to
use it.

v4: https://lore.kernel.org/20250217202503.265318-1-gal@nvidia.com
v3: https://lore.kernel.org/20250212140953.107533-1-gal@nvidia.com
v2: https://lore.kernel.org/20250209101853.15828-1-gal@nvidia.com
====================

Link: https://patch.msgid.link/20250219143256.370277-1-gal@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Feb 20, 2025
2 parents 5d6ba5a + bb5e62f commit 372ab5a
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 14 deletions.
7 changes: 2 additions & 5 deletions include/net/dst_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,8 @@ static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
if (!new_md)
return ERR_PTR(-ENOMEM);

unsafe_memcpy(&new_md->u.tun_info, &md_dst->u.tun_info,
sizeof(struct ip_tunnel_info) + md_size,
/* metadata_dst_alloc() reserves room (md_size bytes) for
* options right after the ip_tunnel_info struct.
*/);
memcpy(&new_md->u.tun_info, &md_dst->u.tun_info,
sizeof(struct ip_tunnel_info) + md_size);
#ifdef CONFIG_DST_CACHE
/* Unclone the dst cache if there is one */
if (new_md->u.tun_info.dst_cache.cache) {
Expand Down
7 changes: 4 additions & 3 deletions include/net/ip_tunnels.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ struct ip_tunnel_encap {

#define ip_tunnel_info_opts(info) \
_Generic(info, \
const struct ip_tunnel_info * : ((const void *)((info) + 1)),\
struct ip_tunnel_info * : ((void *)((info) + 1))\
const struct ip_tunnel_info * : ((const void *)(info)->options),\
struct ip_tunnel_info * : ((void *)(info)->options)\
)

struct ip_tunnel_info {
Expand All @@ -107,6 +107,7 @@ struct ip_tunnel_info {
#endif
u8 options_len;
u8 mode;
u8 options[] __aligned_largest __counted_by(options_len);
};

/* 6rd prefix/relay information */
Expand Down Expand Up @@ -650,7 +651,7 @@ static inline void iptunnel_xmit_stats(struct net_device *dev, int pkt_len)
static inline void ip_tunnel_info_opts_get(void *to,
const struct ip_tunnel_info *info)
{
memcpy(to, info + 1, info->options_len);
memcpy(to, ip_tunnel_info_opts(info), info->options_len);
}

static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info,
Expand Down
6 changes: 4 additions & 2 deletions net/core/dst.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ struct metadata_dst *metadata_dst_alloc(u8 optslen, enum metadata_type type,
{
struct metadata_dst *md_dst;

md_dst = kmalloc(sizeof(*md_dst) + optslen, flags);
md_dst = kmalloc(struct_size(md_dst, u.tun_info.options, optslen),
flags);
if (!md_dst)
return NULL;

Expand Down Expand Up @@ -314,7 +315,8 @@ metadata_dst_alloc_percpu(u8 optslen, enum metadata_type type, gfp_t flags)
int cpu;
struct metadata_dst __percpu *md_dst;

md_dst = __alloc_percpu_gfp(sizeof(struct metadata_dst) + optslen,
md_dst = __alloc_percpu_gfp(struct_size(md_dst, u.tun_info.options,
optslen),
__alignof__(struct metadata_dst), flags);
if (!md_dst)
return NULL;
Expand Down
8 changes: 4 additions & 4 deletions net/sched/act_tunnel_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,16 +571,16 @@ static void tunnel_key_release(struct tc_action *a)
static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
const struct ip_tunnel_info *info)
{
const u8 *src = ip_tunnel_info_opts(info);
int len = info->options_len;
u8 *src = (u8 *)(info + 1);
struct nlattr *start;

start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
if (!start)
return -EMSGSIZE;

while (len > 0) {
struct geneve_opt *opt = (struct geneve_opt *)src;
const struct geneve_opt *opt = (const struct geneve_opt *)src;

if (nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS,
opt->opt_class) ||
Expand All @@ -603,7 +603,7 @@ static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
static int tunnel_key_vxlan_opts_dump(struct sk_buff *skb,
const struct ip_tunnel_info *info)
{
struct vxlan_metadata *md = (struct vxlan_metadata *)(info + 1);
const struct vxlan_metadata *md = ip_tunnel_info_opts(info);
struct nlattr *start;

start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_VXLAN);
Expand All @@ -622,7 +622,7 @@ static int tunnel_key_vxlan_opts_dump(struct sk_buff *skb,
static int tunnel_key_erspan_opts_dump(struct sk_buff *skb,
const struct ip_tunnel_info *info)
{
struct erspan_metadata *md = (struct erspan_metadata *)(info + 1);
const struct erspan_metadata *md = ip_tunnel_info_opts(info);
struct nlattr *start;

start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN);
Expand Down

0 comments on commit 372ab5a

Please sign in to comment.