aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/arp.c
diff options
context:
space:
mode:
authorJiri Benc <jbenc@redhat.com>2015-09-22 12:12:11 -0400
committerDavid S. Miller <davem@davemloft.net>2015-09-24 17:31:36 -0400
commit63d008a4e9ee86614ca5671b7f3ba447df007190 (patch)
tree3122aaf73744bc976113cffb2367b4e770b901f8 /net/ipv4/arp.c
parentd5b8d6404395641987db76e28334cae4cef771ae (diff)
ipv4: send arp replies to the correct tunnel
When using ip lwtunnels, the additional data for xmit (basically, the actual tunnel to use) are carried in ip_tunnel_info either in dst->lwtstate or in metadata dst. When replying to ARP requests, we need to send the reply to the same tunnel the request came from. This means we need to construct proper metadata dst for ARP replies. We could perform another route lookup to get a dst entry with the correct lwtstate. However, this won't always ensure that the outgoing tunnel is the same as the incoming one, and it won't work anyway for IPv4 duplicate address detection. The only thing to do is to "reverse" the ip_tunnel_info. Signed-off-by: Jiri Benc <jbenc@redhat.com> Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
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);