• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Based on net/ipv6/ndisc.c
4  *	Authors:
5  *	Pedro Roque		<roque@di.fc.ul.pt>
6  *	Mike Shaver		<shaver@ingenia.com>
7  *
8  *	Changes:
9  *
10  *	Alexey I. Froloff		:	RFC6106 (DNSSL) support
11  *	Pierre Ynard			:	export userland ND options
12  *						through netlink (RDNSS support)
13  *	Lars Fenneberg			:	fixed MTU setting on receipt
14  *						of an RA.
15  *	Janos Farkas			:	kmalloc failure checks
16  *	Alexey Kuznetsov		:	state machine reworked
17  *						and moved to net/core.
18  *	Pekka Savola			:	RFC2461 validation
19  *	YOSHIFUJI Hideaki @USAGI	:	Verify ND options properly
20  *
21  * Neighbour Discovery for NewIP
22  * Linux NewIP INET implementation
23  */
24 #define pr_fmt(fmt) KBUILD_MODNAME ": [%s:%d] " fmt, __func__, __LINE__
25 
26 #include <net/sock.h>
27 #include <net/nip.h>
28 #include <net/nip_udp.h>
29 #include <net/protocol.h>
30 #include <net/nndisc.h>
31 #include <net/nip_route.h>
32 #include <net/addrconf.h>
33 #include <net/nip_fib.h>
34 #include <net/netlink.h>
35 #include <net/flow.h>
36 #include <net/inet_common.h>
37 #include <net/nip_addrconf.h>
38 #include <linux/module.h>
39 #include <linux/errno.h>
40 #include <linux/types.h>
41 #include <linux/socket.h>
42 #include <linux/sockios.h>
43 #include <linux/net.h>
44 #include <linux/route.h>
45 #include <linux/init.h>
46 #include <linux/rcupdate.h>
47 #include <linux/nip.h>
48 #include <linux/nip_icmp.h>
49 #include <linux/jhash.h>
50 #include <linux/rtnetlink.h>
51 #include <linux/newip_route.h>
52 #include <linux/netfilter.h>
53 #include "nip_hdr.h"
54 #include "nip_checksum.h"
55 #include "tcp_nip_parameter.h"
56 
57 /* NUD_INCOMPLETE
58  * The neighbor request packet has been sent but no response has been received
59  * NUD_REACHABLE
60  * Reachable: Indicates that the neighbor is reachable
61  * NUD_STAL
62  * Idle state, which has not been confirmed for a long time,
63  * and the idle time exceeds the rated time
64  * NUD_DELAY
65  * If the acknowledgment time expires but the idle time does not exceed the rated time,
66  * you need to obtain the acknowledgment packet
67  * NUD_PROBE
68  * After NUD_DELAY does not receive confirmation for a long time, ARP request messages are sent
69  * NUD_FAILED
70  * The neighbor is unreachable
71  * NUD_NOARP
72  * Indicates the status of the neighbor that does not need the ARP status change
73  * NUD_PERMANENT
74  * Indicates that the status of the neighbor item is permanent and does not need to change
75  * NUD_NONE
76  * Initialization status of the neighbor item
77  */
78 static void nndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
79 
80 static u32 nndisc_hash(const void *pkey,
81 		       const struct net_device *dev, __u32 *hash_rnd);
82 static bool nndisc_key_eq(const struct neighbour *neigh, const void *pkey);
83 static int nndisc_constructor(struct neighbour *neigh);
84 
nndisc_error_report(struct neighbour * neigh,struct sk_buff * skb)85 static void nndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
86 {
87 	kfree_skb(skb);
88 }
89 
nndisc_generic_error_report(struct neighbour * neigh,struct sk_buff * skb)90 static void nndisc_generic_error_report(struct neighbour *neigh, struct sk_buff *skb)
91 {
92 }
93 
94 static const struct neigh_ops nndisc_generic_ops = {
95 	.family = AF_NINET,
96 	.solicit = nndisc_solicit,
97 	.output = neigh_resolve_output,
98 	.connected_output = neigh_connected_output,
99 	.error_report = nndisc_generic_error_report,
100 };
101 
102 static const struct neigh_ops nndisc_hh_ops = {
103 	.family = AF_NINET,
104 	.solicit = nndisc_solicit,
105 	.error_report = nndisc_error_report,
106 	.output = neigh_resolve_output,
107 	.connected_output = neigh_resolve_output,
108 };
109 
110 static const struct neigh_ops nndisc_direct_ops = {
111 	.family = AF_NINET,
112 	.output = neigh_direct_output,
113 	.connected_output = neigh_direct_output,
114 };
115 
116 #define NIP_NEIGH_MCAST_PROBES 4
117 #define NIP_NEIGH_UCAST_PROBES 4
118 #define NIP_NEIGH_DELAY_PROBE_TIME (5 * HZ)
119 #define NIP_NEIGH_GC_STALETIME (60 * HZ)
120 #define NIP_NEIGH_QUEUE_LEN_BYTES (64 * 1024)
121 #define NIP_NEIGH_PROXY_QLEN 64
122 #define NIP_NEIGH_ANYCAST_DELAY (1 * HZ)
123 #define NIP_NEIGH_PROXY_DELAY ((8 * HZ) / 10)
124 #define NIP_NEIGH_GC_INTERVAL (30 * HZ)
125 #define NIP_NEIGH_GC_THRESH_1 128
126 #define NIP_NEIGH_GC_THRESH_2 512
127 #define NIP_NEIGH_GC_THRESH_3 1024
128 
nndisc_proxy_redo(struct sk_buff * skb)129 static void nndisc_proxy_redo(struct sk_buff *skb)
130 {
131 }
132 
nndisc_is_multicast(const void * pkey)133 static int nndisc_is_multicast(const void *pkey)
134 {
135 	return -EINVAL;
136 }
137 
138 struct neigh_table nnd_tbl = {
139 	.family = AF_NINET,
140 	.key_len = sizeof(struct nip_addr),
141 	.protocol = cpu_to_be16(ETH_P_NEWIP),
142 	.hash = nndisc_hash,
143 	.key_eq = nndisc_key_eq,
144 	.constructor = nndisc_constructor,
145 	.proxy_redo = nndisc_proxy_redo,
146 	.is_multicast = nndisc_is_multicast,
147 	.id = "nndisc_cache",
148 	.parms = {
149 		  .tbl = &nnd_tbl,
150 		  .reachable_time = ND_REACHABLE_TIME,
151 		  .data = {
152 			   [NEIGH_VAR_MCAST_PROBES] = NIP_NEIGH_MCAST_PROBES,
153 			   [NEIGH_VAR_UCAST_PROBES] = NIP_NEIGH_UCAST_PROBES,
154 			   [NEIGH_VAR_RETRANS_TIME] = ND_RETRANS_TIMER,
155 			   [NEIGH_VAR_BASE_REACHABLE_TIME] = ND_REACHABLE_TIME,
156 			   [NEIGH_VAR_DELAY_PROBE_TIME] = NIP_NEIGH_DELAY_PROBE_TIME,
157 			   [NEIGH_VAR_GC_STALETIME] = NIP_NEIGH_GC_STALETIME,
158 			   [NEIGH_VAR_QUEUE_LEN_BYTES] = NIP_NEIGH_QUEUE_LEN_BYTES,
159 			   [NEIGH_VAR_PROXY_QLEN] = NIP_NEIGH_PROXY_QLEN,
160 			   [NEIGH_VAR_ANYCAST_DELAY] = NIP_NEIGH_ANYCAST_DELAY,
161 			   [NEIGH_VAR_PROXY_DELAY] = NIP_NEIGH_PROXY_DELAY,
162 			   },
163 		   },
164 	.gc_interval = NIP_NEIGH_GC_INTERVAL,
165 	.gc_thresh1 = NIP_NEIGH_GC_THRESH_1,
166 	.gc_thresh2 = NIP_NEIGH_GC_THRESH_2,
167 	.gc_thresh3 = NIP_NEIGH_GC_THRESH_3,
168 };
169 
nndisc_hash(const void * pkey,const struct net_device * dev,__u32 * hash_rnd)170 static u32 nndisc_hash(const void *pkey,
171 		       const struct net_device *dev, __u32 *hash_rnd)
172 {
173 	return nndisc_hashfn(pkey, dev, hash_rnd);
174 }
175 
nndisc_key_eq(const struct neighbour * neigh,const void * pkey)176 static bool nndisc_key_eq(const struct neighbour *neigh, const void *pkey)
177 {
178 	return neigh_key_eq800(neigh, pkey);
179 }
180 
nndisc_constructor(struct neighbour * neigh)181 static int nndisc_constructor(struct neighbour *neigh)
182 {
183 	struct nip_addr *addr = (struct nip_addr *)&neigh->primary_key;
184 	struct net_device *dev = neigh->dev;
185 	struct ninet_dev *nin_dev;
186 	struct neigh_parms *parms;
187 	bool is_broadcast = (bool)nip_addr_eq(addr, &nip_broadcast_addr_arp);
188 
189 	nin_dev = nin_dev_get(dev);
190 	if (!nin_dev)
191 		return -EINVAL;
192 
193 	parms = nin_dev->nd_parms;
194 	__neigh_parms_put(neigh->parms);
195 	neigh->parms = neigh_parms_clone(parms);
196 	neigh->type = RTN_UNICAST;
197 	if (!dev->header_ops) {
198 		neigh->nud_state = NUD_NOARP;
199 		neigh->ops = &nndisc_direct_ops;
200 		neigh->output = neigh_direct_output;
201 	} else {
202 		if (is_broadcast ||
203 		    (dev->flags & IFF_POINTOPOINT)) {
204 			neigh->nud_state = NUD_NOARP;
205 			memcpy(neigh->ha, dev->broadcast, dev->addr_len);
206 		} else if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) {
207 			neigh->nud_state = NUD_NOARP;
208 			memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
209 			if (dev->flags & IFF_LOOPBACK)
210 				neigh->type = RTN_LOCAL;
211 		}
212 
213 		if (dev->header_ops->cache)
214 			neigh->ops = &nndisc_hh_ops;
215 		else
216 			neigh->ops = &nndisc_generic_ops;
217 
218 		if (neigh->nud_state & NUD_VALID)
219 			neigh->output = neigh->ops->connected_output;
220 		else
221 			neigh->output = neigh->ops->output;
222 	}
223 
224 	nin_dev_put(nin_dev);
225 
226 	return 0;
227 }
228 
nip_insert_nndisc_send_checksum(struct sk_buff * skb,u_short checksum)229 void nip_insert_nndisc_send_checksum(struct sk_buff *skb, u_short checksum)
230 {
231 #define NNDISC_CHECKSUM_BIAS 2
232 	*(__u16 *)(skb_transport_header(skb) + NNDISC_CHECKSUM_BIAS) =
233 	htons(checksum);
234 }
235 
nip_get_nndisc_send_checksum(struct sk_buff * skb,struct nip_hdr_encap * head,int payload_len)236 unsigned short nip_get_nndisc_send_checksum(struct sk_buff *skb,
237 					    struct nip_hdr_encap *head,
238 					    int payload_len)
239 {
240 	struct nip_pseudo_header nph = {0};
241 
242 	nph.nexthdr = head->nexthdr;
243 	nph.saddr = head->saddr;
244 	nph.daddr = head->daddr;
245 	nph.check_len = htons(payload_len);
246 	return nip_check_sum_build(skb_transport_header(skb),
247 				   payload_len, &nph);
248 }
249 
nip_get_nndisc_rcv_checksum(struct sk_buff * skb,const u_char * transport_tail)250 bool nip_get_nndisc_rcv_checksum(struct sk_buff *skb,
251 				 const u_char *transport_tail)
252 {
253 	struct nip_pseudo_header nph = {0};
254 	unsigned short check_len = (unsigned short)(transport_tail - (skb_transport_header(skb)));
255 
256 	nph.nexthdr = nipcb(skb)->nexthdr;
257 	nph.saddr = nipcb(skb)->srcaddr;
258 	nph.daddr = nipcb(skb)->dstaddr;
259 	nph.check_len = htons(check_len);
260 
261 	return nip_check_sum_parse(skb_transport_header(skb), check_len, &nph)
262 	       == 0xffff ? true : false;
263 }
264 
nndisc_payload_ns_pack(const struct nip_addr * solicit,struct sk_buff * skb)265 static void nndisc_payload_ns_pack(const struct nip_addr *solicit,
266 				   struct sk_buff *skb)
267 {
268 	struct nnd_msg *msg = (struct nnd_msg *)skb->data;
269 	u_char *p = msg->data;
270 
271 	memset(&msg->icmph, 0, sizeof(msg->icmph));
272 	msg->icmph.nip_icmp_type = NIP_ARP_NS;
273 	msg->icmph.nip_icmp_cksum = 0;
274 	p = build_nip_addr(solicit, p);
275 }
276 
nndisc_dst_alloc(struct net_device * dev)277 static struct dst_entry *nndisc_dst_alloc(struct net_device *dev)
278 {
279 	struct nip_rt_info *rt;
280 	struct net *net = dev_net(dev);
281 
282 	rt = nip_dst_alloc(net, dev, 0);
283 	if (!rt)
284 		return NULL;
285 
286 	rt->dst.flags |= DST_HOST;
287 	rt->dst.input = nip_input;
288 	rt->dst.output = nip_output;
289 	atomic_set(&rt->dst.__refcnt, 1);
290 
291 	return &rt->dst;
292 }
293 
get_ns_payload_len(const struct nip_addr * solicit)294 static int get_ns_payload_len(const struct nip_addr *solicit)
295 {
296 	return sizeof(struct nip_icmp_hdr) + get_nip_addr_len(solicit);
297 }
298 
nndisc_send_skb(struct net_device * dev,struct sk_buff * skb,struct nip_hdr_encap * head,const int payload_len)299 static int nndisc_send_skb(struct net_device *dev,
300 			   struct sk_buff *skb, struct nip_hdr_encap *head,
301 			   const int payload_len)
302 {
303 	int ret = 0;
304 	struct sock *sk = NULL;
305 	struct dst_entry *dst = NULL;
306 	u_short checksum = 0;
307 
308 	/* skip transport hdr */
309 	skb_reserve(skb, payload_len);
310 
311 	/* set skb->data to point network header */
312 	skb->data = skb_network_header(skb);
313 	skb->len = head->hdr_buf_pos + payload_len;
314 
315 	dst = nndisc_dst_alloc(dev);
316 	if (!dst) {
317 		kfree_skb(skb);
318 		return -ENOMEM;
319 	}
320 	/* add check sum */
321 	checksum = nip_get_nndisc_send_checksum(skb, head, payload_len);
322 	nip_insert_nndisc_send_checksum(skb, checksum);
323 
324 	skb_dst_set(skb, dst);
325 	ret = dst_output(dev_net(skb->dev), sk, skb);
326 	return ret;
327 }
328 
nndisc_alloc_skb(struct net_device * dev,struct nip_hdr_encap * head,int payload_len)329 static struct sk_buff *nndisc_alloc_skb(struct net_device *dev,
330 					struct nip_hdr_encap *head, int payload_len)
331 {
332 	struct sk_buff *skb = NULL;
333 	int len = NIP_ETH_HDR_LEN + NIP_HDR_MAX + payload_len;
334 
335 	skb = alloc_skb(len, 0);
336 	if (!skb)
337 		/* If you add log here, there will be an alarm:
338 		 * WARNING: Possible unnecessary 'out of memory' message
339 		 */
340 		return skb;
341 
342 	skb->protocol = htons(ETH_P_NEWIP);
343 	skb->ip_summed = CHECKSUM_NONE;
344 	skb->csum = 0;
345 	skb->dev = dev;
346 	memset(nipcb(skb), 0, sizeof(struct ninet_skb_parm));
347 
348 	nipcb(skb)->dstaddr = head->daddr;
349 	nipcb(skb)->srcaddr = head->saddr;
350 	nipcb(skb)->nexthdr = head->nexthdr;
351 	/* reserve space for hardware header */
352 	skb_reserve(skb, NIP_ETH_HDR_LEN);
353 	skb_reset_network_header(skb);
354 
355 	/* build nwk header */
356 	head->hdr_buf = (unsigned char *)skb->data;
357 	nip_hdr_comm_encap(head);
358 	head->total_len = head->hdr_buf_pos + payload_len;
359 	nip_update_total_len(head, htons(head->total_len));
360 	skb_reserve(skb, head->hdr_buf_pos);
361 	skb_reset_transport_header(skb);
362 	return skb;
363 }
364 
nndisc_send_ns(struct net_device * dev,const struct nip_addr * solicit,const struct nip_addr * daddr,const struct nip_addr * saddr)365 static void nndisc_send_ns(struct net_device *dev,
366 			   const struct nip_addr *solicit,
367 			   const struct nip_addr *daddr,
368 			   const struct nip_addr *saddr)
369 {
370 	int ret;
371 	struct sk_buff *skb;
372 	int payload_len = get_ns_payload_len(solicit);
373 	struct nip_hdr_encap head = {0};
374 
375 	head.saddr = *saddr;
376 	head.daddr = *daddr;
377 	head.ttl = NIP_ARP_DEFAULT_TTL;
378 	head.nexthdr = IPPROTO_NIP_ICMP;
379 
380 	skb = nndisc_alloc_skb(dev, &head, payload_len);
381 	if (!skb)
382 		/* If you add log here, there will be an alarm:
383 		 * WARNING: Possible unnecessary 'out of memory' message
384 		 */
385 		return;
386 	/* build ns header */
387 	nndisc_payload_ns_pack(solicit, skb);
388 
389 	ret = nndisc_send_skb(dev, skb, &head, payload_len);
390 	if (ret)
391 		nip_dbg("dst output fail");
392 }
393 
__send_ns_packet(__u8 nud_state,struct net_device * dev,const struct nip_addr * target,const struct nip_addr * saddr)394 static void __send_ns_packet(__u8 nud_state, struct net_device *dev,
395 			     const struct nip_addr *target, const struct nip_addr *saddr)
396 {
397 	if (nud_state & NUD_VALID) {
398 		nndisc_send_ns(dev, target, target, saddr);
399 		nip_dbg("unicast ns");
400 	} else {
401 		nndisc_send_ns(dev, target, &nip_broadcast_addr_arp, saddr);
402 		nip_dbg("multicast ns");
403 	}
404 }
405 
nndisc_solicit(struct neighbour * neigh,struct sk_buff * skb)406 static void nndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
407 {
408 	struct net_device *dev = neigh->dev;
409 	struct nip_addr *target = (struct nip_addr *)&neigh->primary_key;
410 	struct ninet_dev *idev;
411 
412 	/* Obtain the NewIP address from the current dev as
413 	 * the source address of the request packet
414 	 */
415 	rcu_read_lock();
416 	idev = __nin_dev_get(dev);
417 	if (!idev) {
418 		nip_dbg("idev don't exist");
419 		rcu_read_unlock();
420 		return;
421 	}
422 	read_lock_bh(&idev->lock);
423 	if (!list_empty(&idev->addr_list)) {
424 		struct ninet_ifaddr *ifp;
425 
426 		list_for_each_entry(ifp, &idev->addr_list, if_list) {
427 			__send_ns_packet(neigh->nud_state, dev, target, &ifp->addr);
428 		}
429 	}
430 	read_unlock_bh(&idev->lock);
431 	rcu_read_unlock();
432 }
433 
build_na_hdr(u_char * smac,u_char mac_len,struct sk_buff * skb)434 static void build_na_hdr(u_char *smac, u_char mac_len, struct sk_buff *skb)
435 {
436 	struct nnd_msg *msg = (struct nnd_msg *)skb->data;
437 	u_char *p = msg->data;
438 
439 	memset(&msg->icmph, 0, sizeof(msg->icmph));
440 	msg->icmph.nip_icmp_type = NIP_ARP_NA;
441 	msg->icmph.nip_icmp_cksum = 0;
442 	*p = mac_len;
443 	p++;
444 	memcpy(p, smac, mac_len);
445 }
446 
get_na_payload_len(struct net_device * dev)447 static int get_na_payload_len(struct net_device *dev)
448 {
449 	/* Icmp Header Length
450 	 * Number of bytes in the MAC address length field
451 	 * MAC Address Length
452 	 */
453 	return sizeof(struct nip_icmp_hdr) + 1 + dev->addr_len;
454 }
455 
nndisc_send_na(struct net_device * dev,const struct nip_addr * daddr,const struct nip_addr * saddr)456 static void nndisc_send_na(struct net_device *dev,
457 			   const struct nip_addr *daddr,
458 			   const struct nip_addr *saddr)
459 {
460 	int ret;
461 	struct sk_buff *skb = NULL;
462 	int payload_len = get_na_payload_len(dev);
463 	u_char *smac = dev->dev_addr;
464 	struct nip_hdr_encap head = {0};
465 
466 	head.saddr = *saddr;
467 	head.daddr = *daddr;
468 	head.ttl = NIP_ARP_DEFAULT_TTL;
469 	head.nexthdr = IPPROTO_NIP_ICMP;
470 
471 	skb = nndisc_alloc_skb(dev, &head, payload_len);
472 	if (!skb)
473 		/* If you add log here, there will be an alarm:
474 		 * WARNING: Possible unnecessary 'out of memory' message
475 		 */
476 		return;
477 	/* build na header */
478 	build_na_hdr(smac, dev->addr_len, skb);
479 
480 	ret = nndisc_send_skb(dev, skb, &head, payload_len);
481 	if (ret)
482 		nip_dbg("dst output fail");
483 }
484 
nip_addr_local(struct net_device * dev,struct nip_addr * addr)485 bool nip_addr_local(struct net_device *dev, struct nip_addr *addr)
486 {
487 	struct ninet_dev *idev;
488 	bool ret = false;
489 
490 	rcu_read_lock();
491 	idev = __nin_dev_get(dev);
492 	if (!idev)
493 		goto out;
494 
495 	read_lock_bh(&idev->lock);
496 	if (!list_empty(&idev->addr_list)) {
497 		struct ninet_ifaddr *ifp;
498 
499 		list_for_each_entry(ifp, &idev->addr_list, if_list) {
500 			if (nip_addr_eq(addr, &ifp->addr)) {
501 				ret = true;
502 				break;
503 			}
504 		}
505 	}
506 	read_unlock_bh(&idev->lock);
507 out:
508 	rcu_read_unlock();
509 	return ret;
510 }
511 
nndisc_rcv_ns(struct sk_buff * skb)512 int nndisc_rcv_ns(struct sk_buff *skb)
513 {
514 	struct nnd_msg *msg;
515 	u_char *p;
516 	u_char *lladdr;
517 	struct nip_addr addr = {0};
518 	struct neighbour *neigh;
519 	struct ethhdr *eth;
520 	struct net_device *dev = skb->dev;
521 	int err = 0;
522 	struct nip_buff nbuf;
523 
524 	if (!pskb_may_pull(skb, sizeof(struct nnd_msg))) {
525 		nip_dbg("invalid ns packet");
526 		err = -EFAULT;
527 		goto out;
528 	}
529 
530 	msg = (struct nnd_msg *)skb->data;
531 	nbuf.data = msg->data;
532 	nbuf.remaining_len = skb->len - sizeof(struct nip_icmp_hdr);
533 
534 	p = decode_nip_addr(&nbuf, &addr);
535 	if (!p) {
536 		nip_dbg("failure when decode source address");
537 		err = -EFAULT;
538 		goto out;
539 	}
540 
541 	if (nip_addr_invalid(&addr)) {
542 		nip_dbg("icmp hdr addr invalid, bitlen=%u", addr.bitlen);
543 		err = -EFAULT;
544 		goto out;
545 	}
546 
547 	if (!nip_addr_local(dev, &addr)) {
548 		err = -ENXIO;
549 		goto out;
550 	}
551 
552 	eth = (struct ethhdr *)skb_mac_header(skb);
553 	lladdr = eth->h_source;
554 
555 	/* checksum parse */
556 	if (!nip_get_nndisc_rcv_checksum(skb, nbuf.data)) {
557 		nip_dbg("ns ICMP checksum failed, drop the packet");
558 		err = -EINVAL;
559 		goto out;
560 	}
561 
562 	neigh = __neigh_lookup(&nnd_tbl, &nipcb(skb)->srcaddr, dev, lladdr || !dev->addr_len);
563 	if (neigh) {
564 		neigh_update(neigh, lladdr, NUD_STALE, NEIGH_UPDATE_F_OVERRIDE, 0);
565 		neigh_release(neigh);
566 	}
567 
568 	nndisc_send_na(dev, &nipcb(skb)->srcaddr, &addr);
569 out:
570 	kfree_skb(skb);
571 	return err;
572 }
573 
nndisc_rcv_na(struct sk_buff * skb)574 int nndisc_rcv_na(struct sk_buff *skb)
575 {
576 	struct nnd_msg *msg;
577 	u_char *p;
578 	u_char len;
579 	u8 lladdr[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
580 	struct net_device *dev = skb->dev;
581 	struct neighbour *neigh;
582 
583 	if (!pskb_may_pull(skb, sizeof(struct nnd_msg))) {
584 		nip_dbg("invalid na packet");
585 		kfree_skb(skb);
586 		return -EINVAL;
587 	}
588 
589 	msg = (struct nnd_msg *)skb->data;
590 	p = msg->data;
591 	if (skb->len - sizeof(struct nip_icmp_hdr) < sizeof(unsigned char)) {
592 		nip_dbg("invalid msg data");
593 		kfree_skb(skb);
594 		return -EINVAL;
595 	}
596 	len = *p;
597 	if (len > MAX_ADDR_LEN) {
598 		nip_dbg("invalid length,  drop the packet(len=%u)", len);
599 		kfree_skb(skb);
600 		return 0;
601 	}
602 
603 	p++;
604 	memset(lladdr, 0, ALIGN(MAX_ADDR_LEN, sizeof(unsigned long)));
605 	if (skb->len - sizeof(struct nip_icmp_hdr) - sizeof(unsigned char) < len) {
606 		nip_dbg("invalid msg data");
607 		kfree_skb(skb);
608 		return -EINVAL;
609 	}
610 	memcpy(lladdr, p, len);
611 
612 	if (!nip_get_nndisc_rcv_checksum(skb, p + len)) {
613 		nip_dbg("na ICMP checksum failed, drop the packet");
614 		kfree_skb(skb);
615 		return 0;
616 	}
617 
618 	neigh = neigh_lookup(&nnd_tbl, &nipcb(skb)->srcaddr, dev);
619 	if (neigh) {
620 		neigh_update(neigh, lladdr, NUD_REACHABLE, NEIGH_UPDATE_F_OVERRIDE, 0);
621 		neigh_release(neigh);
622 		kfree_skb(skb);
623 		return 0;
624 	}
625 	kfree_skb(skb);
626 	return -EFAULT;
627 }
628 
nndisc_rcv(struct sk_buff * skb)629 int nndisc_rcv(struct sk_buff *skb)
630 {
631 	int ret = 0;
632 	struct nip_icmp_hdr *hdr = nip_icmp_header(skb);
633 	u8 type = hdr->nip_icmp_type;
634 
635 	switch (type) {
636 	case NIP_ARP_NS:
637 		ret = nndisc_rcv_ns(skb);
638 		break;
639 	case NIP_ARP_NA:
640 		ret = nndisc_rcv_na(skb);
641 		break;
642 	default:
643 		nip_dbg("nd packet type error");
644 	}
645 
646 	return ret;
647 }
648 
nndisc_init(void)649 int __init nndisc_init(void)
650 {
651 	neigh_table_init(NEIGH_NND_TABLE, &nnd_tbl);
652 	return 0;
653 }
654