summaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r--net/ipv6/udp.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 4c79dc5329bc..c55698d19d68 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -554,7 +554,7 @@ void udpv6_encap_enable(void)
554} 554}
555EXPORT_SYMBOL(udpv6_encap_enable); 555EXPORT_SYMBOL(udpv6_encap_enable);
556 556
557static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) 557static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
558{ 558{
559 struct udp_sock *up = udp_sk(sk); 559 struct udp_sock *up = udp_sk(sk);
560 int is_udplite = IS_UDPLITE(sk); 560 int is_udplite = IS_UDPLITE(sk);
@@ -637,6 +637,28 @@ drop:
637 return -1; 637 return -1;
638} 638}
639 639
640static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
641{
642 struct sk_buff *next, *segs;
643 int ret;
644
645 if (likely(!udp_unexpected_gso(sk, skb)))
646 return udpv6_queue_rcv_one_skb(sk, skb);
647
648 __skb_push(skb, -skb_mac_offset(skb));
649 segs = udp_rcv_segment(sk, skb, false);
650 for (skb = segs; skb; skb = next) {
651 next = skb->next;
652 __skb_pull(skb, skb_transport_offset(skb));
653
654 ret = udpv6_queue_rcv_one_skb(sk, skb);
655 if (ret > 0)
656 ip6_protocol_deliver_rcu(dev_net(skb->dev), skb, ret,
657 true);
658 }
659 return 0;
660}
661
640static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk, 662static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk,
641 __be16 loc_port, const struct in6_addr *loc_addr, 663 __be16 loc_port, const struct in6_addr *loc_addr,
642 __be16 rmt_port, const struct in6_addr *rmt_addr, 664 __be16 rmt_port, const struct in6_addr *rmt_addr,