1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
#ifndef _NDISC_H
#define _NDISC_H
/*
* Neighbor Cache Entry States (7.3.2.)
*/
/*
* The lsb is set for states that have a timer associated
*/
#define NUD_NONE 0x00
#define NUD_INCOMPLETE 0x11
#define NUD_REACHABLE 0x20
#define NUD_STALE 0x30
#define NUD_DELAY 0x41
#define NUD_PROBE 0x51
#define NUD_FAILED 0x60 /* neighbour discovery failed */
#define NUD_IN_TIMER 0x01
#define NDISC_QUEUE_LEN 3
#define NCF_NOARP 0x0100 /* no ARP needed on this device */
#define NCF_SUBNET 0x0200 /* NC entry for subnet */
#define NCF_INVALID 0x0400
#define NCF_DELAY_EXPIRED 0x0800 /* time to move to PROBE */
#define NCF_ROUTER 0x1000 /* neighbour is a router */
#define NCF_HHVALID 0x2000 /* Hardware header is valid */
/*
* ICMP codes for neighbour discovery messages
*/
#define NDISC_ROUTER_SOLICITATION 133
#define NDISC_ROUTER_ADVERTISEMENT 134
#define NDISC_NEIGHBOUR_SOLICITATION 135
#define NDISC_NEIGHBOUR_ADVERTISEMENT 136
#define NDISC_REDIRECT 137
/*
* ndisc options
*/
#define ND_OPT_SOURCE_LL_ADDR 1
#define ND_OPT_TARGET_LL_ADDR 2
#define ND_OPT_PREFIX_INFO 3
#define ND_OPT_REDIRECT_HDR 4
#define ND_OPT_MTU 5
#define MAX_RTR_SOLICITATION_DELAY HZ
#define RECHABLE_TIME (30*HZ)
#define RETRANS_TIMER HZ
#define MIN_RANDOM_FACTOR (1/2)
#define MAX_RANDOM_FACTOR (3/2)
#define REACH_RANDOM_INTERVAL (60*60*HZ) /* 1 hour */
#ifdef __KERNEL__
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/icmpv6.h>
#include <net/neighbour.h>
#include <asm/atomic.h>
/*
* neighbour cache entry
* used by neighbour discovery module
*/
struct nd_neigh {
struct neighbour neigh;
struct in6_addr ndn_addr; /* next hop addr */
__u8 ndn_plen, /* prefix len */
ndn_type, /* {unicast, multicast} */
ndn_nud_state,
ndn_probes;
unsigned long ndn_expires; /* timer expires at */
#define ndn_refcnt neigh.refcnt
#define ndn_tstamp neigh.lastused
#define ndn_dev neigh.dev
#define ndn_flags neigh.flags
#define ndn_ha neigh.ha
};
struct nd_msg {
struct icmp6hdr icmph;
struct in6_addr target;
struct {
__u8 opt_type;
__u8 opt_len;
__u8 link_addr[MAX_ADDR_LEN];
} opt;
};
struct ra_msg {
struct icmp6hdr icmph;
__u32 reachable_time;
__u32 retrans_timer;
};
struct ndisc_statistics {
__u32 allocs; /* allocated entries */
__u32 free_delayed; /* zombie entries */
__u32 snt_probes_ucast; /* ns probes sent (ucast) */
__u32 snt_probes_mcast; /* ns probes sent (mcast) */
__u32 rcv_probes_ucast; /* ns probes rcv (ucast) */
__u32 rcv_probes_mcast; /* ns probes rcv (mcast) */
__u32 rcv_upper_conf; /* confirmations from upper layers */
__u32 res_failed; /* address resolution failures */
};
extern struct neighbour * ndisc_find_neigh(struct device *dev,
struct in6_addr *addr);
extern void ndisc_validate(struct neighbour *neigh);
extern void ndisc_init(struct net_proto_family *ops);
extern struct neighbour* ndisc_get_neigh(struct device *dev,
struct in6_addr *addr);
extern void ndisc_cleanup(void);
extern int ndisc_rcv(struct sk_buff *skb,
struct device *dev,
struct in6_addr *saddr,
struct in6_addr *daddr,
struct ipv6_options *opt,
unsigned short len);
extern void ndisc_event_send(struct neighbour *neigh,
struct sk_buff *skb);
extern void ndisc_send_ns(struct device *dev,
struct neighbour *neigh,
struct in6_addr *solicit,
struct in6_addr *daddr,
struct in6_addr *saddr);
extern void ndisc_send_rs(struct device *dev,
struct in6_addr *saddr,
struct in6_addr *daddr);
extern int ndisc_eth_resolv(unsigned char *,
struct sk_buff *);
extern void ndisc_forwarding_on(void);
extern void ndisc_forwarding_off(void);
extern void ndisc_send_redirect(struct sk_buff *skb,
struct neighbour *neigh,
struct in6_addr *target);
struct rt6_info * dflt_rt_lookup(void);
extern unsigned long nd_rand_seed;
extern unsigned long ipv6_random(void);
/*
* IGMP
*/
extern void igmp6_init(struct net_proto_family *ops);
extern int igmp6_event_query(struct sk_buff *skb,
struct icmp6hdr *hdr,
int len);
extern int igmp6_event_report(struct sk_buff *skb,
struct icmp6hdr *hdr,
int len);
#endif /* __KERNEL__ */
#endif
|