Re: preparations for IP_SENDSRCADDR / (un)tangle pcb_bind...

2013-08-06 Thread Claudio Jeker
On Tue, Aug 06, 2013 at 09:24:13PM +0200, Christopher Zimmermann wrote:
> Hi,
> 
> I'm currently working towards an IP_SENDSRCADDR implementation.
> As a first step I moved the calls to in_pcbrehash() from 
> in_pcb(dis)connect() and in_pcbbind() to the call sites of those 
> functions. This should save some calls to in_pcbrehash() in the 
> in_pcbconnect() codepath.
> Also I improved code sharing between the IPv4 and IPv6 stacks by 
> implementing a generic in_pcbsetport used by both stacks.
> The next step will be to replace in_pcbconnect() by in_selectsrc() 
> and in_pcbsetport() in udp_output() like the IPv6 stack does it.
> The splsoftnet() lock could then be removed. Also implementing
> IP_SENDSRCADDR will become trivial because in_selectsrc() won't
> modify the struct inpcb like in_pcbconnect() does at the moment.
> 
> Not much testing yet. Just surfing the web and sending this mail...
> 
> I'd really like some feedback on whether I'm on the right track or 
> doing something stupid here. I have no experience in the OpenBSD 
> IP-stack yet.
> 
> 

Moving the calls of of in_pcbrehash() to outside of in_pcb.c is wrong.
This is an internal function for the specific way fast PCB lookups are
done at the moment.  Having that all over the place in higher level code
where someone does a bind or connect call is not an option IMO.
This needs to be done differently, sorry.

-- 
:wq Claudio

