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.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 30409b75e925..f03db8b7abee 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -113,6 +113,8 @@
113#include <net/arp.h> 113#include <net/arp.h>
114#include <net/ax25.h> 114#include <net/ax25.h>
115#include <net/netrom.h> 115#include <net/netrom.h>
116#include <net/dst_metadata.h>
117#include <net/ip_tunnels.h>
116 118
117#include <linux/uaccess.h> 119#include <linux/uaccess.h>
118 120
@@ -296,7 +298,8 @@ static void arp_send_dst(int type, int ptype, __be32 dest_ip,
296 struct net_device *dev, __be32 src_ip, 298 struct net_device *dev, __be32 src_ip,
297 const unsigned char *dest_hw, 299 const unsigned char *dest_hw,
298 const unsigned char *src_hw, 300 const unsigned char *src_hw,
299 const unsigned char *target_hw, struct sk_buff *oskb) 301 const unsigned char *target_hw,
302 struct dst_entry *dst)
300{ 303{
301 struct sk_buff *skb; 304 struct sk_buff *skb;
302 305
@@ -309,9 +312,7 @@ static void arp_send_dst(int type, int ptype, __be32 dest_ip,
309 if (!skb) 312 if (!skb)
310 return; 313 return;
311 314
312 if (oskb) 315 skb_dst_set(skb, dst);
313 skb_dst_copy(skb, oskb);
314
315 arp_xmit(skb); 316 arp_xmit(skb);
316} 317}
317 318
@@ -333,6 +334,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
333 __be32 target = *(__be32 *)neigh->primary_key; 334 __be32 target = *(__be32 *)neigh->primary_key;
334 int probes = atomic_read(&neigh->probes); 335 int probes = atomic_read(&neigh->probes);
335 struct in_device *in_dev; 336 struct in_device *in_dev;
337 struct dst_entry *dst = NULL;
336 338
337 rcu_read_lock(); 339 rcu_read_lock();
338 in_dev = __in_dev_get_rcu(dev); 340 in_dev = __in_dev_get_rcu(dev);
@@ -381,9 +383,10 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
381 } 383 }
382 } 384 }
383 385
386 if (skb && !(dev->priv_flags & IFF_XMIT_DST_RELEASE))
387 dst = dst_clone(skb_dst(skb));
384 arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, 388 arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
385 dst_hw, dev->dev_addr, NULL, 389 dst_hw, dev->dev_addr, NULL, dst);
386 dev->priv_flags & IFF_XMIT_DST_RELEASE ? NULL : skb);
387} 390}
388 391
389static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) 392static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
@@ -649,6 +652,7 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
649 int addr_type; 652 int addr_type;
650 struct neighbour *n; 653 struct neighbour *n;
651 struct net *net = dev_net(dev); 654 struct net *net = dev_net(dev);
655 struct dst_entry *reply_dst = NULL;
652 bool is_garp = false; 656 bool is_garp = false;
653 657
654 /* arp_rcv below verifies the ARP header and verifies the device 658 /* arp_rcv below verifies the ARP header and verifies the device
@@ -749,13 +753,18 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
749 * cache. 753 * cache.
750 */ 754 */
751 755
756 if (arp->ar_op == htons(ARPOP_REQUEST) && skb_metadata_dst(skb))
757 reply_dst = (struct dst_entry *)
758 iptunnel_metadata_reply(skb_metadata_dst(skb),
759 GFP_ATOMIC);
760
752 /* Special case: IPv4 duplicate address detection packet (RFC2131) */ 761 /* Special case: IPv4 duplicate address detection packet (RFC2131) */
753 if (sip == 0) { 762 if (sip == 0) {
754 if (arp->ar_op == htons(ARPOP_REQUEST) && 763 if (arp->ar_op == htons(ARPOP_REQUEST) &&
755 inet_addr_type_dev_table(net, dev, tip) == RTN_LOCAL && 764 inet_addr_type_dev_table(net, dev, tip) == RTN_LOCAL &&
756 !arp_ignore(in_dev, sip, tip)) 765 !arp_ignore(in_dev, sip, tip))
757 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha, 766 arp_send_dst(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip,
758 dev->dev_addr, sha); 767 sha, dev->dev_addr, sha, reply_dst);
759 goto out; 768 goto out;
760 } 769 }
761 770
@@ -774,9 +783,10 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
774 if (!dont_send) { 783 if (!dont_send) {
775 n = neigh_event_ns(&arp_tbl, sha, &sip, dev); 784 n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
776 if (n) { 785 if (n) {
777 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, 786 arp_send_dst(ARPOP_REPLY, ETH_P_ARP,
778 dev, tip, sha, dev->dev_addr, 787 sip, dev, tip, sha,
779 sha); 788 dev->dev_addr, sha,
789 reply_dst);
780 neigh_release(n); 790 neigh_release(n);
781 } 791 }
782 } 792 }
@@ -794,9 +804,10 @@ static int arp_process(struct sock *sk, struct sk_buff *skb)
794 if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED || 804 if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
795 skb->pkt_type == PACKET_HOST || 805 skb->pkt_type == PACKET_HOST ||
796 NEIGH_VAR(in_dev->arp_parms, PROXY_DELAY) == 0) { 806 NEIGH_VAR(in_dev->arp_parms, PROXY_DELAY) == 0) {
797 arp_send(ARPOP_REPLY, ETH_P_ARP, sip, 807 arp_send_dst(ARPOP_REPLY, ETH_P_ARP,
798 dev, tip, sha, dev->dev_addr, 808 sip, dev, tip, sha,
799 sha); 809 dev->dev_addr, sha,
810 reply_dst);
800 } else { 811 } else {
801 pneigh_enqueue(&arp_tbl, 812 pneigh_enqueue(&arp_tbl,
802 in_dev->arp_parms, skb); 813 in_dev->arp_parms, skb);