mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 01:24:47 +01:00
ipv4/inet_sock.h: Avoid thousands of -Wflex-array-member-not-at-end warnings
Use DEFINE_RAW_FLEX() to avoid thousands of -Wflex-array-member-not-at-end warnings. Remove struct ip_options_data, and adjust the rest of the code so that flexible-array member struct ip_options_rcu::opt.__data[] ends last in struct icmp_bxm. Compensate for this by using the DEFINE_RAW_FLEX() helper to define each on-stack struct instance that contained struct ip_options_data as a member, and to define struct ip_options_rcu with a fixed on-stack size for its nested flexible-array member opt.__data[]. Also, add a couple of code comments to prevent people from adding members to a struct after another member that contains a flexible array. With these changes, fix 2600 warnings of the following type: include/net/inet_sock.h:65:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> Link: https://patch.msgid.link/aVteBadWA6AbTp7X@kspp Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
915a5f60ad
commit
c86af46b9c
6 changed files with 79 additions and 68 deletions
|
|
@ -26,6 +26,8 @@
|
|||
#include <net/tcp_states.h>
|
||||
#include <net/l3mdev.h>
|
||||
|
||||
#define IP_OPTIONS_DATA_FIXED_SIZE 40
|
||||
|
||||
/** struct ip_options - IP Options
|
||||
*
|
||||
* @faddr - Saved first hop address
|
||||
|
|
@ -58,12 +60,9 @@ struct ip_options {
|
|||
|
||||
struct ip_options_rcu {
|
||||
struct rcu_head rcu;
|
||||
struct ip_options opt;
|
||||
};
|
||||
|
||||
struct ip_options_data {
|
||||
struct ip_options_rcu opt;
|
||||
char data[40];
|
||||
/* Must be last as it ends in a flexible-array member. */
|
||||
struct ip_options opt;
|
||||
};
|
||||
|
||||
struct inet_request_sock {
|
||||
|
|
|
|||
104
net/ipv4/icmp.c
104
net/ipv4/icmp.c
|
|
@ -112,7 +112,9 @@ struct icmp_bxm {
|
|||
__be32 times[3];
|
||||
} data;
|
||||
int head_len;
|
||||
struct ip_options_data replyopts;
|
||||
|
||||
/* Must be last as it ends in a flexible-array member. */
|
||||
struct ip_options_rcu replyopts;
|
||||
};
|
||||
|
||||
/* An array of errno for error messages from dest unreach. */
|
||||
|
|
@ -353,9 +355,12 @@ void icmp_out_count(struct net *net, unsigned char type)
|
|||
static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct icmp_bxm *icmp_param = from;
|
||||
DEFINE_RAW_FLEX(struct icmp_bxm, icmp_param, replyopts.opt.__data,
|
||||
IP_OPTIONS_DATA_FIXED_SIZE);
|
||||
__wsum csum;
|
||||
|
||||
icmp_param = from;
|
||||
|
||||
csum = skb_copy_and_csum_bits(icmp_param->skb,
|
||||
icmp_param->offset + offset,
|
||||
to, len);
|
||||
|
|
@ -413,7 +418,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
|
|||
int type = icmp_param->data.icmph.type;
|
||||
int code = icmp_param->data.icmph.code;
|
||||
|
||||
if (ip_options_echo(net, &icmp_param->replyopts.opt.opt, skb))
|
||||
if (ip_options_echo(net, &icmp_param->replyopts.opt, skb))
|
||||
return;
|
||||
|
||||
/* Needed by both icmpv4_global_allow and icmp_xmit_lock */
|
||||
|
|
@ -435,10 +440,10 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
|
|||
daddr = ipc.addr = ip_hdr(skb)->saddr;
|
||||
saddr = fib_compute_spec_dst(skb);
|
||||
|
||||
if (icmp_param->replyopts.opt.opt.optlen) {
|
||||
ipc.opt = &icmp_param->replyopts.opt;
|
||||
if (icmp_param->replyopts.opt.optlen) {
|
||||
ipc.opt = &icmp_param->replyopts;
|
||||
if (ipc.opt->opt.srr)
|
||||
daddr = icmp_param->replyopts.opt.opt.faddr;
|
||||
daddr = icmp_param->replyopts.opt.faddr;
|
||||
}
|
||||
memset(&fl4, 0, sizeof(fl4));
|
||||
fl4.daddr = daddr;
|
||||
|
|
@ -491,8 +496,8 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
|
|||
int err;
|
||||
|
||||
memset(fl4, 0, sizeof(*fl4));
|
||||
fl4->daddr = (param->replyopts.opt.opt.srr ?
|
||||
param->replyopts.opt.opt.faddr : iph->saddr);
|
||||
fl4->daddr = (param->replyopts.opt.srr ?
|
||||
param->replyopts.opt.faddr : iph->saddr);
|
||||
fl4->saddr = saddr;
|
||||
fl4->flowi4_mark = mark;
|
||||
fl4->flowi4_uid = sock_net_uid(net, NULL);
|
||||
|
|
@ -775,9 +780,10 @@ free_skb:
|
|||
void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
|
||||
const struct inet_skb_parm *parm)
|
||||
{
|
||||
DEFINE_RAW_FLEX(struct icmp_bxm, icmp_param, replyopts.opt.__data,
|
||||
IP_OPTIONS_DATA_FIXED_SIZE);
|
||||
struct iphdr *iph;
|
||||
int room;
|
||||
struct icmp_bxm icmp_param;
|
||||
struct rtable *rt = skb_rtable(skb_in);
|
||||
bool apply_ratelimit = false;
|
||||
struct sk_buff *ext_skb;
|
||||
|
|
@ -906,7 +912,7 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
|
|||
iph->tos;
|
||||
mark = IP4_REPLY_MARK(net, skb_in->mark);
|
||||
|
||||
if (__ip_options_echo(net, &icmp_param.replyopts.opt.opt, skb_in,
|
||||
if (__ip_options_echo(net, &icmp_param->replyopts.opt, skb_in,
|
||||
&parm->opt))
|
||||
goto out_unlock;
|
||||
|
||||
|
|
@ -915,21 +921,21 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
|
|||
* Prepare data for ICMP header.
|
||||
*/
|
||||
|
||||
icmp_param.data.icmph.type = type;
|
||||
icmp_param.data.icmph.code = code;
|
||||
icmp_param.data.icmph.un.gateway = info;
|
||||
icmp_param.data.icmph.checksum = 0;
|
||||
icmp_param.skb = skb_in;
|
||||
icmp_param.offset = skb_network_offset(skb_in);
|
||||
icmp_param->data.icmph.type = type;
|
||||
icmp_param->data.icmph.code = code;
|
||||
icmp_param->data.icmph.un.gateway = info;
|
||||
icmp_param->data.icmph.checksum = 0;
|
||||
icmp_param->skb = skb_in;
|
||||
icmp_param->offset = skb_network_offset(skb_in);
|
||||
ipcm_init(&ipc);
|
||||
ipc.tos = tos;
|
||||
ipc.addr = iph->saddr;
|
||||
ipc.opt = &icmp_param.replyopts.opt;
|
||||
ipc.opt = &icmp_param->replyopts;
|
||||
ipc.sockc.mark = mark;
|
||||
|
||||
rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr,
|
||||
inet_dsfield_to_dscp(tos), mark, type, code,
|
||||
&icmp_param);
|
||||
icmp_param);
|
||||
if (IS_ERR(rt))
|
||||
goto out_unlock;
|
||||
|
||||
|
|
@ -942,7 +948,7 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
|
|||
room = dst_mtu(&rt->dst);
|
||||
if (room > 576)
|
||||
room = 576;
|
||||
room -= sizeof(struct iphdr) + icmp_param.replyopts.opt.opt.optlen;
|
||||
room -= sizeof(struct iphdr) + icmp_param->replyopts.opt.optlen;
|
||||
room -= sizeof(struct icmphdr);
|
||||
/* Guard against tiny mtu. We need to include at least one
|
||||
* IP network header for this message to make any sense.
|
||||
|
|
@ -950,15 +956,15 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
|
|||
if (room <= (int)sizeof(struct iphdr))
|
||||
goto ende;
|
||||
|
||||
ext_skb = icmp_ext_append(net, skb_in, &icmp_param.data.icmph, room,
|
||||
ext_skb = icmp_ext_append(net, skb_in, &icmp_param->data.icmph, room,
|
||||
parm->iif);
|
||||
if (ext_skb)
|
||||
icmp_param.skb = ext_skb;
|
||||
icmp_param->skb = ext_skb;
|
||||
|
||||
icmp_param.data_len = icmp_param.skb->len - icmp_param.offset;
|
||||
if (icmp_param.data_len > room)
|
||||
icmp_param.data_len = room;
|
||||
icmp_param.head_len = sizeof(struct icmphdr);
|
||||
icmp_param->data_len = icmp_param->skb->len - icmp_param->offset;
|
||||
if (icmp_param->data_len > room)
|
||||
icmp_param->data_len = room;
|
||||
icmp_param->head_len = sizeof(struct icmphdr);
|
||||
|
||||
/* if we don't have a source address at this point, fall back to the
|
||||
* dummy address instead of sending out a packet with a source address
|
||||
|
|
@ -969,7 +975,7 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
|
|||
|
||||
trace_icmp_send(skb_in, type, code);
|
||||
|
||||
icmp_push_reply(sk, &icmp_param, &fl4, &ipc, &rt);
|
||||
icmp_push_reply(sk, icmp_param, &fl4, &ipc, &rt);
|
||||
|
||||
if (ext_skb)
|
||||
consume_skb(ext_skb);
|
||||
|
|
@ -1206,7 +1212,8 @@ static enum skb_drop_reason icmp_redirect(struct sk_buff *skb)
|
|||
|
||||
static enum skb_drop_reason icmp_echo(struct sk_buff *skb)
|
||||
{
|
||||
struct icmp_bxm icmp_param;
|
||||
DEFINE_RAW_FLEX(struct icmp_bxm, icmp_param, replyopts.opt.__data,
|
||||
IP_OPTIONS_DATA_FIXED_SIZE);
|
||||
struct net *net;
|
||||
|
||||
net = skb_dst_dev_net_rcu(skb);
|
||||
|
|
@ -1214,18 +1221,18 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb)
|
|||
if (READ_ONCE(net->ipv4.sysctl_icmp_echo_ignore_all))
|
||||
return SKB_NOT_DROPPED_YET;
|
||||
|
||||
icmp_param.data.icmph = *icmp_hdr(skb);
|
||||
icmp_param.skb = skb;
|
||||
icmp_param.offset = 0;
|
||||
icmp_param.data_len = skb->len;
|
||||
icmp_param.head_len = sizeof(struct icmphdr);
|
||||
icmp_param->data.icmph = *icmp_hdr(skb);
|
||||
icmp_param->skb = skb;
|
||||
icmp_param->offset = 0;
|
||||
icmp_param->data_len = skb->len;
|
||||
icmp_param->head_len = sizeof(struct icmphdr);
|
||||
|
||||
if (icmp_param.data.icmph.type == ICMP_ECHO)
|
||||
icmp_param.data.icmph.type = ICMP_ECHOREPLY;
|
||||
else if (!icmp_build_probe(skb, &icmp_param.data.icmph))
|
||||
if (icmp_param->data.icmph.type == ICMP_ECHO)
|
||||
icmp_param->data.icmph.type = ICMP_ECHOREPLY;
|
||||
else if (!icmp_build_probe(skb, &icmp_param->data.icmph))
|
||||
return SKB_NOT_DROPPED_YET;
|
||||
|
||||
icmp_reply(&icmp_param, skb);
|
||||
icmp_reply(icmp_param, skb);
|
||||
return SKB_NOT_DROPPED_YET;
|
||||
}
|
||||
|
||||
|
|
@ -1353,7 +1360,8 @@ EXPORT_SYMBOL_GPL(icmp_build_probe);
|
|||
*/
|
||||
static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb)
|
||||
{
|
||||
struct icmp_bxm icmp_param;
|
||||
DEFINE_RAW_FLEX(struct icmp_bxm, icmp_param, replyopts.opt.__data,
|
||||
IP_OPTIONS_DATA_FIXED_SIZE);
|
||||
/*
|
||||
* Too short.
|
||||
*/
|
||||
|
|
@ -1363,19 +1371,19 @@ static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb)
|
|||
/*
|
||||
* Fill in the current time as ms since midnight UT:
|
||||
*/
|
||||
icmp_param.data.times[1] = inet_current_timestamp();
|
||||
icmp_param.data.times[2] = icmp_param.data.times[1];
|
||||
icmp_param->data.times[1] = inet_current_timestamp();
|
||||
icmp_param->data.times[2] = icmp_param->data.times[1];
|
||||
|
||||
BUG_ON(skb_copy_bits(skb, 0, &icmp_param.data.times[0], 4));
|
||||
BUG_ON(skb_copy_bits(skb, 0, &icmp_param->data.times[0], 4));
|
||||
|
||||
icmp_param.data.icmph = *icmp_hdr(skb);
|
||||
icmp_param.data.icmph.type = ICMP_TIMESTAMPREPLY;
|
||||
icmp_param.data.icmph.code = 0;
|
||||
icmp_param.skb = skb;
|
||||
icmp_param.offset = 0;
|
||||
icmp_param.data_len = 0;
|
||||
icmp_param.head_len = sizeof(struct icmphdr) + 12;
|
||||
icmp_reply(&icmp_param, skb);
|
||||
icmp_param->data.icmph = *icmp_hdr(skb);
|
||||
icmp_param->data.icmph.type = ICMP_TIMESTAMPREPLY;
|
||||
icmp_param->data.icmph.code = 0;
|
||||
icmp_param->skb = skb;
|
||||
icmp_param->offset = 0;
|
||||
icmp_param->data_len = 0;
|
||||
icmp_param->head_len = sizeof(struct icmphdr) + 12;
|
||||
icmp_reply(icmp_param, skb);
|
||||
return SKB_NOT_DROPPED_YET;
|
||||
|
||||
out_err:
|
||||
|
|
|
|||
|
|
@ -1606,7 +1606,8 @@ void ip_send_unicast_reply(struct sock *sk, const struct sock *orig_sk,
|
|||
const struct ip_reply_arg *arg,
|
||||
unsigned int len, u64 transmit_time, u32 txhash)
|
||||
{
|
||||
struct ip_options_data replyopts;
|
||||
DEFINE_RAW_FLEX(struct ip_options_rcu, replyopts, opt.__data,
|
||||
IP_OPTIONS_DATA_FIXED_SIZE);
|
||||
struct ipcm_cookie ipc;
|
||||
struct flowi4 fl4;
|
||||
struct rtable *rt = skb_rtable(skb);
|
||||
|
|
@ -1615,18 +1616,18 @@ void ip_send_unicast_reply(struct sock *sk, const struct sock *orig_sk,
|
|||
int err;
|
||||
int oif;
|
||||
|
||||
if (__ip_options_echo(net, &replyopts.opt.opt, skb, sopt))
|
||||
if (__ip_options_echo(net, &replyopts->opt, skb, sopt))
|
||||
return;
|
||||
|
||||
ipcm_init(&ipc);
|
||||
ipc.addr = daddr;
|
||||
ipc.sockc.transmit_time = transmit_time;
|
||||
|
||||
if (replyopts.opt.opt.optlen) {
|
||||
ipc.opt = &replyopts.opt;
|
||||
if (replyopts->opt.optlen) {
|
||||
ipc.opt = replyopts;
|
||||
|
||||
if (replyopts.opt.opt.srr)
|
||||
daddr = replyopts.opt.opt.faddr;
|
||||
if (replyopts->opt.srr)
|
||||
daddr = replyopts->opt.faddr;
|
||||
}
|
||||
|
||||
oif = arg->bound_dev_if;
|
||||
|
|
|
|||
|
|
@ -690,6 +690,8 @@ EXPORT_IPV6_MOD_GPL(ping_common_sendmsg);
|
|||
|
||||
static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
{
|
||||
DEFINE_RAW_FLEX(struct ip_options_rcu, opt_copy, opt.__data,
|
||||
IP_OPTIONS_DATA_FIXED_SIZE);
|
||||
struct net *net = sock_net(sk);
|
||||
struct flowi4 fl4;
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
|
|
@ -697,7 +699,6 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
struct icmphdr user_icmph;
|
||||
struct pingfakehdr pfh;
|
||||
struct rtable *rt = NULL;
|
||||
struct ip_options_data opt_copy;
|
||||
int free = 0;
|
||||
__be32 saddr, daddr, faddr;
|
||||
u8 scope;
|
||||
|
|
@ -746,9 +747,9 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
rcu_read_lock();
|
||||
inet_opt = rcu_dereference(inet->inet_opt);
|
||||
if (inet_opt) {
|
||||
memcpy(&opt_copy, inet_opt,
|
||||
memcpy(opt_copy, inet_opt,
|
||||
sizeof(*inet_opt) + inet_opt->opt.optlen);
|
||||
ipc.opt = &opt_copy.opt;
|
||||
ipc.opt = opt_copy;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ static int raw_getfrag(void *from, char *to, int offset, int len, int odd,
|
|||
|
||||
static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
{
|
||||
DEFINE_RAW_FLEX(struct ip_options_rcu, opt_copy, opt.__data,
|
||||
IP_OPTIONS_DATA_FIXED_SIZE);
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
struct net *net = sock_net(sk);
|
||||
struct ipcm_cookie ipc;
|
||||
|
|
@ -491,7 +493,6 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
__be32 daddr;
|
||||
__be32 saddr;
|
||||
int uc_index, err;
|
||||
struct ip_options_data opt_copy;
|
||||
struct raw_frag_vec rfv;
|
||||
int hdrincl;
|
||||
|
||||
|
|
@ -561,9 +562,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
rcu_read_lock();
|
||||
inet_opt = rcu_dereference(inet->inet_opt);
|
||||
if (inet_opt) {
|
||||
memcpy(&opt_copy, inet_opt,
|
||||
memcpy(opt_copy, inet_opt,
|
||||
sizeof(*inet_opt) + inet_opt->opt.optlen);
|
||||
ipc.opt = &opt_copy.opt;
|
||||
ipc.opt = opt_copy;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1269,6 +1269,8 @@ EXPORT_IPV6_MOD_GPL(udp_cmsg_send);
|
|||
|
||||
int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
{
|
||||
DEFINE_RAW_FLEX(struct ip_options_rcu, opt_copy, opt.__data,
|
||||
IP_OPTIONS_DATA_FIXED_SIZE);
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
struct udp_sock *up = udp_sk(sk);
|
||||
DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
|
||||
|
|
@ -1286,7 +1288,6 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
int corkreq = udp_test_bit(CORK, sk) || msg->msg_flags & MSG_MORE;
|
||||
int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
|
||||
struct sk_buff *skb;
|
||||
struct ip_options_data opt_copy;
|
||||
int uc_index;
|
||||
|
||||
if (len > 0xFFFF)
|
||||
|
|
@ -1368,9 +1369,9 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
rcu_read_lock();
|
||||
inet_opt = rcu_dereference(inet->inet_opt);
|
||||
if (inet_opt) {
|
||||
memcpy(&opt_copy, inet_opt,
|
||||
memcpy(opt_copy, inet_opt,
|
||||
sizeof(*inet_opt) + inet_opt->opt.optlen);
|
||||
ipc.opt = &opt_copy.opt;
|
||||
ipc.opt = opt_copy;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue