diff options
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r-- | net/ipv4/ip_output.c | 35 |
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 | */ |
1512 | static DEFINE_PER_CPU(struct inet_sock, unicast_sock) = { | 1508 | void 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 | |||
1525 | void 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 | } |
1596 | out: | 1573 | out: |
1597 | put_cpu_var(unicast_sock); | ||
1598 | |||
1599 | ip_rt_put(rt); | 1574 | ip_rt_put(rt); |
1600 | } | 1575 | } |
1601 | 1576 | ||