* Do link-level ifa job: * 1) Add lle entry for added address * 2) Notifies routing socket users about new address * 3) join appropriate multicast group * 4) start DAD if enabled */
| 1190 | * 4) start DAD if enabled |
| 1191 | */ |
| 1192 | static int |
| 1193 | in6_broadcast_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, |
| 1194 | struct in6_ifaddr *ia, int flags) |
| 1195 | { |
| 1196 | struct in6_multi *in6m_sol; |
| 1197 | int error = 0; |
| 1198 | |
| 1199 | /* Add local address to lltable, if necessary (ex. on p2p link). */ |
| 1200 | if ((error = nd6_add_ifa_lle(ia)) != 0) { |
| 1201 | in6_purgeaddr(&ia->ia_ifa); |
| 1202 | ifa_free(&ia->ia_ifa); |
| 1203 | return (error); |
| 1204 | } |
| 1205 | |
| 1206 | /* Join necessary multicast groups. */ |
| 1207 | in6m_sol = NULL; |
| 1208 | if ((ifp->if_flags & IFF_MULTICAST) != 0) { |
| 1209 | error = in6_update_ifa_join_mc(ifp, ifra, ia, flags, &in6m_sol); |
| 1210 | if (error != 0) { |
| 1211 | in6_purgeaddr(&ia->ia_ifa); |
| 1212 | ifa_free(&ia->ia_ifa); |
| 1213 | return (error); |
| 1214 | } |
| 1215 | } |
| 1216 | |
| 1217 | /* Perform DAD, if the address is TENTATIVE. */ |
| 1218 | if ((ia->ia6_flags & IN6_IFF_TENTATIVE)) { |
| 1219 | int delay, mindelay, maxdelay; |
| 1220 | |
| 1221 | delay = 0; |
| 1222 | if ((flags & IN6_IFAUPDATE_DADDELAY)) { |
| 1223 | /* |
| 1224 | * We need to impose a delay before sending an NS |
| 1225 | * for DAD. Check if we also needed a delay for the |
| 1226 | * corresponding MLD message. If we did, the delay |
| 1227 | * should be larger than the MLD delay (this could be |
| 1228 | * relaxed a bit, but this simple logic is at least |
| 1229 | * safe). |
| 1230 | * XXX: Break data hiding guidelines and look at |
| 1231 | * state for the solicited multicast group. |
| 1232 | */ |
| 1233 | mindelay = 0; |
| 1234 | if (in6m_sol != NULL && |
| 1235 | in6m_sol->in6m_state == MLD_REPORTING_MEMBER) { |
| 1236 | mindelay = in6m_sol->in6m_timer; |
| 1237 | } |
| 1238 | maxdelay = MAX_RTR_SOLICITATION_DELAY * hz; |
| 1239 | if (maxdelay - mindelay == 0) |
| 1240 | delay = 0; |
| 1241 | else { |
| 1242 | delay = |
| 1243 | (arc4random() % (maxdelay - mindelay)) + |
| 1244 | mindelay; |
| 1245 | } |
| 1246 | } |
| 1247 | nd6_dad_start((struct ifaddr *)ia, delay); |
| 1248 | } |
| 1249 |
no test coverage detected