#include <net/sock.h>
#include <net/tcp_states.h>
#include <linux/llc.h>
+#include <linux/slab.h>
static int llc_mac_header_len(unsigned short devtype)
{
case ARPHRD_ETHER:
case ARPHRD_LOOPBACK:
return sizeof(struct ethhdr);
-#ifdef CONFIG_TR
+#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
case ARPHRD_IEEE802_TR:
return sizeof(struct trh_hdr);
#endif
{
struct sock *rc;
struct hlist_nulls_node *node;
+ int slot = llc_sk_laddr_hashfn(sap, laddr);
+ struct hlist_nulls_head *laddr_hb = &sap->sk_laddr_hash[slot];
rcu_read_lock_bh();
again:
- sk_nulls_for_each_rcu(rc, node, &sap->sk_list) {
+ sk_nulls_for_each_rcu(rc, node, laddr_hb) {
if (llc_dgram_match(sap, laddr, rc)) {
/* Extra checks required by SLAB_DESTROY_BY_RCU */
if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt)))
}
}
rc = NULL;
+ /*
+ * if the nulls value we got at the end of this lookup is
+ * not the expected one, we must restart lookup.
+ * We probably met an item that was moved to another chain.
+ */
+ if (unlikely(get_nulls_value(node) != slot))
+ goto again;
found:
rcu_read_unlock_bh();
return rc;
{
int i = 0, count = 256 / sizeof(struct sock *);
struct sock *sk, *stack[count];
- struct hlist_nulls_node *node;
+ struct hlist_node *node;
+ struct llc_sock *llc;
+ struct hlist_head *dev_hb = llc_sk_dev_hash(sap, skb->dev->ifindex);
spin_lock_bh(&sap->sk_lock);
- sk_nulls_for_each_rcu(sk, node, &sap->sk_list) {
+ hlist_for_each_entry(llc, node, dev_hb, dev_hash_node) {
+
+ sk = &llc->sk;
if (!llc_mcast_match(sap, laddr, skb, sk))
continue;