* Retransmit a Gratuitous ARP (GARP) and, if necessary, schedule a callout to * retransmit it again. A pending callout owns a reference to the ifa. */
| 1353 | * retransmit it again. A pending callout owns a reference to the ifa. |
| 1354 | */ |
| 1355 | static void |
| 1356 | garp_rexmit(void *arg) |
| 1357 | { |
| 1358 | struct in_ifaddr *ia = arg; |
| 1359 | |
| 1360 | if (callout_pending(&ia->ia_garp_timer) || |
| 1361 | !callout_active(&ia->ia_garp_timer)) { |
| 1362 | IF_ADDR_WUNLOCK(ia->ia_ifa.ifa_ifp); |
| 1363 | ifa_free(&ia->ia_ifa); |
| 1364 | return; |
| 1365 | } |
| 1366 | |
| 1367 | CURVNET_SET(ia->ia_ifa.ifa_ifp->if_vnet); |
| 1368 | |
| 1369 | /* |
| 1370 | * Drop lock while the ARP request is generated. |
| 1371 | */ |
| 1372 | IF_ADDR_WUNLOCK(ia->ia_ifa.ifa_ifp); |
| 1373 | |
| 1374 | arprequest(ia->ia_ifa.ifa_ifp, &IA_SIN(ia)->sin_addr, |
| 1375 | &IA_SIN(ia)->sin_addr, IF_LLADDR(ia->ia_ifa.ifa_ifp)); |
| 1376 | |
| 1377 | /* |
| 1378 | * Increment the count of retransmissions. If the count has reached the |
| 1379 | * maximum value, stop sending the GARP packets. Otherwise, schedule |
| 1380 | * the callout to retransmit another GARP packet. |
| 1381 | */ |
| 1382 | ++ia->ia_garp_count; |
| 1383 | if (ia->ia_garp_count >= garp_rexmit_count) { |
| 1384 | ifa_free(&ia->ia_ifa); |
| 1385 | } else { |
| 1386 | int rescheduled; |
| 1387 | IF_ADDR_WLOCK(ia->ia_ifa.ifa_ifp); |
| 1388 | rescheduled = callout_reset(&ia->ia_garp_timer, |
| 1389 | (1 << ia->ia_garp_count) * hz, |
| 1390 | garp_rexmit, ia); |
| 1391 | IF_ADDR_WUNLOCK(ia->ia_ifa.ifa_ifp); |
| 1392 | if (rescheduled) { |
| 1393 | ifa_free(&ia->ia_ifa); |
| 1394 | } |
| 1395 | } |
| 1396 | |
| 1397 | CURVNET_RESTORE(); |
| 1398 | } |
| 1399 | |
| 1400 | /* |
| 1401 | * Start the GARP retransmit timer. |
nothing calls this directly
no test coverage detected