aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2015-08-04 12:28:21 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2015-08-04 12:28:21 +0200
commit99e30be38bc167a3b5729154a27ccdb15bbaadb2 (patch)
treee66c9e2df659f1810c8faf38aef071156dec9eb4
parent16aa7a73c40ba5dfaabaedb8a5533619cb8b6cb6 (diff)
downloadbusybox-w32-99e30be38bc167a3b5729154a27ccdb15bbaadb2.tar.gz
busybox-w32-99e30be38bc167a3b5729154a27ccdb15bbaadb2.tar.bz2
busybox-w32-99e30be38bc167a3b5729154a27ccdb15bbaadb2.zip
zcip: code shrink
function old new delta zcip_main 1263 1230 -33 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/zcip.c137
1 files changed, 59 insertions, 78 deletions
diff --git a/networking/zcip.c b/networking/zcip.c
index 69644b230..5877a8317 100644
--- a/networking/zcip.c
+++ b/networking/zcip.c
@@ -215,19 +215,17 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
215 const struct ether_addr null_addr; 215 const struct ether_addr null_addr;
216 struct ifreq ifr; 216 struct ifreq ifr;
217 uint32_t chosen_nip; 217 uint32_t chosen_nip;
218 int timeout_ms; /* must be signed */ 218 int timeout_ms; // must be signed
219 unsigned conflicts; 219 unsigned conflicts;
220 unsigned nprobes; 220 unsigned nsent;
221 unsigned nclaims;
222 int verbose; 221 int verbose;
223 } L; 222 } L;
224#define null_addr (L.null_addr ) 223#define null_addr (L.null_addr )
225#define chosen_nip (L.chosen_nip)
226#define ifr (L.ifr ) 224#define ifr (L.ifr )
225#define chosen_nip (L.chosen_nip)
227#define timeout_ms (L.timeout_ms) 226#define timeout_ms (L.timeout_ms)
228#define conflicts (L.conflicts ) 227#define conflicts (L.conflicts )
229#define nprobes (L.nprobes ) 228#define nsent (L.nsent )
230#define nclaims (L.nclaims )
231#define verbose (L.verbose ) 229#define verbose (L.verbose )
232 230
233 memset(&L, 0, sizeof(L)); 231 memset(&L, 0, sizeof(L));
@@ -351,8 +349,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
351 struct pollfd fds[1]; 349 struct pollfd fds[1];
352 unsigned deadline_us; 350 unsigned deadline_us;
353 struct arp_packet p; 351 struct arp_packet p;
354 int source_ip_conflict; 352 int ip_conflict;
355 int target_ip_conflict;
356 353
357 fds[0].fd = sock_fd; 354 fds[0].fd = sock_fd;
358 fds[0].events = POLLIN; 355 fds[0].events = POLLIN;
@@ -368,8 +365,8 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
368 // set deadline_us to the point in time when we timeout 365 // set deadline_us to the point in time when we timeout
369 deadline_us = MONOTONIC_US() + timeout_ms * 1000; 366 deadline_us = MONOTONIC_US() + timeout_ms * 1000;
370 367
371 VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", 368 VDBG("...wait %d %s nsent=%u\n",
372 timeout_ms, argv_intf, nprobes, nclaims); 369 timeout_ms, argv_intf, nsent);
373 370
374 switch (safe_poll(fds, 1, timeout_ms)) { 371 switch (safe_poll(fds, 1, timeout_ms)) {
375 372
@@ -384,10 +381,10 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
384 case PROBE: 381 case PROBE:
385 // timeouts in the PROBE state mean no conflicting ARP packets 382 // timeouts in the PROBE state mean no conflicting ARP packets
386 // have been received, so we can progress through the states 383 // have been received, so we can progress through the states
387 if (nprobes < PROBE_NUM) { 384 if (nsent < PROBE_NUM) {
388 nprobes++; 385 nsent++;
389 VDBG("probe/%u %s@%s\n", 386 VDBG("probe/%u %s@%s\n",
390 nprobes, argv_intf, nip_to_a(chosen_nip)); 387 nsent, argv_intf, nip_to_a(chosen_nip));
391 timeout_ms = PROBE_MIN * 1000; 388 timeout_ms = PROBE_MIN * 1000;
392 timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); 389 timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN);
393 arp(/* ARPOP_REQUEST, */ 390 arp(/* ARPOP_REQUEST, */
@@ -395,25 +392,25 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
395 &null_addr, chosen_nip); 392 &null_addr, chosen_nip);
396 break; 393 break;
397 } 394 }
398 // Switch to announce state. 395 // Switch to announce state
399 nclaims = 0; 396 nsent = 0;
400 state = ANNOUNCE; 397 state = ANNOUNCE;
401 goto send_announce; 398 goto send_announce;
402 case ANNOUNCE: 399 case ANNOUNCE:
403 // timeouts in the ANNOUNCE state mean no conflicting ARP packets 400 // timeouts in the ANNOUNCE state mean no conflicting ARP packets
404 // have been received, so we can progress through the states 401 // have been received, so we can progress through the states
405 if (nclaims < ANNOUNCE_NUM) { 402 if (nsent < ANNOUNCE_NUM) {
406 send_announce: 403 send_announce:
407 nclaims++; 404 nsent++;
408 VDBG("announce/%u %s@%s\n", 405 VDBG("announce/%u %s@%s\n",
409 nclaims, argv_intf, nip_to_a(chosen_nip)); 406 nsent, argv_intf, nip_to_a(chosen_nip));
410 timeout_ms = ANNOUNCE_INTERVAL * 1000; 407 timeout_ms = ANNOUNCE_INTERVAL * 1000;
411 arp(/* ARPOP_REQUEST, */ 408 arp(/* ARPOP_REQUEST, */
412 /* &G.eth_addr, */ chosen_nip, 409 /* &G.eth_addr, */ chosen_nip,
413 &G.eth_addr, chosen_nip); 410 &G.eth_addr, chosen_nip);
414 break; 411 break;
415 } 412 }
416 // Switch to monitor state. 413 // Switch to monitor state
417 // FIXME update filters 414 // FIXME update filters
418 run(argv, "config", chosen_nip); 415 run(argv, "config", chosen_nip);
419 // NOTE: all other exit paths should deconfig... 416 // NOTE: all other exit paths should deconfig...
@@ -424,7 +421,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
424 state = MONITOR; 421 state = MONITOR;
425 break; 422 break;
426 case DEFEND: 423 case DEFEND:
427 // Defend period ended with no ARP replies - we won. 424 // Defend period ended with no ARP replies - we won
428 conflicts = 0; 425 conflicts = 0;
429 timeout_ms = -1; 426 timeout_ms = -1;
430 state = MONITOR; 427 state = MONITOR;
@@ -443,7 +440,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
443 diff = 0; 440 diff = 0;
444 } 441 }
445 VDBG("adjusting timeout\n"); 442 VDBG("adjusting timeout\n");
446 timeout_ms = (diff / 1000) | 1; /* never 0 */ 443 timeout_ms = (diff / 1000) | 1; // never 0
447 } 444 }
448 445
449 if ((fds[0].revents & POLLIN) == 0) { 446 if ((fds[0].revents & POLLIN) == 0) {
@@ -452,7 +449,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
452 // this shouldn't necessarily exit. 449 // this shouldn't necessarily exit.
453 bb_error_msg("iface %s is down", argv_intf); 450 bb_error_msg("iface %s is down", argv_intf);
454 if (state >= MONITOR) { 451 if (state >= MONITOR) {
455 /* only if we are in MONITOR or DEFEND */ 452 // only if we are in MONITOR or DEFEND
456 run(argv, "deconfig", chosen_nip); 453 run(argv, "deconfig", chosen_nip);
457 } 454 }
458 return EXIT_FAILURE; 455 return EXIT_FAILURE;
@@ -478,81 +475,65 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
478 struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; 475 struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha;
479 struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; 476 struct in_addr *spa = (struct in_addr *) p.arp.arp_spa;
480 struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; 477 struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa;
481 VDBG("%s recv arp type=%d, op=%d,\n", 478 VDBG("source=%s %s\n", ether_ntoa(sha), inet_ntoa(*spa));
482 argv_intf, ntohs(p.eth.ether_type), 479 VDBG("target=%s %s\n", ether_ntoa(tha), inet_ntoa(*tpa));
483 ntohs(p.arp.arp_op));
484 VDBG("\tsource=%s %s\n",
485 ether_ntoa(sha),
486 inet_ntoa(*spa));
487 VDBG("\ttarget=%s %s\n",
488 ether_ntoa(tha),
489 inet_ntoa(*tpa));
490 } 480 }
491#endif 481#endif
492 source_ip_conflict = 0; 482 ip_conflict = 0;
493 target_ip_conflict = 0;
494
495 if (memcmp(&p.arp.arp_sha, &G.eth_addr, ETH_ALEN) != 0) { 483 if (memcmp(&p.arp.arp_sha, &G.eth_addr, ETH_ALEN) != 0) {
496 if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { 484 if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) {
497 /* A probe or reply with source_ip == chosen ip */ 485 // A probe or reply with source_ip == chosen ip
498 source_ip_conflict = 1; 486 ip_conflict = 1;
499 } 487 }
500 if (p.arp.arp_op == htons(ARPOP_REQUEST) 488 if (p.arp.arp_op == htons(ARPOP_REQUEST)
501 && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 489 && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0
502 && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 490 && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0
503 ) { 491 ) {
504 /* A probe with source_ip == 0.0.0.0, target_ip == chosen ip: 492 // A probe with source_ip == 0.0.0.0, target_ip == chosen ip:
505 * another host trying to claim this ip! 493 // another host trying to claim this ip!
506 */ 494 ip_conflict |= 2;
507 target_ip_conflict = 1;
508 } 495 }
509 } 496 }
497 VDBG("state:%d ip_conflict:%d\n", state, ip_conflict);
498 if (!ip_conflict)
499 break;
510 500
511 VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n", 501 // Either src or target IP conflict exists
512 state, source_ip_conflict, target_ip_conflict); 502 if (state <= ANNOUNCE) {
513 switch (state) { 503 // PROBE or ANNOUNCE
514 case PROBE: 504 conflicts++;
515 case ANNOUNCE: 505 timeout_ms = PROBE_MIN * 1000
516 // When probing or announcing, check for source IP conflicts 506 + CONFLICT_MULTIPLIER * random_delay_ms(conflicts);
517 // and other hosts doing ARP probes (target IP conflicts). 507 chosen_nip = pick_nip();
518 if (source_ip_conflict || target_ip_conflict) { 508 nsent = 0;
519 conflicts++; 509 state = PROBE;
520 timeout_ms = PROBE_MIN * 1000
521 + CONFLICT_MULTIPLIER * random_delay_ms(conflicts);
522 chosen_nip = pick_nip();
523 nprobes = 0;
524 nclaims = 0;
525 state = PROBE;
526 }
527 break; 510 break;
528 case MONITOR: 511 }
529 // If a conflict, we try to defend with a single ARP probe. 512 // MONITOR or DEFEND: only src IP conflict is a problem
530 if (source_ip_conflict) { 513 if (ip_conflict & 1) {
531 VDBG("monitor conflict -- defending\n"); 514 if (state == MONITOR) {
515 // Src IP conflict, defend with a single ARP probe
516 VDBG("monitor conflict - defending\n");
532 timeout_ms = DEFEND_INTERVAL * 1000; 517 timeout_ms = DEFEND_INTERVAL * 1000;
533 state = DEFEND; 518 state = DEFEND;
534 arp(/* ARPOP_REQUEST, */ 519 arp(/* ARPOP_REQUEST, */
535 /* &G.eth_addr, */ chosen_nip, 520 /* &G.eth_addr, */ chosen_nip,
536 &G.eth_addr, chosen_nip); 521 &G.eth_addr, chosen_nip);
522 break;
537 } 523 }
538 break; 524 // state == DEFEND
539 case DEFEND: 525 // Another src IP conflict, start over
540 // Well, we tried. Start over (on conflict). 526 VDBG("defend conflict - starting over\n");
541 if (source_ip_conflict) { 527 run(argv, "deconfig", chosen_nip);
542 VDBG("defend conflict -- starting over\n"); 528
543 run(argv, "deconfig", chosen_nip); 529 // restart the whole protocol
544 530 timeout_ms = 0;
545 // restart the whole protocol 531 chosen_nip = pick_nip();
546 timeout_ms = 0; 532 nsent = 0;
547 chosen_nip = pick_nip(); 533 state = PROBE;
548 nprobes = 0; 534 }
549 nclaims = 0; 535 break; // case 1 (packet arrived)
550 state = PROBE; 536 } // switch (poll)
551 }
552 break;
553 } // switch state
554 break; // case 1 (packets arriving)
555 } // switch poll
556 } // while (1) 537 } // while (1)
557#undef argv_intf 538#undef argv_intf
558} 539}