blob: 1d5675efcfbc00fa8753f841570623a27d0703ba [file] [log] [blame]
Uwe Zeisbergerf30c2262006-10-03 23:01:26 +02001/* linux/net/ipv4/arp.c
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 * Copyright (C) 1994 by Florian La Roche
4 *
5 * This module implements the Address Resolution Protocol ARP (RFC 826),
6 * which is used to convert IP addresses (or in the future maybe other
7 * high-level addresses) into a low-level hardware address (like an Ethernet
8 * address).
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
15 * Fixes:
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090016 * Alan Cox : Removed the Ethernet assumptions in
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 * Florian's code
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090018 * Alan Cox : Fixed some small errors in the ARP
Linus Torvalds1da177e2005-04-16 15:20:36 -070019 * logic
20 * Alan Cox : Allow >4K in /proc
21 * Alan Cox : Make ARP add its own protocol entry
22 * Ross Martin : Rewrote arp_rcv() and arp_get_info()
23 * Stephen Henson : Add AX25 support to arp_get_info()
24 * Alan Cox : Drop data when a device is downed.
25 * Alan Cox : Use init_timer().
26 * Alan Cox : Double lock fixes.
27 * Martin Seine : Move the arphdr structure
28 * to if_arp.h for compatibility.
29 * with BSD based programs.
30 * Andrew Tridgell : Added ARP netmask code and
31 * re-arranged proxy handling.
32 * Alan Cox : Changed to use notifiers.
33 * Niibe Yutaka : Reply for this device or proxies only.
34 * Alan Cox : Don't proxy across hardware types!
35 * Jonathan Naylor : Added support for NET/ROM.
36 * Mike Shaver : RFC1122 checks.
37 * Jonathan Naylor : Only lookup the hardware address for
38 * the correct hardware type.
39 * Germano Caronni : Assorted subtle races.
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090040 * Craig Schlenter : Don't modify permanent entry
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 * during arp_rcv.
42 * Russ Nelson : Tidied up a few bits.
43 * Alexey Kuznetsov: Major changes to caching and behaviour,
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090044 * eg intelligent arp probing and
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 * generation
46 * of host down events.
47 * Alan Cox : Missing unlock in device events.
48 * Eckes : ARP ioctl control errors.
49 * Alexey Kuznetsov: Arp free fix.
50 * Manuel Rodriguez: Gratuitous ARP.
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +090051 * Jonathan Layes : Added arpd support through kerneld
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 * message queue (960314)
53 * Mike Shaver : /proc/sys/net/ipv4/arp_* support
54 * Mike McLagan : Routing by source
55 * Stuart Cheshire : Metricom and grat arp fixes
56 * *** FOR 2.1 clean this up ***
57 * Lawrence V. Stefani: (08/12/96) Added FDDI support.
Changli Gaodeffd772010-09-02 03:56:51 +000058 * Alan Cox : Took the AP1000 nasty FDDI hack and
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 * folded into the mainstream FDDI code.
60 * Ack spit, Linus how did you allow that
61 * one in...
62 * Jes Sorensen : Make FDDI work again in 2.1.x and
63 * clean up the APFDDI & gen. FDDI bits.
64 * Alexey Kuznetsov: new arp state machine;
65 * now it is in net/core/neighbour.c.
66 * Krzysztof Halasa: Added Frame Relay ARP support.
67 * Arnaldo C. Melo : convert /proc/net/arp to seq_file
68 * Shmulik Hen: Split arp_send to arp_create and
69 * arp_xmit so intermediate drivers like
70 * bonding can change the skb before
71 * sending (e.g. insert 8021q tag).
72 * Harald Welte : convert to make use of jenkins hash
Jesper Dangaard Brouer65324142010-01-05 05:50:47 +000073 * Jesper D. Brouer: Proxy ARP PVLAN RFC 3069 support.
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 */
75
76#include <linux/module.h>
77#include <linux/types.h>
78#include <linux/string.h>
79#include <linux/kernel.h>
Randy Dunlap4fc268d2006-01-11 12:17:47 -080080#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070081#include <linux/socket.h>
82#include <linux/sockios.h>
83#include <linux/errno.h>
84#include <linux/in.h>
85#include <linux/mm.h>
86#include <linux/inet.h>
Arnaldo Carvalho de Melo14c85022005-12-27 02:43:12 -020087#include <linux/inetdevice.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070088#include <linux/netdevice.h>
89#include <linux/etherdevice.h>
90#include <linux/fddidevice.h>
91#include <linux/if_arp.h>
92#include <linux/trdevice.h>
93#include <linux/skbuff.h>
94#include <linux/proc_fs.h>
95#include <linux/seq_file.h>
96#include <linux/stat.h>
97#include <linux/init.h>
98#include <linux/net.h>
99#include <linux/rcupdate.h>
100#include <linux/jhash.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +0900101#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102#ifdef CONFIG_SYSCTL
103#include <linux/sysctl.h>
104#endif
105
Eric W. Biederman457c4cb2007-09-12 12:01:34 +0200106#include <net/net_namespace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107#include <net/ip.h>
108#include <net/icmp.h>
109#include <net/route.h>
110#include <net/protocol.h>
111#include <net/tcp.h>
112#include <net/sock.h>
113#include <net/arp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114#include <net/ax25.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115#include <net/netrom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
117#include <net/atmclip.h>
118struct neigh_table *clip_tbl_hook;
Eric Dumazet4bc2f182010-07-09 21:22:10 +0000119EXPORT_SYMBOL(clip_tbl_hook);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120#endif
121
122#include <asm/system.h>
Changli Gaodeffd772010-09-02 03:56:51 +0000123#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
125#include <linux/netfilter_arp.h>
126
127/*
128 * Interface to generic neighbour cache.
129 */
Eric Dumazetd6bf7812010-10-04 06:15:44 +0000130static u32 arp_hash(const void *pkey, const struct net_device *dev, __u32 rnd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131static int arp_constructor(struct neighbour *neigh);
132static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb);
133static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb);
134static void parp_redo(struct sk_buff *skb);
135
Stephen Hemminger89d69d22009-09-01 11:13:19 +0000136static const struct neigh_ops arp_generic_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 .family = AF_INET,
138 .solicit = arp_solicit,
139 .error_report = arp_error_report,
140 .output = neigh_resolve_output,
141 .connected_output = neigh_connected_output,
142 .hh_output = dev_queue_xmit,
143 .queue_xmit = dev_queue_xmit,
144};
145
Stephen Hemminger89d69d22009-09-01 11:13:19 +0000146static const struct neigh_ops arp_hh_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 .family = AF_INET,
148 .solicit = arp_solicit,
149 .error_report = arp_error_report,
150 .output = neigh_resolve_output,
151 .connected_output = neigh_resolve_output,
152 .hh_output = dev_queue_xmit,
153 .queue_xmit = dev_queue_xmit,
154};
155
Stephen Hemminger89d69d22009-09-01 11:13:19 +0000156static const struct neigh_ops arp_direct_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 .family = AF_INET,
158 .output = dev_queue_xmit,
159 .connected_output = dev_queue_xmit,
160 .hh_output = dev_queue_xmit,
161 .queue_xmit = dev_queue_xmit,
162};
163
stephen hemmingera64de472010-09-28 17:08:02 +0000164static const struct neigh_ops arp_broken_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 .family = AF_INET,
166 .solicit = arp_solicit,
167 .error_report = arp_error_report,
168 .output = neigh_compat_output,
169 .connected_output = neigh_compat_output,
170 .hh_output = dev_queue_xmit,
171 .queue_xmit = dev_queue_xmit,
172};
173
174struct neigh_table arp_tbl = {
Changli Gaodeffd772010-09-02 03:56:51 +0000175 .family = AF_INET,
176 .entry_size = sizeof(struct neighbour) + 4,
177 .key_len = 4,
178 .hash = arp_hash,
179 .constructor = arp_constructor,
180 .proxy_redo = parp_redo,
181 .id = "arp_cache",
182 .parms = {
183 .tbl = &arp_tbl,
184 .base_reachable_time = 30 * HZ,
185 .retrans_time = 1 * HZ,
186 .gc_staletime = 60 * HZ,
187 .reachable_time = 30 * HZ,
188 .delay_probe_time = 5 * HZ,
189 .queue_len = 3,
190 .ucast_probes = 3,
191 .mcast_probes = 3,
192 .anycast_delay = 1 * HZ,
193 .proxy_delay = (8 * HZ) / 10,
194 .proxy_qlen = 64,
195 .locktime = 1 * HZ,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 },
Changli Gaodeffd772010-09-02 03:56:51 +0000197 .gc_interval = 30 * HZ,
198 .gc_thresh1 = 128,
199 .gc_thresh2 = 512,
200 .gc_thresh3 = 1024,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201};
Eric Dumazet4bc2f182010-07-09 21:22:10 +0000202EXPORT_SYMBOL(arp_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
Al Viro714e85b2006-11-14 20:51:49 -0800204int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205{
206 switch (dev->type) {
207 case ARPHRD_ETHER:
208 case ARPHRD_FDDI:
209 case ARPHRD_IEEE802:
210 ip_eth_mc_map(addr, haddr);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900211 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212 case ARPHRD_IEEE802_TR:
213 ip_tr_mc_map(addr, haddr);
214 return 0;
215 case ARPHRD_INFINIBAND:
Rolf Manderscheida9e527e2007-12-10 13:38:41 -0700216 ip_ib_mc_map(addr, dev->broadcast, haddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217 return 0;
Timo Teräs93ca3bb2011-03-28 22:40:53 +0000218 case ARPHRD_IPGRE:
219 ip_ipgre_mc_map(addr, dev->broadcast, haddr);
220 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 default:
222 if (dir) {
223 memcpy(haddr, dev->broadcast, dev->addr_len);
224 return 0;
225 }
226 }
227 return -EINVAL;
228}
229
230
Eric Dumazetd6bf7812010-10-04 06:15:44 +0000231static u32 arp_hash(const void *pkey,
232 const struct net_device *dev,
233 __u32 hash_rnd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234{
Eric Dumazetd6bf7812010-10-04 06:15:44 +0000235 return jhash_2words(*(u32 *)pkey, dev->ifindex, hash_rnd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236}
237
238static int arp_constructor(struct neighbour *neigh)
239{
Changli Gaodeffd772010-09-02 03:56:51 +0000240 __be32 addr = *(__be32 *)neigh->primary_key;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 struct net_device *dev = neigh->dev;
242 struct in_device *in_dev;
243 struct neigh_parms *parms;
244
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 rcu_read_lock();
Herbert Xue5ed6392005-10-03 14:35:55 -0700246 in_dev = __in_dev_get_rcu(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 if (in_dev == NULL) {
248 rcu_read_unlock();
249 return -EINVAL;
250 }
251
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +0900252 neigh->type = inet_addr_type(dev_net(dev), addr);
Denis V. Luneva79878f2008-01-14 22:56:01 -0800253
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 parms = in_dev->arp_parms;
255 __neigh_parms_put(neigh->parms);
256 neigh->parms = neigh_parms_clone(parms);
257 rcu_read_unlock();
258
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700259 if (!dev->header_ops) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 neigh->nud_state = NUD_NOARP;
261 neigh->ops = &arp_direct_ops;
262 neigh->output = neigh->ops->queue_xmit;
263 } else {
264 /* Good devices (checked by reading texts, but only Ethernet is
265 tested)
266
267 ARPHRD_ETHER: (ethernet, apfddi)
268 ARPHRD_FDDI: (fddi)
269 ARPHRD_IEEE802: (tr)
270 ARPHRD_METRICOM: (strip)
271 ARPHRD_ARCNET:
272 etc. etc. etc.
273
274 ARPHRD_IPDDP will also work, if author repairs it.
275 I did not it, because this driver does not work even
276 in old paradigm.
277 */
278
279#if 1
280 /* So... these "amateur" devices are hopeless.
281 The only thing, that I can say now:
282 It is very sad that we need to keep ugly obsolete
283 code to make them happy.
284
285 They should be moved to more reasonable state, now
286 they use rebuild_header INSTEAD OF hard_start_xmit!!!
287 Besides that, they are sort of out of date
288 (a lot of redundant clones/copies, useless in 2.1),
289 I wonder why people believe that they work.
290 */
291 switch (dev->type) {
292 default:
293 break;
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900294 case ARPHRD_ROSE:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
296 case ARPHRD_AX25:
297#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
298 case ARPHRD_NETROM:
299#endif
300 neigh->ops = &arp_broken_ops;
301 neigh->output = neigh->ops->output;
302 return 0;
Changli Gaodeffd772010-09-02 03:56:51 +0000303#else
304 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305#endif
Changli Gaodeffd772010-09-02 03:56:51 +0000306 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307#endif
308 if (neigh->type == RTN_MULTICAST) {
309 neigh->nud_state = NUD_NOARP;
310 arp_mc_map(addr, neigh->ha, dev, 1);
Changli Gaodeffd772010-09-02 03:56:51 +0000311 } else if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 neigh->nud_state = NUD_NOARP;
313 memcpy(neigh->ha, dev->dev_addr, dev->addr_len);
Changli Gaodeffd772010-09-02 03:56:51 +0000314 } else if (neigh->type == RTN_BROADCAST ||
315 (dev->flags & IFF_POINTOPOINT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 neigh->nud_state = NUD_NOARP;
317 memcpy(neigh->ha, dev->broadcast, dev->addr_len);
318 }
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700319
320 if (dev->header_ops->cache)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 neigh->ops = &arp_hh_ops;
322 else
323 neigh->ops = &arp_generic_ops;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700324
Changli Gaodeffd772010-09-02 03:56:51 +0000325 if (neigh->nud_state & NUD_VALID)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 neigh->output = neigh->ops->connected_output;
327 else
328 neigh->output = neigh->ops->output;
329 }
330 return 0;
331}
332
333static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb)
334{
335 dst_link_failure(skb);
336 kfree_skb(skb);
337}
338
339static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
340{
Al Viroa61ced52006-09-26 21:27:54 -0700341 __be32 saddr = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 u8 *dst_ha = NULL;
343 struct net_device *dev = neigh->dev;
Changli Gaodeffd772010-09-02 03:56:51 +0000344 __be32 target = *(__be32 *)neigh->primary_key;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 int probes = atomic_read(&neigh->probes);
Eric Dumazet4b4194c2010-06-22 07:43:15 +0000346 struct in_device *in_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347
Eric Dumazet4b4194c2010-06-22 07:43:15 +0000348 rcu_read_lock();
349 in_dev = __in_dev_get_rcu(dev);
350 if (!in_dev) {
351 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 return;
Eric Dumazet4b4194c2010-06-22 07:43:15 +0000353 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
355 default:
356 case 0: /* By default announce any local IP */
Changli Gaodeffd772010-09-02 03:56:51 +0000357 if (skb && inet_addr_type(dev_net(dev),
358 ip_hdr(skb)->saddr) == RTN_LOCAL)
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700359 saddr = ip_hdr(skb)->saddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 break;
361 case 1: /* Restrict announcements of saddr in same subnet */
362 if (!skb)
363 break;
Arnaldo Carvalho de Meloeddc9ec2007-04-20 22:47:35 -0700364 saddr = ip_hdr(skb)->saddr;
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +0900365 if (inet_addr_type(dev_net(dev), saddr) == RTN_LOCAL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 /* saddr should be known to target */
367 if (inet_addr_onlink(in_dev, target, saddr))
368 break;
369 }
370 saddr = 0;
371 break;
372 case 2: /* Avoid secondary IPs, get a primary/preferred one */
373 break;
374 }
Eric Dumazet4b4194c2010-06-22 07:43:15 +0000375 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 if (!saddr)
378 saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
379
Changli Gaodeffd772010-09-02 03:56:51 +0000380 probes -= neigh->parms->ucast_probes;
381 if (probes < 0) {
382 if (!(neigh->nud_state & NUD_VALID))
383 printk(KERN_DEBUG
384 "trying to ucast probe in NUD_INVALID\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 dst_ha = neigh->ha;
David S. Miller9ff56602008-02-17 18:39:54 -0800386 read_lock_bh(&neigh->lock);
Changli Gaodeffd772010-09-02 03:56:51 +0000387 } else {
388 probes -= neigh->parms->app_probes;
389 if (probes < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390#ifdef CONFIG_ARPD
Changli Gaodeffd772010-09-02 03:56:51 +0000391 neigh_app_ns(neigh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392#endif
Changli Gaodeffd772010-09-02 03:56:51 +0000393 return;
394 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 }
396
397 arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
398 dst_ha, dev->dev_addr, NULL);
David S. Miller9ff56602008-02-17 18:39:54 -0800399 if (dst_ha)
400 read_unlock_bh(&neigh->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401}
402
Denis V. Lunev9bd85e32008-01-14 23:05:55 -0800403static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404{
405 int scope;
406
407 switch (IN_DEV_ARP_IGNORE(in_dev)) {
408 case 0: /* Reply, the tip is already validated */
409 return 0;
410 case 1: /* Reply only if tip is configured on the incoming interface */
411 sip = 0;
412 scope = RT_SCOPE_HOST;
413 break;
414 case 2: /*
415 * Reply only if tip is configured on the incoming interface
416 * and is in same subnet as sip
417 */
418 scope = RT_SCOPE_HOST;
419 break;
420 case 3: /* Do not reply for scope host addresses */
421 sip = 0;
422 scope = RT_SCOPE_LINK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 break;
424 case 4: /* Reserved */
425 case 5:
426 case 6:
427 case 7:
428 return 0;
429 case 8: /* Do not reply */
430 return 1;
431 default:
432 return 0;
433 }
Denis V. Lunev9bd85e32008-01-14 23:05:55 -0800434 return !inet_confirm_addr(in_dev, sip, tip, scope);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435}
436
Al Viroed9bad02006-09-27 18:36:36 -0700437static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 struct rtable *rt;
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900440 int flag = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 /*unsigned long now; */
Pavel Emelyanovca12a1a2008-07-16 20:28:42 -0700442 struct net *net = dev_net(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443
David S. Miller78fbfd82011-03-12 00:00:52 -0500444 rt = ip_route_output(net, sip, tip, 0, 0);
David S. Millerb23dd4f2011-03-02 14:31:35 -0800445 if (IS_ERR(rt))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 return 1;
Changli Gaod8d1f302010-06-10 23:31:35 -0700447 if (rt->dst.dev != dev) {
Pavel Emelyanovde0744a2008-07-16 20:31:16 -0700448 NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 flag = 1;
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900450 }
451 ip_rt_put(rt);
452 return flag;
453}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454
455/* OBSOLETE FUNCTIONS */
456
457/*
458 * Find an arp mapping in the cache. If not found, post a request.
459 *
460 * It is very UGLY routine: it DOES NOT use skb->dst->neighbour,
461 * even if it exists. It is supposed that skb->dev was mangled
462 * by a virtual device (eql, shaper). Nobody but broken devices
463 * is allowed to use this function, it is scheduled to be removed. --ANK
464 */
465
Changli Gaodeffd772010-09-02 03:56:51 +0000466static int arp_set_predefined(int addr_hint, unsigned char *haddr,
467 __be32 paddr, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468{
469 switch (addr_hint) {
470 case RTN_LOCAL:
471 printk(KERN_DEBUG "ARP: arp called for own IP address\n");
472 memcpy(haddr, dev->dev_addr, dev->addr_len);
473 return 1;
474 case RTN_MULTICAST:
475 arp_mc_map(paddr, haddr, dev, 1);
476 return 1;
477 case RTN_BROADCAST:
478 memcpy(haddr, dev->broadcast, dev->addr_len);
479 return 1;
480 }
481 return 0;
482}
483
484
485int arp_find(unsigned char *haddr, struct sk_buff *skb)
486{
487 struct net_device *dev = skb->dev;
Al Virofd683222006-09-26 22:17:51 -0700488 __be32 paddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 struct neighbour *n;
490
Eric Dumazetadf30902009-06-02 05:19:30 +0000491 if (!skb_dst(skb)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 printk(KERN_DEBUG "arp_find is called with dst==NULL\n");
493 kfree_skb(skb);
494 return 1;
495 }
496
Eric Dumazet511c3f92009-06-02 05:14:27 +0000497 paddr = skb_rtable(skb)->rt_gateway;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
Changli Gaodeffd772010-09-02 03:56:51 +0000499 if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr,
500 paddr, dev))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 return 0;
502
503 n = __neigh_lookup(&arp_tbl, &paddr, dev, 1);
504
505 if (n) {
506 n->used = jiffies;
Eric Dumazet0ed8ddf2010-10-07 10:44:07 +0000507 if (n->nud_state & NUD_VALID || neigh_event_send(n, skb) == 0) {
508 neigh_ha_snapshot(haddr, n, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 neigh_release(n);
510 return 0;
511 }
512 neigh_release(n);
513 } else
514 kfree_skb(skb);
515 return 1;
516}
Eric Dumazet4bc2f182010-07-09 21:22:10 +0000517EXPORT_SYMBOL(arp_find);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
519/* END OF OBSOLETE FUNCTIONS */
520
Eric Dumazet8a533662012-02-09 16:13:19 -0500521struct neighbour *__arp_bind_neighbour(struct dst_entry *dst, __be32 nexthop)
522{
523 struct net_device *dev = dst->dev;
524
525 if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
526 nexthop = 0;
527 return __neigh_lookup_errno(
528#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
529 dev->type == ARPHRD_ATM ?
530 clip_tbl_hook :
531#endif
532 &arp_tbl, &nexthop, dev);
533}
534
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535int arp_bind_neighbour(struct dst_entry *dst)
536{
537 struct net_device *dev = dst->dev;
Eric Dumazet8a533662012-02-09 16:13:19 -0500538 struct neighbour *n = dst_get_neighbour(dst);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
540 if (dev == NULL)
541 return -EINVAL;
542 if (n == NULL) {
Eric Dumazet8a533662012-02-09 16:13:19 -0500543 n = __arp_bind_neighbour(dst, ((struct rtable *)dst)->rt_gateway);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 if (IS_ERR(n))
545 return PTR_ERR(n);
Eric Dumazet8a533662012-02-09 16:13:19 -0500546 dst_set_neighbour(dst, n);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 }
548 return 0;
549}
550
551/*
552 * Check if we can use proxy ARP for this path
553 */
Jesper Dangaard Brouer65324142010-01-05 05:50:47 +0000554static inline int arp_fwd_proxy(struct in_device *in_dev,
555 struct net_device *dev, struct rtable *rt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556{
557 struct in_device *out_dev;
558 int imi, omi = -1;
559
Changli Gaod8d1f302010-06-10 23:31:35 -0700560 if (rt->dst.dev == dev)
Jesper Dangaard Brouer65324142010-01-05 05:50:47 +0000561 return 0;
562
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 if (!IN_DEV_PROXY_ARP(in_dev))
564 return 0;
Changli Gaodeffd772010-09-02 03:56:51 +0000565 imi = IN_DEV_MEDIUM_ID(in_dev);
566 if (imi == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 return 1;
568 if (imi == -1)
569 return 0;
570
571 /* place to check for proxy_arp for routes */
572
Changli Gaod8d1f302010-06-10 23:31:35 -0700573 out_dev = __in_dev_get_rcu(rt->dst.dev);
Eric Dumazetfaa9dcf2010-06-03 04:09:10 +0000574 if (out_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 omi = IN_DEV_MEDIUM_ID(out_dev);
Eric Dumazetfaa9dcf2010-06-03 04:09:10 +0000576
Eric Dumazeta02cec22010-09-22 20:43:57 +0000577 return omi != imi && omi != -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578}
579
580/*
Jesper Dangaard Brouer65324142010-01-05 05:50:47 +0000581 * Check for RFC3069 proxy arp private VLAN (allow to send back to same dev)
582 *
583 * RFC3069 supports proxy arp replies back to the same interface. This
584 * is done to support (ethernet) switch features, like RFC 3069, where
585 * the individual ports are not allowed to communicate with each
586 * other, BUT they are allowed to talk to the upstream router. As
587 * described in RFC 3069, it is possible to allow these hosts to
588 * communicate through the upstream router, by proxy_arp'ing.
589 *
590 * RFC 3069: "VLAN Aggregation for Efficient IP Address Allocation"
591 *
592 * This technology is known by different names:
593 * In RFC 3069 it is called VLAN Aggregation.
594 * Cisco and Allied Telesyn call it Private VLAN.
595 * Hewlett-Packard call it Source-Port filtering or port-isolation.
596 * Ericsson call it MAC-Forced Forwarding (RFC Draft).
597 *
598 */
599static inline int arp_fwd_pvlan(struct in_device *in_dev,
600 struct net_device *dev, struct rtable *rt,
601 __be32 sip, __be32 tip)
602{
603 /* Private VLAN is only concerned about the same ethernet segment */
Changli Gaod8d1f302010-06-10 23:31:35 -0700604 if (rt->dst.dev != dev)
Jesper Dangaard Brouer65324142010-01-05 05:50:47 +0000605 return 0;
606
607 /* Don't reply on self probes (often done by windowz boxes)*/
608 if (sip == tip)
609 return 0;
610
611 if (IN_DEV_PROXY_ARP_PVLAN(in_dev))
612 return 1;
613 else
614 return 0;
615}
616
617/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 * Interface to link layer: send routine and receive handler.
619 */
620
621/*
622 * Create an arp packet. If (dest_hw == NULL), we create a broadcast
623 * message.
624 */
Al Viroed9bad02006-09-27 18:36:36 -0700625struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
626 struct net_device *dev, __be32 src_ip,
Jan Engelhardtabfdf1c2008-01-31 03:59:24 -0800627 const unsigned char *dest_hw,
628 const unsigned char *src_hw,
629 const unsigned char *target_hw)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630{
631 struct sk_buff *skb;
632 struct arphdr *arp;
633 unsigned char *arp_ptr;
634
635 /*
636 * Allocate a buffer
637 */
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900638
Johannes Bergf5184d22008-05-12 20:48:31 -0700639 skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 if (skb == NULL)
641 return NULL;
642
643 skb_reserve(skb, LL_RESERVED_SPACE(dev));
Arnaldo Carvalho de Meloc1d2bbe2007-04-10 20:45:18 -0700644 skb_reset_network_header(skb);
Pavel Emelyanov988b7052008-03-03 12:20:57 -0800645 arp = (struct arphdr *) skb_put(skb, arp_hdr_len(dev));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 skb->dev = dev;
647 skb->protocol = htons(ETH_P_ARP);
648 if (src_hw == NULL)
649 src_hw = dev->dev_addr;
650 if (dest_hw == NULL)
651 dest_hw = dev->broadcast;
652
653 /*
654 * Fill the device header for the ARP frame
655 */
Stephen Hemminger0c4e8582007-10-09 01:36:32 -0700656 if (dev_hard_header(skb, dev, ptype, dest_hw, src_hw, skb->len) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 goto out;
658
659 /*
660 * Fill out the arp protocol part.
661 *
662 * The arp hardware type should match the device type, except for FDDI,
663 * which (according to RFC 1390) should always equal 1 (Ethernet).
664 */
665 /*
666 * Exceptions everywhere. AX.25 uses the AX.25 PID value not the
667 * DIX code for the protocol. Make these device structure fields.
668 */
669 switch (dev->type) {
670 default:
671 arp->ar_hrd = htons(dev->type);
672 arp->ar_pro = htons(ETH_P_IP);
673 break;
674
675#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
676 case ARPHRD_AX25:
677 arp->ar_hrd = htons(ARPHRD_AX25);
678 arp->ar_pro = htons(AX25_P_IP);
679 break;
680
681#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
682 case ARPHRD_NETROM:
683 arp->ar_hrd = htons(ARPHRD_NETROM);
684 arp->ar_pro = htons(AX25_P_IP);
685 break;
686#endif
687#endif
688
David S. Millerf0ecde12010-05-10 04:59:07 -0700689#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 case ARPHRD_FDDI:
691 arp->ar_hrd = htons(ARPHRD_ETHER);
692 arp->ar_pro = htons(ETH_P_IP);
693 break;
694#endif
David S. Millerf0ecde12010-05-10 04:59:07 -0700695#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 case ARPHRD_IEEE802_TR:
697 arp->ar_hrd = htons(ARPHRD_IEEE802);
698 arp->ar_pro = htons(ETH_P_IP);
699 break;
700#endif
701 }
702
703 arp->ar_hln = dev->addr_len;
704 arp->ar_pln = 4;
705 arp->ar_op = htons(type);
706
Changli Gaodeffd772010-09-02 03:56:51 +0000707 arp_ptr = (unsigned char *)(arp + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708
709 memcpy(arp_ptr, src_hw, dev->addr_len);
Jianjun Kongf4cca7f2008-11-03 02:48:14 -0800710 arp_ptr += dev->addr_len;
711 memcpy(arp_ptr, &src_ip, 4);
712 arp_ptr += 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 if (target_hw != NULL)
714 memcpy(arp_ptr, target_hw, dev->addr_len);
715 else
716 memset(arp_ptr, 0, dev->addr_len);
Jianjun Kongf4cca7f2008-11-03 02:48:14 -0800717 arp_ptr += dev->addr_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 memcpy(arp_ptr, &dest_ip, 4);
719
720 return skb;
721
722out:
723 kfree_skb(skb);
724 return NULL;
725}
Eric Dumazet4bc2f182010-07-09 21:22:10 +0000726EXPORT_SYMBOL(arp_create);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727
728/*
729 * Send an arp packet.
730 */
731void arp_xmit(struct sk_buff *skb)
732{
733 /* Send it off, maybe filter it using firewalling first. */
Jan Engelhardtfdc93142008-10-20 03:34:51 -0700734 NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735}
Eric Dumazet4bc2f182010-07-09 21:22:10 +0000736EXPORT_SYMBOL(arp_xmit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737
738/*
739 * Create and send an arp packet.
740 */
Al Viroed9bad02006-09-27 18:36:36 -0700741void arp_send(int type, int ptype, __be32 dest_ip,
742 struct net_device *dev, __be32 src_ip,
Jan Engelhardtabfdf1c2008-01-31 03:59:24 -0800743 const unsigned char *dest_hw, const unsigned char *src_hw,
744 const unsigned char *target_hw)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745{
746 struct sk_buff *skb;
747
748 /*
749 * No arp on this interface.
750 */
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900751
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 if (dev->flags&IFF_NOARP)
753 return;
754
755 skb = arp_create(type, ptype, dest_ip, dev, src_ip,
756 dest_hw, src_hw, target_hw);
Changli Gaodeffd772010-09-02 03:56:51 +0000757 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
760 arp_xmit(skb);
761}
Eric Dumazet4bc2f182010-07-09 21:22:10 +0000762EXPORT_SYMBOL(arp_send);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764/*
765 * Process an arp request.
766 */
767
768static int arp_process(struct sk_buff *skb)
769{
770 struct net_device *dev = skb->dev;
Eric Dumazetfaa9dcf2010-06-03 04:09:10 +0000771 struct in_device *in_dev = __in_dev_get_rcu(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 struct arphdr *arp;
773 unsigned char *arp_ptr;
774 struct rtable *rt;
Mark Rydene0260fe2007-12-19 23:38:11 -0800775 unsigned char *sha;
Al Viro9e12bb22006-09-26 21:25:20 -0700776 __be32 sip, tip;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 u16 dev_type = dev->type;
778 int addr_type;
779 struct neighbour *n;
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +0900780 struct net *net = dev_net(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781
782 /* arp_rcv below verifies the ARP header and verifies the device
783 * is ARP'able.
784 */
785
786 if (in_dev == NULL)
787 goto out;
788
Arnaldo Carvalho de Melod0a92be2007-03-12 20:56:31 -0300789 arp = arp_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
791 switch (dev_type) {
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900792 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 if (arp->ar_pro != htons(ETH_P_IP) ||
794 htons(dev_type) != arp->ar_hrd)
795 goto out;
796 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 case ARPHRD_ETHER:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 case ARPHRD_IEEE802_TR:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 case ARPHRD_FDDI:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 case ARPHRD_IEEE802:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 /*
802 * ETHERNET, Token Ring and Fibre Channel (which are IEEE 802
803 * devices, according to RFC 2625) devices will accept ARP
804 * hardware types of either 1 (Ethernet) or 6 (IEEE 802.2).
805 * This is the case also of FDDI, where the RFC 1390 says that
806 * FDDI devices should accept ARP hardware of (1) Ethernet,
807 * however, to be more robust, we'll accept both 1 (Ethernet)
808 * or 6 (IEEE 802.2)
809 */
810 if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
811 arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
812 arp->ar_pro != htons(ETH_P_IP))
813 goto out;
814 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 case ARPHRD_AX25:
816 if (arp->ar_pro != htons(AX25_P_IP) ||
817 arp->ar_hrd != htons(ARPHRD_AX25))
818 goto out;
819 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 case ARPHRD_NETROM:
821 if (arp->ar_pro != htons(AX25_P_IP) ||
822 arp->ar_hrd != htons(ARPHRD_NETROM))
823 goto out;
824 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 }
826
827 /* Understand only these message types */
828
829 if (arp->ar_op != htons(ARPOP_REPLY) &&
830 arp->ar_op != htons(ARPOP_REQUEST))
831 goto out;
832
833/*
834 * Extract fields
835 */
Changli Gaodeffd772010-09-02 03:56:51 +0000836 arp_ptr = (unsigned char *)(arp + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 sha = arp_ptr;
838 arp_ptr += dev->addr_len;
839 memcpy(&sip, arp_ptr, 4);
840 arp_ptr += 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 arp_ptr += dev->addr_len;
842 memcpy(&tip, arp_ptr, 4);
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900843/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 * Check for bad requests for 127.x.x.x and requests for multicast
845 * addresses. If this is one such, delete it.
846 */
Joe Perchesf97c1e02007-12-16 13:45:43 -0800847 if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 goto out;
849
850/*
851 * Special case: We must set Frame Relay source Q.922 address
852 */
853 if (dev_type == ARPHRD_DLCI)
854 sha = dev->broadcast;
855
856/*
857 * Process entry. The idea here is we want to send a reply if it is a
858 * request for us or if it is a request for someone else that we hold
859 * a proxy for. We want to add an entry to our cache if it is a reply
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900860 * to us or if it is a request for our address.
861 * (The assumption for this last is that if someone is requesting our
862 * address, they are probably intending to talk to us, so it saves time
863 * if we cache their address. Their address is also probably not in
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 * our cache, since ours is not in their cache.)
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900865 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 * Putting this another way, we only care about replies if they are to
867 * us, in which case we add them to the cache. For requests, we care
868 * about those for us and those for our proxies. We reply to both,
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900869 * and in the case of requests for us we add the requester to the arp
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 * cache.
871 */
872
Eric W. Biedermanf8a68e72009-06-30 16:27:17 +0000873 /* Special case: IPv4 duplicate address detection packet (RFC2131) */
874 if (sip == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 if (arp->ar_op == htons(ARPOP_REQUEST) &&
Denis V. Lunev49e8a272008-03-24 15:28:12 -0700876 inet_addr_type(net, tip) == RTN_LOCAL &&
Denis V. Lunev9bd85e32008-01-14 23:05:55 -0800877 !arp_ignore(in_dev, sip, tip))
Jonas Danielssonb4a98112007-11-20 17:38:16 -0800878 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
879 dev->dev_addr, sha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 goto out;
881 }
882
883 if (arp->ar_op == htons(ARPOP_REQUEST) &&
Eric Dumazet4a944452010-05-10 11:33:06 +0000884 ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
Eric Dumazet511c3f92009-06-02 05:14:27 +0000886 rt = skb_rtable(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 addr_type = rt->rt_type;
888
889 if (addr_type == RTN_LOCAL) {
Changli Gaodeffd772010-09-02 03:56:51 +0000890 int dont_send;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
Changli Gaodeffd772010-09-02 03:56:51 +0000892 dont_send = arp_ignore(in_dev, sip, tip);
Ben Greear8164f1b2008-11-16 19:19:38 -0800893 if (!dont_send && IN_DEV_ARPFILTER(in_dev))
Changli Gaoae9c4162010-12-01 20:07:31 +0000894 dont_send = arp_filter(sip, tip, dev);
Ben Greear8164f1b2008-11-16 19:19:38 -0800895 if (!dont_send) {
896 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
897 if (n) {
Changli Gaodeffd772010-09-02 03:56:51 +0000898 arp_send(ARPOP_REPLY, ETH_P_ARP, sip,
899 dev, tip, sha, dev->dev_addr,
900 sha);
Ben Greear8164f1b2008-11-16 19:19:38 -0800901 neigh_release(n);
902 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 }
904 goto out;
905 } else if (IN_DEV_FORWARD(in_dev)) {
Jesper Dangaard Brouer65324142010-01-05 05:50:47 +0000906 if (addr_type == RTN_UNICAST &&
907 (arp_fwd_proxy(in_dev, dev, rt) ||
908 arp_fwd_pvlan(in_dev, dev, rt, sip, tip) ||
Changli Gaodeffd772010-09-02 03:56:51 +0000909 pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
911 if (n)
912 neigh_release(n);
913
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +0900914 if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 skb->pkt_type == PACKET_HOST ||
916 in_dev->arp_parms->proxy_delay == 0) {
Changli Gaodeffd772010-09-02 03:56:51 +0000917 arp_send(ARPOP_REPLY, ETH_P_ARP, sip,
918 dev, tip, sha, dev->dev_addr,
919 sha);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 } else {
Changli Gaodeffd772010-09-02 03:56:51 +0000921 pneigh_enqueue(&arp_tbl,
922 in_dev->arp_parms, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 return 0;
924 }
925 goto out;
926 }
927 }
928 }
929
930 /* Update our ARP tables */
931
932 n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
933
YOSHIFUJI Hideakic346dca2008-03-25 21:47:49 +0900934 if (IPV4_DEVCONF_ALL(dev_net(dev), ARP_ACCEPT)) {
Neil Hormanabd596a2006-03-20 22:39:47 -0800935 /* Unsolicited ARP is not accepted by default.
936 It is possible, that this option should be enabled for some
937 devices (strip is candidate)
938 */
939 if (n == NULL &&
Octavian Purdila6d955182010-01-18 12:58:44 +0000940 (arp->ar_op == htons(ARPOP_REPLY) ||
941 (arp->ar_op == htons(ARPOP_REQUEST) && tip == sip)) &&
Denis V. Lunev49e8a272008-03-24 15:28:12 -0700942 inet_addr_type(net, sip) == RTN_UNICAST)
Jean Delvare1b1ac752007-07-14 20:51:44 -0700943 n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
Neil Hormanabd596a2006-03-20 22:39:47 -0800944 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
946 if (n) {
947 int state = NUD_REACHABLE;
948 int override;
949
950 /* If several different ARP replies follows back-to-back,
951 use the FIRST one. It is possible, if several proxy
952 agents are active. Taking the first reply prevents
953 arp trashing and chooses the fastest router.
954 */
955 override = time_after(jiffies, n->updated + n->parms->locktime);
956
957 /* Broadcast replies and request packets
958 do not assert neighbour reachability.
959 */
960 if (arp->ar_op != htons(ARPOP_REPLY) ||
961 skb->pkt_type != PACKET_HOST)
962 state = NUD_STALE;
Changli Gaodeffd772010-09-02 03:56:51 +0000963 neigh_update(n, sha, state,
964 override ? NEIGH_UPDATE_F_OVERRIDE : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 neigh_release(n);
966 }
967
968out:
Neil Hormanead2ceb2009-03-11 09:49:55 +0000969 consume_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 return 0;
971}
972
Herbert Xu444fc8f2005-10-03 14:18:10 -0700973static void parp_redo(struct sk_buff *skb)
974{
975 arp_process(skb);
976}
977
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978
979/*
980 * Receive an arp request from the device layer.
981 */
982
Adrian Bunk6c97e722006-04-12 13:57:59 -0700983static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
984 struct packet_type *pt, struct net_device *orig_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985{
986 struct arphdr *arp;
987
988 /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
Pavel Emelyanov988b7052008-03-03 12:20:57 -0800989 if (!pskb_may_pull(skb, arp_hdr_len(dev)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 goto freeskb;
991
Arnaldo Carvalho de Melod0a92be2007-03-12 20:56:31 -0300992 arp = arp_hdr(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 if (arp->ar_hln != dev->addr_len ||
994 dev->flags & IFF_NOARP ||
995 skb->pkt_type == PACKET_OTHERHOST ||
996 skb->pkt_type == PACKET_LOOPBACK ||
997 arp->ar_pln != 4)
998 goto freeskb;
999
Changli Gaodeffd772010-09-02 03:56:51 +00001000 skb = skb_share_check(skb, GFP_ATOMIC);
1001 if (skb == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 goto out_of_mem;
1003
Patrick McHardya61bbcf2005-08-14 17:24:31 -07001004 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
1005
Jan Engelhardtfdc93142008-10-20 03:34:51 -07001006 return NF_HOOK(NFPROTO_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
1008freeskb:
1009 kfree_skb(skb);
1010out_of_mem:
1011 return 0;
1012}
1013
1014/*
1015 * User level interface (ioctl)
1016 */
1017
1018/*
1019 * Set (create) an ARP cache entry.
1020 */
1021
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001022static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on)
Pavel Emelyanovf8b33fd2007-12-05 21:20:50 -08001023{
1024 if (dev == NULL) {
Pavel Emelyanov586f1212007-12-16 13:32:48 -08001025 IPV4_DEVCONF_ALL(net, PROXY_ARP) = on;
Pavel Emelyanovf8b33fd2007-12-05 21:20:50 -08001026 return 0;
1027 }
Eric Dumazetc5066532011-01-24 13:16:16 -08001028 if (__in_dev_get_rtnl(dev)) {
1029 IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on);
Pavel Emelyanovf8b33fd2007-12-05 21:20:50 -08001030 return 0;
1031 }
1032 return -ENXIO;
1033}
1034
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001035static int arp_req_set_public(struct net *net, struct arpreq *r,
1036 struct net_device *dev)
Pavel Emelyanov43dc1702007-12-05 21:19:44 -08001037{
1038 __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
1039 __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
1040
1041 if (mask && mask != htonl(0xFFFFFFFF))
1042 return -EINVAL;
1043 if (!dev && (r->arp_flags & ATF_COM)) {
Eric Dumazet941666c2010-12-05 01:23:53 +00001044 dev = dev_getbyhwaddr_rcu(net, r->arp_ha.sa_family,
Changli Gaodeffd772010-09-02 03:56:51 +00001045 r->arp_ha.sa_data);
Pavel Emelyanov43dc1702007-12-05 21:19:44 -08001046 if (!dev)
1047 return -ENODEV;
1048 }
1049 if (mask) {
Denis V. Lunev2db82b52008-01-14 22:58:55 -08001050 if (pneigh_lookup(&arp_tbl, net, &ip, dev, 1) == NULL)
Pavel Emelyanov43dc1702007-12-05 21:19:44 -08001051 return -ENOBUFS;
1052 return 0;
1053 }
Pavel Emelyanovf8b33fd2007-12-05 21:20:50 -08001054
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001055 return arp_req_set_proxy(net, dev, 1);
Pavel Emelyanov43dc1702007-12-05 21:19:44 -08001056}
1057
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001058static int arp_req_set(struct net *net, struct arpreq *r,
Changli Gaodeffd772010-09-02 03:56:51 +00001059 struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060{
Pavel Emelyanov43dc1702007-12-05 21:19:44 -08001061 __be32 ip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 struct neighbour *neigh;
1063 int err;
1064
Pavel Emelyanov43dc1702007-12-05 21:19:44 -08001065 if (r->arp_flags & ATF_PUBL)
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001066 return arp_req_set_public(net, r, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067
Pavel Emelyanov43dc1702007-12-05 21:19:44 -08001068 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 if (r->arp_flags & ATF_PERM)
1070 r->arp_flags |= ATF_COM;
1071 if (dev == NULL) {
David S. Miller78fbfd82011-03-12 00:00:52 -05001072 struct rtable *rt = ip_route_output(net, ip, 0, RTO_ONLINK, 0);
David S. Millerb23dd4f2011-03-02 14:31:35 -08001073
1074 if (IS_ERR(rt))
1075 return PTR_ERR(rt);
Changli Gaod8d1f302010-06-10 23:31:35 -07001076 dev = rt->dst.dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 ip_rt_put(rt);
1078 if (!dev)
1079 return -EINVAL;
1080 }
1081 switch (dev->type) {
David S. Millerf0ecde12010-05-10 04:59:07 -07001082#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 case ARPHRD_FDDI:
1084 /*
1085 * According to RFC 1390, FDDI devices should accept ARP
1086 * hardware types of 1 (Ethernet). However, to be more
1087 * robust, we'll accept hardware types of either 1 (Ethernet)
1088 * or 6 (IEEE 802.2).
1089 */
1090 if (r->arp_ha.sa_family != ARPHRD_FDDI &&
1091 r->arp_ha.sa_family != ARPHRD_ETHER &&
1092 r->arp_ha.sa_family != ARPHRD_IEEE802)
1093 return -EINVAL;
1094 break;
1095#endif
1096 default:
1097 if (r->arp_ha.sa_family != dev->type)
1098 return -EINVAL;
1099 break;
1100 }
1101
1102 neigh = __neigh_lookup_errno(&arp_tbl, &ip, dev);
1103 err = PTR_ERR(neigh);
1104 if (!IS_ERR(neigh)) {
1105 unsigned state = NUD_STALE;
1106 if (r->arp_flags & ATF_PERM)
1107 state = NUD_PERMANENT;
Changli Gaodeffd772010-09-02 03:56:51 +00001108 err = neigh_update(neigh, (r->arp_flags & ATF_COM) ?
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +09001109 r->arp_ha.sa_data : NULL, state,
Changli Gaodeffd772010-09-02 03:56:51 +00001110 NEIGH_UPDATE_F_OVERRIDE |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 NEIGH_UPDATE_F_ADMIN);
1112 neigh_release(neigh);
1113 }
1114 return err;
1115}
1116
1117static unsigned arp_state_to_flags(struct neighbour *neigh)
1118{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 if (neigh->nud_state&NUD_PERMANENT)
Changli Gaodeffd772010-09-02 03:56:51 +00001120 return ATF_PERM | ATF_COM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 else if (neigh->nud_state&NUD_VALID)
Changli Gaodeffd772010-09-02 03:56:51 +00001122 return ATF_COM;
1123 else
1124 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125}
1126
1127/*
1128 * Get an ARP cache entry.
1129 */
1130
1131static int arp_req_get(struct arpreq *r, struct net_device *dev)
1132{
Al Viroed9bad02006-09-27 18:36:36 -07001133 __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 struct neighbour *neigh;
1135 int err = -ENXIO;
1136
1137 neigh = neigh_lookup(&arp_tbl, &ip, dev);
1138 if (neigh) {
1139 read_lock_bh(&neigh->lock);
1140 memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
1141 r->arp_flags = arp_state_to_flags(neigh);
1142 read_unlock_bh(&neigh->lock);
1143 r->arp_ha.sa_family = dev->type;
1144 strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
1145 neigh_release(neigh);
1146 err = 0;
1147 }
1148 return err;
1149}
1150
Maxim Levitsky545ecdc2011-01-08 13:57:12 +00001151int arp_invalidate(struct net_device *dev, __be32 ip)
1152{
1153 struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
1154 int err = -ENXIO;
1155
1156 if (neigh) {
1157 if (neigh->nud_state & ~NUD_NOARP)
1158 err = neigh_update(neigh, NULL, NUD_FAILED,
1159 NEIGH_UPDATE_F_OVERRIDE|
1160 NEIGH_UPDATE_F_ADMIN);
1161 neigh_release(neigh);
1162 }
1163
1164 return err;
1165}
1166EXPORT_SYMBOL(arp_invalidate);
1167
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001168static int arp_req_delete_public(struct net *net, struct arpreq *r,
1169 struct net_device *dev)
Pavel Emelyanov46479b42007-12-05 21:20:18 -08001170{
1171 __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
1172 __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
1173
1174 if (mask == htonl(0xFFFFFFFF))
Denis V. Lunev2db82b52008-01-14 22:58:55 -08001175 return pneigh_delete(&arp_tbl, net, &ip, dev);
Pavel Emelyanov46479b42007-12-05 21:20:18 -08001176
Pavel Emelyanovf8b33fd2007-12-05 21:20:50 -08001177 if (mask)
1178 return -EINVAL;
1179
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001180 return arp_req_set_proxy(net, dev, 0);
Pavel Emelyanov46479b42007-12-05 21:20:18 -08001181}
1182
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001183static int arp_req_delete(struct net *net, struct arpreq *r,
Changli Gaodeffd772010-09-02 03:56:51 +00001184 struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185{
Pavel Emelyanov46479b42007-12-05 21:20:18 -08001186 __be32 ip;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187
Pavel Emelyanov46479b42007-12-05 21:20:18 -08001188 if (r->arp_flags & ATF_PUBL)
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001189 return arp_req_delete_public(net, r, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
Pavel Emelyanov46479b42007-12-05 21:20:18 -08001191 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 if (dev == NULL) {
David S. Miller78fbfd82011-03-12 00:00:52 -05001193 struct rtable *rt = ip_route_output(net, ip, 0, RTO_ONLINK, 0);
David S. Millerb23dd4f2011-03-02 14:31:35 -08001194 if (IS_ERR(rt))
1195 return PTR_ERR(rt);
Changli Gaod8d1f302010-06-10 23:31:35 -07001196 dev = rt->dst.dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 ip_rt_put(rt);
1198 if (!dev)
1199 return -EINVAL;
1200 }
Maxim Levitsky545ecdc2011-01-08 13:57:12 +00001201 return arp_invalidate(dev, ip);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202}
1203
1204/*
1205 * Handle an ARP layer I/O control request.
1206 */
1207
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001208int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209{
1210 int err;
1211 struct arpreq r;
1212 struct net_device *dev = NULL;
1213
1214 switch (cmd) {
Changli Gaodeffd772010-09-02 03:56:51 +00001215 case SIOCDARP:
1216 case SIOCSARP:
1217 if (!capable(CAP_NET_ADMIN))
1218 return -EPERM;
1219 case SIOCGARP:
1220 err = copy_from_user(&r, arg, sizeof(struct arpreq));
1221 if (err)
1222 return -EFAULT;
1223 break;
1224 default:
1225 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 }
1227
1228 if (r.arp_pa.sa_family != AF_INET)
1229 return -EPFNOSUPPORT;
1230
1231 if (!(r.arp_flags & ATF_PUBL) &&
Changli Gaodeffd772010-09-02 03:56:51 +00001232 (r.arp_flags & (ATF_NETMASK | ATF_DONTPUB)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 return -EINVAL;
1234 if (!(r.arp_flags & ATF_NETMASK))
1235 ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr =
1236 htonl(0xFFFFFFFFUL);
Eric Dumazetc5066532011-01-24 13:16:16 -08001237 rtnl_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 if (r.arp_dev[0]) {
1239 err = -ENODEV;
Eric Dumazetc5066532011-01-24 13:16:16 -08001240 dev = __dev_get_by_name(net, r.arp_dev);
Changli Gaodeffd772010-09-02 03:56:51 +00001241 if (dev == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 goto out;
1243
1244 /* Mmmm... It is wrong... ARPHRD_NETROM==0 */
1245 if (!r.arp_ha.sa_family)
1246 r.arp_ha.sa_family = dev->type;
1247 err = -EINVAL;
1248 if ((r.arp_flags & ATF_COM) && r.arp_ha.sa_family != dev->type)
1249 goto out;
1250 } else if (cmd == SIOCGARP) {
1251 err = -ENODEV;
1252 goto out;
1253 }
1254
Stephen Hemminger132adf52007-03-08 20:44:43 -08001255 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 case SIOCDARP:
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001257 err = arp_req_delete(net, &r, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 break;
1259 case SIOCSARP:
Pavel Emelyanov32e569b2007-12-16 13:30:39 -08001260 err = arp_req_set(net, &r, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 break;
1262 case SIOCGARP:
1263 err = arp_req_get(&r, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 break;
1265 }
1266out:
Eric Dumazetc5066532011-01-24 13:16:16 -08001267 rtnl_unlock();
Eric Dumazet941666c2010-12-05 01:23:53 +00001268 if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r)))
1269 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 return err;
1271}
1272
Changli Gaodeffd772010-09-02 03:56:51 +00001273static int arp_netdev_event(struct notifier_block *this, unsigned long event,
1274 void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275{
1276 struct net_device *dev = ptr;
1277
1278 switch (event) {
1279 case NETDEV_CHANGEADDR:
1280 neigh_changeaddr(&arp_tbl, dev);
Denis V. Lunev76e6ebf2008-07-05 19:00:44 -07001281 rt_cache_flush(dev_net(dev), 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 break;
1283 default:
1284 break;
1285 }
1286
1287 return NOTIFY_DONE;
1288}
1289
1290static struct notifier_block arp_netdev_notifier = {
1291 .notifier_call = arp_netdev_event,
1292};
1293
1294/* Note, that it is not on notifier chain.
1295 It is necessary, that this routine was called after route cache will be
1296 flushed.
1297 */
1298void arp_ifdown(struct net_device *dev)
1299{
1300 neigh_ifdown(&arp_tbl, dev);
1301}
1302
1303
1304/*
1305 * Called once on startup.
1306 */
1307
Stephen Hemminger7546dd92009-03-09 08:18:29 +00001308static struct packet_type arp_packet_type __read_mostly = {
Harvey Harrison09640e62009-02-01 00:45:17 -08001309 .type = cpu_to_be16(ETH_P_ARP),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310 .func = arp_rcv,
1311};
1312
1313static int arp_proc_init(void);
1314
1315void __init arp_init(void)
1316{
1317 neigh_table_init(&arp_tbl);
1318
1319 dev_add_pack(&arp_packet_type);
1320 arp_proc_init();
1321#ifdef CONFIG_SYSCTL
Eric W. Biederman54716e32010-02-14 03:27:03 +00001322 neigh_sysctl_register(NULL, &arp_tbl.parms, "ipv4", NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323#endif
1324 register_netdevice_notifier(&arp_netdev_notifier);
1325}
1326
1327#ifdef CONFIG_PROC_FS
1328#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
1329
1330/* ------------------------------------------------------------------------ */
1331/*
1332 * ax25 -> ASCII conversion
1333 */
1334static char *ax2asc2(ax25_address *a, char *buf)
1335{
1336 char c, *s;
1337 int n;
1338
1339 for (n = 0, s = buf; n < 6; n++) {
1340 c = (a->ax25_call[n] >> 1) & 0x7F;
1341
Changli Gaodeffd772010-09-02 03:56:51 +00001342 if (c != ' ')
1343 *s++ = c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 }
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +09001345
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 *s++ = '-';
Changli Gaodeffd772010-09-02 03:56:51 +00001347 n = (a->ax25_call[6] >> 1) & 0x0F;
1348 if (n > 9) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 *s++ = '1';
1350 n -= 10;
1351 }
YOSHIFUJI Hideakie905a9e2007-02-09 23:24:47 +09001352
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 *s++ = n + '0';
1354 *s++ = '\0';
1355
1356 if (*buf == '\0' || *buf == '-')
Changli Gaodeffd772010-09-02 03:56:51 +00001357 return "*";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358
1359 return buf;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360}
1361#endif /* CONFIG_AX25 */
1362
1363#define HBUFFERLEN 30
1364
1365static void arp_format_neigh_entry(struct seq_file *seq,
1366 struct neighbour *n)
1367{
1368 char hbuffer[HBUFFERLEN];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 int k, j;
1370 char tbuf[16];
1371 struct net_device *dev = n->dev;
1372 int hatype = dev->type;
1373
1374 read_lock(&n->lock);
1375 /* Convert hardware address to XX:XX:XX:XX ... form. */
1376#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
1377 if (hatype == ARPHRD_AX25 || hatype == ARPHRD_NETROM)
1378 ax2asc2((ax25_address *)n->ha, hbuffer);
1379 else {
1380#endif
1381 for (k = 0, j = 0; k < HBUFFERLEN - 3 && j < dev->addr_len; j++) {
Denis Cheng51f82a22008-05-21 17:34:32 -07001382 hbuffer[k++] = hex_asc_hi(n->ha[j]);
1383 hbuffer[k++] = hex_asc_lo(n->ha[j]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 hbuffer[k++] = ':';
1385 }
roel kluina3e8ee62009-07-29 23:46:59 +00001386 if (k != 0)
1387 --k;
1388 hbuffer[k] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
1390 }
1391#endif
Harvey Harrison673d57e2008-10-31 00:53:57 -07001392 sprintf(tbuf, "%pI4", n->primary_key);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 seq_printf(seq, "%-16s 0x%-10x0x%-10x%s * %s\n",
1394 tbuf, hatype, arp_state_to_flags(n), hbuffer, dev->name);
1395 read_unlock(&n->lock);
1396}
1397
1398static void arp_format_pneigh_entry(struct seq_file *seq,
1399 struct pneigh_entry *n)
1400{
1401 struct net_device *dev = n->dev;
1402 int hatype = dev ? dev->type : 0;
1403 char tbuf[16];
1404
Harvey Harrison673d57e2008-10-31 00:53:57 -07001405 sprintf(tbuf, "%pI4", n->key);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 seq_printf(seq, "%-16s 0x%-10x0x%-10x%s * %s\n",
1407 tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
1408 dev ? dev->name : "*");
1409}
1410
1411static int arp_seq_show(struct seq_file *seq, void *v)
1412{
1413 if (v == SEQ_START_TOKEN) {
1414 seq_puts(seq, "IP address HW type Flags "
1415 "HW address Mask Device\n");
1416 } else {
1417 struct neigh_seq_state *state = seq->private;
1418
1419 if (state->flags & NEIGH_SEQ_IS_PNEIGH)
1420 arp_format_pneigh_entry(seq, v);
1421 else
1422 arp_format_neigh_entry(seq, v);
1423 }
1424
1425 return 0;
1426}
1427
1428static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
1429{
1430 /* Don't want to confuse "arp -a" w/ magic entries,
1431 * so we tell the generic iterator to skip NUD_NOARP.
1432 */
1433 return neigh_seq_start(seq, pos, &arp_tbl, NEIGH_SEQ_SKIP_NOARP);
1434}
1435
1436/* ------------------------------------------------------------------------ */
1437
Stephen Hemmingerf6908082007-03-12 14:34:29 -07001438static const struct seq_operations arp_seq_ops = {
Changli Gaodeffd772010-09-02 03:56:51 +00001439 .start = arp_seq_start,
1440 .next = neigh_seq_next,
1441 .stop = neigh_seq_stop,
1442 .show = arp_seq_show,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443};
1444
1445static int arp_seq_open(struct inode *inode, struct file *file)
1446{
Eric W. Biederman426b5302008-01-24 00:13:18 -08001447 return seq_open_net(inode, file, &arp_seq_ops,
1448 sizeof(struct neigh_seq_state));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449}
1450
Arjan van de Ven9a321442007-02-12 00:55:35 -08001451static const struct file_operations arp_seq_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 .owner = THIS_MODULE,
1453 .open = arp_seq_open,
1454 .read = seq_read,
1455 .llseek = seq_lseek,
Eric W. Biederman426b5302008-01-24 00:13:18 -08001456 .release = seq_release_net,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457};
1458
Denis V. Lunevffc31d32008-03-24 15:28:43 -07001459
1460static int __net_init arp_net_init(struct net *net)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461{
Denis V. Lunevffc31d32008-03-24 15:28:43 -07001462 if (!proc_net_fops_create(net, "arp", S_IRUGO, &arp_seq_fops))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 return -ENOMEM;
1464 return 0;
1465}
1466
Denis V. Lunevffc31d32008-03-24 15:28:43 -07001467static void __net_exit arp_net_exit(struct net *net)
1468{
1469 proc_net_remove(net, "arp");
1470}
1471
1472static struct pernet_operations arp_net_ops = {
1473 .init = arp_net_init,
1474 .exit = arp_net_exit,
1475};
1476
1477static int __init arp_proc_init(void)
1478{
1479 return register_pernet_subsys(&arp_net_ops);
1480}
1481
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482#else /* CONFIG_PROC_FS */
1483
1484static int __init arp_proc_init(void)
1485{
1486 return 0;
1487}
1488
1489#endif /* CONFIG_PROC_FS */