Commits
Dmitrij Tejblum authored and Denis Ovsienko committed 10d04cdb419
202 202 | * (e.g. Linux, Solaris) behave when leaving groups on down interfaces, |
203 203 | * but this behavior should not be harmful if they behave the same way, |
204 204 | * allow leaves, or implicitly leave all groups joined to down interfaces. |
205 205 | */ |
206 206 | int |
207 207 | setsockopt_ipv4_multicast(int sock, |
208 208 | int optname, |
209 209 | unsigned int mcast_addr, |
210 210 | unsigned int ifindex) |
211 211 | { |
212 + | |
213 + | struct group_req gr; |
214 + | struct sockaddr_in *si; |
215 + | int ret; |
216 + | memset (&gr, 0, sizeof(gr)); |
217 + | si = (struct sockaddr_in *)&gr.gr_group; |
218 + | gr.gr_interface = ifindex; |
219 + | si->sin_family = AF_INET; |
220 + | |
221 + | si->sin_len = sizeof(struct sockaddr_in); |
222 + | /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ |
223 + | si->sin_addr.s_addr = mcast_addr; |
224 + | ret = setsockopt(sock, IPPROTO_IP, (optname == IP_ADD_MEMBERSHIP) ? |
225 + | MCAST_JOIN_GROUP : MCAST_LEAVE_GROUP, (void *)&gr, sizeof(gr)); |
226 + | if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) |
227 + | { |
228 + | setsockopt(sock, IPPROTO_IP, MCAST_LEAVE_GROUP, (void *)&gr, sizeof(gr)); |
229 + | ret = setsockopt(sock, IPPROTO_IP, MCAST_JOIN_GROUP, (void *)&gr, sizeof(gr)); |
230 + | } |
231 + | return ret; |
212 232 | |
213 - | |
233 + | |
214 234 | struct ip_mreqn mreqn; |
215 235 | int ret; |
216 236 | |
217 237 | assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP); |
218 238 | memset (&mreqn, 0, sizeof(mreqn)); |
219 239 | |
220 - | if (mcast_addr) |
221 - | mreqn.imr_multiaddr.s_addr = mcast_addr; |
222 - | |
240 + | mreqn.imr_multiaddr.s_addr = mcast_addr; |
223 241 | mreqn.imr_ifindex = ifindex; |
224 242 | |
225 243 | ret = setsockopt(sock, IPPROTO_IP, optname, |
226 244 | (void *)&mreqn, sizeof(mreqn)); |
227 245 | if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) |
228 246 | { |
229 247 | /* see above: handle possible problem when interface comes back up */ |
230 248 | char buf[1][INET_ADDRSTRLEN]; |
231 249 | zlog_info("setsockopt_ipv4_multicast attempting to drop and " |
232 250 | "re-add (fd %d, mcast %s, ifindex %u)", |