Commit 9ebcb397 authored by David S. Miller's avatar David S. Miller

Merge branch 'sock-cookie-initializers'

Willem de Bruijn says:

====================
sock cookie initializers

Recent UDP GSO and SO_TXTIME features added new fields to cookie
structs.

When adding a field, all sites where a struct is initialized have to
be updated, which is a lot of boilerplate. Alternatively, a field can
be initialized selectively, but this is fragile. I introduced a bug
in udp gso where an uninitialized field was read. See also fix commit
("9887cba1 ip: limit use of gso_size to udp").

Introduce initializers for structs ipcm(6)_cookie and sockc_cookie.

patch 1..3 do exactly this.
patch 4..5 make ipv4 and ipv6 handle cookies the same way and
           remove some boilerplate in doing so.
patch 6    removes the udp gso branch that needed the above fix
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ab8565af fbf47813
...@@ -72,13 +72,27 @@ struct ipcm_cookie { ...@@ -72,13 +72,27 @@ struct ipcm_cookie {
__be32 addr; __be32 addr;
int oif; int oif;
struct ip_options_rcu *opt; struct ip_options_rcu *opt;
__u8 tx_flags;
__u8 ttl; __u8 ttl;
__s16 tos; __s16 tos;
char priority; char priority;
__u16 gso_size; __u16 gso_size;
}; };
static inline void ipcm_init(struct ipcm_cookie *ipcm)
{
*ipcm = (struct ipcm_cookie) { .tos = -1 };
}
static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
const struct inet_sock *inet)
{
ipcm_init(ipcm);
ipcm->sockc.tsflags = inet->sk.sk_tsflags;
ipcm->oif = inet->sk.sk_bound_dev_if;
ipcm->addr = inet->inet_saddr;
}
#define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
#define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb)) #define PKTINFO_SKB_CB(skb) ((struct in_pktinfo *)((skb)->cb))
......
...@@ -294,6 +294,7 @@ struct ipv6_fl_socklist { ...@@ -294,6 +294,7 @@ struct ipv6_fl_socklist {
}; };
struct ipcm6_cookie { struct ipcm6_cookie {
struct sockcm_cookie sockc;
__s16 hlimit; __s16 hlimit;
__s16 tclass; __s16 tclass;
__s8 dontfrag; __s8 dontfrag;
...@@ -301,6 +302,25 @@ struct ipcm6_cookie { ...@@ -301,6 +302,25 @@ struct ipcm6_cookie {
__u16 gso_size; __u16 gso_size;
}; };
static inline void ipcm6_init(struct ipcm6_cookie *ipc6)
{
*ipc6 = (struct ipcm6_cookie) {
.hlimit = -1,
.tclass = -1,
.dontfrag = -1,
};
}
static inline void ipcm6_init_sk(struct ipcm6_cookie *ipc6,
const struct ipv6_pinfo *np)
{
*ipc6 = (struct ipcm6_cookie) {
.hlimit = -1,
.tclass = np->tclass,
.dontfrag = np->dontfrag,
};
}
static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np) static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
{ {
struct ipv6_txoptions *opt; struct ipv6_txoptions *opt;
...@@ -940,8 +960,7 @@ int ip6_append_data(struct sock *sk, ...@@ -940,8 +960,7 @@ int ip6_append_data(struct sock *sk,
int odd, struct sk_buff *skb), int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen, void *from, int length, int transhdrlen,
struct ipcm6_cookie *ipc6, struct flowi6 *fl6, struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
struct rt6_info *rt, unsigned int flags, struct rt6_info *rt, unsigned int flags);
const struct sockcm_cookie *sockc);
int ip6_push_pending_frames(struct sock *sk); int ip6_push_pending_frames(struct sock *sk);
...@@ -958,8 +977,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, ...@@ -958,8 +977,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
void *from, int length, int transhdrlen, void *from, int length, int transhdrlen,
struct ipcm6_cookie *ipc6, struct flowi6 *fl6, struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
struct rt6_info *rt, unsigned int flags, struct rt6_info *rt, unsigned int flags,
struct inet_cork_full *cork, struct inet_cork_full *cork);
const struct sockcm_cookie *sockc);
static inline struct sk_buff *ip6_finish_skb(struct sock *sk) static inline struct sk_buff *ip6_finish_skb(struct sock *sk)
{ {
......
...@@ -1600,6 +1600,12 @@ struct sockcm_cookie { ...@@ -1600,6 +1600,12 @@ struct sockcm_cookie {
u16 tsflags; u16 tsflags;
}; };
static inline void sockcm_init(struct sockcm_cookie *sockc,
const struct sock *sk)
{
*sockc = (struct sockcm_cookie) { .tsflags = sk->sk_tsflags };
}
int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg, int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg,
struct sockcm_cookie *sockc); struct sockcm_cookie *sockc);
int sock_cmsg_send(struct sock *sk, struct msghdr *msg, int sock_cmsg_send(struct sock *sk, struct msghdr *msg,
......
...@@ -42,8 +42,7 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg, ...@@ -42,8 +42,7 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
struct sk_buff *skb); struct sk_buff *skb);
int ip6_datagram_send_ctl(struct net *net, struct sock *sk, struct msghdr *msg, int ip6_datagram_send_ctl(struct net *net, struct sock *sk, struct msghdr *msg,
struct flowi6 *fl6, struct ipcm6_cookie *ipc6, struct flowi6 *fl6, struct ipcm6_cookie *ipc6);
struct sockcm_cookie *sockc);
void __ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp, void __ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
__u16 srcp, __u16 destp, int rqueue, int bucket); __u16 srcp, __u16 destp, int rqueue, int bucket);
......
...@@ -429,15 +429,11 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) ...@@ -429,15 +429,11 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
icmp_param->data.icmph.checksum = 0; icmp_param->data.icmph.checksum = 0;
ipcm_init(&ipc);
inet->tos = ip_hdr(skb)->tos; inet->tos = ip_hdr(skb)->tos;
sk->sk_mark = mark; sk->sk_mark = mark;
daddr = ipc.addr = ip_hdr(skb)->saddr; daddr = ipc.addr = ip_hdr(skb)->saddr;
saddr = fib_compute_spec_dst(skb); saddr = fib_compute_spec_dst(skb);
ipc.opt = NULL;
ipc.tx_flags = 0;
ipc.ttl = 0;
ipc.tos = -1;
ipc.sockc.transmit_time = 0;
if (icmp_param->replyopts.opt.opt.optlen) { if (icmp_param->replyopts.opt.opt.optlen) {
ipc.opt = &icmp_param->replyopts.opt; ipc.opt = &icmp_param->replyopts.opt;
...@@ -711,12 +707,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) ...@@ -711,12 +707,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
icmp_param.offset = skb_network_offset(skb_in); icmp_param.offset = skb_network_offset(skb_in);
inet_sk(sk)->tos = tos; inet_sk(sk)->tos = tos;
sk->sk_mark = mark; sk->sk_mark = mark;
ipcm_init(&ipc);
ipc.addr = iph->saddr; ipc.addr = iph->saddr;
ipc.opt = &icmp_param.replyopts.opt; ipc.opt = &icmp_param.replyopts.opt;
ipc.tx_flags = 0;
ipc.ttl = 0;
ipc.tos = -1;
ipc.sockc.transmit_time = 0;
rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos, mark, rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos, mark,
type, code, &icmp_param); type, code, &icmp_param);
......
...@@ -1146,15 +1146,15 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork, ...@@ -1146,15 +1146,15 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
cork->fragsize = ip_sk_use_pmtu(sk) ? cork->fragsize = ip_sk_use_pmtu(sk) ?
dst_mtu(&rt->dst) : rt->dst.dev->mtu; dst_mtu(&rt->dst) : rt->dst.dev->mtu;
cork->gso_size = sk->sk_type == SOCK_DGRAM && cork->gso_size = ipc->gso_size;
sk->sk_protocol == IPPROTO_UDP ? ipc->gso_size : 0;
cork->dst = &rt->dst; cork->dst = &rt->dst;
cork->length = 0; cork->length = 0;
cork->ttl = ipc->ttl; cork->ttl = ipc->ttl;
cork->tos = ipc->tos; cork->tos = ipc->tos;
cork->priority = ipc->priority; cork->priority = ipc->priority;
cork->tx_flags = ipc->tx_flags;
cork->transmit_time = ipc->sockc.transmit_time; cork->transmit_time = ipc->sockc.transmit_time;
cork->tx_flags = 0;
sock_tx_timestamp(sk, ipc->sockc.tsflags, &cork->tx_flags);
return 0; return 0;
} }
...@@ -1548,12 +1548,8 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, ...@@ -1548,12 +1548,8 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
if (__ip_options_echo(net, &replyopts.opt.opt, skb, sopt)) if (__ip_options_echo(net, &replyopts.opt.opt, skb, sopt))
return; return;
ipcm_init(&ipc);
ipc.addr = daddr; ipc.addr = daddr;
ipc.opt = NULL;
ipc.tx_flags = 0;
ipc.ttl = 0;
ipc.tos = -1;
ipc.sockc.transmit_time = 0;
if (replyopts.opt.opt.optlen) { if (replyopts.opt.opt.optlen) {
ipc.opt = &replyopts.opt; ipc.opt = &replyopts.opt;
......
...@@ -739,14 +739,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -739,14 +739,7 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
/* no remote port */ /* no remote port */
} }
ipc.sockc.tsflags = sk->sk_tsflags; ipcm_init_sk(&ipc, inet);
ipc.addr = inet->inet_saddr;
ipc.opt = NULL;
ipc.oif = sk->sk_bound_dev_if;
ipc.tx_flags = 0;
ipc.ttl = 0;
ipc.tos = -1;
ipc.sockc.transmit_time = 0;
if (msg->msg_controllen) { if (msg->msg_controllen) {
err = ip_cmsg_send(sk, msg, &ipc, false); err = ip_cmsg_send(sk, msg, &ipc, false);
...@@ -770,8 +763,6 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -770,8 +763,6 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
rcu_read_unlock(); rcu_read_unlock();
} }
sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags);
saddr = ipc.addr; saddr = ipc.addr;
ipc.addr = faddr = daddr; ipc.addr = faddr = daddr;
......
...@@ -562,14 +562,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -562,14 +562,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
daddr = inet->inet_daddr; daddr = inet->inet_daddr;
} }
ipc.sockc.tsflags = sk->sk_tsflags; ipcm_init_sk(&ipc, inet);
ipc.sockc.transmit_time = 0;
ipc.addr = inet->inet_saddr;
ipc.opt = NULL;
ipc.tx_flags = 0;
ipc.ttl = 0;
ipc.tos = -1;
ipc.oif = sk->sk_bound_dev_if;
if (msg->msg_controllen) { if (msg->msg_controllen) {
err = ip_cmsg_send(sk, msg, &ipc, false); err = ip_cmsg_send(sk, msg, &ipc, false);
...@@ -672,8 +665,6 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -672,8 +665,6 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
&rt, msg->msg_flags, &ipc.sockc); &rt, msg->msg_flags, &ipc.sockc);
else { else {
sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags);
if (!ipc.addr) if (!ipc.addr)
ipc.addr = fl4.daddr; ipc.addr = fl4.daddr;
lock_sock(sk); lock_sock(sk);
......
...@@ -1241,7 +1241,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) ...@@ -1241,7 +1241,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
/* 'common' sending to sendq */ /* 'common' sending to sendq */
} }
sockc.tsflags = sk->sk_tsflags; sockcm_init(&sockc, sk);
if (msg->msg_controllen) { if (msg->msg_controllen) {
err = sock_cmsg_send(sk, msg, &sockc); err = sock_cmsg_send(sk, msg, &sockc);
if (unlikely(err)) { if (unlikely(err)) {
......
...@@ -926,12 +926,6 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -926,12 +926,6 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */ if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */
return -EOPNOTSUPP; return -EOPNOTSUPP;
ipc.opt = NULL;
ipc.tx_flags = 0;
ipc.ttl = 0;
ipc.tos = -1;
ipc.sockc.transmit_time = 0;
getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
fl4 = &inet->cork.fl.u.ip4; fl4 = &inet->cork.fl.u.ip4;
...@@ -978,9 +972,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -978,9 +972,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
connected = 1; connected = 1;
} }
ipc.sockc.tsflags = sk->sk_tsflags; ipcm_init_sk(&ipc, inet);
ipc.addr = inet->inet_saddr;
ipc.oif = sk->sk_bound_dev_if;
ipc.gso_size = up->gso_size; ipc.gso_size = up->gso_size;
if (msg->msg_controllen) { if (msg->msg_controllen) {
...@@ -1028,8 +1020,6 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1028,8 +1020,6 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
saddr = ipc.addr; saddr = ipc.addr;
ipc.addr = faddr = daddr; ipc.addr = faddr = daddr;
sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags);
if (ipc.opt && ipc.opt->opt.srr) { if (ipc.opt && ipc.opt->opt.srr) {
if (!daddr) { if (!daddr) {
err = -EINVAL; err = -EINVAL;
......
...@@ -736,7 +736,7 @@ EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl); ...@@ -736,7 +736,7 @@ EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl);
int ip6_datagram_send_ctl(struct net *net, struct sock *sk, int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
struct msghdr *msg, struct flowi6 *fl6, struct msghdr *msg, struct flowi6 *fl6,
struct ipcm6_cookie *ipc6, struct sockcm_cookie *sockc) struct ipcm6_cookie *ipc6)
{ {
struct in6_pktinfo *src_info; struct in6_pktinfo *src_info;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
...@@ -755,7 +755,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk, ...@@ -755,7 +755,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
} }
if (cmsg->cmsg_level == SOL_SOCKET) { if (cmsg->cmsg_level == SOL_SOCKET) {
err = __sock_cmsg_send(sk, msg, cmsg, sockc); err = __sock_cmsg_send(sk, msg, cmsg, &ipc6->sockc);
if (err) if (err)
return err; return err;
continue; continue;
......
...@@ -430,7 +430,6 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, ...@@ -430,7 +430,6 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
struct icmp6hdr tmp_hdr; struct icmp6hdr tmp_hdr;
struct flowi6 fl6; struct flowi6 fl6;
struct icmpv6_msg msg; struct icmpv6_msg msg;
struct sockcm_cookie sockc_unused = {0};
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
int iif = 0; int iif = 0;
int addr_type = 0; int addr_type = 0;
...@@ -545,7 +544,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, ...@@ -545,7 +544,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
else if (!fl6.flowi6_oif) else if (!fl6.flowi6_oif)
fl6.flowi6_oif = np->ucast_oif; fl6.flowi6_oif = np->ucast_oif;
ipc6.tclass = np->tclass; ipcm6_init_sk(&ipc6, np);
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
dst = icmpv6_route_lookup(net, skb, sk, &fl6); dst = icmpv6_route_lookup(net, skb, sk, &fl6);
...@@ -553,8 +552,6 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, ...@@ -553,8 +552,6 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
goto out; goto out;
ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
ipc6.dontfrag = np->dontfrag;
ipc6.opt = NULL;
msg.skb = skb; msg.skb = skb;
msg.offset = skb_network_offset(skb); msg.offset = skb_network_offset(skb);
...@@ -575,7 +572,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, ...@@ -575,7 +572,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
len + sizeof(struct icmp6hdr), len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr), sizeof(struct icmp6hdr),
&ipc6, &fl6, (struct rt6_info *)dst, &ipc6, &fl6, (struct rt6_info *)dst,
MSG_DONTWAIT, &sockc_unused)) { MSG_DONTWAIT)) {
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS); ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
ip6_flush_pending_frames(sk); ip6_flush_pending_frames(sk);
} else { } else {
...@@ -679,7 +676,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -679,7 +676,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
struct dst_entry *dst; struct dst_entry *dst;
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
u32 mark = IP6_REPLY_MARK(net, skb->mark); u32 mark = IP6_REPLY_MARK(net, skb->mark);
struct sockcm_cookie sockc_unused = {0};
saddr = &ipv6_hdr(skb)->daddr; saddr = &ipv6_hdr(skb)->daddr;
...@@ -726,16 +722,14 @@ static void icmpv6_echo_reply(struct sk_buff *skb) ...@@ -726,16 +722,14 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
msg.offset = 0; msg.offset = 0;
msg.type = ICMPV6_ECHO_REPLY; msg.type = ICMPV6_ECHO_REPLY;
ipcm6_init_sk(&ipc6, np);
ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
ipc6.tclass = ipv6_get_dsfield(ipv6_hdr(skb)); ipc6.tclass = ipv6_get_dsfield(ipv6_hdr(skb));
ipc6.dontfrag = np->dontfrag;
ipc6.opt = NULL;
if (ip6_append_data(sk, icmpv6_getfrag, &msg, if (ip6_append_data(sk, icmpv6_getfrag, &msg,
skb->len + sizeof(struct icmp6hdr), skb->len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr), &ipc6, &fl6, sizeof(struct icmp6hdr), &ipc6, &fl6,
(struct rt6_info *)dst, MSG_DONTWAIT, (struct rt6_info *)dst, MSG_DONTWAIT)) {
&sockc_unused)) {
__ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS); __ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTERRORS);
ip6_flush_pending_frames(sk); ip6_flush_pending_frames(sk);
} else { } else {
......
...@@ -373,7 +373,6 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, ...@@ -373,7 +373,6 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
if (olen > 0) { if (olen > 0) {
struct msghdr msg; struct msghdr msg;
struct flowi6 flowi6; struct flowi6 flowi6;
struct sockcm_cookie sockc_junk;
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
err = -ENOMEM; err = -ENOMEM;
...@@ -392,7 +391,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, ...@@ -392,7 +391,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
memset(&flowi6, 0, sizeof(flowi6)); memset(&flowi6, 0, sizeof(flowi6));
ipc6.opt = fl->opt; ipc6.opt = fl->opt;
err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, &ipc6, &sockc_junk); err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, &ipc6);
if (err) if (err)
goto done; goto done;
err = -EINVAL; err = -EINVAL;
......
...@@ -1158,8 +1158,7 @@ static void ip6_append_data_mtu(unsigned int *mtu, ...@@ -1158,8 +1158,7 @@ static void ip6_append_data_mtu(unsigned int *mtu,
static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6, struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6,
struct rt6_info *rt, struct flowi6 *fl6, struct rt6_info *rt, struct flowi6 *fl6)
const struct sockcm_cookie *sockc)
{ {
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
unsigned int mtu; unsigned int mtu;
...@@ -1220,14 +1219,15 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, ...@@ -1220,14 +1219,15 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
if (mtu < IPV6_MIN_MTU) if (mtu < IPV6_MIN_MTU)
return -EINVAL; return -EINVAL;
cork->base.fragsize = mtu; cork->base.fragsize = mtu;
cork->base.gso_size = sk->sk_type == SOCK_DGRAM && cork->base.gso_size = ipc6->gso_size;
sk->sk_protocol == IPPROTO_UDP ? ipc6->gso_size : 0; cork->base.tx_flags = 0;
sock_tx_timestamp(sk, ipc6->sockc.tsflags, &cork->base.tx_flags);
if (dst_allfrag(xfrm_dst_path(&rt->dst))) if (dst_allfrag(xfrm_dst_path(&rt->dst)))
cork->base.flags |= IPCORK_ALLFRAG; cork->base.flags |= IPCORK_ALLFRAG;
cork->base.length = 0; cork->base.length = 0;
cork->base.transmit_time = sockc->transmit_time; cork->base.transmit_time = ipc6->sockc.transmit_time;
return 0; return 0;
} }
...@@ -1241,8 +1241,7 @@ static int __ip6_append_data(struct sock *sk, ...@@ -1241,8 +1241,7 @@ static int __ip6_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int getfrag(void *from, char *to, int offset,
int len, int odd, struct sk_buff *skb), int len, int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen, void *from, int length, int transhdrlen,
unsigned int flags, struct ipcm6_cookie *ipc6, unsigned int flags, struct ipcm6_cookie *ipc6)
const struct sockcm_cookie *sockc)
{ {
struct sk_buff *skb, *skb_prev = NULL; struct sk_buff *skb, *skb_prev = NULL;
unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu; unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
...@@ -1252,7 +1251,6 @@ static int __ip6_append_data(struct sock *sk, ...@@ -1252,7 +1251,6 @@ static int __ip6_append_data(struct sock *sk,
int copy; int copy;
int err; int err;
int offset = 0; int offset = 0;
__u8 tx_flags = 0;
u32 tskey = 0; u32 tskey = 0;
struct rt6_info *rt = (struct rt6_info *)cork->dst; struct rt6_info *rt = (struct rt6_info *)cork->dst;
struct ipv6_txoptions *opt = v6_cork->opt; struct ipv6_txoptions *opt = v6_cork->opt;
...@@ -1271,6 +1269,10 @@ static int __ip6_append_data(struct sock *sk, ...@@ -1271,6 +1269,10 @@ static int __ip6_append_data(struct sock *sk,
mtu = cork->gso_size ? IP6_MAX_MTU : cork->fragsize; mtu = cork->gso_size ? IP6_MAX_MTU : cork->fragsize;
orig_mtu = mtu; orig_mtu = mtu;
if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
tskey = sk->sk_tskey++;
hh_len = LL_RESERVED_SPACE(rt->dst.dev); hh_len = LL_RESERVED_SPACE(rt->dst.dev);
fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
...@@ -1320,13 +1322,6 @@ static int __ip6_append_data(struct sock *sk, ...@@ -1320,13 +1322,6 @@ static int __ip6_append_data(struct sock *sk,
rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
csummode = CHECKSUM_PARTIAL; csummode = CHECKSUM_PARTIAL;
if (sk->sk_type == SOCK_DGRAM || sk->sk_type == SOCK_RAW) {
sock_tx_timestamp(sk, sockc->tsflags, &tx_flags);
if (tx_flags & SKBTX_ANY_SW_TSTAMP &&
sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
tskey = sk->sk_tskey++;
}
/* /*
* Let's try using as much space as possible. * Let's try using as much space as possible.
* Use MTU if total length of the message fits into the MTU. * Use MTU if total length of the message fits into the MTU.
...@@ -1445,8 +1440,8 @@ static int __ip6_append_data(struct sock *sk, ...@@ -1445,8 +1440,8 @@ static int __ip6_append_data(struct sock *sk,
dst_exthdrlen); dst_exthdrlen);
/* Only the initial fragment is time stamped */ /* Only the initial fragment is time stamped */
skb_shinfo(skb)->tx_flags = tx_flags; skb_shinfo(skb)->tx_flags = cork->tx_flags;
tx_flags = 0; cork->tx_flags = 0;
skb_shinfo(skb)->tskey = tskey; skb_shinfo(skb)->tskey = tskey;
tskey = 0; tskey = 0;
...@@ -1563,8 +1558,7 @@ int ip6_append_data(struct sock *sk, ...@@ -1563,8 +1558,7 @@ int ip6_append_data(struct sock *sk,
int odd, struct sk_buff *skb), int odd, struct sk_buff *skb),
void *from, int length, int transhdrlen, void *from, int length, int transhdrlen,
struct ipcm6_cookie *ipc6, struct flowi6 *fl6, struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
struct rt6_info *rt, unsigned int flags, struct rt6_info *rt, unsigned int flags)
const struct sockcm_cookie *sockc)
{ {
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
...@@ -1578,7 +1572,7 @@ int ip6_append_data(struct sock *sk, ...@@ -1578,7 +1572,7 @@ int ip6_append_data(struct sock *sk,
* setup for corking * setup for corking
*/ */
err = ip6_setup_cork(sk, &inet->cork, &np->cork, err = ip6_setup_cork(sk, &inet->cork, &np->cork,
ipc6, rt, fl6, sockc); ipc6, rt, fl6);
if (err) if (err)
return err; return err;
...@@ -1592,7 +1586,7 @@ int ip6_append_data(struct sock *sk, ...@@ -1592,7 +1586,7 @@ int ip6_append_data(struct sock *sk,
return __ip6_append_data(sk, fl6, &sk->sk_write_queue, &inet->cork.base, return __ip6_append_data(sk, fl6, &sk->sk_write_queue, &inet->cork.base,
&np->cork, sk_page_frag(sk), getfrag, &np->cork, sk_page_frag(sk), getfrag,
from, length, transhdrlen, flags, ipc6, sockc); from, length, transhdrlen, flags, ipc6);
} }
EXPORT_SYMBOL_GPL(ip6_append_data); EXPORT_SYMBOL_GPL(ip6_append_data);
...@@ -1752,8 +1746,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, ...@@ -1752,8 +1746,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
void *from, int length, int transhdrlen, void *from, int length, int transhdrlen,
struct ipcm6_cookie *ipc6, struct flowi6 *fl6, struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
struct rt6_info *rt, unsigned int flags, struct rt6_info *rt, unsigned int flags,
struct inet_cork_full *cork, struct inet_cork_full *cork)
const struct sockcm_cookie *sockc)
{ {
struct inet6_cork v6_cork; struct inet6_cork v6_cork;
struct sk_buff_head queue; struct sk_buff_head queue;
...@@ -1770,7 +1763,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, ...@@ -1770,7 +1763,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
cork->base.opt = NULL; cork->base.opt = NULL;
cork->base.dst = NULL; cork->base.dst = NULL;
v6_cork.opt = NULL; v6_cork.opt = NULL;
err = ip6_setup_cork(sk, cork, &v6_cork, ipc6, rt, fl6, sockc); err = ip6_setup_cork(sk, cork, &v6_cork, ipc6, rt, fl6);
if (err) { if (err) {
ip6_cork_release(cork, &v6_cork); ip6_cork_release(cork, &v6_cork);
return ERR_PTR(err); return ERR_PTR(err);
...@@ -1781,7 +1774,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, ...@@ -1781,7 +1774,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
err = __ip6_append_data(sk, fl6, &queue, &cork->base, &v6_cork, err = __ip6_append_data(sk, fl6, &queue, &cork->base, &v6_cork,
&current->task_frag, getfrag, from, &current->task_frag, getfrag, from,
length + exthdrlen, transhdrlen + exthdrlen, length + exthdrlen, transhdrlen + exthdrlen,
flags, ipc6, sockc); flags, ipc6);
if (err) { if (err) {
__ip6_flush_pending_frames(sk, &queue, cork, &v6_cork); __ip6_flush_pending_frames(sk, &queue, cork, &v6_cork);
return ERR_PTR(err); return ERR_PTR(err);
......
...@@ -489,7 +489,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, ...@@ -489,7 +489,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
struct ipv6_txoptions *opt = NULL; struct ipv6_txoptions *opt = NULL;
struct msghdr msg; struct msghdr msg;
struct flowi6 fl6; struct flowi6 fl6;
struct sockcm_cookie sockc_junk;
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
memset(&fl6, 0, sizeof(fl6)); memset(&fl6, 0, sizeof(fl6));
...@@ -522,7 +521,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, ...@@ -522,7 +521,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
msg.msg_control = (void *)(opt+1); msg.msg_control = (void *)(opt+1);
ipc6.opt = opt; ipc6.opt = opt;
retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, &ipc6, &sockc_junk); retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, &ipc6);
if (retv) if (retv)
goto done; goto done;
update: update:
......
...@@ -62,7 +62,6 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -62,7 +62,6 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
struct dst_entry *dst; struct dst_entry *dst;
struct rt6_info *rt; struct rt6_info *rt;
struct pingfakehdr pfh; struct pingfakehdr pfh;
struct sockcm_cookie junk = {0};
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num); pr_debug("ping_v6_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
...@@ -119,7 +118,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -119,7 +118,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
fl6.fl6_icmp_code = user_icmph.icmp6_code; fl6.fl6_icmp_code = user_icmph.icmp6_code;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
ipc6.tclass = np->tclass; ipcm6_init_sk(&ipc6, np);
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel); fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, false); dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, false);
...@@ -142,13 +141,11 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -142,13 +141,11 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
pfh.family = AF_INET6; pfh.family = AF_INET6;
ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst); ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
ipc6.dontfrag = np->dontfrag;
ipc6.opt = NULL;
lock_sock(sk); lock_sock(sk);
err = ip6_append_data(sk, ping_getfrag, &pfh, len, err = ip6_append_data(sk, ping_getfrag, &pfh, len,
0, &ipc6, &fl6, rt, 0, &ipc6, &fl6, rt,
MSG_DONTWAIT, &junk); MSG_DONTWAIT);
if (err) { if (err) {
ICMP6_INC_STATS(sock_net(sk), rt->rt6i_idev, ICMP6_INC_STATS(sock_net(sk), rt->rt6i_idev,
......
...@@ -767,7 +767,6 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -767,7 +767,6 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
struct dst_entry *dst = NULL; struct dst_entry *dst = NULL;
struct raw6_frag_vec rfv; struct raw6_frag_vec rfv;
struct flowi6 fl6; struct flowi6 fl6;
struct sockcm_cookie sockc;
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
int addr_len = msg->msg_namelen; int addr_len = msg->msg_namelen;
u16 proto; u16 proto;
...@@ -791,10 +790,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -791,10 +790,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
fl6.flowi6_mark = sk->sk_mark; fl6.flowi6_mark = sk->sk_mark;
fl6.flowi6_uid = sk->sk_uid; fl6.flowi6_uid = sk->sk_uid;
ipc6.hlimit = -1; ipcm6_init(&ipc6);
ipc6.tclass = -1; ipc6.sockc.tsflags = sk->sk_tsflags;
ipc6.dontfrag = -1;
ipc6.opt = NULL;
if (sin6) { if (sin6) {
if (addr_len < SIN6_LEN_RFC2133) if (addr_len < SIN6_LEN_RFC2133)
...@@ -848,15 +845,13 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -848,15 +845,13 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (fl6.flowi6_oif == 0) if (fl6.flowi6_oif == 0)
fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_oif = sk->sk_bound_dev_if;
sockc.tsflags = sk->sk_tsflags;
sockc.transmit_time = 0;
if (msg->msg_controllen) { if (msg->msg_controllen) {
opt = &opt_space; opt = &opt_space;
memset(opt, 0, sizeof(struct ipv6_txoptions)); memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(struct ipv6_txoptions); opt->tot_len = sizeof(struct ipv6_txoptions);
ipc6.opt = opt; ipc6.opt = opt;
err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, &sockc); err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6);
if (err < 0) { if (err < 0) {
fl6_sock_release(flowlabel); fl6_sock_release(flowlabel);
return err; return err;
...@@ -924,13 +919,13 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -924,13 +919,13 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
back_from_confirm: back_from_confirm:
if (inet->hdrincl) if (inet->hdrincl)
err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst, err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst,
msg->msg_flags, &sockc); msg->msg_flags, &ipc6.sockc);
else { else {
ipc6.opt = opt; ipc6.opt = opt;
lock_sock(sk); lock_sock(sk);
err = ip6_append_data(sk, raw6_getfrag, &rfv, err = ip6_append_data(sk, raw6_getfrag, &rfv,
len, 0, &ipc6, &fl6, (struct rt6_info *)dst, len, 0, &ipc6, &fl6, (struct rt6_info *)dst,
msg->msg_flags, &sockc); msg->msg_flags);
if (err) if (err)
ip6_flush_pending_frames(sk); ip6_flush_pending_frames(sk);
......
...@@ -1141,14 +1141,10 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1141,14 +1141,10 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
int err; int err;
int is_udplite = IS_UDPLITE(sk); int is_udplite = IS_UDPLITE(sk);
int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
struct sockcm_cookie sockc;
ipc6.hlimit = -1; ipcm6_init(&ipc6);
ipc6.tclass = -1;
ipc6.dontfrag = -1;
ipc6.gso_size = up->gso_size; ipc6.gso_size = up->gso_size;
sockc.tsflags = sk->sk_tsflags; ipc6.sockc.tsflags = sk->sk_tsflags;
sockc.transmit_time = 0;
/* destination address check */ /* destination address check */
if (sin6) { if (sin6) {
...@@ -1283,7 +1279,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1283,7 +1279,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
err = udp_cmsg_send(sk, msg, &ipc6.gso_size); err = udp_cmsg_send(sk, msg, &ipc6.gso_size);
if (err > 0) if (err > 0)
err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6,
&ipc6, &sockc); &ipc6);
if (err < 0) { if (err < 0) {
fl6_sock_release(flowlabel); fl6_sock_release(flowlabel);
return err; return err;
...@@ -1377,7 +1373,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1377,7 +1373,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
skb = ip6_make_skb(sk, getfrag, msg, ulen, skb = ip6_make_skb(sk, getfrag, msg, ulen,
sizeof(struct udphdr), &ipc6, sizeof(struct udphdr), &ipc6,
&fl6, (struct rt6_info *)dst, &fl6, (struct rt6_info *)dst,
msg->msg_flags, &cork, &sockc); msg->msg_flags, &cork);
err = PTR_ERR(skb); err = PTR_ERR(skb);
if (!IS_ERR_OR_NULL(skb)) if (!IS_ERR_OR_NULL(skb))
err = udp_v6_send_skb(skb, &fl6, &cork.base); err = udp_v6_send_skb(skb, &fl6, &cork.base);
...@@ -1403,7 +1399,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1403,7 +1399,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
up->len += ulen; up->len += ulen;
err = ip6_append_data(sk, getfrag, msg, ulen, sizeof(struct udphdr), err = ip6_append_data(sk, getfrag, msg, ulen, sizeof(struct udphdr),
&ipc6, &fl6, (struct rt6_info *)dst, &ipc6, &fl6, (struct rt6_info *)dst,
corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, &sockc); corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
if (err) if (err)
udp_v6_flush_pending_frames(sk); udp_v6_flush_pending_frames(sk);
else if (!corkreq) else if (!corkreq)
......
...@@ -500,7 +500,6 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -500,7 +500,6 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
struct ip6_flowlabel *flowlabel = NULL; struct ip6_flowlabel *flowlabel = NULL;
struct dst_entry *dst = NULL; struct dst_entry *dst = NULL;
struct flowi6 fl6; struct flowi6 fl6;
struct sockcm_cookie sockc_unused = {0};
struct ipcm6_cookie ipc6; struct ipcm6_cookie ipc6;
int addr_len = msg->msg_namelen; int addr_len = msg->msg_namelen;
int transhdrlen = 4; /* zero session-id */ int transhdrlen = 4; /* zero session-id */
...@@ -525,9 +524,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -525,9 +524,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
fl6.flowi6_mark = sk->sk_mark; fl6.flowi6_mark = sk->sk_mark;
fl6.flowi6_uid = sk->sk_uid; fl6.flowi6_uid = sk->sk_uid;
ipc6.hlimit = -1; ipcm6_init(&ipc6);
ipc6.tclass = -1;
ipc6.dontfrag = -1;
if (lsa) { if (lsa) {
if (addr_len < SIN6_LEN_RFC2133) if (addr_len < SIN6_LEN_RFC2133)
...@@ -575,8 +572,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -575,8 +572,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
opt->tot_len = sizeof(struct ipv6_txoptions); opt->tot_len = sizeof(struct ipv6_txoptions);
ipc6.opt = opt; ipc6.opt = opt;
err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6, err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, &ipc6);
&sockc_unused);
if (err < 0) { if (err < 0) {
fl6_sock_release(flowlabel); fl6_sock_release(flowlabel);
return err; return err;
...@@ -641,7 +637,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -641,7 +637,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
err = ip6_append_data(sk, ip_generic_getfrag, msg, err = ip6_append_data(sk, ip_generic_getfrag, msg,
ulen, transhdrlen, &ipc6, ulen, transhdrlen, &ipc6,
&fl6, (struct rt6_info *)dst, &fl6, (struct rt6_info *)dst,
msg->msg_flags, &sockc_unused); msg->msg_flags);
if (err) if (err)
ip6_flush_pending_frames(sk); ip6_flush_pending_frames(sk);
else if (!(msg->msg_flags & MSG_MORE)) else if (!(msg->msg_flags & MSG_MORE))
......
...@@ -1951,8 +1951,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg, ...@@ -1951,8 +1951,7 @@ static int packet_sendmsg_spkt(struct socket *sock, struct msghdr *msg,
goto out_unlock; goto out_unlock;
} }
sockc.transmit_time = 0; sockcm_init(&sockc, sk);
sockc.tsflags = sk->sk_tsflags;
if (msg->msg_controllen) { if (msg->msg_controllen) {
err = sock_cmsg_send(sk, msg, &sockc); err = sock_cmsg_send(sk, msg, &sockc);
if (unlikely(err)) if (unlikely(err))
...@@ -2636,8 +2635,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -2636,8 +2635,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
if (unlikely(!(dev->flags & IFF_UP))) if (unlikely(!(dev->flags & IFF_UP)))
goto out_put; goto out_put;
sockc.transmit_time = 0; sockcm_init(&sockc, &po->sk);
sockc.tsflags = po->sk.sk_tsflags;
if (msg->msg_controllen) { if (msg->msg_controllen) {
err = sock_cmsg_send(&po->sk, msg, &sockc); err = sock_cmsg_send(&po->sk, msg, &sockc);
if (unlikely(err)) if (unlikely(err))
...@@ -2833,8 +2831,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) ...@@ -2833,8 +2831,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
if (unlikely(!(dev->flags & IFF_UP))) if (unlikely(!(dev->flags & IFF_UP)))
goto out_unlock; goto out_unlock;
sockc.transmit_time = 0; sockcm_init(&sockc, sk);
sockc.tsflags = sk->sk_tsflags;
sockc.mark = sk->sk_mark; sockc.mark = sk->sk_mark;
if (msg->msg_controllen) { if (msg->msg_controllen) {
err = sock_cmsg_send(sk, msg, &sockc); err = sock_cmsg_send(sk, msg, &sockc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment