Get IP multicast working on VLAN devices:
- Allocate zeroed memory in ether_resolvemulti() to prevent equal() from comparing garbage and determining that two otherwise-equal sockaddr_dls are different. - Fill in all required fields of the sockaddr_dl - Actually copy the multicast address into the sockaddr_dl when calling if_addmulti() - Don't claim that we don't have a way to resolve layer 3 addresses into layer 2 addresses; use the ethernet way.
This commit is contained in:
parent
4cb0ebe811
commit
26e3096360
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=76213
@ -837,14 +837,12 @@ ether_resolvemulti(ifp, llsa, sa)
|
||||
if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
|
||||
return EADDRNOTAVAIL;
|
||||
MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
|
||||
M_WAITOK);
|
||||
M_WAITOK|M_ZERO);
|
||||
sdl->sdl_len = sizeof *sdl;
|
||||
sdl->sdl_family = AF_LINK;
|
||||
sdl->sdl_index = ifp->if_index;
|
||||
sdl->sdl_type = IFT_ETHER;
|
||||
sdl->sdl_nlen = 0;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
e_addr = LLADDR(sdl);
|
||||
ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr);
|
||||
*llsa = (struct sockaddr *)sdl;
|
||||
@ -866,14 +864,12 @@ ether_resolvemulti(ifp, llsa, sa)
|
||||
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
|
||||
return EADDRNOTAVAIL;
|
||||
MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
|
||||
M_WAITOK);
|
||||
M_WAITOK|M_ZERO);
|
||||
sdl->sdl_len = sizeof *sdl;
|
||||
sdl->sdl_family = AF_LINK;
|
||||
sdl->sdl_index = ifp->if_index;
|
||||
sdl->sdl_type = IFT_ETHER;
|
||||
sdl->sdl_nlen = 0;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN;
|
||||
sdl->sdl_slen = 0;
|
||||
e_addr = LLADDR(sdl);
|
||||
ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
|
||||
*llsa = (struct sockaddr *)sdl;
|
||||
|
@ -123,6 +123,8 @@ vlan_setmulti(struct ifnet *ifp)
|
||||
bzero((char *)&sdl, sizeof sdl);
|
||||
sdl.sdl_len = sizeof sdl;
|
||||
sdl.sdl_family = AF_LINK;
|
||||
sdl.sdl_index = ifp_p->if_index;
|
||||
sdl.sdl_type = IFT_ETHER;
|
||||
sdl.sdl_alen = ETHER_ADDR_LEN;
|
||||
|
||||
/* First, remove any existing filter entries. */
|
||||
@ -144,6 +146,8 @@ vlan_setmulti(struct ifnet *ifp)
|
||||
bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
|
||||
(char *)&mc->mc_addr, ETHER_ADDR_LEN);
|
||||
SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries);
|
||||
bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
|
||||
LLADDR(&sdl), ETHER_ADDR_LEN);
|
||||
error = if_addmulti(ifp_p, (struct sockaddr *)&sdl, &rifma);
|
||||
if (error)
|
||||
return(error);
|
||||
@ -177,7 +181,6 @@ vlaninit(void)
|
||||
/* Now undo some of the damage... */
|
||||
ifp->if_data.ifi_type = IFT_8021_VLAN;
|
||||
ifp->if_data.ifi_hdrlen = EVL_ENCAPLEN;
|
||||
ifp->if_resolvemulti = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user