Am 04.08.2015 um 14:36 schrieb Denys Vlasenko:
On Tue, Aug 4, 2015 at 12:00 PM, Sebastian Fett <[email protected]> wrote:
On Tue, Jul 21, 2015 at 2:03 PM, dbextern <[email protected]> wrote:
For our link local functionality I'm using udhcpc together with zcip out
of busybox on a Blackfin BF-537 CPU without MMU.
The base functionality is there.
But when I connect two networks with stable IP addresses, and both
networks had the same IP(s) in them, the conflict stays unresolved.
My setup is one master PC or MAC and several embedded boards.
What I would expect (following RFC3927
https://tools.ietf.org/html/rfc3927#page-10[https://3c.gmx.net/mail/client/dereferrer?redirectUrl=https%3A%2F%2Ftools.ietf.org%2Fhtml%2Frfc3927%23page-10];
chapter 2.x and 4) is that after a while the ARP messages will resolve the
problem because the still running zcip sees ARP responses on it's own IP and
reacts accordingly.
What really happens is:
* Windows only sends broadcast ARP requests as long as it never got an
answer. After that there is only unicast. And the requested device answers
with a unicast as well.
* the MAC always sends broadcasts. And both embedded devices with the
conflicting IP answer. But with a unicast ARP reply to the MAC.
As I understand the specification (last paragraph in chapter 2.5) then
all ARP messages between devices with link local addresses should be link
layer broadcasts.
Did I get that right? And if yes, why does zcip not follow that rule?
zcip does use bcast for all packets it sends:
# tcpdump -nliwlan0 -s0 -vv -e arp
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size
65535 bytes
<zcip runs>
02:49:51.078369 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ethertype ARP
(0x0806), length 42: arp who-has 169.254.194.171 tell 0.0.0.0
02:49:52.391711 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ethertype ARP
(0x0806), length 42: arp who-has 169.254.194.171 tell 0.0.0.0
02:49:54.254628 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ethertype ARP
(0x0806), length 42: arp who-has 169.254.194.171 tell 0.0.0.0
02:49:55.305731 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ethertype ARP
(0x0806), length 42: arp who-has 169.254.194.171 (00:04:e2:64:23:c2)
tell 169.254.194.171
02:49:57.307788 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ethertype ARP
(0x0806), length 42: arp who-has 169.254.194.171 (00:04:e2:64:23:c2)
tell 169.254.194.171
02:49:59.309844 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ethertype ARP
(0x0806), length 42: arp who-has 169.254.194.171 (00:04:e2:64:23:c2)
tell 169.254.194.171
Thanks for looking into that.
These are the probing and announcement messages from zcip. They need to be
and are bcasts.
What it does not do is answer normal ARP requests with a broadcast. Which is
specified in RCF3927 as the right thing to do.
Looking at the code, it should answer to them:
// packets arriving, or link went down
case 1:
...
switch (state) {
... case MONITOR:
// If a conflict, we try to defend
with a single ARP probe.
if (source_ip_conflict) {
VDBG("monitor conflict --
defending\n");
state = DEFEND;
timeout_ms = DEFEND_INTERVAL * 1000;
arp(/* ARPOP_REQUEST, */
/* ð_addr, */ ip,
ð_addr, ip);
}
break;
The call to arp() in the code snippet above should send a broadcast
ARP probe.
That was my first thought, too. But this only resolves the problem when
another device does it's probing.
What I needed was a bcast answer to a general ARP request.
This is the patch I use. It's not tidy and the comments are in german,
sorry.
And the result of this ist that the devices answers to an ARP request
twice. A bcast from zcip and a unicast from the kernel. Not really nice,
but acceptable in my usecase.
--- a/networking/zcip.c 2015-07-21 15:10:45.047362400 +0200
+++ c/networking/zcip.c 2015-07-22 14:44:13.280779500 +0200
@@ -117,12 +117,12 @@
* Broadcast an ARP packet.
*/
static void arp(
- /* int op, - always ARPOP_REQUEST */
+ int op, /*- always ARPOP_REQUEST */
/* const struct ether_addr *source_eth, - always ð_addr */
struct in_addr source_ip,
const struct ether_addr *target_eth, struct in_addr target_ip)
{
- enum { op = ARPOP_REQUEST };
+// enum { op = ARPOP_REQUEST }; //wir uebergeben wieder von aussen
#define source_eth (ð_addr)
struct arp_packet p;
@@ -348,6 +348,7 @@
struct arp_packet p;
int source_ip_conflict;
int target_ip_conflict;
+ int bcast_arp_response;
fds[0].fd = sock_fd;
fds[0].events = POLLIN;
@@ -385,7 +386,7 @@
nprobes, argv_intf,
inet_ntoa(ip));
timeout_ms = PROBE_MIN * 1000;
timeout_ms += random_delay_ms(PROBE_MAX
- PROBE_MIN);
- arp(/* ARPOP_REQUEST, */
+ arp( ARPOP_REQUEST, /**/
/* ð_addr, */
null_ip,
&null_addr, ip);
}
@@ -396,7 +397,7 @@
VDBG("announce/%u %s@%s\n",
nclaims, argv_intf,
inet_ntoa(ip));
timeout_ms = ANNOUNCE_INTERVAL * 1000;
- arp(/* ARPOP_REQUEST, */
+ arp(ARPOP_REQUEST, /* */
/* ð_addr, */ ip,
ð_addr, ip);
}
@@ -409,7 +410,7 @@
VDBG("announce/%u %s@%s\n",
nclaims, argv_intf,
inet_ntoa(ip));
timeout_ms = ANNOUNCE_INTERVAL * 1000;
- arp(/* ARPOP_REQUEST, */
+ arp( ARPOP_REQUEST, /**/
/* ð_addr, */ ip,
ð_addr, ip);
break;
@@ -421,7 +422,7 @@
VDBG("announce/%u %s@%s\n",
nclaims, argv_intf,
inet_ntoa(ip));
timeout_ms = ANNOUNCE_INTERVAL * 1000;
- arp(/* ARPOP_REQUEST, */
+ arp( ARPOP_REQUEST, /**/
/* ð_addr, */ ip,
ð_addr, ip);
}
@@ -519,6 +520,7 @@
source_ip_conflict = 0;
target_ip_conflict = 0;
+ bcast_arp_response = 0;
if (memcmp(&p.arp.arp_sha, ð_addr, ETH_ALEN) != 0) {
if (memcmp(p.arp.arp_spa, &ip.s_addr,
sizeof(struct in_addr)) == 0) {
@@ -526,13 +528,20 @@
source_ip_conflict = 1;
}
if (p.arp.arp_op == htons(ARPOP_REQUEST)
- && memcmp(p.arp.arp_spa, &null_ip,
sizeof(struct in_addr)) == 0
&& memcmp(p.arp.arp_tpa, &ip.s_addr,
sizeof(struct in_addr)) == 0
) {
- /* A probe with source_ip == 0.0.0.0,
target_ip == chosen ip:
- * another host trying to claim this ip!
- */
- target_ip_conflict = 1;
+
+ if ( memcmp(p.arp.arp_spa, &null_ip, sizeof(struct in_addr)) == 0
) //Probe eines anders LL Geraetes
+ {
+ /* A probe with source_ip ==
0.0.0.0, target_ip == chosen ip:
+ * another host trying to claim
this ip!
+ */
+ target_ip_conflict = 1;
+ }
+ else //normaler ARP Request an meine Adresse, wir Antworten mit
BCast ARP Response
+ {
+ bcast_arp_response = 1;
+ }
}
}
@@ -564,7 +573,13 @@
VDBG("monitor conflict -- defending\n");
state = DEFEND;
timeout_ms = DEFEND_INTERVAL * 1000;
- arp(/* ARPOP_REQUEST, */
+ arp( ARPOP_REQUEST, /**/
+ /* ð_addr, */ ip,
+ ð_addr, ip);
+ }
+ else if (bcast_arp_response)//no conflict --> send broadcast arp
response
+ {
+ arp( ARPOP_REPLY, /**/
/* ð_addr, */ ip,
ð_addr, ip);
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox