aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r--net/ipv4/udp.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 62c19fdd102d..a7e4729e974b 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1600,20 +1600,15 @@ static void flush_stack(struct sock **stack, unsigned int count,
1600} 1600}
1601 1601
1602/* For TCP sockets, sk_rx_dst is protected by socket lock 1602/* For TCP sockets, sk_rx_dst is protected by socket lock
1603 * For UDP, we use sk_dst_lock to guard against concurrent changes. 1603 * For UDP, we use xchg() to guard against concurrent changes.
1604 */ 1604 */
1605static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) 1605static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
1606{ 1606{
1607 struct dst_entry *old; 1607 struct dst_entry *old;
1608 1608
1609 spin_lock(&sk->sk_dst_lock); 1609 dst_hold(dst);
1610 old = sk->sk_rx_dst; 1610 old = xchg(&sk->sk_rx_dst, dst);
1611 if (likely(old != dst)) { 1611 dst_release(old);
1612 dst_hold(dst);
1613 sk->sk_rx_dst = dst;
1614 dst_release(old);
1615 }
1616 spin_unlock(&sk->sk_dst_lock);
1617} 1612}
1618 1613
1619/* 1614/*
@@ -2483,6 +2478,7 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2483 netdev_features_t features) 2478 netdev_features_t features)
2484{ 2479{
2485 struct sk_buff *segs = ERR_PTR(-EINVAL); 2480 struct sk_buff *segs = ERR_PTR(-EINVAL);
2481 u16 mac_offset = skb->mac_header;
2486 int mac_len = skb->mac_len; 2482 int mac_len = skb->mac_len;
2487 int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); 2483 int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb);
2488 __be16 protocol = skb->protocol; 2484 __be16 protocol = skb->protocol;
@@ -2502,8 +2498,11 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2502 /* segment inner packet. */ 2498 /* segment inner packet. */
2503 enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); 2499 enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
2504 segs = skb_mac_gso_segment(skb, enc_features); 2500 segs = skb_mac_gso_segment(skb, enc_features);
2505 if (!segs || IS_ERR(segs)) 2501 if (!segs || IS_ERR(segs)) {
2502 skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset,
2503 mac_len);
2506 goto out; 2504 goto out;
2505 }
2507 2506
2508 outer_hlen = skb_tnl_header_len(skb); 2507 outer_hlen = skb_tnl_header_len(skb);
2509 skb = segs; 2508 skb = segs;