Module Name: src
Committed By: christos
Date: Sat Oct 11 20:53:16 UTC 2014
Modified Files:
src/sys/netinet6: in6_pcb.c in6_pcb.h ip6_output.c udp6_output.c
Log Message:
Make IPV4 mapped addresses able to do IPV4 multicast. Fixes needed:
- allow binding to mapped v4 multicast addresses
- define v4moptions, allow setting it via ioctl, pass it to ip_output,
free it when killing the pcb.
Ideally we would allow the IPV6 multicast setsockopts work on mapped addresses
too, but this is a lot more work and linux does not do it either.
To generate a diff of this commit:
cvs rdiff -u -r1.129 -r1.130 src/sys/netinet6/in6_pcb.c
cvs rdiff -u -r1.39 -r1.40 src/sys/netinet6/in6_pcb.h
cvs rdiff -u -r1.158 -r1.159 src/sys/netinet6/ip6_output.c
cvs rdiff -u -r1.44 -r1.45 src/sys/netinet6/udp6_output.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/netinet6/in6_pcb.c
diff -u src/sys/netinet6/in6_pcb.c:1.129 src/sys/netinet6/in6_pcb.c:1.130
--- src/sys/netinet6/in6_pcb.c:1.129 Sat Sep 6 20:50:56 2014
+++ src/sys/netinet6/in6_pcb.c Sat Oct 11 16:53:16 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_pcb.c,v 1.129 2014/09/07 00:50:56 rmind Exp $ */
+/* $NetBSD: in6_pcb.c,v 1.130 2014/10/11 20:53:16 christos Exp $ */
/* $KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.129 2014/09/07 00:50:56 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.130 2014/10/11 20:53:16 christos Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@@ -229,7 +229,8 @@ in6_pcbbind_addr(struct in6pcb *in6p, st
sin.sin_family = AF_INET;
bcopy(&sin6->sin6_addr.s6_addr32[3],
&sin.sin_addr, sizeof(sin.sin_addr));
- if (ifa_ifwithaddr((struct sockaddr *)&sin) == 0)
+ if (!IN_MULTICAST(sin.sin_addr.s_addr) &&
+ ifa_ifwithaddr((struct sockaddr *)&sin) == 0)
return EADDRNOTAVAIL;
}
} else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
@@ -618,6 +619,7 @@ in6_pcbdetach(struct in6pcb *in6p)
}
rtcache_free(&in6p->in6p_route);
ip6_freemoptions(in6p->in6p_moptions);
+ ip_freemoptions(in6p->in6p_v4moptions);
sofree(so); /* drops the socket's lock */
pool_put(&in6pcb_pool, in6p);
Index: src/sys/netinet6/in6_pcb.h
diff -u src/sys/netinet6/in6_pcb.h:1.39 src/sys/netinet6/in6_pcb.h:1.40
--- src/sys/netinet6/in6_pcb.h:1.39 Tue Aug 5 01:24:27 2014
+++ src/sys/netinet6/in6_pcb.h Sat Oct 11 16:53:16 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_pcb.h,v 1.39 2014/08/05 05:24:27 rtr Exp $ */
+/* $NetBSD: in6_pcb.h,v 1.40 2014/10/11 20:53:16 christos Exp $ */
/* $KAME: in6_pcb.h,v 1.45 2001/02/09 05:59:46 itojun Exp $ */
/*
@@ -100,6 +100,7 @@ struct in6pcb {
struct icmp6_filter *in6p_icmp6filt;
int in6p_cksum; /* IPV6_CHECKSUM setsockopt */
bool in6p_bindportonsend;
+ struct ip_moptions *in6p_v4moptions;/* IP4 multicast options */
};
#define in6p_faddr in6p_ip6.ip6_dst
Index: src/sys/netinet6/ip6_output.c
diff -u src/sys/netinet6/ip6_output.c:1.158 src/sys/netinet6/ip6_output.c:1.159
--- src/sys/netinet6/ip6_output.c:1.158 Sat Aug 16 13:27:09 2014
+++ src/sys/netinet6/ip6_output.c Sat Oct 11 16:53:16 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_output.c,v 1.158 2014/08/16 17:27:09 maxv Exp $ */
+/* $NetBSD: ip6_output.c,v 1.159 2014/10/11 20:53:16 christos Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.158 2014/08/16 17:27:09 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.159 2014/10/11 20:53:16 christos Exp $");
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -86,6 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_output.c
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/ip6.h>
+#include <netinet/ip_var.h>
#include <netinet/icmp6.h>
#include <netinet/in_offload.h>
#include <netinet/portalgo.h>
@@ -1264,6 +1265,7 @@ ip6_ctloutput(int op, struct socket *so,
int optdatalen, uproto;
void *optdata;
struct in6pcb *in6p = sotoin6pcb(so);
+ struct ip_moptions **mopts;
int error, optval;
int level, optname;
@@ -1275,7 +1277,29 @@ ip6_ctloutput(int op, struct socket *so,
error = optval = 0;
uproto = (int)so->so_proto->pr_protocol;
- if (level != IPPROTO_IPV6) {
+ switch (level) {
+ case IPPROTO_IP:
+ switch (optname) {
+ case IP_ADD_MEMBERSHIP:
+ case IP_DROP_MEMBERSHIP:
+ case IP_MULTICAST_IF:
+ case IP_MULTICAST_LOOP:
+ case IP_MULTICAST_TTL:
+ mopts = &in6p->in6p_v4moptions;
+ switch (op) {
+ case PRCO_GETOPT:
+ return ip_getmoptions(*mopts, sopt);
+ case PRCO_SETOPT:
+ return ip_setmoptions(mopts, sopt);
+ default:
+ return EINVAL;
+ }
+ default:
+ return ENOPROTOOPT;
+ }
+ case IPPROTO_IPV6:
+ break;
+ default:
return ENOPROTOOPT;
}
switch (op) {
Index: src/sys/netinet6/udp6_output.c
diff -u src/sys/netinet6/udp6_output.c:1.44 src/sys/netinet6/udp6_output.c:1.45
--- src/sys/netinet6/udp6_output.c:1.44 Sat Jan 5 19:17:13 2013
+++ src/sys/netinet6/udp6_output.c Sat Oct 11 16:53:16 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: udp6_output.c,v 1.44 2013/01/06 00:17:13 christos Exp $ */
+/* $NetBSD: udp6_output.c,v 1.45 2014/10/11 20:53:16 christos Exp $ */
/* $KAME: udp6_output.c,v 1.43 2001/10/15 09:19:52 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp6_output.c,v 1.44 2013/01/06 00:17:13 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp6_output.c,v 1.45 2014/10/11 20:53:16 christos Exp $");
#include "opt_inet.h"
@@ -404,7 +404,7 @@ udp6_output(struct in6pcb * const in6p,
UDP_STATINC(UDP_STAT_OPACKETS);
error = ip_output(m, NULL, &in6p->in6p_route, flags /* XXX */,
- NULL, (struct socket *)in6p->in6p_socket);
+ in6p->in6p_v4moptions, (struct socket *)in6p->in6p_socket);
break;
#else
error = EAFNOSUPPORT;