acd.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. /**
  2. * @file
  3. *
  4. * ACD IPv4 Address Conflict Detection
  5. *
  6. * This is an IPv4 address conflict detection implementation for the lwIP TCP/IP
  7. * stack. It aims to be conform to RFC5227.
  8. *
  9. * @defgroup acd ACD
  10. * @ingroup ip4
  11. * ACD related functions
  12. * USAGE:
  13. *
  14. * define @ref LWIP_ACD 1 in your lwipopts.h
  15. * Options:
  16. * ACD_TMR_INTERVAL msecs,
  17. * I recommend a value of 100. The value must divide 1000 with a remainder almost 0.
  18. * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 ....
  19. *
  20. * For fixed IP:
  21. * - call acd_start after selecting an IP address. The caller will be informed
  22. * on conflict status via the callback function.
  23. *
  24. * With AUTOIP:
  25. * - will be called from the autoip module. No extra's needed.
  26. *
  27. * With DHCP:
  28. * - enable LWIP_DHCP_DOES_ACD_CHECK. Then it will be called from the dhcp module.
  29. * No extra's needed.
  30. */
  31. /*
  32. *
  33. * Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
  34. * Copyright (c) 2018 Jasper Verschueren <jasper.verschueren@apart-audio.com>
  35. * All rights reserved.
  36. *
  37. * Redistribution and use in source and binary forms, with or without modification,
  38. * are permitted provided that the following conditions are met:
  39. *
  40. * 1. Redistributions of source code must retain the above copyright notice,
  41. * this list of conditions and the following disclaimer.
  42. * 2. Redistributions in binary form must reproduce the above copyright notice,
  43. * this list of conditions and the following disclaimer in the documentation
  44. * and/or other materials provided with the distribution.
  45. * 3. The name of the author may not be used to endorse or promote products
  46. * derived from this software without specific prior written permission.
  47. *
  48. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  49. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  50. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  51. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  52. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  53. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  54. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  55. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  56. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  57. * OF SUCH DAMAGE.
  58. *
  59. * Author: Jasper Verschueren <jasper.verschueren@apart-audio.com>
  60. * Author: Dominik Spies <kontakt@dspies.de>
  61. */
  62. #include "lwip/opt.h"
  63. /* don't build if not configured for use in lwipopts.h */
  64. #if LWIP_IPV4 && LWIP_ACD
  65. #include <string.h>
  66. #include "lwip/acd.h"
  67. #include "lwip/prot/acd.h"
  68. #define ACD_FOREACH(acd, acd_list) for ((acd) = acd_list; (acd) != NULL; (acd) = (acd)->next)
  69. #define ACD_TICKS_PER_SECOND (1000 / ACD_TMR_INTERVAL)
  70. /* Define good random function (LWIP_RAND) in lwipopts.h */
  71. #ifdef LWIP_RAND
  72. #define LWIP_ACD_RAND(netif, acd) LWIP_RAND()
  73. #else /* LWIP_RAND */
  74. #ifdef LWIP_AUTOIP_RAND
  75. #include "lwip/autoip.h"
  76. #define LWIP_ACD_RAND(netif, acd) LWIP_AUTOIP_RAND(netif) /* for backwards compatibility */
  77. #else
  78. #define LWIP_ACD_RAND(netif, acd) ((((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
  79. ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
  80. ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
  81. ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
  82. (acd->sent_num))
  83. #endif /* LWIP_AUTOIP_RAND */
  84. #endif /* LWIP_RAND */
  85. #define ACD_RANDOM_PROBE_WAIT(netif, acd) (LWIP_ACD_RAND(netif, acd) % \
  86. (PROBE_WAIT * ACD_TICKS_PER_SECOND))
  87. #define ACD_RANDOM_PROBE_INTERVAL(netif, acd) ((LWIP_ACD_RAND(netif, acd) % \
  88. ((PROBE_MAX - PROBE_MIN) * ACD_TICKS_PER_SECOND)) + \
  89. (PROBE_MIN * ACD_TICKS_PER_SECOND ))
  90. /* Function definitions */
  91. static void acd_restart(struct netif *netif, struct acd *acd);
  92. static void acd_handle_arp_conflict(struct netif *netif, struct acd *acd);
  93. static void acd_put_in_passive_mode(struct netif *netif, struct acd *acd);
  94. /**
  95. * @ingroup acd
  96. * Add ACD client to the client list and initialize callback function
  97. *
  98. * @param netif network interface on which to start the acd
  99. * client
  100. * @param acd acd module to be added to the list
  101. * @param acd_conflict_callback callback to be called when conflict information
  102. * is available
  103. */
  104. err_t
  105. acd_add(struct netif *netif, struct acd *acd,
  106. acd_conflict_callback_t acd_conflict_callback)
  107. {
  108. struct acd *acd2;
  109. /* Set callback */
  110. LWIP_ASSERT_CORE_LOCKED();
  111. LWIP_ASSERT("acd_conflict_callback != NULL", acd_conflict_callback != NULL);
  112. acd->acd_conflict_callback = acd_conflict_callback;
  113. /* Check if the acd struct is already added */
  114. for (acd2 = netif->acd_list; acd2 != NULL; acd2 = acd2->next) {
  115. if (acd2 == acd) {
  116. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  117. ("acd_add(): acd already added to list\n"));
  118. return ERR_OK;
  119. }
  120. }
  121. /* add acd struct to the list */
  122. acd->next = netif->acd_list;
  123. netif->acd_list = acd;
  124. return ERR_OK;
  125. }
  126. /**
  127. * @ingroup acd
  128. * Remove ACD client from the client list
  129. *
  130. * @param netif network interface from which to remove the acd client
  131. * @param acd acd module to be removed from the list
  132. */
  133. void
  134. acd_remove(struct netif *netif, struct acd *acd)
  135. {
  136. struct acd *acd2, *prev = NULL;
  137. LWIP_ASSERT_CORE_LOCKED();
  138. for (acd2 = netif->acd_list; acd2 != NULL; acd2 = acd2->next) {
  139. if (acd2 == acd) {
  140. if (prev) {
  141. prev->next = acd->next;
  142. } else {
  143. netif->acd_list = acd->next;
  144. }
  145. return;
  146. }
  147. prev = acd2;
  148. }
  149. LWIP_ASSERT(("acd_remove(): acd not on list\n"), 0);
  150. }
  151. /**
  152. * @ingroup acd
  153. * Start ACD client
  154. *
  155. * @param netif network interface on which to start the acd client
  156. * @param acd acd module to start
  157. * @param ipaddr ip address to perform acd on
  158. */
  159. err_t
  160. acd_start(struct netif *netif, struct acd *acd, ip4_addr_t ipaddr)
  161. {
  162. err_t result = ERR_OK;
  163. LWIP_UNUSED_ARG(netif);
  164. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  165. ("acd_start(netif=%p) %c%c%"U16_F"\n",
  166. (void *)netif, netif->name[0],
  167. netif->name[1], (u16_t)netif->num));
  168. /* init probing state */
  169. acd->sent_num = 0;
  170. acd->lastconflict = 0;
  171. ip4_addr_copy(acd->ipaddr, ipaddr);
  172. acd->state = ACD_STATE_PROBE_WAIT;
  173. acd->ttw = (u16_t)(ACD_RANDOM_PROBE_WAIT(netif, acd));
  174. return result;
  175. }
  176. /**
  177. * @ingroup acd
  178. * Stop ACD client
  179. *
  180. * @param acd acd module to stop
  181. */
  182. err_t
  183. acd_stop(struct acd *acd)
  184. {
  185. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("acd_stop\n"));
  186. if (acd != NULL) {
  187. acd->state = ACD_STATE_OFF;
  188. }
  189. return ERR_OK;
  190. }
  191. /**
  192. * @ingroup acd
  193. * Inform the ACD modules when the link goes down
  194. *
  195. * @param netif network interface on which to inform the ACD clients
  196. */
  197. void
  198. acd_network_changed_link_down(struct netif *netif)
  199. {
  200. struct acd *acd;
  201. /* loop over the acd's*/
  202. ACD_FOREACH(acd, netif->acd_list) {
  203. acd_stop(acd);
  204. }
  205. }
  206. /**
  207. * Has to be called in loop every ACD_TMR_INTERVAL milliseconds
  208. */
  209. void
  210. acd_tmr(void)
  211. {
  212. struct netif *netif;
  213. struct acd *acd;
  214. /* loop through netif's */
  215. NETIF_FOREACH(netif) {
  216. ACD_FOREACH(acd, netif->acd_list) {
  217. if (acd->lastconflict > 0) {
  218. acd->lastconflict--;
  219. }
  220. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE,
  221. ("acd_tmr() ACD-State: %"U16_F", ttw=%"U16_F"\n",
  222. (u16_t)(acd->state), acd->ttw));
  223. if (acd->ttw > 0) {
  224. acd->ttw--;
  225. }
  226. switch (acd->state) {
  227. case ACD_STATE_PROBE_WAIT:
  228. case ACD_STATE_PROBING:
  229. if (acd->ttw == 0) {
  230. acd->state = ACD_STATE_PROBING;
  231. etharp_acd_probe(netif, &acd->ipaddr);
  232. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE,
  233. ("acd_tmr() PROBING Sent Probe\n"));
  234. acd->sent_num++;
  235. if (acd->sent_num >= PROBE_NUM) {
  236. /* Switch to ANNOUNCE_WAIT: last probe is sent*/
  237. acd->state = ACD_STATE_ANNOUNCE_WAIT;
  238. acd->sent_num = 0;
  239. /* calculate time to wait before announcing */
  240. acd->ttw = (u16_t)(ANNOUNCE_WAIT * ACD_TICKS_PER_SECOND);
  241. } else {
  242. /* calculate time to wait to next probe */
  243. acd->ttw = (u16_t)(ACD_RANDOM_PROBE_INTERVAL(netif, acd));
  244. }
  245. }
  246. break;
  247. case ACD_STATE_ANNOUNCE_WAIT:
  248. case ACD_STATE_ANNOUNCING:
  249. if (acd->ttw == 0) {
  250. if (acd->sent_num == 0) {
  251. acd->state = ACD_STATE_ANNOUNCING;
  252. /* reset conflict count to ensure fast re-probing after announcing */
  253. acd->num_conflicts = 0;
  254. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  255. ("acd_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
  256. ip4_addr1_16(&acd->ipaddr), ip4_addr2_16(&acd->ipaddr),
  257. ip4_addr3_16(&acd->ipaddr), ip4_addr4_16(&acd->ipaddr)));
  258. }
  259. etharp_acd_announce(netif, &acd->ipaddr);
  260. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE,
  261. ("acd_tmr() ANNOUNCING Sent Announce\n"));
  262. acd->ttw = ANNOUNCE_INTERVAL * ACD_TICKS_PER_SECOND;
  263. acd->sent_num++;
  264. if (acd->sent_num >= ANNOUNCE_NUM) {
  265. acd->state = ACD_STATE_ONGOING;
  266. acd->sent_num = 0;
  267. acd->ttw = 0;
  268. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  269. ("acd_tmr(): changing state to ONGOING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
  270. ip4_addr1_16(&acd->ipaddr), ip4_addr2_16(&acd->ipaddr),
  271. ip4_addr3_16(&acd->ipaddr), ip4_addr4_16(&acd->ipaddr)));
  272. /* finally, let acd user know that the address is good and can be used */
  273. acd->acd_conflict_callback(netif, ACD_IP_OK);
  274. }
  275. }
  276. break;
  277. case ACD_STATE_RATE_LIMIT:
  278. if (acd->ttw == 0) {
  279. /* acd should be stopped because ipaddr isn't valid any more */
  280. acd_stop(acd);
  281. /* let the acd user (after rate limit interval) know that their is
  282. * a conflict detected. So it can restart the address acquiring
  283. * process.*/
  284. acd->acd_conflict_callback(netif, ACD_RESTART_CLIENT);
  285. }
  286. break;
  287. default:
  288. /* nothing to do in other states */
  289. break;
  290. }
  291. }
  292. }
  293. }
  294. /**
  295. * Restarts the acd module
  296. *
  297. * The number of conflicts is increased and the upper layer is informed.
  298. */
  299. static void
  300. acd_restart(struct netif *netif, struct acd *acd)
  301. {
  302. /* increase conflict counter. */
  303. acd->num_conflicts++;
  304. /* Decline the address */
  305. acd->acd_conflict_callback(netif, ACD_DECLINE);
  306. /* if we tried more then MAX_CONFLICTS we must limit our rate for
  307. * acquiring and probing addresses. compliant to RFC 5227 Section 2.1.1 */
  308. if (acd->num_conflicts >= MAX_CONFLICTS) {
  309. acd->state = ACD_STATE_RATE_LIMIT;
  310. acd->ttw = (u16_t)(RATE_LIMIT_INTERVAL * ACD_TICKS_PER_SECOND);
  311. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
  312. ("acd_restart(): rate limiting initiated. too many conflicts\n"));
  313. }
  314. else {
  315. /* acd should be stopped because ipaddr isn't valid any more */
  316. acd_stop(acd);
  317. /* let the acd user know right away that their is a conflict detected.
  318. * So it can restart the address acquiring process. */
  319. acd->acd_conflict_callback(netif, ACD_RESTART_CLIENT);
  320. }
  321. }
  322. /**
  323. * Handles every incoming ARP Packet, called by etharp_input().
  324. *
  325. * @param netif network interface to use for acd processing
  326. * @param hdr Incoming ARP packet
  327. */
  328. void
  329. acd_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
  330. {
  331. struct acd *acd;
  332. ip4_addr_t sipaddr, dipaddr;
  333. struct eth_addr netifaddr;
  334. SMEMCPY(netifaddr.addr, netif->hwaddr, ETH_HWADDR_LEN);
  335. /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support
  336. * compilers without structure packing (not using structure copy which
  337. * breaks strict-aliasing rules).
  338. */
  339. IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr);
  340. IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr);
  341. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE, ("acd_arp_reply()\n"));
  342. /* loop over the acd's*/
  343. ACD_FOREACH(acd, netif->acd_list) {
  344. switch(acd->state) {
  345. case ACD_STATE_OFF:
  346. case ACD_STATE_RATE_LIMIT:
  347. default:
  348. /* do nothing */
  349. break;
  350. case ACD_STATE_PROBE_WAIT:
  351. case ACD_STATE_PROBING:
  352. case ACD_STATE_ANNOUNCE_WAIT:
  353. /* RFC 5227 Section 2.1.1:
  354. * from beginning to after ANNOUNCE_WAIT seconds we have a conflict if
  355. * ip.src == ipaddr (someone is already using the address)
  356. * OR
  357. * ip.dst == ipaddr && hw.src != own hwaddr (someone else is probing it)
  358. */
  359. if ((ip4_addr_eq(&sipaddr, &acd->ipaddr)) ||
  360. (ip4_addr_isany_val(sipaddr) &&
  361. ip4_addr_eq(&dipaddr, &acd->ipaddr) &&
  362. !eth_addr_eq(&netifaddr, &hdr->shwaddr))) {
  363. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
  364. ("acd_arp_reply(): Probe Conflict detected\n"));
  365. acd_restart(netif, acd);
  366. }
  367. break;
  368. case ACD_STATE_ANNOUNCING:
  369. case ACD_STATE_ONGOING:
  370. case ACD_STATE_PASSIVE_ONGOING:
  371. /* RFC 5227 Section 2.4:
  372. * in any state we have a conflict if
  373. * ip.src == ipaddr && hw.src != own hwaddr (someone is using our address)
  374. */
  375. if (ip4_addr_eq(&sipaddr, &acd->ipaddr) &&
  376. !eth_addr_eq(&netifaddr, &hdr->shwaddr)) {
  377. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
  378. ("acd_arp_reply(): Conflicting ARP-Packet detected\n"));
  379. acd_handle_arp_conflict(netif, acd);
  380. }
  381. break;
  382. }
  383. }
  384. }
  385. /**
  386. * Handle a IP address conflict after an ARP conflict detection
  387. */
  388. static void
  389. acd_handle_arp_conflict(struct netif *netif, struct acd *acd)
  390. {
  391. /* RFC5227, 2.4 "Ongoing Address Conflict Detection and Address Defense"
  392. allows three options where:
  393. a) means retreat on the first conflict,
  394. b) allows to keep an already configured address when having only one
  395. conflict in DEFEND_INTERVAL seconds and
  396. c) the host will not give up it's address and defend it indefinitely
  397. We use option b) when the acd module represents the netif address, since it
  398. helps to improve the chance that one of the two conflicting hosts may be
  399. able to retain its address. while we are flexible enough to help network
  400. performance
  401. We use option a) when the acd module does not represent the netif address,
  402. since we cannot have the acd module announcing or restarting. This
  403. situation occurs for the LL acd module when a routable address is used on
  404. the netif but the LL address is still open in the background. */
  405. if (acd->state == ACD_STATE_PASSIVE_ONGOING) {
  406. /* Immediately back off on a conflict. */
  407. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  408. ("acd_handle_arp_conflict(): conflict when we are in passive mode -> back off\n"));
  409. acd_stop(acd);
  410. acd->acd_conflict_callback(netif, ACD_DECLINE);
  411. }
  412. else {
  413. if (acd->lastconflict > 0) {
  414. /* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */
  415. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  416. ("acd_handle_arp_conflict(): conflict within DEFEND_INTERVAL -> retreating\n"));
  417. /* Active TCP sessions are aborted when removing the ip address but a bad
  418. * connection was inevitable anyway with conflicting hosts */
  419. acd_restart(netif, acd);
  420. } else {
  421. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  422. ("acd_handle_arp_conflict(): we are defending, send ARP Announce\n"));
  423. etharp_acd_announce(netif, &acd->ipaddr);
  424. acd->lastconflict = DEFEND_INTERVAL * ACD_TICKS_PER_SECOND;
  425. }
  426. }
  427. }
  428. /**
  429. * Put the acd module in passive ongoing conflict detection.
  430. */
  431. static void
  432. acd_put_in_passive_mode(struct netif *netif, struct acd *acd)
  433. {
  434. switch(acd->state) {
  435. case ACD_STATE_OFF:
  436. case ACD_STATE_PASSIVE_ONGOING:
  437. default:
  438. /* do nothing */
  439. break;
  440. case ACD_STATE_PROBE_WAIT:
  441. case ACD_STATE_PROBING:
  442. case ACD_STATE_ANNOUNCE_WAIT:
  443. case ACD_STATE_RATE_LIMIT:
  444. acd_stop(acd);
  445. acd->acd_conflict_callback(netif, ACD_DECLINE);
  446. break;
  447. case ACD_STATE_ANNOUNCING:
  448. case ACD_STATE_ONGOING:
  449. acd->state = ACD_STATE_PASSIVE_ONGOING;
  450. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  451. ("acd_put_in_passive_mode()\n"));
  452. break;
  453. }
  454. }
  455. /**
  456. * @ingroup acd
  457. * Inform the ACD modules of address changes
  458. *
  459. * @param netif network interface on which the address is changing
  460. * @param old_addr old ip address
  461. * @param new_addr new ip address
  462. */
  463. void
  464. acd_netif_ip_addr_changed(struct netif *netif, const ip_addr_t *old_addr,
  465. const ip_addr_t *new_addr)
  466. {
  467. struct acd *acd;
  468. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  469. ("acd_netif_ip_addr_changed(): Address changed\n"));
  470. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  471. ("acd_netif_ip_addr_changed(): old address = %s\n", ipaddr_ntoa(old_addr)));
  472. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  473. ("acd_netif_ip_addr_changed(): new address = %s\n", ipaddr_ntoa(new_addr)));
  474. /* If we change from ANY to an IP or from an IP to ANY we do nothing */
  475. if (ip_addr_isany(old_addr) || ip_addr_isany(new_addr)) {
  476. return;
  477. }
  478. ACD_FOREACH(acd, netif->acd_list) {
  479. /* Find ACD module of old address */
  480. if(ip4_addr_eq(&acd->ipaddr, ip_2_ip4(old_addr))) {
  481. /* Did we change from a LL address to a routable address? */
  482. if (ip_addr_islinklocal(old_addr) && !ip_addr_islinklocal(new_addr)) {
  483. LWIP_DEBUGF(ACD_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
  484. ("acd_netif_ip_addr_changed(): changed from LL to routable address\n"));
  485. /* Put the module in passive conflict detection mode */
  486. acd_put_in_passive_mode(netif, acd);
  487. }
  488. }
  489. }
  490. }
  491. #endif /* LWIP_IPV4 && LWIP_ACD */