IPv6 was not work on FDDI.
Reported by: Akihiro IIJIMA <aki@noc.titech.ac.jp> Submitted by: JINMEI Tatuya <jinmei@isl.rdc.toshiba.co.jp> Reviewed by: Akihiro IIJIMA <aki@noc.titech.ac.jp>
This commit is contained in:
parent
506f494939
commit
e1a3fa4d50
@ -93,6 +93,9 @@ extern u_char at_org_code[ 3 ];
|
||||
extern u_char aarp_org_code[ 3 ];
|
||||
#endif /* NETATALK */
|
||||
|
||||
static int fddi_resolvemulti __P((struct ifnet *, struct sockaddr **,
|
||||
struct sockaddr *));
|
||||
|
||||
#define senderr(e) { error = (e); goto bad;}
|
||||
|
||||
/*
|
||||
@ -542,6 +545,7 @@ fddi_ifattach(ifp)
|
||||
ifp->if_addrlen = 6;
|
||||
ifp->if_hdrlen = 21;
|
||||
ifp->if_mtu = FDDIMTU;
|
||||
ifp->if_resolvemulti = fddi_resolvemulti;
|
||||
ifp->if_baudrate = 100000000;
|
||||
#ifdef IFF_NOTRAILERS
|
||||
ifp->if_flags |= IFF_NOTRAILERS;
|
||||
@ -569,3 +573,86 @@ fddi_ifattach(ifp)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
fddi_resolvemulti(ifp, llsa, sa)
|
||||
struct ifnet *ifp;
|
||||
struct sockaddr **llsa;
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
struct sockaddr_dl *sdl;
|
||||
struct sockaddr_in *sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
u_char *e_addr;
|
||||
|
||||
switch(sa->sa_family) {
|
||||
case AF_LINK:
|
||||
/*
|
||||
* No mapping needed. Just check that it's a valid MC address.
|
||||
*/
|
||||
sdl = (struct sockaddr_dl *)sa;
|
||||
e_addr = LLADDR(sdl);
|
||||
if ((e_addr[0] & 1) != 1)
|
||||
return EADDRNOTAVAIL;
|
||||
*llsa = 0;
|
||||
return 0;
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
|
||||
return EADDRNOTAVAIL;
|
||||
MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
|
||||
M_WAITOK);
|
||||
sdl->sdl_len = sizeof *sdl;
|
||||
sdl->sdl_family = AF_LINK;
|
||||
sdl->sdl_index = ifp->if_index;
|
||||
sdl->sdl_type = IFT_FDDI;
|
||||
sdl->sdl_nlen = 0;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN; /* XXX */
|
||||
sdl->sdl_slen = 0;
|
||||
e_addr = LLADDR(sdl);
|
||||
ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr);
|
||||
*llsa = (struct sockaddr *)sdl;
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)sa;
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
|
||||
/*
|
||||
* An IP6 address of 0 means listen to all
|
||||
* of the Ethernet multicast address used for IP6.
|
||||
* (This is used for multicast routers.)
|
||||
*/
|
||||
ifp->if_flags |= IFF_ALLMULTI;
|
||||
*llsa = 0;
|
||||
return 0;
|
||||
}
|
||||
if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
|
||||
return EADDRNOTAVAIL;
|
||||
MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
|
||||
M_WAITOK);
|
||||
sdl->sdl_len = sizeof *sdl;
|
||||
sdl->sdl_family = AF_LINK;
|
||||
sdl->sdl_index = ifp->if_index;
|
||||
sdl->sdl_type = IFT_FDDI;
|
||||
sdl->sdl_nlen = 0;
|
||||
sdl->sdl_alen = ETHER_ADDR_LEN; /* XXX */
|
||||
sdl->sdl_slen = 0;
|
||||
e_addr = LLADDR(sdl);
|
||||
ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
|
||||
*llsa = (struct sockaddr *)sdl;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
default:
|
||||
/*
|
||||
* Well, the text isn't quite right, but it's the name
|
||||
* that counts...
|
||||
*/
|
||||
return EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user