int ip6_datagram_send_ctl(struct net *net, struct sock *sk, struct msghdr *msg,
                          struct flowi6 *fl6, struct ipv6_txoptions *opt,
-                         int *hlimit, int *tclass, int *dontfrag);
+                         int *hlimit, int *tclass, int *dontfrag,
+                         struct sockcm_cookie *sockc);
 
 void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
                             __u16 srcp, __u16 destp, int bucket);
 
 int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
                          struct msghdr *msg, struct flowi6 *fl6,
                          struct ipv6_txoptions *opt,
-                         int *hlimit, int *tclass, int *dontfrag)
+                         int *hlimit, int *tclass, int *dontfrag,
+                         struct sockcm_cookie *sockc)
 {
        struct in6_pktinfo *src_info;
        struct cmsghdr *cmsg;
                        goto exit_f;
                }
 
+               if (cmsg->cmsg_level == SOL_SOCKET) {
+                       if (__sock_cmsg_send(sk, msg, cmsg, sockc))
+                               return -EINVAL;
+                       continue;
+               }
+
                if (cmsg->cmsg_level != SOL_IPV6)
                        continue;
 
 
        if (olen > 0) {
                struct msghdr msg;
                struct flowi6 flowi6;
+               struct sockcm_cookie sockc_junk;
                int junk;
 
                err = -ENOMEM;
                memset(&flowi6, 0, sizeof(flowi6));
 
                err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, fl->opt,
-                                           &junk, &junk, &junk);
+                                           &junk, &junk, &junk, &sockc_junk);
                if (err)
                        goto done;
                err = -EINVAL;
 
                struct ipv6_txoptions *opt = NULL;
                struct msghdr msg;
                struct flowi6 fl6;
+               struct sockcm_cookie sockc_junk;
                int junk;
 
                memset(&fl6, 0, sizeof(fl6));
                msg.msg_control = (void *)(opt+1);
 
                retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk,
-                                            &junk, &junk);
+                                            &junk, &junk, &sockc_junk);
                if (retv)
                        goto done;
 update:
 
        struct dst_entry *dst = NULL;
        struct raw6_frag_vec rfv;
        struct flowi6 fl6;
+       struct sockcm_cookie sockc;
        int addr_len = msg->msg_namelen;
        int hlimit = -1;
        int tclass = -1;
        if (fl6.flowi6_oif == 0)
                fl6.flowi6_oif = sk->sk_bound_dev_if;
 
+       sockc.tsflags = 0;
+
        if (msg->msg_controllen) {
                opt = &opt_space;
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(struct ipv6_txoptions);
 
                err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-                                           &hlimit, &tclass, &dontfrag);
+                                           &hlimit, &tclass, &dontfrag,
+                                           &sockc);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
 
        int connected = 0;
        int is_udplite = IS_UDPLITE(sk);
        int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
+       struct sockcm_cookie sockc;
 
        /* destination address check */
        if (sin6) {
                fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
 
        fl6.flowi6_mark = sk->sk_mark;
+       sockc.tsflags = 0;
 
        if (msg->msg_controllen) {
                opt = &opt_space;
                opt->tot_len = sizeof(*opt);
 
                err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-                                           &hlimit, &tclass, &dontfrag);
+                                           &hlimit, &tclass, &dontfrag,
+                                           &sockc);
                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
 
        struct ip6_flowlabel *flowlabel = NULL;
        struct dst_entry *dst = NULL;
        struct flowi6 fl6;
+       struct sockcm_cookie sockc_unused = {0};
        int addr_len = msg->msg_namelen;
        int hlimit = -1;
        int tclass = -1;
                memset(opt, 0, sizeof(struct ipv6_txoptions));
                opt->tot_len = sizeof(struct ipv6_txoptions);
 
-               err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
-                                           &hlimit, &tclass, &dontfrag);
-               if (err < 0) {
+                err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt,
+                                            &hlimit, &tclass, &dontfrag,
+                                            &sockc_unused);
+                if (err < 0) {
                        fl6_sock_release(flowlabel);
                        return err;
                }