1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Based on include/net/ndisc.h
4 * No Authors, no Copyright
5 */
6 #ifndef _NNDISC_H
7 #define _NNDISC_H
8
9 #include <net/neighbour.h>
10 #include <linux/compiler.h>
11 #include <linux/types.h>
12 #include <linux/if_arp.h>
13 #include <linux/netdevice.h>
14 #include <linux/hash.h>
15 #include <linux/nip_icmp.h>
16
17 #define NEWIP_NEIGH_BUCKET_MAX 8
18 extern struct neigh_table nnd_tbl;
19
20 #define NIP_ARP_NS 0x01 /* ARP request */
21 #define NIP_ARP_NA 0x02 /* ARP response */
22
23 struct nnd_msg {
24 struct nip_icmp_hdr icmph;
25 __u8 data[0];
26 };
27
neigh_key_eq800(const struct neighbour * n,const void * pkey)28 static inline bool neigh_key_eq800(const struct neighbour *n, const void *pkey)
29 {
30 struct nip_addr *a1, *a2;
31
32 a1 = (struct nip_addr *)(pkey);
33 a2 = (struct nip_addr *)(n->primary_key);
34
35 #define RIGHT_POS_3 3
36 return a1->bitlen == a2->bitlen && a1->bitlen <= NIP_ADDR_BIT_LEN_MAX &&
37 memcmp(&a1->v.u, &a2->v.u, a1->bitlen >> RIGHT_POS_3) == 0;
38 }
39
nndisc_hashfn(const void * pkey,const struct net_device * dev,__u32 * hash_rnd)40 static inline u32 nndisc_hashfn(const void *pkey, const struct net_device *dev,
41 __u32 *hash_rnd)
42 {
43 return (*(int *)pkey % NEWIP_NEIGH_BUCKET_MAX);
44 }
45
__nip_neigh_lookup_noref(struct net_device * dev,const void * pkey)46 static inline struct neighbour *__nip_neigh_lookup_noref(struct net_device *dev,
47 const void *pkey)
48 {
49 return ___neigh_lookup_noref(&nnd_tbl, neigh_key_eq800, nndisc_hashfn,
50 pkey, dev);
51 }
52
__nip_neigh_lookup(struct net_device * dev,const void * pkey)53 static inline struct neighbour *__nip_neigh_lookup(struct net_device *dev,
54 const void *pkey)
55 {
56 struct neighbour *n;
57
58 rcu_read_lock_bh();
59 n = __nip_neigh_lookup_noref(dev, pkey);
60 if (n && !refcount_inc_not_zero(&n->refcnt))
61 n = NULL;
62 rcu_read_unlock_bh();
63
64 return n;
65 }
66
67 int nndisc_rcv(struct sk_buff *skb);
68
69 int nndisc_init(void);
70
71 #endif
72