Ejemplo n.º 1
0
/*
 * Note: called only from the BH handler context,
 * so we don't need to lock the hashes.
 */
static void udpv6_mcast_deliver(struct udphdr *uh,
                                struct in6_addr *saddr, struct in6_addr *daddr,
                                struct sk_buff *skb)
{
    struct sock *sk, *sk2;
    struct sk_buff *buff;
    int dif;

    read_lock(&udp_hash_lock);
    sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)];
    dif = skb->dev->ifindex;
    sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
    if (!sk)
        goto free_skb;

    buff = NULL;
    sk2 = sk;
    while((sk2 = udp_v6_mcast_next(sk2->next, uh->dest, daddr,
                                   uh->source, saddr, dif))) {
        if (!buff) {
            buff = skb_clone(skb, GFP_ATOMIC);
            if (!buff)
                continue;
        }
        if (sock_queue_rcv_skb(sk2, buff) >= 0)
            buff = NULL;
    }
    if (buff)
        kfree_skb(buff);
    if (sock_queue_rcv_skb(sk, skb) < 0) {
free_skb:
        kfree_skb(skb);
    }
    read_unlock(&udp_hash_lock);
}
Ejemplo n.º 2
0
/*
 * Note: called only from the BH handler context,
 * so we don't need to lock the hashes.
 */
static void udpv6_mcast_deliver(struct udphdr *uh,
				struct in6_addr *saddr, struct in6_addr *daddr,
				struct sk_buff *skb)
{
	struct sock *sk, *sk2;
	int dif;

	read_lock(&udp_hash_lock);
	sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)];
	dif = skb->dev->ifindex;
	sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
	if (!sk) {
		kfree_skb(skb);
		goto out;
	}

	sk2 = sk;
	while((sk2 = udp_v6_mcast_next(sk2->next, uh->dest, daddr,
						  uh->source, saddr, dif))) {
		struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
		if (buff)
			udpv6_queue_rcv_skb(sk2, buff);
	}
	udpv6_queue_rcv_skb(sk, skb);
out:
	read_unlock(&udp_hash_lock);
}