OSDN Git Service

net: ipv6: Hook into time based transmission
authorJesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
Tue, 3 Jul 2018 22:42:50 +0000 (15:42 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 Jul 2018 13:30:27 +0000 (22:30 +0900)
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: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/ip6_output.c
net/ipv6/raw.c
net/ipv6/udp.c

index a14fb4f..f48af7e 100644 (file)
@@ -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,
                          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);
        unsigned int mtu;
@@ -1226,6 +1227,8 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
                cork->base.flags |= IPCORK_ALLFRAG;
        cork->base.length = 0;
 
+       cork->base.transmit_time = sockc->transmit_time;
+
        return 0;
 }
 
@@ -1575,7 +1578,7 @@ int ip6_append_data(struct sock *sk,
                 * setup for corking
                 */
                err = ip6_setup_cork(sk, &inet->cork, &np->cork,
-                                    ipc6, rt, fl6);
+                                    ipc6, rt, fl6, sockc);
                if (err)
                        return err;
 
@@ -1673,6 +1676,8 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
 
+       skb->tstamp = cork->base.transmit_time;
+
        skb_dst_set(skb, dst_clone(&rt->dst));
        IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
        if (proto == IPPROTO_ICMPV6) {
@@ -1765,7 +1770,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
        cork->base.opt = NULL;
        cork->base.dst = 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) {
                ip6_cork_release(cork, &v6_cork);
                return ERR_PTR(err);
index afc307c..5737c50 100644 (file)
@@ -620,7 +620,7 @@ out:
 
 static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
                        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 net *net = sock_net(sk);
@@ -650,6 +650,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
        skb->protocol = htons(ETH_P_IPV6);
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
+       skb->tstamp = sockc->transmit_time;
        skb_dst_set(skb, &rt->dst);
        *dstp = NULL;
 
@@ -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;
 
        sockc.tsflags = sk->sk_tsflags;
+       sockc.transmit_time = 0;
        if (msg->msg_controllen) {
                opt = &opt_space;
                memset(opt, 0, sizeof(struct ipv6_txoptions));
@@ -921,7 +923,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 
 back_from_confirm:
        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 {
                ipc6.opt = opt;
                lock_sock(sk);
index e6645ca..ac6fc67 100644 (file)
@@ -1148,6 +1148,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        ipc6.dontfrag = -1;
        ipc6.gso_size = up->gso_size;
        sockc.tsflags = sk->sk_tsflags;
+       sockc.transmit_time = 0;
 
        /* destination address check */
        if (sin6) {