Commit a818f75e authored by Jesus Sanchez-Palencia's avatar Jesus Sanchez-Palencia Committed by David S. Miller

net: ipv6: Hook into time based transmission

Add a struct sockcm_cookie parameter to ip6_setup_cork() so
we can easily re-use the transmit_time field from struct inet_cork
for most paths, by copying the timestamp from the CMSG cookie.
This is later copied into the skb during __ip6_make_skb().

For the raw fast path, also pass the sockcm_cookie as a parameter
so we can just perform the copy at rawv6_send_hdrinc() directly.
Signed-off-by: default avatarJesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bc969a97
...@@ -1158,7 +1158,8 @@ static void ip6_append_data_mtu(unsigned int *mtu, ...@@ -1158,7 +1158,8 @@ 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;
...@@ -1226,6 +1227,8 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, ...@@ -1226,6 +1227,8 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
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;
return 0; return 0;
} }
...@@ -1575,7 +1578,7 @@ int ip6_append_data(struct sock *sk, ...@@ -1575,7 +1578,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); ipc6, rt, fl6, sockc);
if (err) if (err)
return err; return err;
...@@ -1673,6 +1676,8 @@ struct sk_buff *__ip6_make_skb(struct sock *sk, ...@@ -1673,6 +1676,8 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
skb->priority = sk->sk_priority; skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark; skb->mark = sk->sk_mark;
skb->tstamp = cork->base.transmit_time;
skb_dst_set(skb, dst_clone(&rt->dst)); skb_dst_set(skb, dst_clone(&rt->dst));
IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
if (proto == IPPROTO_ICMPV6) { if (proto == IPPROTO_ICMPV6) {
...@@ -1765,7 +1770,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, ...@@ -1765,7 +1770,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); err = ip6_setup_cork(sk, cork, &v6_cork, ipc6, rt, fl6, sockc);
if (err) { if (err) {
ip6_cork_release(cork, &v6_cork); ip6_cork_release(cork, &v6_cork);
return ERR_PTR(err); return ERR_PTR(err);
......
...@@ -620,7 +620,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, ...@@ -620,7 +620,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length, static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
struct flowi6 *fl6, struct dst_entry **dstp, struct flowi6 *fl6, struct dst_entry **dstp,
unsigned int flags) unsigned int flags, const struct sockcm_cookie *sockc)
{ {
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
...@@ -650,6 +650,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length, ...@@ -650,6 +650,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
skb->protocol = htons(ETH_P_IPV6); skb->protocol = htons(ETH_P_IPV6);
skb->priority = sk->sk_priority; skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark; skb->mark = sk->sk_mark;
skb->tstamp = sockc->transmit_time;
skb_dst_set(skb, &rt->dst); skb_dst_set(skb, &rt->dst);
*dstp = NULL; *dstp = NULL;
...@@ -848,6 +849,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -848,6 +849,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_oif = sk->sk_bound_dev_if;
sockc.tsflags = sk->sk_tsflags; 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));
...@@ -921,7 +923,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -921,7 +923,8 @@ 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, msg->msg_flags); err = rawv6_send_hdrinc(sk, msg, len, &fl6, &dst,
msg->msg_flags, &sockc);
else { else {
ipc6.opt = opt; ipc6.opt = opt;
lock_sock(sk); lock_sock(sk);
......
...@@ -1148,6 +1148,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1148,6 +1148,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
ipc6.dontfrag = -1; ipc6.dontfrag = -1;
ipc6.gso_size = up->gso_size; ipc6.gso_size = up->gso_size;
sockc.tsflags = sk->sk_tsflags; sockc.tsflags = sk->sk_tsflags;
sockc.transmit_time = 0;
/* destination address check */ /* destination address check */
if (sin6) { if (sin6) {
......
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