compat/compat-3.5.c: Fixed double lock in dev_mc_add_excl
[compat-rdma/compat.git] / compat / compat-3.5.c
index 8e87e18..186487d 100644 (file)
@@ -7,9 +7,16 @@
  *
  * Compatibility file for Linux wireless for kernels 3.4.
  */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/export.h>
+#include <linux/types.h>
 #include <linux/pkt_sched.h>
+
 #define ECN_OR_COST(class)     TC_PRIO_##class
 
+#ifndef CONFIG_COMPAT_IS_IP_TOS2PRIO
 const __u8 ip_tos2prio[16] = {
        TC_PRIO_BESTEFFORT,
        ECN_OR_COST(BESTEFFORT),
@@ -29,3 +36,65 @@ const __u8 ip_tos2prio[16] = {
        ECN_OR_COST(INTERACTIVE_BULK)
 };
 EXPORT_SYMBOL(ip_tos2prio);
+#endif
+
+int dev_uc_add_excl(struct net_device *dev, unsigned char *addr)
+{
+       struct netdev_hw_addr *ha;
+       int err;
+
+       netif_addr_lock_bh(dev);
+       netdev_for_each_uc_addr(ha, dev) {
+               if (!memcmp(ha->addr, addr, dev->addr_len) &&
+                   ha->type == NETDEV_HW_ADDR_T_UNICAST) {
+                       err = -EEXIST;
+                       goto out;
+               }
+       }
+       netif_addr_unlock_bh(dev);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+       return dev_uc_add(dev, addr);
+#else
+       return dev_unicast_add(dev, addr);
+#endif
+
+out:
+       netif_addr_unlock_bh(dev);
+       return err;
+}
+EXPORT_SYMBOL(dev_uc_add_excl);
+
+int dev_mc_add_excl(struct net_device *dev, unsigned char *addr)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+       struct netdev_hw_addr *ha;
+#else
+       struct dev_addr_list *ha;
+#endif
+       int err;
+
+       netif_addr_lock_bh(dev);
+       netdev_for_each_mc_addr(ha, dev) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+               if (!memcmp(ha->addr, addr, dev->addr_len)) {
+#else
+               if (!memcmp(ha->da_addr, addr, dev->addr_len)) {
+#endif
+                       err = -EEXIST;
+                       goto out;
+               }
+       }
+       netif_addr_unlock_bh(dev);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+       return dev_mc_add(dev, addr);
+#else
+       return dev_mc_add(dev, addr, ETH_ALEN, true);
+#endif
+
+out:
+       netif_addr_unlock_bh(dev);
+       return err;
+}
+EXPORT_SYMBOL(dev_mc_add_excl);