Skip to content

Commit 372ab5a

Browse files
committed
Merge branch 'flexible-array-for-ip-tunnel-options'
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/[email protected] v3: https://lore.kernel.org/[email protected] v2: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 5d6ba5a + bb5e62f commit 372ab5a

File tree

4 files changed

+14
-14
lines changed

4 files changed

+14
-14
lines changed

include/net/dst_metadata.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,8 @@ static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
163163
if (!new_md)
164164
return ERR_PTR(-ENOMEM);
165165

166-
unsafe_memcpy(&new_md->u.tun_info, &md_dst->u.tun_info,
167-
sizeof(struct ip_tunnel_info) + md_size,
168-
/* metadata_dst_alloc() reserves room (md_size bytes) for
169-
* options right after the ip_tunnel_info struct.
170-
*/);
166+
memcpy(&new_md->u.tun_info, &md_dst->u.tun_info,
167+
sizeof(struct ip_tunnel_info) + md_size);
171168
#ifdef CONFIG_DST_CACHE
172169
/* Unclone the dst cache if there is one */
173170
if (new_md->u.tun_info.dst_cache.cache) {

include/net/ip_tunnels.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ struct ip_tunnel_encap {
9595

9696
#define ip_tunnel_info_opts(info) \
9797
_Generic(info, \
98-
const struct ip_tunnel_info * : ((const void *)((info) + 1)),\
99-
struct ip_tunnel_info * : ((void *)((info) + 1))\
98+
const struct ip_tunnel_info * : ((const void *)(info)->options),\
99+
struct ip_tunnel_info * : ((void *)(info)->options)\
100100
)
101101

102102
struct ip_tunnel_info {
@@ -107,6 +107,7 @@ struct ip_tunnel_info {
107107
#endif
108108
u8 options_len;
109109
u8 mode;
110+
u8 options[] __aligned_largest __counted_by(options_len);
110111
};
111112

112113
/* 6rd prefix/relay information */
@@ -650,7 +651,7 @@ static inline void iptunnel_xmit_stats(struct net_device *dev, int pkt_len)
650651
static inline void ip_tunnel_info_opts_get(void *to,
651652
const struct ip_tunnel_info *info)
652653
{
653-
memcpy(to, info + 1, info->options_len);
654+
memcpy(to, ip_tunnel_info_opts(info), info->options_len);
654655
}
655656

656657
static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info,

net/core/dst.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ struct metadata_dst *metadata_dst_alloc(u8 optslen, enum metadata_type type,
286286
{
287287
struct metadata_dst *md_dst;
288288

289-
md_dst = kmalloc(sizeof(*md_dst) + optslen, flags);
289+
md_dst = kmalloc(struct_size(md_dst, u.tun_info.options, optslen),
290+
flags);
290291
if (!md_dst)
291292
return NULL;
292293

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

317-
md_dst = __alloc_percpu_gfp(sizeof(struct metadata_dst) + optslen,
318+
md_dst = __alloc_percpu_gfp(struct_size(md_dst, u.tun_info.options,
319+
optslen),
318320
__alignof__(struct metadata_dst), flags);
319321
if (!md_dst)
320322
return NULL;

net/sched/act_tunnel_key.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -571,16 +571,16 @@ static void tunnel_key_release(struct tc_action *a)
571571
static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
572572
const struct ip_tunnel_info *info)
573573
{
574+
const u8 *src = ip_tunnel_info_opts(info);
574575
int len = info->options_len;
575-
u8 *src = (u8 *)(info + 1);
576576
struct nlattr *start;
577577

578578
start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
579579
if (!start)
580580
return -EMSGSIZE;
581581

582582
while (len > 0) {
583-
struct geneve_opt *opt = (struct geneve_opt *)src;
583+
const struct geneve_opt *opt = (const struct geneve_opt *)src;
584584

585585
if (nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS,
586586
opt->opt_class) ||
@@ -603,7 +603,7 @@ static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
603603
static int tunnel_key_vxlan_opts_dump(struct sk_buff *skb,
604604
const struct ip_tunnel_info *info)
605605
{
606-
struct vxlan_metadata *md = (struct vxlan_metadata *)(info + 1);
606+
const struct vxlan_metadata *md = ip_tunnel_info_opts(info);
607607
struct nlattr *start;
608608

609609
start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_VXLAN);
@@ -622,7 +622,7 @@ static int tunnel_key_vxlan_opts_dump(struct sk_buff *skb,
622622
static int tunnel_key_erspan_opts_dump(struct sk_buff *skb,
623623
const struct ip_tunnel_info *info)
624624
{
625-
struct erspan_metadata *md = (struct erspan_metadata *)(info + 1);
625+
const struct erspan_metadata *md = ip_tunnel_info_opts(info);
626626
struct nlattr *start;
627627

628628
start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN);

0 commit comments

Comments
 (0)