Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Willem de Bruijn and committed by
David S. Miller
1cd7884d a9537c93

+25 -22
+1 -1
include/net/ip.h
··· 171 171 int len, int odd, struct sk_buff *skb), 172 172 void *from, int length, int transhdrlen, 173 173 struct ipcm_cookie *ipc, struct rtable **rtp, 174 - unsigned int flags); 174 + struct inet_cork *cork, unsigned int flags); 175 175 176 176 static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4) 177 177 {
+1
include/net/ipv6.h
··· 950 950 void *from, int length, int transhdrlen, 951 951 struct ipcm6_cookie *ipc6, struct flowi6 *fl6, 952 952 struct rt6_info *rt, unsigned int flags, 953 + struct inet_cork_full *cork, 953 954 const struct sockcm_cookie *sockc); 954 955 955 956 static inline struct sk_buff *ip6_finish_skb(struct sock *sk)
+8 -9
net/ipv4/ip_output.c
··· 1470 1470 int len, int odd, struct sk_buff *skb), 1471 1471 void *from, int length, int transhdrlen, 1472 1472 struct ipcm_cookie *ipc, struct rtable **rtp, 1473 - unsigned int flags) 1473 + struct inet_cork *cork, unsigned int flags) 1474 1474 { 1475 - struct inet_cork cork; 1476 1475 struct sk_buff_head queue; 1477 1476 int err; 1478 1477 ··· 1480 1481 1481 1482 __skb_queue_head_init(&queue); 1482 1483 1483 - cork.flags = 0; 1484 - cork.addr = 0; 1485 - cork.opt = NULL; 1486 - err = ip_setup_cork(sk, &cork, ipc, rtp); 1484 + cork->flags = 0; 1485 + cork->addr = 0; 1486 + cork->opt = NULL; 1487 + err = ip_setup_cork(sk, cork, ipc, rtp); 1487 1488 if (err) 1488 1489 return ERR_PTR(err); 1489 1490 1490 - err = __ip_append_data(sk, fl4, &queue, &cork, 1491 + err = __ip_append_data(sk, fl4, &queue, cork, 1491 1492 &current->task_frag, getfrag, 1492 1493 from, length, transhdrlen, flags); 1493 1494 if (err) { 1494 - __ip_flush_pending_frames(sk, &queue, &cork); 1495 + __ip_flush_pending_frames(sk, &queue, cork); 1495 1496 return ERR_PTR(err); 1496 1497 } 1497 1498 1498 - return __ip_make_skb(sk, fl4, &queue, &cork); 1499 + return __ip_make_skb(sk, fl4, &queue, cork); 1499 1500 } 1500 1501 1501 1502 /*
+3 -1
net/ipv4/udp.c
··· 1030 1030 1031 1031 /* Lockless fast path for the non-corking case. */ 1032 1032 if (!corkreq) { 1033 + struct inet_cork cork; 1034 + 1033 1035 skb = ip_make_skb(sk, fl4, getfrag, msg, ulen, 1034 1036 sizeof(struct udphdr), &ipc, &rt, 1035 - msg->msg_flags); 1037 + &cork, msg->msg_flags); 1036 1038 err = PTR_ERR(skb); 1037 1039 if (!IS_ERR_OR_NULL(skb)) 1038 1040 err = udp_send_skb(skb, fl4);
+10 -10
net/ipv6/ip6_output.c
··· 1755 1755 void *from, int length, int transhdrlen, 1756 1756 struct ipcm6_cookie *ipc6, struct flowi6 *fl6, 1757 1757 struct rt6_info *rt, unsigned int flags, 1758 + struct inet_cork_full *cork, 1758 1759 const struct sockcm_cookie *sockc) 1759 1760 { 1760 - struct inet_cork_full cork; 1761 1761 struct inet6_cork v6_cork; 1762 1762 struct sk_buff_head queue; 1763 1763 int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0); ··· 1768 1768 1769 1769 __skb_queue_head_init(&queue); 1770 1770 1771 - cork.base.flags = 0; 1772 - cork.base.addr = 0; 1773 - cork.base.opt = NULL; 1774 - cork.base.dst = NULL; 1771 + cork->base.flags = 0; 1772 + cork->base.addr = 0; 1773 + cork->base.opt = NULL; 1774 + cork->base.dst = NULL; 1775 1775 v6_cork.opt = NULL; 1776 - err = ip6_setup_cork(sk, &cork, &v6_cork, ipc6, rt, fl6); 1776 + err = ip6_setup_cork(sk, cork, &v6_cork, ipc6, rt, fl6); 1777 1777 if (err) { 1778 - ip6_cork_release(&cork, &v6_cork); 1778 + ip6_cork_release(cork, &v6_cork); 1779 1779 return ERR_PTR(err); 1780 1780 } 1781 1781 if (ipc6->dontfrag < 0) 1782 1782 ipc6->dontfrag = inet6_sk(sk)->dontfrag; 1783 1783 1784 - err = __ip6_append_data(sk, fl6, &queue, &cork.base, &v6_cork, 1784 + err = __ip6_append_data(sk, fl6, &queue, &cork->base, &v6_cork, 1785 1785 &current->task_frag, getfrag, from, 1786 1786 length + exthdrlen, transhdrlen + exthdrlen, 1787 1787 flags, ipc6, sockc); 1788 1788 if (err) { 1789 - __ip6_flush_pending_frames(sk, &queue, &cork, &v6_cork); 1789 + __ip6_flush_pending_frames(sk, &queue, cork, &v6_cork); 1790 1790 return ERR_PTR(err); 1791 1791 } 1792 1792 1793 - return __ip6_make_skb(sk, &queue, &cork, &v6_cork); 1793 + return __ip6_make_skb(sk, &queue, cork, &v6_cork); 1794 1794 }
+2 -1
net/ipv6/udp.c
··· 1324 1324 1325 1325 /* Lockless fast path for the non-corking case */ 1326 1326 if (!corkreq) { 1327 + struct inet_cork_full cork; 1327 1328 struct sk_buff *skb; 1328 1329 1329 1330 skb = ip6_make_skb(sk, getfrag, msg, ulen, 1330 1331 sizeof(struct udphdr), &ipc6, 1331 1332 &fl6, (struct rt6_info *)dst, 1332 - msg->msg_flags, &sockc); 1333 + msg->msg_flags, &cork, &sockc); 1333 1334 err = PTR_ERR(skb); 1334 1335 if (!IS_ERR_OR_NULL(skb)) 1335 1336 err = udp_v6_send_skb(skb, &fl6);