aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/arp.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2015-07-21 04:43:57 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-21 13:39:05 -0400
commit0accfc268f4d3345693d3af3d5780aae3ad93d8d (patch)
tree355a63ecdb2642680e8a4b21c5ff02f84f5a992d /net/ipv4/arp.c
parentf38a9eb1f77b296ff07e000823884a0f64d67b2a (diff)
arp: Inherit metadata dst when creating ARP requests
If output device wants to see the dst, inherit the dst of the original skb and pass it on to generate the ARP request. Signed-off-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.c65
1 files changed, 37 insertions, 28 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 933a92820d26..1d59e50ce8b7 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -291,6 +291,40 @@ static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb)
291 kfree_skb(skb); 291 kfree_skb(skb);
292} 292}
293 293
294/* Create and send an arp packet. */
295static void arp_send_dst(int type, int ptype, __be32 dest_ip,
296 struct net_device *dev, __be32 src_ip,
297 const unsigned char *dest_hw,
298 const unsigned char *src_hw,
299 const unsigned char *target_hw, struct sk_buff *oskb)
300{
301 struct sk_buff *skb;
302
303 /* arp on this interface. */
304 if (dev->flags & IFF_NOARP)
305 return;
306
307 skb = arp_create(type, ptype, dest_ip, dev, src_ip,
308 dest_hw, src_hw, target_hw);
309 if (!skb)
310 return;
311
312 if (oskb)
313 skb_dst_copy(skb, oskb);
314
315 arp_xmit(skb);
316}
317
318void arp_send(int type, int ptype, __be32 dest_ip,
319 struct net_device *dev, __be32 src_ip,
320 const unsigned char *dest_hw, const unsigned char *src_hw,
321 const unsigned char *target_hw)
322{
323 arp_send_dst(type, ptype, dest_ip, dev, src_ip, dest_hw, src_hw,
324 target_hw, NULL);
325}
326EXPORT_SYMBOL(arp_send);
327
294static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) 328static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
295{ 329{
296 __be32 saddr = 0; 330 __be32 saddr = 0;
@@ -346,8 +380,9 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
346 } 380 }
347 } 381 }
348 382
349 arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, 383 arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
350 dst_hw, dev->dev_addr, NULL); 384 dst_hw, dev->dev_addr, NULL,
385 dev->priv_flags & IFF_XMIT_DST_RELEASE ? NULL : skb);
351} 386}
352 387
353static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) 388static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
@@ -597,32 +632,6 @@ void arp_xmit(struct sk_buff *skb)
597EXPORT_SYMBOL(arp_xmit); 632EXPORT_SYMBOL(arp_xmit);
598 633
599/* 634/*
600 * Create and send an arp packet.
601 */
602void arp_send(int type, int ptype, __be32 dest_ip,
603 struct net_device *dev, __be32 src_ip,
604 const unsigned char *dest_hw, const unsigned char *src_hw,
605 const unsigned char *target_hw)
606{
607 struct sk_buff *skb;
608
609 /*
610 * No arp on this interface.
611 */
612
613 if (dev->flags&IFF_NOARP)
614 return;
615
616 skb = arp_create(type, ptype, dest_ip, dev, src_ip,
617 dest_hw, src_hw, target_hw);
618 if (!skb)
619 return;
620
621 arp_xmit(skb);
622}
623EXPORT_SYMBOL(arp_send);
624
625/*
626 * Process an arp request. 635 * Process an arp request.
627 */ 636 */
628 637