Source-Changes-HG archive

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

[src/trunk]: src Add support IP_PKTINFO for sendmsg(2).



details:   https://anonhg.NetBSD.org/src/rev/467058d6dacb
branches:  trunk
changeset: 825986:467058d6dacb
user:      ryo <ryo%NetBSD.org@localhost>
date:      Thu Aug 10 04:31:58 2017 +0000

description:
Add support IP_PKTINFO for sendmsg(2).

The source address or output interface can be specified by adding IP_PKTINFO
to the control part of the message on a SOCK_DGRAM or SOCK_RAW socket.

Reviewed by ozaki-r@ and christos@. thanks.

diffstat:

 distrib/sets/lists/debug/mi    |    3 +-
 distrib/sets/lists/tests/mi    |    3 +-
 share/man/man4/ip.4            |   15 +-
 sys/netinet/in.c               |   41 +-
 sys/netinet/in.h               |    3 +-
 sys/netinet/in_pcb.c           |   25 +-
 sys/netinet/in_pcb.h           |    3 +-
 sys/netinet/ip_output.c        |  161 +++++++-
 sys/netinet/ip_var.h           |   13 +-
 sys/netinet/raw_ip.c           |   88 ++-
 sys/netinet/udp_usrreq.c       |   55 +-
 sys/netinet/udp_var.h          |    4 +-
 tests/net/net/Makefile         |    6 +-
 tests/net/net/t_pktinfo_send.c |  822 +++++++++++++++++++++++++++++++++++++++++
 14 files changed, 1163 insertions(+), 79 deletions(-)

diffs (truncated from 1648 to 300 lines):

diff -r 29acafb973f5 -r 467058d6dacb distrib/sets/lists/debug/mi
--- a/distrib/sets/lists/debug/mi       Wed Aug 09 23:01:06 2017 +0000
+++ b/distrib/sets/lists/debug/mi       Thu Aug 10 04:31:58 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.221 2017/07/23 19:26:05 perseant Exp $
+# $NetBSD: mi,v 1.222 2017/08/10 04:31:58 ryo Exp $
 ./etc/mtree/set.debug                           comp-sys-root
 ./usr/lib                                      comp-sys-usr            compatdir
 ./usr/lib/i18n/libBIG5_g.a                     comp-c-debuglib         debuglib,compatfile
@@ -2280,6 +2280,7 @@
 ./usr/libdata/debug/usr/tests/net/mcast/mcast.debug            tests-net-debug         debug,atf,rump
 ./usr/libdata/debug/usr/tests/net/mcast/t_mcast.debug          tests-obsolete          debug,atf,rump,obsolete
 ./usr/libdata/debug/usr/tests/net/net/t_pktinfo.debug          tests-net-debug         debug,atf,compattestfile
+./usr/libdata/debug/usr/tests/net/net/t_pktinfo_test.debug     tests-net-debug         debug,atf,rump
 ./usr/libdata/debug/usr/tests/net/net/t_raw.debug              tests-net-debug         debug,atf,rump
 ./usr/libdata/debug/usr/tests/net/net/t_tcp.debug              tests-net-debug         debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/net/net/t_udp.debug              tests-net-debug         debug,atf,compattestfile
diff -r 29acafb973f5 -r 467058d6dacb distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi       Wed Aug 09 23:01:06 2017 +0000
+++ b/distrib/sets/lists/tests/mi       Thu Aug 10 04:31:58 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.759 2017/08/02 02:19:56 ozaki-r Exp $
+# $NetBSD: mi,v 1.760 2017/08/10 04:31:58 ryo Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -3361,6 +3361,7 @@
 ./usr/tests/net/net/t_ping6_opts               tests-net-tests         atf,rump
 ./usr/tests/net/net/t_ping_opts                        tests-net-tests         atf,rump
 ./usr/tests/net/net/t_pktinfo                  tests-net-tests         compattestfile,atf
+./usr/tests/net/net/t_pktinfo_send             tests-net-tests         atf,rump
 ./usr/tests/net/net/t_raw                      tests-net-tests         atf,rump
 ./usr/tests/net/net/t_tcp                      tests-net-tests         compattestfile,atf
 ./usr/tests/net/net/t_udp                      tests-net-tests         compattestfile,atf
diff -r 29acafb973f5 -r 467058d6dacb share/man/man4/ip.4
--- a/share/man/man4/ip.4       Wed Aug 09 23:01:06 2017 +0000
+++ b/share/man/man4/ip.4       Thu Aug 10 04:31:58 2017 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: ip.4,v 1.37 2017/07/03 21:30:58 wiz Exp $
+.\"    $NetBSD: ip.4,v 1.38 2017/08/10 04:31:58 ryo Exp $
 .\"
 .\" Copyright (c) 1983, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)ip.4       8.2 (Berkeley) 11/30/93
 .\"
