Merge tag 'ktest-v3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
[cascardo/linux.git] / include / net / addrconf.h
index df4ef94..40be2a0 100644 (file)
 
 #define IPV6_MAX_ADDRESSES             16
 
+#define ADDRCONF_TIMER_FUZZ_MINUS      (HZ > 50 ? HZ / 50 : 1)
+#define ADDRCONF_TIMER_FUZZ            (HZ / 4)
+#define ADDRCONF_TIMER_FUZZ_MAX                (HZ)
+
 #include <linux/in.h>
 #include <linux/in6.h>
 
@@ -150,7 +154,31 @@ extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
 extern bool ipv6_chk_mcast_addr(struct net_device *dev,
                                const struct in6_addr *group,
                                const struct in6_addr *src_addr);
-extern bool ipv6_is_mld(struct sk_buff *skb, int nexthdr);
+
+/*
+ * identify MLD packets for MLD filter exceptions
+ */
+static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset)
+{
+       struct icmp6hdr *hdr;
+
+       if (nexthdr != IPPROTO_ICMPV6 ||
+           !pskb_network_may_pull(skb, offset + sizeof(struct icmp6hdr)))
+               return false;
+
+       hdr = (struct icmp6hdr *)(skb_network_header(skb) + offset);
+
+       switch (hdr->icmp6_type) {
+       case ICMPV6_MGM_QUERY:
+       case ICMPV6_MGM_REPORT:
+       case ICMPV6_MGM_REDUCTION:
+       case ICMPV6_MLD2_REPORT:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
 
 extern void addrconf_prefix_rcv(struct net_device *dev,
                                u8 *opt, int len, bool sllao);
@@ -257,30 +285,55 @@ static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
                      htonl(0xFF000000) | addr->s6_addr32[3]);
 }
 
-static inline int ipv6_addr_is_multicast(const struct in6_addr *addr)
+static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
 {
        return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
 }
 
-static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
+static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
 {
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
+       __u64 *p = (__u64 *)addr;
+       return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL;
+#else
        return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
                addr->s6_addr32[1] | addr->s6_addr32[2] |
                (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
+#endif
 }
 
-static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
+static inline bool ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
 {
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
+       __u64 *p = (__u64 *)addr;
+       return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL;
+#else
        return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
                addr->s6_addr32[1] | addr->s6_addr32[2] |
                (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
+#endif
 }
 
-static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
 {
        return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
 }
 
+static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
+{
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
+       __u64 *p = (__u64 *)addr;
+       return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) |
+               ((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
+                cpu_to_be64(0xffffffffff000000UL))) == 0UL;
+#else
+       return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
+               addr->s6_addr32[1] |
+               (addr->s6_addr32[2] ^ htonl(0x00000001)) |
+               (addr->s6_addr[12] ^ 0xff)) == 0;
+#endif
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);