aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/arp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/arp.c')
-rw-r--r--net/ipv4/arp.c114
1 files changed, 77 insertions, 37 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index c95cd93acf29..96c1955b3e2f 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -70,6 +70,7 @@
70 * bonding can change the skb before 70 * bonding can change the skb before
71 * sending (e.g. insert 8021q tag). 71 * sending (e.g. insert 8021q tag).
72 * Harald Welte : convert to make use of jenkins hash 72 * Harald Welte : convert to make use of jenkins hash
73 * Jesper D. Brouer: Proxy ARP PVLAN RFC 3069 support.
73 */ 74 */
74 75
75#include <linux/module.h> 76#include <linux/module.h>
@@ -97,6 +98,7 @@
97#include <linux/net.h> 98#include <linux/net.h>
98#include <linux/rcupdate.h> 99#include <linux/rcupdate.h>
99#include <linux/jhash.h> 100#include <linux/jhash.h>
101#include <linux/slab.h>
100#ifdef CONFIG_SYSCTL 102#ifdef CONFIG_SYSCTL
101#include <linux/sysctl.h> 103#include <linux/sysctl.h>
102#endif 104#endif
@@ -114,6 +116,7 @@
114#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) 116#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
115#include <net/atmclip.h> 117#include <net/atmclip.h>
116struct neigh_table *clip_tbl_hook; 118struct neigh_table *clip_tbl_hook;
119EXPORT_SYMBOL(clip_tbl_hook);
117#endif 120#endif
118 121
119#include <asm/system.h> 122#include <asm/system.h>
@@ -167,6 +170,7 @@ const struct neigh_ops arp_broken_ops = {
167 .hh_output = dev_queue_xmit, 170 .hh_output = dev_queue_xmit,
168 .queue_xmit = dev_queue_xmit, 171 .queue_xmit = dev_queue_xmit,
169}; 172};
173EXPORT_SYMBOL(arp_broken_ops);
170 174
171struct neigh_table arp_tbl = { 175struct neigh_table arp_tbl = {
172 .family = AF_INET, 176 .family = AF_INET,
@@ -196,6 +200,7 @@ struct neigh_table arp_tbl = {
196 .gc_thresh2 = 512, 200 .gc_thresh2 = 512,
197 .gc_thresh3 = 1024, 201 .gc_thresh3 = 1024,
198}; 202};
203EXPORT_SYMBOL(arp_tbl);
199 204
200int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir) 205int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
201{ 206{
@@ -331,11 +336,14 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
331 struct net_device *dev = neigh->dev; 336 struct net_device *dev = neigh->dev;
332 __be32 target = *(__be32*)neigh->primary_key; 337 __be32 target = *(__be32*)neigh->primary_key;
333 int probes = atomic_read(&neigh->probes); 338 int probes = atomic_read(&neigh->probes);
334 struct in_device *in_dev = in_dev_get(dev); 339 struct in_device *in_dev;
335 340
336 if (!in_dev) 341 rcu_read_lock();
342 in_dev = __in_dev_get_rcu(dev);
343 if (!in_dev) {
344 rcu_read_unlock();
337 return; 345 return;
338 346 }
339 switch (IN_DEV_ARP_ANNOUNCE(in_dev)) { 347 switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
340 default: 348 default:
341 case 0: /* By default announce any local IP */ 349 case 0: /* By default announce any local IP */
@@ -356,9 +364,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
356 case 2: /* Avoid secondary IPs, get a primary/preferred one */ 364 case 2: /* Avoid secondary IPs, get a primary/preferred one */
357 break; 365 break;
358 } 366 }
367 rcu_read_unlock();
359 368
360 if (in_dev)
361 in_dev_put(in_dev);
362 if (!saddr) 369 if (!saddr)
363 saddr = inet_select_addr(dev, target, RT_SCOPE_LINK); 370 saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
364 371
@@ -425,7 +432,7 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
425 432
426 if (ip_route_output_key(net, &rt, &fl) < 0) 433 if (ip_route_output_key(net, &rt, &fl) < 0)
427 return 1; 434 return 1;
428 if (rt->u.dst.dev != dev) { 435 if (rt->dst.dev != dev) {
429 NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER); 436 NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER);
430 flag = 1; 437 flag = 1;
431 } 438 }
@@ -495,6 +502,7 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb)
495 kfree_skb(skb); 502 kfree_skb(skb);
496 return 1; 503 return 1;
497} 504}
505EXPORT_SYMBOL(arp_find);
498 506
499/* END OF OBSOLETE FUNCTIONS */ 507/* END OF OBSOLETE FUNCTIONS */
500 508
@@ -524,12 +532,15 @@ int arp_bind_neighbour(struct dst_entry *dst)
524/* 532/*
525 * Check if we can use proxy ARP for this path 533 * Check if we can use proxy ARP for this path
526 */ 534 */
527 535static inline int arp_fwd_proxy(struct in_device *in_dev,
528static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt) 536 struct net_device *dev, struct rtable *rt)
529{ 537{
530 struct in_device *out_dev; 538 struct in_device *out_dev;
531 int imi, omi = -1; 539 int imi, omi = -1;
532 540
541 if (rt->dst.dev == dev)
542 return 0;
543
533 if (!IN_DEV_PROXY_ARP(in_dev)) 544 if (!IN_DEV_PROXY_ARP(in_dev))
534 return 0; 545 return 0;
535 546
@@ -540,14 +551,51 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
540 551
541 /* place to check for proxy_arp for routes */ 552 /* place to check for proxy_arp for routes */
542 553
543 if ((out_dev = in_dev_get(rt->u.dst.dev)) != NULL) { 554 out_dev = __in_dev_get_rcu(rt->dst.dev);
555 if (out_dev)
544 omi = IN_DEV_MEDIUM_ID(out_dev); 556 omi = IN_DEV_MEDIUM_ID(out_dev);
545 in_dev_put(out_dev); 557
546 }
547 return (omi != imi && omi != -1); 558 return (omi != imi && omi != -1);
548} 559}
549 560
550/* 561/*
562 * Check for RFC3069 proxy arp private VLAN (allow to send back to same dev)
563 *
564 * RFC3069 supports proxy arp replies back to the same interface. This
565 * is done to support (ethernet) switch features, like RFC 3069, where
566 * the individual ports are not allowed to communicate with each
567 * other, BUT they are allowed to talk to the upstream router. As
568 * described in RFC 3069, it is possible to allow these hosts to
569 * communicate through the upstream router, by proxy_arp'ing.
570 *
571 * RFC 3069: "VLAN Aggregation for Efficient IP Address Allocation"
572 *
573 * This technology is known by different names:
574 * In RFC 3069 it is called VLAN Aggregation.
575 * Cisco and Allied Telesyn call it Private VLAN.
576 * Hewlett-Packard call it Source-Port filtering or port-isolation.
577 * Ericsson call it MAC-Forced Forwarding (RFC Draft).
578 *
579 */
580static inline int arp_fwd_pvlan(struct in_device *in_dev,
581 struct net_device *dev, struct rtable *rt,
582 __be32 sip, __be32 tip)
583{
584 /* Private VLAN is only concerned about the same ethernet segment */
585 if (rt->dst.dev != dev)
586 return 0;
587
588 /* Don't reply on self probes (often done by windowz boxes)*/
589 if (sip == tip)
590 return 0;
591
592 if (IN_DEV_PROXY_ARP_PVLAN(in_dev))
593 return 1;
594 else
595 return 0;
596}
597
598/*
551 * Interface to link layer: send routine and receive handler. 599 * Interface to link layer: send routine and receive handler.
552 */ 600 */
553 601
@@ -619,13 +667,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
619#endif 667#endif
620#endif 668#endif
621 669
622#ifdef CONFIG_FDDI 670#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
623 case ARPHRD_FDDI: 671 case ARPHRD_FDDI:
624 arp->ar_hrd = htons(ARPHRD_ETHER); 672 arp->ar_hrd = htons(ARPHRD_ETHER);
625 arp->ar_pro = htons(ETH_P_IP); 673 arp->ar_pro = htons(ETH_P_IP);
626 break; 674 break;
627#endif 675#endif
628#ifdef CONFIG_TR 676#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
629 case ARPHRD_IEEE802_TR: 677 case ARPHRD_IEEE802_TR:
630 arp->ar_hrd = htons(ARPHRD_IEEE802); 678 arp->ar_hrd = htons(ARPHRD_IEEE802);
631 arp->ar_pro = htons(ETH_P_IP); 679 arp->ar_pro = htons(ETH_P_IP);
@@ -656,6 +704,7 @@ out:
656 kfree_skb(skb); 704 kfree_skb(skb);
657 return NULL; 705 return NULL;
658} 706}
707EXPORT_SYMBOL(arp_create);
659 708
660/* 709/*
661 * Send an arp packet. 710 * Send an arp packet.
@@ -665,6 +714,7 @@ void arp_xmit(struct sk_buff *skb)
665 /* Send it off, maybe filter it using firewalling first. */ 714 /* Send it off, maybe filter it using firewalling first. */
666 NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit); 715 NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit);
667} 716}
717EXPORT_SYMBOL(arp_xmit);
668 718
669/* 719/*
670 * Create and send an arp packet. 720 * Create and send an arp packet.
@@ -691,6 +741,7 @@ void arp_send(int type, int ptype, __be32 dest_ip,
691 741
692 arp_xmit(skb); 742 arp_xmit(skb);
693} 743}
744EXPORT_SYMBOL(arp_send);
694 745
695/* 746/*
696 * Process an arp request. 747 * Process an arp request.
@@ -699,7 +750,7 @@ void arp_send(int type, int ptype, __be32 dest_ip,
699static int arp_process(struct sk_buff *skb) 750static int arp_process(struct sk_buff *skb)
700{ 751{
701 struct net_device *dev = skb->dev; 752 struct net_device *dev = skb->dev;
702 struct in_device *in_dev = in_dev_get(dev); 753 struct in_device *in_dev = __in_dev_get_rcu(dev);
703 struct arphdr *arp; 754 struct arphdr *arp;
704 unsigned char *arp_ptr; 755 unsigned char *arp_ptr;
705 struct rtable *rt; 756 struct rtable *rt;
@@ -812,7 +863,7 @@ static int arp_process(struct sk_buff *skb)
812 } 863 }
813 864
814 if (arp->ar_op == htons(ARPOP_REQUEST) && 865 if (arp->ar_op == htons(ARPOP_REQUEST) &&
815 ip_route_input(skb, tip, sip, 0, dev) == 0) { 866 ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {
816 867
817 rt = skb_rtable(skb); 868 rt = skb_rtable(skb);
818 addr_type = rt->rt_type; 869 addr_type = rt->rt_type;
@@ -833,8 +884,11 @@ static int arp_process(struct sk_buff *skb)
833 } 884 }
834 goto out; 885 goto out;
835 } else if (IN_DEV_FORWARD(in_dev)) { 886 } else if (IN_DEV_FORWARD(in_dev)) {
836 if (addr_type == RTN_UNICAST && rt->u.dst.dev != dev && 887 if (addr_type == RTN_UNICAST &&
837 (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) { 888 (arp_fwd_proxy(in_dev, dev, rt) ||
889 arp_fwd_pvlan(in_dev, dev, rt, sip, tip) ||
890 pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))
891 {
838 n = neigh_event_ns(&arp_tbl, sha, &sip, dev); 892 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
839 if (n) 893 if (n)
840 neigh_release(n); 894 neigh_release(n);
@@ -845,7 +899,6 @@ static int arp_process(struct sk_buff *skb)
845 arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); 899 arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
846 } else { 900 } else {
847 pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb); 901 pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb);
848 in_dev_put(in_dev);
849 return 0; 902 return 0;
850 } 903 }
851 goto out; 904 goto out;
@@ -863,7 +916,8 @@ static int arp_process(struct sk_buff *skb)
863 devices (strip is candidate) 916 devices (strip is candidate)
864 */ 917 */
865 if (n == NULL && 918 if (n == NULL &&
866 arp->ar_op == htons(ARPOP_REPLY) && 919 (arp->ar_op == htons(ARPOP_REPLY) ||
920 (arp->ar_op == htons(ARPOP_REQUEST) && tip == sip)) &&
867 inet_addr_type(net, sip) == RTN_UNICAST) 921 inet_addr_type(net, sip) == RTN_UNICAST)
868 n = __neigh_lookup(&arp_tbl, &sip, dev, 1); 922 n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
869 } 923 }
@@ -890,8 +944,6 @@ static int arp_process(struct sk_buff *skb)
890 } 944 }
891 945
892out: 946out:
893 if (in_dev)
894 in_dev_put(in_dev);
895 consume_skb(skb); 947 consume_skb(skb);
896 return 0; 948 return 0;
897} 949}
@@ -999,13 +1051,13 @@ static int arp_req_set(struct net *net, struct arpreq *r,
999 struct rtable * rt; 1051 struct rtable * rt;
1000 if ((err = ip_route_output_key(net, &rt, &fl)) != 0) 1052 if ((err = ip_route_output_key(net, &rt, &fl)) != 0)
1001 return err; 1053 return err;
1002 dev = rt->u.dst.dev; 1054 dev = rt->dst.dev;
1003 ip_rt_put(rt); 1055 ip_rt_put(rt);
1004 if (!dev) 1056 if (!dev)
1005 return -EINVAL; 1057 return -EINVAL;
1006 } 1058 }
1007 switch (dev->type) { 1059 switch (dev->type) {
1008#ifdef CONFIG_FDDI 1060#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
1009 case ARPHRD_FDDI: 1061 case ARPHRD_FDDI:
1010 /* 1062 /*
1011 * According to RFC 1390, FDDI devices should accept ARP 1063 * According to RFC 1390, FDDI devices should accept ARP
@@ -1106,7 +1158,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
1106 struct rtable * rt; 1158 struct rtable * rt;
1107 if ((err = ip_route_output_key(net, &rt, &fl)) != 0) 1159 if ((err = ip_route_output_key(net, &rt, &fl)) != 0)
1108 return err; 1160 return err;
1109 dev = rt->u.dst.dev; 1161 dev = rt->dst.dev;
1110 ip_rt_put(rt); 1162 ip_rt_put(rt);
1111 if (!dev) 1163 if (!dev)
1112 return -EINVAL; 1164 return -EINVAL;
@@ -1239,8 +1291,7 @@ void __init arp_init(void)
1239 dev_add_pack(&arp_packet_type); 1291 dev_add_pack(&arp_packet_type);
1240 arp_proc_init(); 1292 arp_proc_init();
1241#ifdef CONFIG_SYSCTL 1293#ifdef CONFIG_SYSCTL
1242 neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4, 1294 neigh_sysctl_register(NULL, &arp_tbl.parms, "ipv4", NULL);
1243 NET_IPV4_NEIGH, "ipv4", NULL);
1244#endif 1295#endif
1245 register_netdevice_notifier(&arp_netdev_notifier); 1296 register_netdevice_notifier(&arp_netdev_notifier);
1246} 1297}
@@ -1408,14 +1459,3 @@ static int __init arp_proc_init(void)
1408} 1459}
1409 1460
1410#endif /* CONFIG_PROC_FS */ 1461#endif /* CONFIG_PROC_FS */
1411
1412EXPORT_SYMBOL(arp_broken_ops);
1413EXPORT_SYMBOL(arp_find);
1414EXPORT_SYMBOL(arp_create);
1415EXPORT_SYMBOL(arp_xmit);
1416EXPORT_SYMBOL(arp_send);
1417EXPORT_SYMBOL(arp_tbl);
1418
1419#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
1420EXPORT_SYMBOL(clip_tbl_hook);
1421#endif