> Christopher
> 
> 
> 
> Index: netinet/in_pcb.c
> ===
> RCS file: /cvs/src/sys/netinet/in_pcb.c,v
> retrieving revision 1.139
> diff -u -p -r1.139 in_pcb.c
> --- netinet/in_pcb.c  1 Jun 2013 13:25:40 -   1.139
> +++ netinet/in_pcb.c  6 Aug 2013 18:25:54 -
> @@ -218,7 +218,6 @@ in_pcbbind(struct inpcb *inp, struct mbu
>  {
>   struct socket *so = inp->inp_socket;
>   struct inpcbtable *table = inp->inp_table;
> - u_int16_t *lastport = &inp->inp_table->inpt_lastport;
>   struct sockaddr_in *sin;
>   u_int16_t lport = 0;
>   int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
> @@ -293,71 +292,121 @@ in_pcbbind(struct inpcb *inp, struct mbu
>   inp->inp_laddr = sin->sin_addr;
>   }
>   if (lport == 0) {
> - u_int16_t first, last;
> - int count;
> + error = in_pcbsetport(inp, p);
> + if (error != 0)
> + return error;
> + }
> + else
> + inp->inp_lport = lport;
> + return (0);
> +}
>  
> - if (inp->inp_flags & INP_HIGHPORT) {
> - first = ipport_hifirstauto; /* sysctl */
> - last = ipport_hilastauto;
> - } else if (inp->inp_flags & INP_LOWPORT) {
> - if ((error = suser(p, 0)))
> - return (EACCES);
> - first = IPPORT_RESERVED-1; /* 1023 */
> - last = 600;/* not IPPORT_RESERVED/2 */
> - } else {
> - first = ipport_firstauto;   /* sysctl */
> - last  = ipport_lastauto;
> - }
> +int
> +in_pcbsetport(struct inpcb *inp, struct proc *p)
> +{
> + struct socket *so = inp->inp_socket;
> + struct inpcbtable *table = inp->inp_table;
> + u_int16_t first, last;
> + u_int16_t *lastport = &inp->inp_table->inpt_lastport;
> + u_int16_t lport = 0;
> + int count;
> + int error;
> + int wild;
> + u_int rtableid;
> + void *faddrp, *laddrp;
> +#ifdef INET6
> + extern struct in6_addr zeroin6_addr;
>  
> - /*
> -  * Simple check to ensure all ports are not used up causing
> -  * a deadlock here.
> -  *
> -  * We split the two cases (up and down) so that the direction
> -  * is not being tested on each round of the loop.
> -  */
> + if (sotopf(so) == PF_INET6) {
> + wild = INPLOOKUP_IPV6;
> + rtableid = 0;
> + faddrp = &zeroin6_addr;
> + laddrp = &inp->inp_laddr6;
> + }
> + else
> +#endif /* INET6 */
> + {
> + wild = 0;
> + rtableid = inp->inp_rtableid;
> + faddrp = &zeroin_addr;
> + laddrp = &inp->inp_laddr;
> + }
>  
> - if (first > last) {
> - /*
> -  * counting down
> -  */
> - count = first - last;
> - if (count)
> - *lastport = first - arc4random_uniform(count);
> + if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
> + ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
> +  (so->so_options & SO_ACCEPTCONN) == 0))
> + wild |= INPLOOKUP_WILDCARD;
>  
> - do {
> - if (count-- < 0)/* completely used? */
> - 

include netinet/in_var.h in arch/dev

2013-08-06 Thread Alexander Bluhm
Hi,

I have just removed a bunch of useless include netinet/in_var.h
from the machine independent drivers.  I suspect that they are also
not needed in the architecture specific network drivers.  Unfortunately
I don't have any of these machines.  So if you have access to one
of

macppc mvme68k octeon sgi sparc vax

could you please test if this diff compiles.

ok?

bluhm

Index: arch/macppc/dev/if_mc.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/macppc/dev/if_mc.c,v
retrieving revision 1.14
diff -u -p -r1.14 if_mc.c
--- arch/macppc/dev/if_mc.c 21 Apr 2010 03:03:26 -  1.14
+++ arch/macppc/dev/if_mc.c 7 Aug 2013 00:57:57 -
@@ -56,7 +56,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #endif
 
Index: arch/mvme68k/dev/if_ie.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/mvme68k/dev/if_ie.c,v
retrieving revision 1.40
diff -u -p -r1.40 if_ie.c
--- arch/mvme68k/dev/if_ie.c10 Oct 2012 04:52:16 -  1.40
+++ arch/mvme68k/dev/if_ie.c7 Aug 2013 00:57:57 -
@@ -120,7 +120,6 @@ Mode of operation:
 #ifdef INET
 #include 
 #include 
-#include 
 #include 
 #include 
 #endif
Index: arch/mvme88k/dev/if_ie.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/mvme88k/dev/if_ie.c,v
retrieving revision 1.45
diff -u -p -r1.45 if_ie.c
--- arch/mvme88k/dev/if_ie.c10 Oct 2012 04:52:16 -  1.45
+++ arch/mvme88k/dev/if_ie.c7 Aug 2013 00:57:57 -
@@ -119,7 +119,6 @@ Mode of operation:
 #ifdef INET
 #include 
 #include 
-#include 
 #include 
 #include 
 #endif
Index: arch/octeon/dev/if_cnmac.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/octeon/dev/if_cnmac.c,v
retrieving revision 1.10
diff -u -p -r1.10 if_cnmac.c
--- arch/octeon/dev/if_cnmac.c  12 Apr 2013 15:22:26 -  1.10
+++ arch/octeon/dev/if_cnmac.c  7 Aug 2013 00:57:57 -
@@ -66,7 +66,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include 
Index: arch/sgi/dev/if_iec.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/sgi/dev/if_iec.c,v
retrieving revision 1.8
diff -u -p -r1.8 if_iec.c
--- arch/sgi/dev/if_iec.c   22 May 2012 19:24:59 -  1.8
+++ arch/sgi/dev/if_iec.c   7 Aug 2013 00:57:57 -
@@ -101,7 +101,6 @@
 #ifdef INET
 #include 
 #include 
-#include 
 #include 
 #endif
 
Index: arch/sgi/dev/if_mec.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/sgi/dev/if_mec.c,v
retrieving revision 1.25
diff -u -p -r1.25 if_mec.c
--- arch/sgi/dev/if_mec.c   3 Oct 2012 22:46:09 -   1.25
+++ arch/sgi/dev/if_mec.c   7 Aug 2013 00:57:57 -
@@ -85,7 +85,6 @@
 #ifdef INET
 #include 
 #include 
-#include 
 #include 
 #endif
 
Index: arch/sgi/hpc/if_sq.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/sgi/hpc/if_sq.c,v
retrieving revision 1.8
diff -u -p -r1.8 if_sq.c
--- arch/sgi/hpc/if_sq.c28 May 2012 17:03:35 -  1.8
+++ arch/sgi/hpc/if_sq.c7 Aug 2013 00:57:57 -
@@ -57,7 +57,6 @@
 #ifdef INET
 #include 
 #include 
-#include 
 #include 
 #endif
 
Index: arch/sparc/dev/be.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/sparc/dev/be.c,v
retrieving revision 1.43
diff -u -p -r1.43 be.c
--- arch/sparc/dev/be.c 28 Nov 2008 02:44:17 -  1.43
+++ arch/sparc/dev/be.c 7 Aug 2013 00:57:57 -
@@ -46,7 +46,6 @@
 #ifdef INET
 #include 
 #include 
-#include 
 #include 
 #include 
 #endif
Index: arch/sparc/dev/hme.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/sparc/dev/hme.c,v
retrieving revision 1.62
diff -u -p -r1.62 hme.c
--- arch/sparc/dev/hme.c13 Aug 2009 17:01:31 -  1.62
+++ arch/sparc/dev/hme.c7 Aug 2013 00:57:57 -
@@ -59,7 +59,6 @@
 #ifdef INET
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
Index: arch/sparc/dev/if_gem_sbus.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/sparc/dev/if_gem_sbus.c,v
retrieving revision 1.1
diff -u -p -r1.1 if_gem_sbus.c
--- arch/sparc/dev/if_gem_sbus.c13 Jul 2009 19:53:58 -  1.1
+++ arch/sparc/dev/if_gem_sbus.c7 Aug 2013 00:57:57 -
@@ -48,7 +48,6 @@
 #ifdef INET
 #include 
 #include 
-#include 
 #include 
 #include 
 #endif
Index: arch/sparc/dev/if_ie.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/sparc/dev/if_ie.c,v
retrieving revision 1.42
diff -u -p -r1.42 if_ie.c
--- arch/sparc/dev/if_i

preparations for IP_SENDSRCADDR / (un)tangle pcb_bind...

2013-08-06 Thread Christopher Zimmermann
Hi,

I'm currently working towards an IP_SENDSRCADDR implementation.
As a first step I moved the calls to in_pcbrehash() from 
in_pcb(dis)connect() and in_pcbbind() to the call sites of those 
functions. This should save some calls to in_pcbrehash() in the 
in_pcbconnect() codepath.
Also I improved code sharing between the IPv4 and IPv6 stacks by 
implementing a generic in_pcbsetport used by both stacks.
The next step will be to replace in_pcbconnect() by in_selectsrc() 
and in_pcbsetport() in udp_output() like the IPv6 stack does it.
The splsoftnet() lock could then be removed. Also implementing
IP_SENDSRCADDR will become trivial because in_selectsrc() won't
modify the struct inpcb like in_pcbconnect() does at the moment.

Not much testing yet. Just surfing the web and sending this mail...

I'd really like some feedback on whether I'm on the right track or 
doing something stupid here. I have no experience in the OpenBSD 
IP-stack yet.


Christopher



Index: netinet/in_pcb.c
===
RCS file: /cvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.139
diff -u -p -r1.139 in_pcb.c
--- netinet/in_pcb.c1 Jun 2013 13:25:40 -   1.139
+++ netinet/in_pcb.c6 Aug 2013 18:25:54 -
@@ -218,7 +218,6 @@ in_pcbbind(struct inpcb *inp, struct mbu
 {
struct socket *so = inp->inp_socket;
struct inpcbtable *table = inp->inp_table;
-   u_int16_t *lastport = &inp->inp_table->inpt_lastport;
struct sockaddr_in *sin;
u_int16_t lport = 0;
int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
@@ -293,71 +292,121 @@ in_pcbbind(struct inpcb *inp, struct mbu
inp->inp_laddr = sin->sin_addr;
}
if (lport == 0) {
-   u_int16_t first, last;
-   int count;
+   error = in_pcbsetport(inp, p);
+   if (error != 0)
+   return error;
+   }
+   else
+   inp->inp_lport = lport;
+   return (0);
+}
 
-   if (inp->inp_flags & INP_HIGHPORT) {
-   first = ipport_hifirstauto; /* sysctl */
-   last = ipport_hilastauto;
-   } else if (inp->inp_flags & INP_LOWPORT) {
-   if ((error = suser(p, 0)))
-   return (EACCES);
-   first = IPPORT_RESERVED-1; /* 1023 */
-   last = 600;/* not IPPORT_RESERVED/2 */
-   } else {
-   first = ipport_firstauto;   /* sysctl */
-   last  = ipport_lastauto;
-   }
+int
+in_pcbsetport(struct inpcb *inp, struct proc *p)
+{
+   struct socket *so = inp->inp_socket;
+   struct inpcbtable *table = inp->inp_table;
+   u_int16_t first, last;
+   u_int16_t *lastport = &inp->inp_table->inpt_lastport;
+   u_int16_t lport = 0;
+   int count;
+   int error;
+   int wild;
+   u_int rtableid;
+   void *faddrp, *laddrp;
+#ifdef INET6
+   extern struct in6_addr zeroin6_addr;
 
-   /*
-* Simple check to ensure all ports are not used up causing
-* a deadlock here.
-*
-* We split the two cases (up and down) so that the direction
-* is not being tested on each round of the loop.
-*/
+   if (sotopf(so) == PF_INET6) {
+   wild = INPLOOKUP_IPV6;
+   rtableid = 0;
+   faddrp = &zeroin6_addr;
+   laddrp = &inp->inp_laddr6;
+   }
+   else
+#endif /* INET6 */
+   {
+   wild = 0;
+   rtableid = inp->inp_rtableid;
+   faddrp = &zeroin_addr;
+   laddrp = &inp->inp_laddr;
+   }
 
-   if (first > last) {
-   /*
-* counting down
-*/
-   count = first - last;
-   if (count)
-   *lastport = first - arc4random_uniform(count);
+   if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 &&
+   ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
+(so->so_options & SO_ACCEPTCONN) == 0))
+   wild |= INPLOOKUP_WILDCARD;
 
-   do {
-   if (count-- < 0)/* completely used? */
-   return (EADDRNOTAVAIL);
-   --*lastport;
-   if (*lastport > first || *lastport < last)
-   *lastport = first;
-   lport = htons(*lastport);
-   } while (in_baddynamic(*lastport, 
so->so_proto->pr_protocol) ||
-   in_pcblookup(table, &zeroin_addr, 0,
-   &inp->inp_laddr, lport, wild, inp->inp_rtable

Re: make IPv6 macros look nicer

2013-08-06 Thread Philip Guenther
On Tue, Aug 6, 2013 at 11:40 AM, Christopher Zimmermann
 wrote:
> I'm currently working on the OpenBSD ip-stack for the first time.
> Here's a small cosmetic improvement.
> OK?

No, because the system doesn't build with that.


Philip Guenther



make IPv6 macros look nicer

2013-08-06 Thread Christopher Zimmermann
Hi,

I'm currently working on the OpenBSD ip-stack for the first time.
Here's a small cosmetic improvement.
OK?

Christopher

Index: netinet6/in6.h
===
RCS file: /cvs/src/sys/netinet6/in6.h,v
retrieving revision 1.65
diff -u -p -r1.65 in6.h
--- netinet6/in6.h  26 Jun 2013 09:12:40 -  1.65
+++ netinet6/in6.h  6 Aug 2013 18:26:05 -
@@ -214,37 +214,37 @@ extern const struct in6_addr in6addr_lin
  * Unspecified
  */
 #define IN6_IS_ADDR_UNSPECIFIED(a) \
-   ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[12]) == 0))
+   (((a)->s6_addr32[0] == 0) &&\
+((a)->s6_addr32[1] == 0) &&\
+((a)->s6_addr32[2] == 0) &&\
+((a)->s6_addr32[3] == 0))
 
 /*
  * Loopback
  */
 #define IN6_IS_ADDR_LOOPBACK(a)\
-   ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[12]) == ntohl(1)))
+   (((a)->s6_addr32[0] == 0) &&\
+((a)->s6_addr32[1] == 0) &&\
+((a)->s6_addr32[2] == 0) &&\
+((a)->s6_addr32[3] == ntohl(1)))
 
 /*
  * IPv4 compatible
  */
 #define IN6_IS_ADDR_V4COMPAT(a)\
