• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: コミット

2.4.36-stable kernel tree


コミットメタ情報

リビジョン72144472666cd5096d485c6057172ee8493e1b33 (tree)
日時2007-02-03 18:53:25
作者Christian Praehauser <cpraehaus@cosy...>
コミッターWilly Tarreau

ログメッセージ

[NET] ethernet: Fix first packet goes out with MAC 00:00:00:00:00:00

This is a backport of a patch which was first included in Linux 2.6.16-rc5.
What follows between the "======" markers is the original description.


When you turn off ARP on a netdevice then the first packet always goes
out with a dstMAC of all zeroes. This is because the first packet is
used to resolve ARP entries. Even though the ARP entry may be resolved
(I tried by setting a static ARP entry for a host i was pinging from),
it gets overwritten by virtue of having the netdevice disabling ARP.

Subsequent packets go out fine with correct dstMAC address (which may
be why people have ignored reporting this issue).

To cut the story short:

the culprit code is in net/ethernet/eth.c::eth_header()


/*
            • Anyway, the loopback-device should never use this function...
              */
if (dev->flags & (IFF_LOOPBACK|IFF_NOARP))
{
memset(eth->h_dest, 0, dev->addr_len);
return ETH_HLEN;
}
if(daddr)
{
memcpy(eth->h_dest,daddr,dev->addr_len);
return ETH_HLEN;
}

Note how the h_dest is being reset when device has IFF_NOARP.

As a note:
All devices including loopback pass a daddr. loopback in fact passes
a 0 all the time ;->
This means i can delete the check totaly or i can remove the IFF_NOARP

Alexey says:


I think, it was me who did this crap. It was so long ago I do not remember
why it was made.

I remember some troubles with dummy device. It tried to resolve
addresses, apparently, without success and generated errors instead of
blackholing. I think the problem was eventually solved at neighbour
level.

After some thinking I suspect the deletion of this chunk could change
behaviour of some parts which do not use neighbour cache f.e. packet
socket.

I think safer approach would be to move this chunk after if (daddr).
And the possibility to remove this completely could be analyzed later.


Patch updated with Alexey's safer suggestions.

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Acked-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>


This problem also arises when transmitting IP multicast packets. If you send an
IP multicast stream over an ethernet network interface ethX and turn off ARP on
ethX then Linux will produce an ethernet frame with a dest. addresses of
00:00:00:00:00:00 (which is invalid). As IP multicast addresses are directly
mapped to HW (MAC) addresses without invoking any ARP protocol mechanisms - for
IP4 this mapping is performed by the function ip_eth_mc_map - it makes perfect
sense to do this even if ARP is disabled. Further, this problem may occur
periodically, everytime the corresponding struct dst_entry is garbage-collected
(e.g. ~ every 10 minutes).

Patch ported to Linux 2.4 by Christian Praehauser.

Signed-off-by: Christian Praehauser <cpraehaus@cosy.sbg.ac.at>

変更サマリ

差分

--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -96,6 +96,12 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
9696 else
9797 memcpy(eth->h_source,dev->dev_addr,dev->addr_len);
9898
99+ if(daddr)
100+ {
101+ memcpy(eth->h_dest,daddr,dev->addr_len);
102+ return dev->hard_header_len;
103+ }
104+
99105 /*
100106 * Anyway, the loopback-device should never use this function...
101107 */
@@ -106,12 +112,6 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
106112 return(dev->hard_header_len);
107113 }
108114
109- if(daddr)
110- {
111- memcpy(eth->h_dest,daddr,dev->addr_len);
112- return dev->hard_header_len;
113- }
114-
115115 return -dev->hard_header_len;
116116 }
117117
旧リポジトリブラウザで表示