aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r--net/ipv4/ip_output.c35
1 files changed, 5 insertions, 30 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index b50861b22b6b..d68199d9b2b0 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -755,13 +755,11 @@ ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk
755 struct msghdr *msg = from; 755 struct msghdr *msg = from;
756 756
757 if (skb->ip_summed == CHECKSUM_PARTIAL) { 757 if (skb->ip_summed == CHECKSUM_PARTIAL) {
758 /* XXX: stripping const */ 758 if (copy_from_iter(to, len, &msg->msg_iter) != len)
759 if (memcpy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len) < 0)
760 return -EFAULT; 759 return -EFAULT;
761 } else { 760 } else {
762 __wsum csum = 0; 761 __wsum csum = 0;
763 /* XXX: stripping const */ 762 if (csum_and_copy_from_iter(to, len, &csum, &msg->msg_iter) != len)
764 if (csum_partial_copy_fromiovecend(to, (struct iovec *)msg->msg_iter.iov, offset, len, &csum) < 0)
765 return -EFAULT; 763 return -EFAULT;
766 skb->csum = csum_block_add(skb->csum, csum, odd); 764 skb->csum = csum_block_add(skb->csum, csum, odd);
767 } 765 }
@@ -1506,23 +1504,8 @@ static int ip_reply_glue_bits(void *dptr, char *to, int offset,
1506/* 1504/*
1507 * Generic function to send a packet as reply to another packet. 1505 * Generic function to send a packet as reply to another packet.
1508 * Used to send some TCP resets/acks so far. 1506 * Used to send some TCP resets/acks so far.
1509 *
1510 * Use a fake percpu inet socket to avoid false sharing and contention.
1511 */ 1507 */
1512static DEFINE_PER_CPU(struct inet_sock, unicast_sock) = { 1508void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
1513 .sk = {
1514 .__sk_common = {
1515 .skc_refcnt = ATOMIC_INIT(1),
1516 },
1517 .sk_wmem_alloc = ATOMIC_INIT(1),
1518 .sk_allocation = GFP_ATOMIC,
1519 .sk_flags = (1UL << SOCK_USE_WRITE_QUEUE),
1520 },
1521 .pmtudisc = IP_PMTUDISC_WANT,
1522 .uc_ttl = -1,
1523};
1524
1525void ip_send_unicast_reply(struct net *net, struct sk_buff *skb,
1526 const struct ip_options *sopt, 1509 const struct ip_options *sopt,
1527 __be32 daddr, __be32 saddr, 1510 __be32 daddr, __be32 saddr,
1528 const struct ip_reply_arg *arg, 1511 const struct ip_reply_arg *arg,
@@ -1532,9 +1515,8 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb,
1532 struct ipcm_cookie ipc; 1515 struct ipcm_cookie ipc;
1533 struct flowi4 fl4; 1516 struct flowi4 fl4;
1534 struct rtable *rt = skb_rtable(skb); 1517 struct rtable *rt = skb_rtable(skb);
1518 struct net *net = sock_net(sk);
1535 struct sk_buff *nskb; 1519 struct sk_buff *nskb;
1536 struct sock *sk;
1537 struct inet_sock *inet;
1538 int err; 1520 int err;
1539 1521
1540 if (__ip_options_echo(&replyopts.opt.opt, skb, sopt)) 1522 if (__ip_options_echo(&replyopts.opt.opt, skb, sopt))
@@ -1565,15 +1547,11 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb,
1565 if (IS_ERR(rt)) 1547 if (IS_ERR(rt))
1566 return; 1548 return;
1567 1549
1568 inet = &get_cpu_var(unicast_sock); 1550 inet_sk(sk)->tos = arg->tos;
1569 1551
1570 inet->tos = arg->tos;
1571 sk = &inet->sk;
1572 sk->sk_priority = skb->priority; 1552 sk->sk_priority = skb->priority;
1573 sk->sk_protocol = ip_hdr(skb)->protocol; 1553 sk->sk_protocol = ip_hdr(skb)->protocol;
1574 sk->sk_bound_dev_if = arg->bound_dev_if; 1554 sk->sk_bound_dev_if = arg->bound_dev_if;
1575 sock_net_set(sk, net);
1576 __skb_queue_head_init(&sk->sk_write_queue);
1577 sk->sk_sndbuf = sysctl_wmem_default; 1555 sk->sk_sndbuf = sysctl_wmem_default;
1578 err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, 1556 err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base,
1579 len, 0, &ipc, &rt, MSG_DONTWAIT); 1557 len, 0, &ipc, &rt, MSG_DONTWAIT);
@@ -1589,13 +1567,10 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb,
1589 arg->csumoffset) = csum_fold(csum_add(nskb->csum, 1567 arg->csumoffset) = csum_fold(csum_add(nskb->csum,
1590 arg->csum)); 1568 arg->csum));
1591 nskb->ip_summed = CHECKSUM_NONE; 1569 nskb->ip_summed = CHECKSUM_NONE;
1592 skb_orphan(nskb);
1593 skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); 1570 skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb));
1594 ip_push_pending_frames(sk, &fl4); 1571 ip_push_pending_frames(sk, &fl4);
1595 } 1572 }
1596out: 1573out:
1597 put_cpu_var(unicast_sock);
1598
1599 ip_rt_put(rt); 1574 ip_rt_put(rt);
1600} 1575}
1601 1576