Commit 1cd7884d authored by Willem de Bruijn's avatar Willem de Bruijn Committed by David S. Miller

udp: expose inet cork to udp

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: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a9537c93
...@@ -171,7 +171,7 @@ struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4, ...@@ -171,7 +171,7 @@ struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4,
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,
struct ipcm_cookie *ipc, struct rtable **rtp, 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) static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
{ {
......
...@@ -950,6 +950,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, ...@@ -950,6 +950,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,
const struct sockcm_cookie *sockc); 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)
......
...@@ -1470,9 +1470,8 @@ struct sk_buff *ip_make_skb(struct sock *sk, ...@@ -1470,9 +1470,8 @@ struct sk_buff *ip_make_skb(struct sock *sk,
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,
struct ipcm_cookie *ipc, struct rtable **rtp, 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; struct sk_buff_head queue;
int err; int err;
...@@ -1481,22 +1480,22 @@ struct sk_buff *ip_make_skb(struct sock *sk, ...@@ -1481,22 +1480,22 @@ struct sk_buff *ip_make_skb(struct sock *sk,
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
cork.flags = 0; cork->flags = 0;
cork.addr = 0; cork->addr = 0;
cork.opt = NULL; cork->opt = NULL;
err = ip_setup_cork(sk, &cork, ipc, rtp); err = ip_setup_cork(sk, cork, ipc, rtp);
if (err) if (err)
return ERR_PTR(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, &current->task_frag, getfrag,
from, length, transhdrlen, flags); from, length, transhdrlen, flags);
if (err) { if (err) {
__ip_flush_pending_frames(sk, &queue, &cork); __ip_flush_pending_frames(sk, &queue, cork);
return ERR_PTR(err); return ERR_PTR(err);
} }
return __ip_make_skb(sk, fl4, &queue, &cork); return __ip_make_skb(sk, fl4, &queue, cork);
} }
/* /*
......
...@@ -1030,9 +1030,11 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1030,9 +1030,11 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
/* Lockless fast path for the non-corking case. */ /* Lockless fast path for the non-corking case. */
if (!corkreq) { if (!corkreq) {
struct inet_cork cork;
skb = ip_make_skb(sk, fl4, getfrag, msg, ulen, skb = ip_make_skb(sk, fl4, getfrag, msg, ulen,
sizeof(struct udphdr), &ipc, &rt, sizeof(struct udphdr), &ipc, &rt,
msg->msg_flags); &cork, msg->msg_flags);
err = PTR_ERR(skb); err = PTR_ERR(skb);
if (!IS_ERR_OR_NULL(skb)) if (!IS_ERR_OR_NULL(skb))
err = udp_send_skb(skb, fl4); err = udp_send_skb(skb, fl4);
......
...@@ -1755,9 +1755,9 @@ struct sk_buff *ip6_make_skb(struct sock *sk, ...@@ -1755,9 +1755,9 @@ 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,
const struct sockcm_cookie *sockc) const struct sockcm_cookie *sockc)
{ {
struct inet_cork_full cork;
struct inet6_cork v6_cork; struct inet6_cork v6_cork;
struct sk_buff_head queue; struct sk_buff_head queue;
int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0); int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
...@@ -1768,27 +1768,27 @@ struct sk_buff *ip6_make_skb(struct sock *sk, ...@@ -1768,27 +1768,27 @@ struct sk_buff *ip6_make_skb(struct sock *sk,
__skb_queue_head_init(&queue); __skb_queue_head_init(&queue);
cork.base.flags = 0; cork->base.flags = 0;
cork.base.addr = 0; cork->base.addr = 0;
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);
if (err) { if (err) {
ip6_cork_release(&cork, &v6_cork); ip6_cork_release(cork, &v6_cork);
return ERR_PTR(err); return ERR_PTR(err);
} }
if (ipc6->dontfrag < 0) if (ipc6->dontfrag < 0)
ipc6->dontfrag = inet6_sk(sk)->dontfrag; 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, &current->task_frag, getfrag, from,
length + exthdrlen, transhdrlen + exthdrlen, length + exthdrlen, transhdrlen + exthdrlen,
flags, ipc6, sockc); flags, ipc6, sockc);
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);
} }
return __ip6_make_skb(sk, &queue, &cork, &v6_cork); return __ip6_make_skb(sk, &queue, cork, &v6_cork);
} }
...@@ -1324,12 +1324,13 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ...@@ -1324,12 +1324,13 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
/* Lockless fast path for the non-corking case */ /* Lockless fast path for the non-corking case */
if (!corkreq) { if (!corkreq) {
struct inet_cork_full cork;
struct sk_buff *skb; struct sk_buff *skb;
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, &sockc); msg->msg_flags, &cork, &sockc);
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); err = udp_v6_send_skb(skb, &fl6);
......
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