/* SPDX-License-Identifier: GPL-2.0 */ /* * Based on include/net/ndisc.h * No Authors, no Copyright */ #ifndef _NNDISC_H #define _NNDISC_H #include #include #include #include #include #include #include #define NEWIP_NEIGH_BUCKET_MAX 8 extern struct neigh_table nnd_tbl; #define NIP_ARP_NS 0x01 /* ARP request */ #define NIP_ARP_NA 0x02 /* ARP response */ struct nnd_msg { struct nip_icmp_hdr icmph; __u8 data[0]; }; static inline bool neigh_key_eq800(const struct neighbour *n, const void *pkey) { struct nip_addr *a1, *a2; a1 = (struct nip_addr *)(pkey); a2 = (struct nip_addr *)(n->primary_key); #define RIGHT_POS_3 3 return a1->bitlen == a2->bitlen && a1->bitlen <= NIP_ADDR_BIT_LEN_MAX && memcmp(&a1->v.u, &a2->v.u, a1->bitlen >> RIGHT_POS_3) == 0; } static inline u32 nndisc_hashfn(const void *pkey, const struct net_device *dev, __u32 *hash_rnd) { return (*(int *)pkey % NEWIP_NEIGH_BUCKET_MAX); } static inline struct neighbour *__nip_neigh_lookup_noref(struct net_device *dev, const void *pkey) { return ___neigh_lookup_noref(&nnd_tbl, neigh_key_eq800, nndisc_hashfn, pkey, dev); } static inline struct neighbour *__nip_neigh_lookup(struct net_device *dev, const void *pkey) { struct neighbour *n; rcu_read_lock_bh(); n = __nip_neigh_lookup_noref(dev, pkey); if (n && !refcount_inc_not_zero(&n->refcnt)) n = NULL; rcu_read_unlock_bh(); return n; } int nndisc_rcv(struct sk_buff *skb); int nndisc_init(void); #endif