|
@@ -51,6 +51,25 @@ extern struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
|
|
|
#define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
|
|
|
#define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count)
|
|
|
|
|
|
+/* Reserved Ethernet Addresses per IEEE 802.1Q */
|
|
|
+static const u8 br_reserved_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
|
|
|
+
|
|
|
+/**
|
|
|
+ * is_link_local - Determine if given Eth addr is a link local mcast address.
|
|
|
+ * @addr: Pointer to a six-byte array containing the Ethernet address
|
|
|
+ *
|
|
|
+ * Return true if address is link local reserved addr (01:80:c2:00:00:0X) per
|
|
|
+ * IEEE 802.1Q 8.6.3 Frame filtering.
|
|
|
+ */
|
|
|
+static inline int is_link_local(const unsigned char *dest)
|
|
|
+{
|
|
|
+ __be16 *a = (__be16 *)dest;
|
|
|
+ static const __be16 *b = (const __be16 *)br_reserved_address;
|
|
|
+ static const __be16 m = cpu_to_be16(0xfff0);
|
|
|
+
|
|
|
+ return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* is_zero_ether_addr - Determine if give Ethernet address is all zeros.
|
|
|
* @addr: Pointer to a six-byte array containing the Ethernet address
|