-.Dd June 27, 2013
+.Dd August 10, 2017
 .Dt IP 4
 .Os
 .Sh NAME
@@ -121,6 +121,7 @@
        struct in_addr ipi_addr;        /* the source or destination address */
        unsigned int ipi_ifindex;       /* the interface index */
 .Ed
+.Pp
 and added to the control portion of the message:
 The cmsghdr fields have the following values:
 .Bd -literal
@@ -129,6 +130,16 @@
 cmsg_type = IP_PKTINFO
 .Ed
 .Pp
+For
+.Xr sendmsg 2 ,
+the source address or output interface can be specified by adding
+.Dv IP_PKTINFO
+to the control part of the message on a
+.Dv SOCK_DGRAM
+or
+.Dv SOCK_RAW
+socket.
+.Pp
 The
 .Dv IP_PORTALGO
 can be used to randomize the port selection.
diff -r 29acafb973f5 -r 467058d6dacb sys/netinet/in.c
--- a/sys/netinet/in.c  Wed Aug 09 23:01:06 2017 +0000
+++ b/sys/netinet/in.c  Thu Aug 10 04:31:58 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in.c,v 1.206 2017/08/04 20:17:45 uwe Exp $     */
+/*     $NetBSD: in.c,v 1.207 2017/08/10 04:31:58 ryo Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.206 2017/08/04 20:17:45 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.207 2017/08/10 04:31:58 ryo Exp $");
 
 #include "arp.h"
 
@@ -258,6 +258,43 @@
 }
 
 /*
+ * like in_localaddr() but can specify ifp.
+ */
+int
+in_direct(struct in_addr in, struct ifnet *ifp)
+{
+       struct ifaddr *ifa;
+       int localaddr = 0;
+       int s;
+
+       KASSERT(ifp != NULL);
+
+#define ia (ifatoia(ifa))
+       s = pserialize_read_enter();
+       if (subnetsarelocal) {
+               IFADDR_READER_FOREACH(ifa, ifp) {
+                       if (ifa->ifa_addr->sa_family == AF_INET &&
+                           ((in.s_addr & ia->ia_netmask) == ia->ia_net)) {
+                               localaddr = 1;
+                               break;
+                       }
+               }
+       } else {
+               IFADDR_READER_FOREACH(ifa, ifp) {
+                       if (ifa->ifa_addr->sa_family == AF_INET &&
+                           (in.s_addr & ia->ia_subnetmask) == ia->ia_subnet) {
+                               localaddr = 1;
+                               break;
+                       }
+               }
+       }
+       pserialize_read_exit(s);
+
+       return localaddr;
+#undef ia
+}
+
+/*
  * Determine whether an IP address is in a reserved set of addresses
  * that may not be forwarded, or whether datagrams to that destination
  * may be forwarded.
diff -r 29acafb973f5 -r 467058d6dacb sys/netinet/in.h
--- a/sys/netinet/in.h  Wed Aug 09 23:01:06 2017 +0000
+++ b/sys/netinet/in.h  Thu Aug 10 04:31:58 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in.h,v 1.100 2017/02/16 08:12:44 knakahara Exp $       */
+/*     $NetBSD: in.h,v 1.101 2017/08/10 04:31:58 ryo Exp $     */
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -562,6 +562,7 @@
 extern const struct sockaddr_in in_any;
 
 int    in_broadcast(struct in_addr, struct ifnet *);
+int    in_direct(struct in_addr, struct ifnet *);
 int    in_canforward(struct in_addr);
 int    cpu_in_cksum(struct mbuf *, int, int, uint32_t);
 int    in_cksum(struct mbuf *, int);
diff -r 29acafb973f5 -r 467058d6dacb sys/netinet/in_pcb.c
--- a/sys/netinet/in_pcb.c      Wed Aug 09 23:01:06 2017 +0000
+++ b/sys/netinet/in_pcb.c      Thu Aug 10 04:31:58 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_pcb.c,v 1.178 2017/04/25 05:44:11 ozaki-r Exp $     */
+/*     $NetBSD: in_pcb.c,v 1.179 2017/08/10 04:31:58 ryo Exp $ */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -93,7 +93,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.178 2017/04/25 05:44:11 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.179 2017/08/10 04:31:58 ryo Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -270,8 +270,8 @@
        return (0);
 }
 
-static int
-in_pcbbind_addr(struct inpcb *inp, struct sockaddr_in *sin, kauth_cred_t cred)
+int
+in_pcbbindableaddr(struct sockaddr_in *sin, kauth_cred_t cred)
 {
        int error = EADDRNOTAVAIL;
        struct ifaddr *ifa = NULL;
@@ -298,13 +298,20 @@
                if (ia->ia4_flags & IN_IFF_DUPLICATED)
                        goto error;
        }
