Skip to content

Commit ad1e46a

Browse files
soheilhydavem330
authored andcommitted
ipv6: process socket-level control messages in IPv6
Process socket-level control messages by invoking __sock_cmsg_send in ip6_datagram_send_ctl for control messages on the SOL_SOCKET layer. This makes sure whenever ip6_datagram_send_ctl is called for udp and raw, we also process socket-level control messages. This is a bit uglier than IPv4, since IPv6 does not have something like ipcm_cookie. Perhaps we can later create a control message cookie for IPv6? Note that this commit interprets new control messages that were ignored before. As such, this commit does not change the behavior of IPv6 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 24025c4 commit ad1e46a

File tree

7 files changed

+28
-9
lines changed

7 files changed

+28
-9
lines changed

include/net/transp_v6.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
4242

4343
int ip6_datagram_send_ctl(struct net *net, struct sock *sk, struct msghdr *msg,
4444
struct flowi6 *fl6, struct ipv6_txoptions *opt,
45-
int *hlimit, int *tclass, int *dontfrag);
45+
int *hlimit, int *tclass, int *dontfrag,
46+
struct sockcm_cookie *sockc);
4647

4748
void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
4849
__u16 srcp, __u16 destp, int bucket);

net/ipv6/datagram.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,8 @@ EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl);
685685
int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
686686
struct msghdr *msg, struct flowi6 *fl6,
687687
struct ipv6_txoptions *opt,
688-
int *hlimit, int *tclass, int *dontfrag)
688+
int *hlimit, int *tclass, int *dontfrag,
689+
struct sockcm_cookie *sockc)
689690
{
690691
struct in6_pktinfo *src_info;
691692
struct cmsghdr *cmsg;
@@ -702,6 +703,12 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
702703
goto exit_f;
703704
}
704705

706+
if (cmsg->cmsg_level == SOL_SOCKET) {
707+
if (__sock_cmsg_send(sk, msg, cmsg, sockc))
708+
return -EINVAL;
709+
continue;
710+
}
711+
705712
if (cmsg->cmsg_level != SOL_IPV6)
706713
continue;
707714

net/ipv6/ip6_flowlabel.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
372372
if (olen > 0) {
373373
struct msghdr msg;
374374
struct flowi6 flowi6;
375+
struct sockcm_cookie sockc_junk;
375376
int junk;
376377

377378
err = -ENOMEM;
@@ -390,7 +391,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
390391
memset(&flowi6, 0, sizeof(flowi6));
391392

392393
err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt,
393-
&junk, &junk, &junk);
394+
&junk, &junk, &junk, &sockc_junk);
394395
if (err)
395396
goto done;
396397
err = -EINVAL;

net/ipv6/ipv6_sockglue.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
471471
struct ipv6_txoptions *opt = NULL;
472472
struct msghdr msg;
473473
struct flowi6 fl6;
474+
struct sockcm_cookie sockc_junk;
474475
int junk;
475476

476477
memset(&fl6, 0, sizeof(fl6));
@@ -503,7 +504,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
503504
msg.msg_control = (void *)(opt+1);
504505

505506
retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk,
506-
&junk, &junk);
507+
&junk, &junk, &sockc_junk);
507508
if (retv)
508509
goto done;
509510
update:

net/ipv6/raw.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
745745
struct dst_entry *dst = NULL;
746746
struct raw6_frag_vec rfv;
747747
struct flowi6 fl6;
748+
struct sockcm_cookie sockc;
748749
int addr_len = msg->msg_namelen;
749750
int hlimit = -1;
750751
int tclass = -1;
@@ -821,13 +822,16 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
821822
if (fl6.flowi6_oif == 0)
822823
fl6.flowi6_oif = sk->sk_bound_dev_if;
823824

825+
sockc.tsflags = 0;
826+
824827
if (msg->msg_controllen) {
825828
opt = &opt_space;
826829
memset(opt, 0, sizeof(struct ipv6_txoptions));
827830
opt->tot_len = sizeof(struct ipv6_txoptions);
828831

829832
err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
830-
&hlimit, &tclass, &dontfrag);
833+
&hlimit, &tclass, &dontfrag,
834+
&sockc);
831835
if (err < 0) {
832836
fl6_sock_release(flowlabel);
833837
return err;

net/ipv6/udp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
11281128
int connected = 0;
11291129
int is_udplite = IS_UDPLITE(sk);
11301130
int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
1131+
struct sockcm_cookie sockc;
11311132

11321133
/* destination address check */
11331134
if (sin6) {
@@ -1247,14 +1248,16 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
12471248
fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
12481249

12491250
fl6.flowi6_mark = sk->sk_mark;
1251+
sockc.tsflags = 0;
12501252

12511253
if (msg->msg_controllen) {
12521254
opt = &opt_space;
12531255
memset(opt, 0, sizeof(struct ipv6_txoptions));
12541256
opt->tot_len = sizeof(*opt);
12551257

12561258
err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
1257-
&hlimit, &tclass, &dontfrag);
1259+
&hlimit, &tclass, &dontfrag,
1260+
&sockc);
12581261
if (err < 0) {
12591262
fl6_sock_release(flowlabel);
12601263
return err;

net/l2tp/l2tp_ip6.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
492492
struct ip6_flowlabel *flowlabel = NULL;
493493
struct dst_entry *dst = NULL;
494494
struct flowi6 fl6;
495+
struct sockcm_cookie sockc_unused = {0};
495496
int addr_len = msg->msg_namelen;
496497
int hlimit = -1;
497498
int tclass = -1;
@@ -562,9 +563,10 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
562563
memset(opt, 0, sizeof(struct ipv6_txoptions));
563564
opt->tot_len = sizeof(struct ipv6_txoptions);
564565

565-
err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
566-
&hlimit, &tclass, &dontfrag);
567-
if (err < 0) {
566+
err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
567+
&hlimit, &tclass, &dontfrag,
568+
&sockc_unused);
569+
if (err < 0) {
568570
fl6_sock_release(flowlabel);
569571
return err;
570572
}

0 commit comments

Comments
 (0)