| 1208 | } |
| 1209 | |
| 1210 | static void |
| 1211 | lagg_watchdog_infiniband(void *arg) |
| 1212 | { |
| 1213 | struct epoch_tracker et; |
| 1214 | struct lagg_softc *sc; |
| 1215 | struct lagg_port *lp; |
| 1216 | struct ifnet *ifp; |
| 1217 | struct ifnet *lp_ifp; |
| 1218 | |
| 1219 | sc = arg; |
| 1220 | |
| 1221 | /* |
| 1222 | * Because infiniband nodes have a fixed MAC address, which is |
| 1223 | * generated by the so-called GID, we need to regularly update |
| 1224 | * the link level address of the parent lagg<N> device when |
| 1225 | * the active port changes. Possibly we could piggy-back on |
| 1226 | * link up/down events aswell, but using a timer also provides |
| 1227 | * a guarantee against too frequent events. This operation |
| 1228 | * does not have to be atomic. |
| 1229 | */ |
| 1230 | NET_EPOCH_ENTER(et); |
| 1231 | lp = lagg_link_active(sc, sc->sc_primary); |
| 1232 | if (lp != NULL) { |
| 1233 | ifp = sc->sc_ifp; |
| 1234 | lp_ifp = lp->lp_ifp; |
| 1235 | |
| 1236 | if (ifp != NULL && lp_ifp != NULL && |
| 1237 | (memcmp(IF_LLADDR(ifp), IF_LLADDR(lp_ifp), ifp->if_addrlen) != 0 || |
| 1238 | memcmp(sc->sc_bcast_addr, lp_ifp->if_broadcastaddr, ifp->if_addrlen) != 0)) { |
| 1239 | memcpy(IF_LLADDR(ifp), IF_LLADDR(lp_ifp), ifp->if_addrlen); |
| 1240 | memcpy(sc->sc_bcast_addr, lp_ifp->if_broadcastaddr, ifp->if_addrlen); |
| 1241 | |
| 1242 | CURVNET_SET(ifp->if_vnet); |
| 1243 | EVENTHANDLER_INVOKE(iflladdr_event, ifp); |
| 1244 | CURVNET_RESTORE(); |
| 1245 | } |
| 1246 | } |
| 1247 | NET_EPOCH_EXIT(et); |
| 1248 | |
| 1249 | callout_reset(&sc->sc_watchdog, hz, &lagg_watchdog_infiniband, arg); |
| 1250 | } |
| 1251 | |
| 1252 | static void |
| 1253 | lagg_init(void *xsc) |
no test coverage detected