kfree(addr);
}
EXPORT_SYMBOL(kvfree);
+
+#define idr_is_empty LINUX_BACKPORT(idr_is_empty)
+static int idr_has_entry(int id, void *p, void *data)
+{
+ return 1;
+}
+
+bool idr_is_empty(struct idr *idp)
+{
+ return !idr_for_each(idp, idr_has_entry, NULL);
+}
+EXPORT_SYMBOL(idr_is_empty);
return ret;
}
EXPORT_SYMBOL(cpumask_set_cpu_local_first);
+
+static int __hw_addr_del_entry(struct netdev_hw_addr_list *list,
+ struct netdev_hw_addr *ha, bool global,
+ bool sync)
+{
+ if (global && !ha->global_use)
+ return -ENOENT;
+
+ if (sync && !ha->synced)
+ return -ENOENT;
+
+ if (global)
+ ha->global_use = false;
+
+ if (sync)
+ ha->synced--;
+
+ if (--ha->refcount)
+ return 0;
+ list_del_rcu(&ha->list);
+ kfree_rcu(ha, rcu_head);
+ list->count--;
+ return 0;
+}
+
+/**
+ * __hw_addr_sync_dev - Synchonize device's multicast list
+ * @list: address list to syncronize
+ * @dev: device to sync
+ * @sync: function to call if address should be added
+ * @unsync: function to call if address should be removed
+ *
+ * This funciton is intended to be called from the ndo_set_rx_mode
+ * function of devices that require explicit address add/remove
+ * notifications. The unsync function may be NULL in which case
+ * the addresses requiring removal will simply be removed without
+ * any notification to the device.
+ **/
+#define __hw_addr_sync_dev LINUX_BACKPORT(__hw_addr_sync_dev)
+int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
+ struct net_device *dev,
+ int (*sync)(struct net_device *, const unsigned char *),
+ int (*unsync)(struct net_device *,
+ const unsigned char *))
+{
+ struct netdev_hw_addr *ha, *tmp;
+ int err;
+
+ /* first go through and flush out any stale entries */
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ if (!ha->sync_cnt || ha->refcount != 1)
+ continue;
+
+ /* if unsync is defined and fails defer unsyncing address */
+ if (unsync && unsync(dev, ha->addr))
+ continue;
+
+ ha->sync_cnt--;
+ __hw_addr_del_entry(list, ha, false, false);
+ }
+
+ /* go through and sync new entries to the list */
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ if (ha->sync_cnt)
+ continue;
+
+ err = sync(dev, ha->addr);
+ if (err)
+ return err;
+
+ ha->sync_cnt++;
+ ha->refcount++;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(__hw_addr_sync_dev);
#define LINUX_3_15_COMPAT_H
#include <linux/version.h>
+#include <linux/idr.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
#define kvfree LINUX_BACKPORT(kvfree)
extern void kvfree(const void *addr);
+#ifndef HAVE_IDR_IS_EMPTY
+#define idr_is_empty LINUX_BACKPORT(idr_is_empty)
+bool idr_is_empty(struct idr *idp);
+#endif
+
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)) */
#endif /* LINUX_3_15_COMPAT_H */
#define NETIF_F_GSO_UDP_TUNNEL_CSUM 0
#endif
+#if !defined(HAVE___DEV_UC_SYNC) && !defined(HAVE___DEV_MC_SYNC)
+
+#include <linux/netdevice.h>
+
+#define __hw_addr_sync_dev LINUX_BACKPORT(__hw_addr_sync_dev)
+int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
+ struct net_device *dev,
+ int (*sync)(struct net_device *, const unsigned char *),
+ int (*unsync)(struct net_device *,
+ const unsigned char *));
+
+/**
+ * __dev_uc_sync - Synchonize device's unicast list
+ * @dev: device to sync
+ * @sync: function to call if address should be added
+ * @unsync: function to call if address should be removed
+ *
+ * Add newly added addresses to the interface, and release
+ * addresses that have been deleted.
+ */
+#define __dev_uc_sync LINUX_BACKPORT(__dev_uc_sync)
+static inline int __dev_uc_sync(struct net_device *dev,
+ int (*sync)(struct net_device *,
+ const unsigned char *),
+ int (*unsync)(struct net_device *,
+ const unsigned char *))
+{
+ return __hw_addr_sync_dev(&dev->uc, dev, sync, unsync);
+}
+
+/**
+ * __dev_mc_sync - Synchonize device's multicast list
+ * @dev: device to sync
+ * @sync: function to call if address should be added
+ * @unsync: function to call if address should be removed
+ *
+ * Add newly added addresses to the interface, and release
+ * addresses that have been deleted.
+ */
+#define __dev_mc_sync LINUX_BACKPORT(__dev_mc_sync)
+static inline int __dev_mc_sync(struct net_device *dev,
+ int (*sync)(struct net_device *,
+ const unsigned char *),
+ int (*unsync)(struct net_device *,
+ const unsigned char *))
+{
+ return __hw_addr_sync_dev(&dev->mc, dev, sync, unsync);
+}
+#endif
+
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)) */
#endif /* LINUX_3_16_COMPAT_H */
#endif
#include <linux/cpumask.h>
+#include <linux/if_vlan.h>
#define cpumask_local_spread LINUX_BACKPORT(cpumask_local_spread)
unsigned int cpumask_local_spread(unsigned int i, int node);
#endif
+#ifndef HAVE_SKB_VLAN_TAGGED
+/*
+ * skb_vlan_tagged - check if skb is vlan tagged.
+ * @skb: skbuff to query
+ *
+ * Returns true if the skb is tagged, regardless of whether it is hardware
+ * accelerated or not.
+ */
+static inline bool skb_vlan_tagged(const struct sk_buff *skb)
+{
+ if (!skb_vlan_tag_present(skb) &&
+ likely(skb->protocol != htons(ETH_P_8021Q) &&
+ skb->protocol != htons(ETH_P_8021AD)))
+ return false;
+
+ return true;
+}
+#endif
+
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0)) */
#endif /* LINUX_4_1_COMPAT_H */