-   ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[12]) != 0) &&
\
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[12]) != ntohl(1)))
+   (((a)->s6_addr32[0] == 0) &&\
+((a)->s6_addr32[1] == 0) &&\
+((a)->s6_addr32[2] == 0) &&\
+((a)->s6_addr32[3] != 0) &&\
+((a)->s6_addr32[3] != ntohl(1)))
 
 /*
  * Mapped
  */
 #define IN6_IS_ADDR_V4MAPPED(a)  \
-   ((*(const u_int32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
-(*(const u_int32_t *)(const void *)(&(a)->s6_addr[8]) == 
ntohl(0x)))
+   (((a)->s6_addr32[0] == 0) &&\
+((a)->s6_addr32[1] == 0) &&\
+((a)->s6_addr32[2] == ntohl(0x)))
 
 /*
  * KAME Scope Values



-- 
http://gmerlin.de
OpenPGP: http://gmerlin.de/christopher.pub
1917 680A 723C BF3D 2CA3  0E44 7E24 D19F 34B8 2A2A



Re: include netinet/in_var.h in dev

2013-08-06 Thread Mike Belopuhov
On 6 August 2013 03:54, Alexander Bluhm  wrote:
> Hi,
>
> For an upcoming change in in6_var.h I would like to minimize the
> impact.  Most network drivers include netinet/in_var.h, but apparently
> they don't have to.  Can we remove these includes?
>
> compiled on amd64 and i386
>
> ok?
>
> bluhm
>

should be fine.  ok mikeb



Re: Inline assembly is hard...

2013-08-06 Thread Marc Espie
On Tue, Aug 06, 2013 at 12:37:49AM +0200, Mark Kettenis wrote:
> The atomic_setbits_int() and atomic_clearbits_int() implementations
> use stwcx., which touches the condition code register.  This means we
> need to tell GCC that it gets clobbered.  Fixes issues with
> uvm_page_physload() which currently gets miscompiled.
> 
> ok?
> 
> 
> Index: atomic.h
> ===
> RCS file: /cvs/src/sys/arch/powerpc/include/atomic.h,v
> retrieving revision 1.4
> diff -u -p -r1.4 atomic.h
> --- atomic.h  23 Mar 2011 16:54:36 -  1.4
> +++ atomic.h  5 Aug 2013 22:34:00 -
> @@ -17,7 +17,7 @@ atomic_setbits_int(__volatile unsigned i
>   "   or  %0, %1, %0  \n"
>   "   stwcx.  %0, 0, %2   \n"
>   "   bne-1b  \n"
> - "   sync" : "=&r" (tmp) : "r" (v), "r" (uip) : "memory");
> + "   sync" : "=&r" (tmp) : "r" (v), "r" (uip) : "cc", "memory");
>  }
>  
>  static __inline void
> @@ -30,7 +30,7 @@ atomic_clearbits_int(__volatile unsigned
>   "   andc%0, %0, %1  \n"
>   "   stwcx.  %0, 0, %2   \n"
>   "   bne-1b  \n"
> - "   sync" : "=&r" (tmp) : "r" (v), "r" (uip) : "memory");
> + "   sync" : "=&r" (tmp) : "r" (v), "r" (uip) : "cc", "memory");
>  }
>  
>  #endif /* defined(_KERNEL) */
Obviously okay.