@@ -2146,7 +2146,8 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
21462146 return (ENOPROTOOPT );
21472147 }
21482148
2149- if (name == IPV6_NEXTHOP ) {
2149+ switch (name ) {
2150+ case IPV6_NEXTHOP : {
21502151 len = args -> optlen ;
21512152 error = linux_to_bsd_sockaddr (PTRIN (args -> optval ), & sa , & len );
21522153 if (error != 0 )
@@ -2155,7 +2156,34 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
21552156 error = kern_setsockopt (td , args -> s , level ,
21562157 name , sa , UIO_SYSSPACE , len );
21572158 free (sa , M_SONAME );
2158- } else {
2159+ break ;
2160+ }
2161+ case MCAST_JOIN_GROUP :
2162+ case MCAST_LEAVE_GROUP :
2163+ case MCAST_JOIN_SOURCE_GROUP :
2164+ case MCAST_LEAVE_SOURCE_GROUP : {
2165+ struct group_source_req req ;
2166+ size_t size ;
2167+
2168+ size = (name == MCAST_JOIN_SOURCE_GROUP ||
2169+ name == MCAST_LEAVE_SOURCE_GROUP ) ?
2170+ sizeof (struct group_source_req ) : sizeof (struct group_req );
2171+
2172+ if ((error = copyin (PTRIN (args -> optval ), & req , size )))
2173+ return (error );
2174+ len = sizeof (struct sockaddr_storage );
2175+ if ((error = linux_to_bsd_sockaddr (
2176+ (struct l_sockaddr * )& req .gsr_group , NULL , & len )))
2177+ return (error );
2178+ if (size == sizeof (struct group_source_req ) &&
2179+ (error = linux_to_bsd_sockaddr (
2180+ (struct l_sockaddr * )& req .gsr_source , NULL , & len )))
2181+ return (error );
2182+ error = kern_setsockopt (td , args -> s , level , name , & req ,
2183+ UIO_SYSSPACE , size );
2184+ break ;
2185+ }
2186+ default :
21592187 error = kern_setsockopt (td , args -> s , level ,
21602188 name , PTRIN (args -> optval ), UIO_USERSPACE , args -> optlen );
21612189 }
0 commit comments