| 1132 | } |
| 1133 | |
| 1134 | static int |
| 1135 | vxlan_socket_mc_join_group(struct vxlan_socket *vso, |
| 1136 | const union vxlan_sockaddr *group, const union vxlan_sockaddr *local, |
| 1137 | int *ifidx, union vxlan_sockaddr *source) |
| 1138 | { |
| 1139 | struct sockopt sopt; |
| 1140 | int error; |
| 1141 | |
| 1142 | *source = *local; |
| 1143 | |
| 1144 | if (VXLAN_SOCKADDR_IS_IPV4(group)) { |
| 1145 | struct ip_mreq mreq; |
| 1146 | |
| 1147 | mreq.imr_multiaddr = group->in4.sin_addr; |
| 1148 | mreq.imr_interface = local->in4.sin_addr; |
| 1149 | |
| 1150 | bzero(&sopt, sizeof(sopt)); |
| 1151 | sopt.sopt_dir = SOPT_SET; |
| 1152 | sopt.sopt_level = IPPROTO_IP; |
| 1153 | sopt.sopt_name = IP_ADD_MEMBERSHIP; |
| 1154 | sopt.sopt_val = &mreq; |
| 1155 | sopt.sopt_valsize = sizeof(mreq); |
| 1156 | error = sosetopt(vso->vxlso_sock, &sopt); |
| 1157 | if (error) |
| 1158 | return (error); |
| 1159 | |
| 1160 | /* |
| 1161 | * BMV: Ideally, there would be a formal way for us to get |
| 1162 | * the local interface that was selected based on the |
| 1163 | * imr_interface address. We could then update *ifidx so |
| 1164 | * vxlan_sockaddr_mc_info_match() would return a match for |
| 1165 | * later creates that explicitly set the multicast interface. |
| 1166 | * |
| 1167 | * If we really need to, we can of course look in the INP's |
| 1168 | * membership list: |
| 1169 | * sotoinpcb(vso->vxlso_sock)->inp_moptions-> |
| 1170 | * imo_head[]->imf_inm->inm_ifp |
| 1171 | * similarly to imo_match_group(). |
| 1172 | */ |
| 1173 | source->in4.sin_addr = local->in4.sin_addr; |
| 1174 | |
| 1175 | } else if (VXLAN_SOCKADDR_IS_IPV6(group)) { |
| 1176 | struct ipv6_mreq mreq; |
| 1177 | |
| 1178 | mreq.ipv6mr_multiaddr = group->in6.sin6_addr; |
| 1179 | mreq.ipv6mr_interface = *ifidx; |
| 1180 | |
| 1181 | bzero(&sopt, sizeof(sopt)); |
| 1182 | sopt.sopt_dir = SOPT_SET; |
| 1183 | sopt.sopt_level = IPPROTO_IPV6; |
| 1184 | sopt.sopt_name = IPV6_JOIN_GROUP; |
| 1185 | sopt.sopt_val = &mreq; |
| 1186 | sopt.sopt_valsize = sizeof(mreq); |
| 1187 | error = sosetopt(vso->vxlso_sock, &sopt); |
| 1188 | if (error) |
| 1189 | return (error); |
| 1190 | |
| 1191 | /* |
no test coverage detected