* Setup multicast structures. */
| 1374 | * Setup multicast structures. |
| 1375 | */ |
| 1376 | static int |
| 1377 | carp_multicast_setup(struct carp_if *cif, sa_family_t sa) |
| 1378 | { |
| 1379 | struct ifnet *ifp = cif->cif_ifp; |
| 1380 | int error = 0; |
| 1381 | |
| 1382 | switch (sa) { |
| 1383 | #ifdef INET |
| 1384 | case AF_INET: |
| 1385 | { |
| 1386 | struct ip_moptions *imo = &cif->cif_imo; |
| 1387 | struct in_mfilter *imf; |
| 1388 | struct in_addr addr; |
| 1389 | |
| 1390 | if (ip_mfilter_first(&imo->imo_head) != NULL) |
| 1391 | return (0); |
| 1392 | |
| 1393 | imf = ip_mfilter_alloc(M_WAITOK, 0, 0); |
| 1394 | ip_mfilter_init(&imo->imo_head); |
| 1395 | imo->imo_multicast_vif = -1; |
| 1396 | |
| 1397 | addr.s_addr = htonl(INADDR_CARP_GROUP); |
| 1398 | if ((error = in_joingroup(ifp, &addr, NULL, |
| 1399 | &imf->imf_inm)) != 0) { |
| 1400 | ip_mfilter_free(imf); |
| 1401 | break; |
| 1402 | } |
| 1403 | |
| 1404 | ip_mfilter_insert(&imo->imo_head, imf); |
| 1405 | imo->imo_multicast_ifp = ifp; |
| 1406 | imo->imo_multicast_ttl = CARP_DFLTTL; |
| 1407 | imo->imo_multicast_loop = 0; |
| 1408 | break; |
| 1409 | } |
| 1410 | #endif |
| 1411 | #ifdef INET6 |
| 1412 | case AF_INET6: |
| 1413 | { |
| 1414 | struct ip6_moptions *im6o = &cif->cif_im6o; |
| 1415 | struct in6_mfilter *im6f[2]; |
| 1416 | struct in6_addr in6; |
| 1417 | |
| 1418 | if (ip6_mfilter_first(&im6o->im6o_head)) |
| 1419 | return (0); |
| 1420 | |
| 1421 | im6f[0] = ip6_mfilter_alloc(M_WAITOK, 0, 0); |
| 1422 | im6f[1] = ip6_mfilter_alloc(M_WAITOK, 0, 0); |
| 1423 | |
| 1424 | ip6_mfilter_init(&im6o->im6o_head); |
| 1425 | im6o->im6o_multicast_hlim = CARP_DFLTTL; |
| 1426 | im6o->im6o_multicast_ifp = ifp; |
| 1427 | |
| 1428 | /* Join IPv6 CARP multicast group. */ |
| 1429 | bzero(&in6, sizeof(in6)); |
| 1430 | in6.s6_addr16[0] = htons(0xff02); |
| 1431 | in6.s6_addr8[15] = 0x12; |
| 1432 | if ((error = in6_setscope(&in6, ifp, NULL)) != 0) { |
| 1433 | ip6_mfilter_free(im6f[0]); |
no test coverage detected