Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet6 Make IPV4 mapped addresses able to do IPV4 mult...



details:   https://anonhg.NetBSD.org/src/rev/696cc9ac5fd9
branches:  trunk
changeset: 332915:696cc9ac5fd9
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Oct 11 20:53:16 2014 +0000

description:
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.

diffstat:

 sys/netinet6/in6_pcb.c     |   8 +++++---
 sys/netinet6/in6_pcb.h     |   3 ++-
 sys/netinet6/ip6_output.c  |  30 +++++++++++++++++++++++++++---
 sys/netinet6/udp6_output.c |   6 +++---
 4 files changed, 37 insertions(+), 10 deletions(-)

diffs (145 lines):

diff -r 99fdd57cf5ff -r 696cc9ac5fd9 sys/netinet6/in6_pcb.c
--- a/sys/netinet6/in6_pcb.c    Sat Oct 11 20:50:59 2014 +0000
+++ b/sys/netinet6/in6_pcb.c    Sat Oct 11 20:53:16 2014 +0000
@@ -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 @@
                        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 @@
        }
        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);
diff -r 99fdd57cf5ff -r 696cc9ac5fd9 sys/netinet6/in6_pcb.h
--- a/sys/netinet6/in6_pcb.h    Sat Oct 11 20:50:59 2014 +0000
+++ b/sys/netinet6/in6_pcb.h    Sat Oct 11 20:53:16 2014 +0000
@@ -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 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
diff -r 99fdd57cf5ff -r 696cc9ac5fd9 sys/netinet6/ip6_output.c
--- a/sys/netinet6/ip6_output.c Sat Oct 11 20:50:59 2014 +0000
+++ b/sys/netinet6/ip6_output.c Sat Oct 11 20:53:16 2014 +0000
@@ -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 @@
 #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 @@
        int optdatalen, uproto;
        void *optdata;
        struct in6pcb *in6p = sotoin6pcb(so);
+       struct ip_moptions **mopts;
        int error, optval;
        int level, optname;
 
@@ -1275,7 +1277,29 @@
        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) {
diff -r 99fdd57cf5ff -r 696cc9ac5fd9 sys/netinet6/udp6_output.c
--- a/sys/netinet6/udp6_output.c        Sat Oct 11 20:50:59 2014 +0000
+++ b/sys/netinet6/udp6_output.c        Sat Oct 11 20:53:16 2014 +0000
@@ -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 @@
 
                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;



Home | Main Index | Thread Index | Old Index