Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153517444
D19276.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D19276.diff
View Options
Index: head/share/man/man4/ip.4
===================================================================
--- head/share/man/man4/ip.4
+++ head/share/man/man4/ip.4
@@ -28,7 +28,7 @@
.\" @(#)ip.4 8.2 (Berkeley) 11/30/93
.\" $FreeBSD$
.\"
-.Dd August 19, 2018
+.Dd February 22, 2019
.Dt IP 4
.Os
.Sh NAME
@@ -571,32 +571,55 @@
.Dv IP_ADD_MEMBERSHIP
option:
.Bd -literal
-struct ip_mreq mreq;
-setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+struct ip_mreqn mreqn;
+setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreqn, sizeof(mreqn));
.Ed
.Pp
where
-.Fa mreq
+.Fa mreqn
is the following structure:
.Bd -literal
-struct ip_mreq {
+struct ip_mreqn {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
+ int imr_ifindex; /* interface index */
}
.Ed
.Pp
-.Va imr_interface
-should be set to the
-.Tn IP
-address of a particular multicast-capable interface if
+.Va imr_ifindex
+should be set to the index of a particular multicast-capable interface if
the host is multihomed.
-It may be set to
-.Dv INADDR_ANY
-to choose the default interface, although this is not recommended;
-this is considered to be the first interface corresponding
-to the default route.
-Otherwise, the first multicast-capable interface
-configured in the system will be used.
+If
+.Va imr_ifindex
+is non-zero, value of
+.Va imr_interface
+is ignored.
+Otherwise, if
+.Va imr_ifindex
+is 0, kernel will use IP address from
+.Va imr_interface
+to lookup the interface.
+Value of
+.Va imr_interface
+may be set to
+.Va INADDR_ANY
+to choose the default interface, although this is not recommended; this is
+considered to be the first interface corresponding to the default route.
+Otherwise, the first multicast-capable interface configured in the system
+will be used.
+.Pp
+Legacy
+.Vt "struct ip_mreq" ,
+that lacks
+.Va imr_ifindex
+field is also supported by
+.Dv IP_ADD_MEMBERSHIP
+setsockopt.
+In this case kernel would behave as if
+.Va imr_ifindex
+was set to zero:
+.Va imr_interface
+will be used to lookup interface.
.Pp
Prior to
.Fx 7.0 ,
Index: head/sys/netinet/in_mcast.c
===================================================================
--- head/sys/netinet/in_mcast.c
+++ head/sys/netinet/in_mcast.c
@@ -2049,40 +2049,49 @@
ssa->ss.ss_family = AF_UNSPEC;
switch (sopt->sopt_name) {
- case IP_ADD_MEMBERSHIP:
- case IP_ADD_SOURCE_MEMBERSHIP: {
- struct ip_mreq_source mreqs;
+ case IP_ADD_MEMBERSHIP: {
+ struct ip_mreqn mreqn;
- if (sopt->sopt_name == IP_ADD_MEMBERSHIP) {
- error = sooptcopyin(sopt, &mreqs,
- sizeof(struct ip_mreq),
- sizeof(struct ip_mreq));
- /*
- * Do argument switcharoo from ip_mreq into
- * ip_mreq_source to avoid using two instances.
- */
- mreqs.imr_interface = mreqs.imr_sourceaddr;
- mreqs.imr_sourceaddr.s_addr = INADDR_ANY;
- } else if (sopt->sopt_name == IP_ADD_SOURCE_MEMBERSHIP) {
- error = sooptcopyin(sopt, &mreqs,
- sizeof(struct ip_mreq_source),
- sizeof(struct ip_mreq_source));
- }
+ if (sopt->sopt_valsize == sizeof(struct ip_mreqn))
+ error = sooptcopyin(sopt, &mreqn,
+ sizeof(struct ip_mreqn), sizeof(struct ip_mreqn));
+ else
+ error = sooptcopyin(sopt, &mreqn,
+ sizeof(struct ip_mreq), sizeof(struct ip_mreq));
if (error)
return (error);
gsa->sin.sin_family = AF_INET;
gsa->sin.sin_len = sizeof(struct sockaddr_in);
- gsa->sin.sin_addr = mreqs.imr_multiaddr;
+ gsa->sin.sin_addr = mreqn.imr_multiaddr;
+ if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
+ return (EINVAL);
- if (sopt->sopt_name == IP_ADD_SOURCE_MEMBERSHIP) {
- ssa->sin.sin_family = AF_INET;
- ssa->sin.sin_len = sizeof(struct sockaddr_in);
- ssa->sin.sin_addr = mreqs.imr_sourceaddr;
- }
+ if (sopt->sopt_valsize == sizeof(struct ip_mreqn) &&
+ mreqn.imr_ifindex != 0)
+ ifp = ifnet_byindex(mreqn.imr_ifindex);
+ else
+ ifp = inp_lookup_mcast_ifp(inp, &gsa->sin,
+ mreqn.imr_address);
+ break;
+ }
+ case IP_ADD_SOURCE_MEMBERSHIP: {
+ struct ip_mreq_source mreqs;
+ error = sooptcopyin(sopt, &mreqs, sizeof(struct ip_mreq_source),
+ sizeof(struct ip_mreq_source));
+ if (error)
+ return (error);
+
+ gsa->sin.sin_family = ssa->sin.sin_family = AF_INET;
+ gsa->sin.sin_len = ssa->sin.sin_len =
+ sizeof(struct sockaddr_in);
+
+ gsa->sin.sin_addr = mreqs.imr_multiaddr;
if (!IN_MULTICAST(ntohl(gsa->sin.sin_addr.s_addr)))
return (EINVAL);
+
+ ssa->sin.sin_addr = mreqs.imr_sourceaddr;
ifp = inp_lookup_mcast_ifp(inp, &gsa->sin,
mreqs.imr_interface);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 22, 2:08 PM (14 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31984482
Default Alt Text
D19276.diff (4 KB)
Attached To
Mode
D19276: Support struct ip_mreqn in IP_ADD_MEMBERSHIP.
Attached
Detach File
Event Timeline
Log In to Comment