+       error = 0;
+ error:
        pserialize_read_exit(s);
-
-       inp->inp_laddr = sin->sin_addr;
+       return error;
+}
 
-       return (0);
-error:
-       pserialize_read_exit(s);
+static int
+in_pcbbind_addr(struct inpcb *inp, struct sockaddr_in *sin, kauth_cred_t cred)
+{
+       int error;
+
+       error = in_pcbbindableaddr(sin, cred);
+       if (error == 0)
+               inp->inp_laddr = sin->sin_addr;
        return error;
 }
 
diff -r 29acafb973f5 -r 467058d6dacb sys/netinet/in_pcb.h
--- a/sys/netinet/in_pcb.h      Wed Aug 09 23:01:06 2017 +0000
+++ b/sys/netinet/in_pcb.h      Thu Aug 10 04:31:58 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_pcb.h,v 1.63 2017/03/02 05:29:31 ozaki-r Exp $      */
+/*     $NetBSD: in_pcb.h,v 1.64 2017/08/10 04:31:58 ryo Exp $  */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -135,6 +135,7 @@
 #ifdef _KERNEL
 void   in_losing(struct inpcb *);
 int    in_pcballoc(struct socket *, void *);
+int    in_pcbbindableaddr(struct sockaddr_in *, kauth_cred_t);
 int    in_pcbbind(void *, struct sockaddr_in *, struct lwp *);
 int    in_pcbconnect(void *, struct sockaddr_in *, struct lwp *);
 void   in_pcbdetach(void *);
diff -r 29acafb973f5 -r 467058d6dacb sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c   Wed Aug 09 23:01:06 2017 +0000
+++ b/sys/netinet/ip_output.c   Thu Aug 10 04:31:58 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_output.c,v 1.283 2017/07/23 10:55:00 para Exp $     */
+/*     $NetBSD: ip_output.c,v 1.284 2017/08/10 04:31:58 ryo Exp $      */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.283 2017/07/23 10:55:00 para Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.284 2017/08/10 04:31:58 ryo Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -127,6 +127,7 @@
 #include <netinet/in_offload.h>
 #include <netinet/portalgo.h>
 #include <netinet/udp.h>
+#include <netinet/udp_var.h>
 
 #ifdef INET6
 #include <netinet6/ip6_var.h>
@@ -329,8 +330,9 @@
                mtu = ifp->if_mtu;
                ip->ip_ttl = 1;
                isbroadcast = in_broadcast(dst->sin_addr, ifp);
-       } else if ((IN_MULTICAST(ip->ip_dst.s_addr) ||
-           ip->ip_dst.s_addr == INADDR_BROADCAST) &&
+       } else if (((IN_MULTICAST(ip->ip_dst.s_addr) ||
+           ip->ip_dst.s_addr == INADDR_BROADCAST) ||
+           (flags & IP_ROUTETOIFINDEX)) &&
            imo != NULL && imo->imo_multicast_if_index != 0) {
                ifp = mifp = if_get_byindex(imo->imo_multicast_if_index, &psref);
                if (ifp == NULL) {
@@ -344,7 +346,31 @@
                        error = EADDRNOTAVAIL;
                        goto bad;
                }
-               isbroadcast = 0;
+               if (IN_MULTICAST(ip->ip_dst.s_addr) ||
+                   ip->ip_dst.s_addr == INADDR_BROADCAST) {
+                       isbroadcast = 0;
+               } else {
+                       /* IP_ROUTETOIFINDEX */
+                       isbroadcast = in_broadcast(dst->sin_addr, ifp);
+                       if ((isbroadcast == 0) && ((ifp->if_flags &
+                           (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0) &&
+                           (in_direct(dst->sin_addr, ifp) == 0)) {
+                               /* gateway address required */
+                               if (rt == NULL)
+                                       rt = rtcache_init(ro);
+                               if (rt == NULL || rt->rt_ifp != ifp) {
+                                       IP_STATINC(IP_STAT_NOROUTE);
+                                       error = EHOSTUNREACH;
+                                       goto bad;
+                               }
+                               rt->rt_use++;
+                               if (rt->rt_flags & RTF_GATEWAY)
+                                       dst = satosin(rt->rt_gateway);
+                               if (rt->rt_flags & RTF_HOST)
+                                       isbroadcast =
+                                           rt->rt_flags & RTF_BROADCAST;
+                       }
+               }
        } else {
                if (rt == NULL)
                        rt = rtcache_init(ro);
@@ -1320,6 +1346,131 @@



Home | Main Index | Thread Index | Old Index