OSDN Git Service

udp: expose inet cork to udp
authorWillem de Bruijn <willemb@google.com>
Thu, 26 Apr 2018 17:42:15 +0000 (13:42 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 26 Apr 2018 19:06:46 +0000 (15:06 -0400)
UDP segmentation offload needs access to inet_cork in the udp layer.
Pass the struct to ip(6)_make_skb instead of allocating it on the
stack in that function itself.

This patch is a noop otherwise.

Signed-off-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip.h
include/net/ipv6.h
net/ipv4/ip_output.c
net/ipv4/udp.c
net/ipv6/ip6_output.c
net/ipv6/udp.c

index dc4a2d6..7ec543a 100644 (file)
@@ -171,7 +171,7 @@ struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4,
                                        int len, int odd, struct sk_buff *skb),
                            void *from, int length, int transhdrlen,
                            struct ipcm_cookie *ipc, struct rtable **rtp,
-                           unsigned int flags);
+                           struct inet_cork *cork, unsigned int flags);
 
 static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
 {
index 68b167d..0dd722c 100644 (file)
@@ -950,6 +950,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
                             void *from, int length, int transhdrlen,
                             struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
                             struct rt6_info *rt, unsigned int flags,
+                            struct inet_cork_full *cork,
                             const struct sockcm_cookie *sockc);
 
 static inline struct sk_buff *ip6_finish_skb(struct sock *sk)
index 83c73ba..2883ff1 100644 (file)
@@ -1470,9 +1470,8 @@ struct sk_buff *ip_make_skb(struct sock *sk,
                                        int len, int odd, struct sk_buff *skb),
                            void *from, int length, int transhdrlen,
                            struct ipcm_cookie *ipc, struct rtable **rtp,
-                           unsigned int flags)
+                           struct inet_cork *cork, unsigned int flags)
 {
-       struct inet_cork cork;
        struct sk_buff_head queue;
        int err;
 
@@ -1481,22 +1480,22 @@ struct sk_buff *ip_make_skb(struct sock *sk,
 
        __skb_queue_head_init(&queue);
 
-       cork.flags = 0;
-       cork.addr = 0;
-       cork.opt = NULL;
-       err = ip_setup_cork(sk, &cork, ipc, rtp);
+       cork->flags = 0;
+       cork->addr = 0;
+       cork->opt = NULL;
+       err = ip_setup_cork(sk, cork, ipc, rtp);
        if (err)
                return ERR_PTR(err);
 
-       err = __ip_append_data(sk, fl4, &queue, &cork,
+       err = __ip_append_data(sk, fl4, &queue, cork,
                               &current->task_frag, getfrag,
                               from, length, transhdrlen, flags);
        if (err) {
-               __ip_flush_pending_frames(sk, &queue, &cork);
+               __ip_flush_pending_frames(sk, &queue, cork);
                return ERR_PTR(err);
        }
 
-       return __ip_make_skb(sk, fl4, &queue, &cork);
+       return __ip_make_skb(sk, fl4, &queue, cork);
 }
 
 /*
index 24b5c59..6b9d801 100644 (file)
@@ -1030,9 +1030,11 @@ back_from_confirm:
 
        /* Lockless fast path for the non-corking case. */
        if (!corkreq) {
+               struct inet_cork cork;
+
                skb = ip_make_skb(sk, fl4, getfrag, msg, ulen,
                                  sizeof(struct udphdr), &ipc, &rt,
-                                 msg->msg_flags);
+                                 &cork, msg->msg_flags);
                err = PTR_ERR(skb);
                if (!IS_ERR_OR_NULL(skb))
                        err = udp_send_skb(skb, fl4);
index 6a477d5..7fa1db4 100644 (file)
@@ -1755,9 +1755,9 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
                             void *from, int length, int transhdrlen,
                             struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
                             struct rt6_info *rt, unsigned int flags,
+                            struct inet_cork_full *cork,
                             const struct sockcm_cookie *sockc)
 {
-       struct inet_cork_full cork;
        struct inet6_cork v6_cork;
        struct sk_buff_head queue;
        int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
@@ -1768,27 +1768,27 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
 
        __skb_queue_head_init(&queue);
 
-       cork.base.flags = 0;
-       cork.base.addr = 0;
-       cork.base.opt = NULL;
-       cork.base.dst = NULL;
+       cork->base.flags = 0;
+       cork->base.addr = 0;
+       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);
        if (err) {
-               ip6_cork_release(&cork, &v6_cork);
+               ip6_cork_release(cork, &v6_cork);
                return ERR_PTR(err);
        }
        if (ipc6->dontfrag < 0)
                ipc6->dontfrag = inet6_sk(sk)->dontfrag;
 
-       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,
                                length + exthdrlen, transhdrlen + exthdrlen,
                                flags, ipc6, sockc);
        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 __ip6_make_skb(sk, &queue, &cork, &v6_cork);
+       return __ip6_make_skb(sk, &queue, cork, &v6_cork);
 }
index 4ec76a8..824797f 100644 (file)
@@ -1324,12 +1324,13 @@ back_from_confirm:
 
        /* Lockless fast path for the non-corking case */
        if (!corkreq) {
+               struct inet_cork_full cork;
                struct sk_buff *skb;
 
                skb = ip6_make_skb(sk, getfrag, msg, ulen,
                                   sizeof(struct udphdr), &ipc6,
                                   &fl6, (struct rt6_info *)dst,
-                                  msg->msg_flags, &sockc);
+                                  msg->msg_flags, &cork, &sockc);
                err = PTR_ERR(skb);
                if (!IS_ERR_OR_NULL(skb))
                        err = udp_v6_send_skb(skb, &fl6);