aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2006-12-08 03:05:55 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-08 20:19:28 -0500
commit47bbec0282cce900f16a8dd6397260e076400edb (patch)
tree981afee17e1aa412bf3c02770437beaa43e9c079
parente07bca84cd9d31f76ed655d51e68b6a0ca15f162 (diff)
[NETPOLL]: make arp replies through netpoll use mac address of sender
Back in 2.4 arp requests that were recevied by netpoll were processed in netconsole_receive_skb, where they were responded to using the src mac of the request sender. In the 2.6 kernel arp_reply is responsible for this function, but instead of using the src mac address of the incomming request, the stored mac address that was registered for the netconsole application is used. While this is usually ok, it can lead to failures in netpoll in some situations (specifically situations where a network may have two gateways, as arp requests from one may be responded to using the mac address of the other). This patch reverts the behavior to what we had in 2.4, in which all arp requests are sent back using the src address of the request sender. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Acked-by: Chris Lalancette <clalance@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/netpoll.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b3c559b9ac35..8a271285f2f3 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -330,6 +330,7 @@ static void arp_reply(struct sk_buff *skb)
330 unsigned char *arp_ptr; 330 unsigned char *arp_ptr;
331 int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; 331 int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
332 __be32 sip, tip; 332 __be32 sip, tip;
333 unsigned char *sha;
333 struct sk_buff *send_skb; 334 struct sk_buff *send_skb;
334 struct netpoll *np = NULL; 335 struct netpoll *np = NULL;
335 336
@@ -356,9 +357,14 @@ static void arp_reply(struct sk_buff *skb)
356 arp->ar_op != htons(ARPOP_REQUEST)) 357 arp->ar_op != htons(ARPOP_REQUEST))
357 return; 358 return;
358 359
359 arp_ptr = (unsigned char *)(arp+1) + skb->dev->addr_len; 360 arp_ptr = (unsigned char *)(arp+1);
361 /* save the location of the src hw addr */
362 sha = arp_ptr;
363 arp_ptr += skb->dev->addr_len;
360 memcpy(&sip, arp_ptr, 4); 364 memcpy(&sip, arp_ptr, 4);
361 arp_ptr += 4 + skb->dev->addr_len; 365 arp_ptr += 4;
366 /* if we actually cared about dst hw addr, it would get copied here */
367 arp_ptr += skb->dev->addr_len;
362 memcpy(&tip, arp_ptr, 4); 368 memcpy(&tip, arp_ptr, 4);
363 369
364 /* Should we ignore arp? */ 370 /* Should we ignore arp? */
@@ -381,7 +387,7 @@ static void arp_reply(struct sk_buff *skb)
381 387
382 if (np->dev->hard_header && 388 if (np->dev->hard_header &&
383 np->dev->hard_header(send_skb, skb->dev, ptype, 389 np->dev->hard_header(send_skb, skb->dev, ptype,
384 np->remote_mac, np->local_mac, 390 sha, np->local_mac,
385 send_skb->len) < 0) { 391 send_skb->len) < 0) {
386 kfree_skb(send_skb); 392 kfree_skb(send_skb);
387 return; 393 return;
@@ -405,7 +411,7 @@ static void arp_reply(struct sk_buff *skb)
405 arp_ptr += np->dev->addr_len; 411 arp_ptr += np->dev->addr_len;
406 memcpy(arp_ptr, &tip, 4); 412 memcpy(arp_ptr, &tip, 4);
407 arp_ptr += 4; 413 arp_ptr += 4;
408 memcpy(arp_ptr, np->remote_mac, np->dev->addr_len); 414 memcpy(arp_ptr, sha, np->dev->addr_len);
409 arp_ptr += np->dev->addr_len; 415 arp_ptr += np->dev->addr_len;
410 memcpy(arp_ptr, &sip, 4); 416 memcpy(arp_ptr, &sip, 4);
411 417