Skip to content

Commit 24025c4

Browse files
soheilhydavem330
authored andcommitted
ipv4: process socket-level control messages in IPv4
Process socket-level control messages by invoking __sock_cmsg_send in ip_cmsg_send for control messages on the SOL_SOCKET layer. This makes sure whenever ip_cmsg_send is called in udp, icmp, and raw, we also process socket-level control messages. Note that this commit interprets new control messages that were ignored before. As such, this commit does not change the behavior of IPv4 control messages. Signed-off-by: Soheil Hassas Yeganeh <[email protected]> Acked-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3dd17e6 commit 24025c4

File tree

5 files changed

+13
-6
lines changed

5 files changed

+13
-6
lines changed

include/net/ip.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
5656
}
5757

5858
struct ipcm_cookie {
59+
struct sockcm_cookie sockc;
5960
__be32 addr;
6061
int oif;
6162
struct ip_options_rcu *opt;
@@ -550,7 +551,7 @@ int ip_options_rcv_srr(struct sk_buff *skb);
550551

551552
void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb);
552553
void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb, int offset);
553-
int ip_cmsg_send(struct net *net, struct msghdr *msg,
554+
int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
554555
struct ipcm_cookie *ipc, bool allow_ipv6);
555556
int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
556557
unsigned int optlen);

net/ipv4/ip_sockglue.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,12 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb,
219219
}
220220
EXPORT_SYMBOL(ip_cmsg_recv_offset);
221221

222-
int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc,
222+
int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc,
223223
bool allow_ipv6)
224224
{
225225
int err, val;
226226
struct cmsghdr *cmsg;
227+
struct net *net = sock_net(sk);
227228

228229
for_each_cmsghdr(cmsg, msg) {
229230
if (!CMSG_OK(msg, cmsg))
@@ -244,6 +245,12 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc,
244245
continue;
245246
}
246247
#endif
248+
if (cmsg->cmsg_level == SOL_SOCKET) {
249+
if (__sock_cmsg_send(sk, msg, cmsg, &ipc->sockc))
250+
return -EINVAL;
251+
continue;
252+
}
253+
247254
if (cmsg->cmsg_level != SOL_IP)
248255
continue;
249256
switch (cmsg->cmsg_type) {

net/ipv4/ping.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
747747
sock_tx_timestamp(sk, &ipc.tx_flags);
748748

749749
if (msg->msg_controllen) {
750-
err = ip_cmsg_send(sock_net(sk), msg, &ipc, false);
750+
err = ip_cmsg_send(sk, msg, &ipc, false);
751751
if (unlikely(err)) {
752752
kfree(ipc.opt);
753753
return err;

net/ipv4/raw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
548548
ipc.oif = sk->sk_bound_dev_if;
549549

550550
if (msg->msg_controllen) {
551-
err = ip_cmsg_send(net, msg, &ipc, false);
551+
err = ip_cmsg_send(sk, msg, &ipc, false);
552552
if (unlikely(err)) {
553553
kfree(ipc.opt);
554554
goto out;

net/ipv4/udp.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,8 +1034,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
10341034
sock_tx_timestamp(sk, &ipc.tx_flags);
10351035

10361036
if (msg->msg_controllen) {
1037-
err = ip_cmsg_send(sock_net(sk), msg, &ipc,
1038-
sk->sk_family == AF_INET6);
1037+
err = ip_cmsg_send(sk, msg, &ipc, sk->sk_family == AF_INET6);
10391038
if (unlikely(err)) {
10401039
kfree(ipc.opt);
10411040
return err;

0 commit comments

Comments
 (0)