Update the sdmmmc stack to take care of the SMC_CAPS_SINGLE_ONLY capability

2013-10-18 Thread Sylvestre Gallon
Hi tech@

Here is a diff to allow the sdmmc SMC_CAPS_SINGLE_ONLY caps to do
something. The bits I take are from NetBSD and it works well with
ommmc(4) on my Beagle Bone Black.

This capability force the sdmmc stack to only issue single blocks
transfers. It is usefull for debug purpose and/or for broken sdmmmc
controller.

Any OK/Comments ?

Cheers,

Index: sdmmc_mem.c
===
RCS file: /cvs/src/sys/dev/sdmmc/sdmmc_mem.c,v
retrieving revision 1.17
diff -u -p -u -p -r1.17 sdmmc_mem.c
--- sdmmc_mem.c 12 Sep 2013 11:54:04 -  1.17
+++ sdmmc_mem.c 18 Oct 2013 09:31:15 -
@@ -42,6 +42,14 @@ int  sdmmc_mem_mmc_switch(struct sdmmc_fu
 
 intsdmmc_mem_sd_init(struct sdmmc_softc *, struct sdmmc_function *);
 intsdmmc_mem_mmc_init(struct sdmmc_softc *, struct sdmmc_function *);
+intsdmmc_mem_single_read_block(struct sdmmc_function *, int, u_char *,
+   size_t);
+intsdmmc_mem_read_block_subr(struct sdmmc_function *, int, u_char *,
+   size_t);
+intsdmmc_mem_single_write_block(struct sdmmc_function *, int, u_char *,
+   size_t);
+intsdmmc_mem_write_block_subr(struct sdmmc_function *, int, u_char *,
+   size_t);
 
 #ifdef SDMMC_DEBUG
 #define DPRINTF(s) printf s
@@ -551,14 +559,13 @@ sdmmc_mem_set_blocklen(struct sdmmc_soft
 }
 
 int
-sdmmc_mem_read_block(struct sdmmc_function *sf, int blkno, u_char *data,
+sdmmc_mem_read_block_subr(struct sdmmc_function *sf, int blkno, u_char *data,
 size_t datalen)
 {
struct sdmmc_softc *sc = sf-sc;
struct sdmmc_command cmd;
int error;
 
-   rw_enter_write(sc-sc_lock);
 
if ((error = sdmmc_select_card(sc, sf)) != 0)
goto err;
@@ -602,20 +609,53 @@ sdmmc_mem_read_block(struct sdmmc_functi
} while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA));
 
 err:
-   rw_exit(sc-sc_lock);
-   return error;
+   return (error);
 }
 
 int
-sdmmc_mem_write_block(struct sdmmc_function *sf, int blkno, u_char *data,
+sdmmc_mem_single_read_block(struct sdmmc_function *sf, int blkno, u_char *data,
+size_t datalen)
+{
+   int error;
+   int i;
+
+   for (i = 0; i  datalen / sf-csd.sector_size; i++) {
+   error = sdmmc_mem_read_block_subr(sf, blkno + i, data + i *
+   sf-csd.sector_size, sf-csd.sector_size);
+   if (error)
+   break;
+   }
+
+   return (error);
+}
+
+int
+sdmmc_mem_read_block(struct sdmmc_function *sf, int blkno, u_char *data,
 size_t datalen)
 {
struct sdmmc_softc *sc = sf-sc;
-   struct sdmmc_command cmd;
int error;
 
rw_enter_write(sc-sc_lock);
 
+   if (ISSET(sc-sc_caps, SMC_CAPS_SINGLE_ONLY)) {
+   error = sdmmc_mem_single_read_block(sf, blkno, data, datalen);
+   } else {
+   error = sdmmc_mem_read_block_subr(sf, blkno, data, datalen);
+   }
+
+   rw_exit(sc-sc_lock);
+   return (error);
+}
+
+int
+sdmmc_mem_write_block_subr(struct sdmmc_function *sf, int blkno, u_char *data,
+size_t datalen)
+{
+   struct sdmmc_softc *sc = sf-sc;
+   struct sdmmc_command cmd;
+   int error;
+
if ((error = sdmmc_select_card(sc, sf)) != 0)
goto err;
 
@@ -657,6 +697,41 @@ sdmmc_mem_write_block(struct sdmmc_funct
} while (!ISSET(MMC_R1(cmd.c_resp), MMC_R1_READY_FOR_DATA));
 
 err:
+   return (error);
+}
+
+int
+sdmmc_mem_single_write_block(struct sdmmc_function *sf, int blkno, u_char 
*data,
+size_t datalen)
+{
+   int error;
+   int i;
+
+   for (i = 0; i  datalen / sf-csd.sector_size; i++) {
+   error = sdmmc_mem_write_block_subr(sf, blkno + i, data + i *
+   sf-csd.sector_size, sf-csd.sector_size);
+   if (error)
+   break;
+   }
+
+   return (error);
+}
+
+int
+sdmmc_mem_write_block(struct sdmmc_function *sf, int blkno, u_char *data,
+size_t datalen)
+{
+   struct sdmmc_softc *sc = sf-sc;
+   int error;
+
+   rw_enter_write(sc-sc_lock);
+
+   if (ISSET(sc-sc_caps, SMC_CAPS_SINGLE_ONLY)) {
+   error = sdmmc_mem_single_write_block(sf, blkno, data, datalen);
+   } else {
+   error = sdmmc_mem_write_block_subr(sf, blkno, data, datalen);
+   }
+
rw_exit(sc-sc_lock);
-   return error;
+   return (error);
 }



in6_leavegroup work queue

2013-10-18 Thread Alexander Bluhm
Hi,

Ethernet drivers connected via USB might sleep when their multicast
group filter is modified.  Unfortunately this happens from softclock
or softnet interrupt when IPv6 decides to unconfigure its addresses
automatically.

An obvious solution is to use a work queue.  I have put the workq
storage into struct in6_multi_mship.  That requires to include
sys/workq.h before compiling this struct.

Is it a good idea to include sys/workq.h directly form netinet6/in6_var.h?
An alternative is to include sys/workq.h from 50 kernel .c files.

What is the right way?

Note that netinet6/in6_var.h is included from user space and even
from some ports.

bluhm

Index: netinet6/in6.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.120
diff -u -p -u -p -r1.120 in6.c
--- netinet6/in6.c  17 Oct 2013 16:27:45 -  1.120
+++ netinet6/in6.c  18 Oct 2013 10:08:27 -
@@ -124,6 +124,7 @@ int in6_lifaddr_ioctl(struct socket *, u
 int in6_ifinit(struct ifnet *, struct in6_ifaddr *, int);
 void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *);
 void in6_ifloop_request(int, struct ifaddr *);
+void in6_leavegroup_task(void *, void *);
 
 const struct sockaddr_in6 sa6_any = {
sizeof(sa6_any), AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0
@@ -1816,9 +1817,20 @@ in6_leavegroup(struct in6_multi_mship *i
 {
 
if (imm-i6mm_maddr)
-   in6_delmulti(imm-i6mm_maddr);
-   free(imm,  M_IPMADDR);
+   workq_queue_task(NULL, imm-wqt, 0, in6_leavegroup_task, imm,
+   NULL);
+   else 
+   free(imm,  M_IPMADDR);
return 0;
+}
+
+void
+in6_leavegroup_task(void *arg1, void *arg2)
+{
+   struct in6_multi_mship *imm = arg1;
+
+   in6_delmulti(imm-i6mm_maddr);
+   free(imm,  M_IPMADDR);
 }
 
 /*
Index: netinet6/in6_var.h
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6_var.h,v
retrieving revision 1.42
diff -u -p -u -p -r1.42 in6_var.h
--- netinet6/in6_var.h  14 Oct 2013 11:07:42 -  1.42
+++ netinet6/in6_var.h  18 Oct 2013 10:09:52 -
@@ -64,6 +64,8 @@
 #ifndef _NETINET6_IN6_VAR_H_
 #define _NETINET6_IN6_VAR_H_
 
+#include sys/workq.h
+
 /*
  * Interface address, Internet version.  One of these structures
  * is allocated for each interface with an Internet address.
@@ -486,6 +488,7 @@ do {
\
  * belongs to.
  */
 struct in6_multi_mship {
+   struct  workq_task wqt; /* Allow network driver to sleep */
struct  in6_multi *i6mm_maddr;  /* Multicast address pointer */
LIST_ENTRY(in6_multi_mship) i6mm_chain;  /* multicast options chain */
 };



Re: in6_leavegroup work queue

2013-10-18 Thread Martin Pieuchot
Hi Alexander,

On 18/10/13(Fri) 12:45, Alexander Bluhm wrote:
 Hi,
 
 Ethernet drivers connected via USB might sleep when their multicast
 group filter is modified.  Unfortunately this happens from softclock
 or softnet interrupt when IPv6 decides to unconfigure its addresses
 automatically.
 
 An obvious solution is to use a work queue.  I have put the workq
 storage into struct in6_multi_mship.  That requires to include
 sys/workq.h before compiling this struct.

One problem with a work queue is that you cannot guarantee the interface
will still be here when the task will be scheduled, so passing a pointer
might not be a good idea.

That is why I wanted to change the if_get() API to use unique index for
each interface...

But maybe there's another solution at this problem than using a workq...

Martin



Add Xbox 360 Controller USB support

2013-10-18 Thread Jeremy Evans
This was originally submitted by Joe Gidi in November 2010, based on a
FreeBSD commit by Ed Schouten from back in December 2005.  See
http://marc.info/?l=openbsd-techm=128924886803756w=2 for previous
thread.  The only comment was from tedu@, that SMALL_KERNEL should be
added, which I've done but I'm not sure correctly.

Tested on amd64 using usbhidctl and some SDL-based emulators (mednafen,
snes9x-gtk, desmume).  The controller works fine except that the
directional pad is not processed as a hat but as a series of buttons
(that usbhidctl sees but SDL seems not to recognize).  Also, the bottom
L/R triggers are axes instead of buttons.

I've built a release with this, and checked that the amd64 floppy
still fits.

OKs?

Thanks,
Jeremy

Index: uhidev.c
===
RCS file: /cvs/src/sys/dev/usb/uhidev.c,v
retrieving revision 1.46
diff -u -p -r1.46 uhidev.c
--- uhidev.c20 Sep 2013 15:34:50 -  1.46
+++ uhidev.c17 Oct 2013 23:32:55 -
@@ -55,8 +55,11 @@
 
 #include dev/usb/uhidev.h
 
-/* Report descriptor for broken Wacom Graphire */
+/* Replacement report descriptors for devices shipped with broken ones */
 #include dev/usb/ugraphire_rdesc.h
+#ifndef SMALL_KERNEL
+#include dev/usb/uxb360gp_rdesc.h
+#endif /* !SMALL_KERNEL */
 
 #ifdef UHIDEV_DEBUG
 #define DPRINTF(x) do { if (uhidevdebug) printf x; } while (0)
@@ -99,8 +102,17 @@ uhidev_match(struct device *parent, void
if (uaa-iface == NULL)
return (UMATCH_NONE);
id = usbd_get_interface_descriptor(uaa-iface);
-   if (id == NULL || id-bInterfaceClass != UICLASS_HID)
-   return (UMATCH_NONE);
+if (id == NULL)
+return (UMATCH_NONE);
+if  (id-bInterfaceClass != UICLASS_HID) {
+#ifndef SMALL_KERNEL
+/* The Xbox 360 gamepad doesn't use the HID class. */
+if (id-bInterfaceClass != UICLASS_VENDOR ||
+id-bInterfaceSubClass != UISUBCLASS_XBOX360_CONTROLLER ||
+id-bInterfaceProtocol != UIPROTO_XBOX360_GAMEPAD)
+#endif /* !SMALL_KERNEL */
+return (UMATCH_NONE);
+}
if (usbd_get_quirks(uaa-device)-uq_flags  UQ_BAD_HID)
return (UMATCH_NONE);
if (uaa-matchlvl)
@@ -200,7 +212,16 @@ uhidev_attach(struct device *parent, str
/* Keep descriptor */
break;
}
+#ifndef SMALL_KERNEL
+   } else if (id-bInterfaceClass == UICLASS_VENDOR 
+   id-bInterfaceSubClass == UISUBCLASS_XBOX360_CONTROLLER 
+   id-bInterfaceProtocol == UIPROTO_XBOX360_GAMEPAD) {
+   /* The Xbox 360 gamepad has no report descriptor. */
+   size = sizeof uhid_xb360gp_report_descr;
+   descptr = uhid_xb360gp_report_descr;
+#endif /* !SMALL_KERNEL */
}
+
 
if (descptr) {
desc = malloc(size, M_USBDEV, M_NOWAIT);
Index: usb.h
===
RCS file: /cvs/src/sys/dev/usb/usb.h,v
retrieving revision 1.44
diff -u -p -r1.44 usb.h
--- usb.h   17 Apr 2013 11:53:10 -  1.44
+++ usb.h   17 Oct 2013 18:11:59 -
@@ -491,7 +491,8 @@ typedef struct {
 #define  UIPROTO_IRDA  0
 
 #define UICLASS_VENDOR 0xff
-
+#define  UISUBCLASS_XBOX360_CONTROLLER 0x5d
+#define  UIPROTO_XBOX360_GAMEPAD   0x01
 
 #define USB_HUB_MAX_DEPTH 5
 
Index: uxb360gp_rdesc.h
===
RCS file: uxb360gp_rdesc.h
diff -N uxb360gp_rdesc.h
--- /dev/null   1 Jan 1970 00:00:00 -
+++ uxb360gp_rdesc.h17 Oct 2013 18:23:56 -
@@ -0,0 +1,126 @@
+/*-
+ * Copyright (c) 2005 Ed Schouten e...@freebsd.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT 

IPv6 routing header type 0

2013-10-18 Thread Alexander Bluhm
Hi,

Our IPv6 stack scans all extension headers for routing header type
0 and drops the packet if it finds one.  RFC 5095 demands to handle
a routing header type 0 like an unrecognised routing type.  This
is enough to protect the own machine.

To protect a network as a firewall, we have pf which does the same
full scan in pf_walk_header6().  As pf is enabled by default, nothing
changes for most users.  If you turn off pf on your router, you
should not expect extra protection.

I would like to get rid of the double scanning and the old disabled
code in the IPv6 stack.

ok?

bluhm

Index: netinet6/ip6_input.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.115
diff -u -p -u -p -r1.115 ip6_input.c
--- netinet6/ip6_input.c17 Oct 2013 16:27:46 -  1.115
+++ netinet6/ip6_input.c18 Oct 2013 17:21:52 -
@@ -122,7 +122,6 @@ struct ifqueue ip6intrq;
 struct ip6stat ip6stat;
 
 void ip6_init2(void *);
-int ip6_check_rh0hdr(struct mbuf *, int *);
 
 int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
 struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
@@ -318,15 +317,6 @@ ip6_input(struct mbuf *m)
}
 #endif
 
-   if (ip6_check_rh0hdr(m, off)) {
-   ip6stat.ip6s_badoptions++;
-   in6_ifstat_inc(m-m_pkthdr.rcvif, ifs6_in_discard);
-   in6_ifstat_inc(m-m_pkthdr.rcvif, ifs6_in_hdrerr);
-   icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, off);
-   /* m is already freed */
-   return;
-   }
-
 #if NPF  0
 /*
  * Packet filter
@@ -705,74 +695,6 @@ ip6_input(struct mbuf *m)
return;
  bad:
m_freem(m);
-}
-
-/* scan packet for RH0 routing header. Mostly stolen from pf.c:pf_test() */
-int
-ip6_check_rh0hdr(struct mbuf *m, int *offp)
-{
-   struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
-   struct ip6_rthdr rthdr;
-   struct ip6_ext opt6;
-   u_int8_t proto = ip6-ip6_nxt;
-   int done = 0, lim, off, rh_cnt = 0;
-
-   off = ((caddr_t)ip6 - m-m_data) + sizeof(struct ip6_hdr);
-   lim = min(m-m_pkthdr.len, ntohs(ip6-ip6_plen) + sizeof(*ip6));
-   do {
-   switch (proto) {
-   case IPPROTO_ROUTING:
-   *offp = off;
-   if (rh_cnt++) {
-   /* more then one rh header present */
-   return (1);
-   }
-
-   if (off + sizeof(rthdr)  lim) {
-   /* packet to short to make sense */
-   return (1);
-   }
-
-   m_copydata(m, off, sizeof(rthdr), (caddr_t)rthdr);
-
-   if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
-   *offp += offsetof(struct ip6_rthdr, ip6r_type);
-   return (1);
-   }
-
-   off += (rthdr.ip6r_len + 1) * 8;
-   proto = rthdr.ip6r_nxt;
-   break;
-   case IPPROTO_AH:
-   case IPPROTO_HOPOPTS:
-   case IPPROTO_DSTOPTS:
-   /* get next header and header length */
-   if (off + sizeof(opt6)  lim) {
-   /*
-* Packet to short to make sense, we could
-* reject the packet but as a router we 
-* should not do that so forward it.
-*/
-   return (0);
-   }
-
-   m_copydata(m, off, sizeof(opt6), (caddr_t)opt6);
-
-   if (proto == IPPROTO_AH)
-   off += (opt6.ip6e_len + 2) * 4;
-   else
-   off += (opt6.ip6e_len + 1) * 8;
-   proto = opt6.ip6e_nxt;
-   break;
-   case IPPROTO_FRAGMENT:
-   default:
-   /* end of header stack */
-   done = 1;
-   break;
-   }
-   } while (!done);
-
-   return (0);
 }
 
 /*
Index: netinet6/route6.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/route6.c,v
retrieving revision 1.17
diff -u -p -u -p -r1.17 route6.c
--- netinet6/route6.c   11 Jun 2008 19:00:50 -  1.17
+++ netinet6/route6.c   18 Oct 2013 17:59:45 -
@@ -44,10 +44,6 @@
 
 #include netinet/icmp6.h
 
-#if 0
-static int ip6_rthdr0(struct mbuf *, struct ip6_hdr *, struct ip6_rthdr0 *);
-#endif
-
 /*
  * proto is unused
  */
@@ -68,43 +64,12 @@ route6_input(struct mbuf **mp, int *offp
}
 
switch 

cksum pseudo-header wankery

2013-10-18 Thread Henning Brauer
so stop that pseudo-header wankery. v6 doesn't have it at all. instead
of incrementally pre-computing a tiny part of the proto cksum, just do
it in in_proto_cksum_out when needed.
makes everything else in the stack super easy: need cksum? set flag,
done.

stack and pf cases tested with all 3 offloading variants (none /
needs-phdr / full).

and if sk(4) wouldn't be such a weird beast with it's
more-in-software-than-hw RX offloading in_cksum_addword could be
deleted too.

ok?

Index: net/if_pflow.c
===
RCS file: /cvs/src/sys/net/if_pflow.c,v
retrieving revision 1.36
diff -u -p -r1.36 if_pflow.c
--- net/if_pflow.c  17 Oct 2013 16:27:41 -  1.36
+++ net/if_pflow.c  18 Oct 2013 13:35:38 -
@@ -126,9 +126,6 @@ struct if_clone pflow_cloner =
 IF_CLONE_INITIALIZER(pflow, pflow_clone_create,
 pflow_clone_destroy);
 
-/* from udp_usrreq.c */
-extern int udpcksum;
-
 void
 pflowattach(int npflow)
 {
@@ -1535,6 +1532,8 @@ pflow_sendout_mbuf(struct pflow_softc *s
ui-ui_dst = sc-sc_receiver_ip;
ui-ui_dport = sc-sc_receiver_port;
ui-ui_ulen = htons(sizeof(struct udphdr) + len);
+   ui-ui_sum = 0;
+   m-m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
 
ip = (struct ip *)ui;
ip-ip_v = IPVERSION;
@@ -1544,18 +1543,6 @@ pflow_sendout_mbuf(struct pflow_softc *s
ip-ip_tos = IPTOS_LOWDELAY;
ip-ip_ttl = IPDEFTTL;
ip-ip_len = htons(sizeof(struct udpiphdr) + len);
-
-   /*
-* Compute the pseudo-header checksum; defer further checksumming
-* until ip_output() or hardware (if it exists).
-*/
-   if (udpcksum) {
-   m-m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
-   ui-ui_sum = in_cksum_phdr(ui-ui_src.s_addr,
-   ui-ui_dst.s_addr, htons(len + sizeof(struct udphdr) +
-   IPPROTO_UDP));
-   } else
-   ui-ui_sum = 0; 
 
 #if NBPFILTER  0
if (ifp-if_bpf) {
Index: net/pf.c
===
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.844
diff -u -p -r1.844 pf.c
--- net/pf.c17 Oct 2013 16:27:41 -  1.844
+++ net/pf.c18 Oct 2013 13:15:04 -
@@ -6742,20 +6742,10 @@ pf_cksum(struct pf_pdesc *pd, struct mbu
switch (pd-proto) {
case IPPROTO_TCP:
pd-hdr.tcp-th_sum = 0;
-   if (pd-af == AF_INET) {
-   pd-hdr.tcp-th_sum = in_cksum_phdr(pd-src-v4.s_addr,
-   pd-dst-v4.s_addr, htons(pd-tot_len -
-   pd-off + IPPROTO_TCP));
-   }
m-m_pkthdr.csum_flags |= M_TCP_CSUM_OUT;
break;
case IPPROTO_UDP:
pd-hdr.udp-uh_sum = 0;
-   if (pd-af == AF_INET) {
-   pd-hdr.udp-uh_sum = in_cksum_phdr(pd-src-v4.s_addr,
-   pd-dst-v4.s_addr, htons(pd-tot_len -
-   pd-off + IPPROTO_UDP));
-   }
m-m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
break;
case IPPROTO_ICMP:
Index: net/pipex.c
===
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.44
diff -u -p -r1.44 pipex.c
--- net/pipex.c 17 Oct 2013 16:27:43 -  1.44
+++ net/pipex.c 18 Oct 2013 13:34:13 -
@@ -1976,7 +1976,9 @@ pipex_l2tp_output(struct mbuf *m0, struc
udp-uh_sport = session-local.sin6.sin6_port;
udp-uh_dport = session-peer.sin6.sin6_port;
udp-uh_ulen = htons(plen);
+   udp-uh_sum = 0;
 
+   m0-m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
m0-m_pkthdr.rcvif = session-pipex_iface-ifnet_this;
 #if NPF  0
pf_pkt_addr_changed(m0);
@@ -1991,13 +1993,6 @@ pipex_l2tp_output(struct mbuf *m0, struc
ip-ip_ttl = MAXTTL;
ip-ip_tos = 0;
 
-   if (udpcksum) {
-   udp-uh_sum = in_cksum_phdr(ip-ip_src.s_addr,
-  ip-ip_dst.s_addr, htons(plen  + IPPROTO_UDP));
-   m0-m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
-   } else
-   udp-uh_sum = 0;
-
if (ip_output(m0, NULL, NULL, IP_IPSECFLOW, NULL, NULL,
session-proto.l2tp.ipsecflowinfo) != 0) {
PIPEX_DBG((session, LOG_DEBUG, ip_output failed.));
@@ -2017,10 +2012,6 @@ pipex_l2tp_output(struct mbuf *m0, struc
session-peer.sin6, NULL, NULL);
/* ip6-ip6_plen will be filled in ip6_output. */
 
-   udp-uh_sum = 0;
-   if ((udp-uh_sum = in6_cksum(m0, IPPROTO_UDP,
-   sizeof(struct ip6_hdr), plen)) == 0)
-   udp-uh_sum = 0x;
if (ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL) != 0) {
PIPEX_DBG((session, 

in[6]_proto_cksum_out: ICMP checksum fix

2013-10-18 Thread Lawrence Teo
Back in August I sent a diff to fix ICMP checksum calculation in
in_proto_cksum_out() and in_delayed_cksum() in cases where the ICMP
checksum field is not in the first mbuf of an mbuf chain (original post
at http://marc.info/?l=openbsd-techm=137571298511653w=2 ).

bluhm@ replied on tech@ with the following feedback:

On Fri, Aug 09, 2013 at 02:21:29AM +0200, Alexander Bluhm wrote:
 On Mon, Aug 05, 2013 at 10:28:57AM -0400, Lawrence Teo wrote:
  Index: ip_output.c
  ===
  RCS file: /cvs/src/sys/netinet/ip_output.c,v
  retrieving revision 1.244
  diff -U5 -p -r1.244 ip_output.c
  --- ip_output.c 31 Jul 2013 15:41:52 -  1.244
  +++ ip_output.c 5 Aug 2013 02:44:20 -
  @@ -2058,25 +2058,35 @@ ip_mloopback(struct ifnet *ifp, struct m
*/
   void
   in_delayed_cksum(struct mbuf *m)
   {
  struct ip *ip;
  -   u_int16_t csum, offset;
  +   u_int16_t csum = 0, offset;
   
  ip = mtod(m, struct ip *);
  offset = ip-ip_hl  2;
  +
  +   if (ip-ip_p == IPPROTO_ICMP)
  +   if (m_copyback(m, offset + offsetof(struct icmp, icmp_cksum),
  +   sizeof(csum), csum, M_NOWAIT))
  +   return;
 
 The code at the end of this function tries to avoid the m_copyback()
 in the common case unless (offset + sizeof(u_int16_t))  m-m_len).
 Do we want this optimization here?
 
 bluhm

Here's my revised diff that preserves that optimization so that existing
behavior won't change in the common case where the protocol checksum
field is in the first mbuf.

The new diff also implements similar logic in in6_proto_cksum_out().

Comments/feedback appreciated. :)

Thanks,
Lawrence


Index: netinet/in.h
===
RCS file: /cvs/src/sys/netinet/in.h,v
retrieving revision 1.97
diff -u -p -u -p -r1.97 in.h
--- netinet/in.h9 Oct 2013 09:33:43 -   1.97
+++ netinet/in.h16 Oct 2013 15:14:39 -
@@ -835,7 +835,7 @@ intin_broadcast(struct in_addr, stru
 int   in_canforward(struct in_addr);
 int   in_cksum(struct mbuf *, int);
 int   in4_cksum(struct mbuf *, u_int8_t, int, int);
-void  in_delayed_cksum(struct mbuf *);
+void  in_delayed_cksum(struct mbuf *, u_int8_t, u_int16_t);
 int   in_localaddr(struct in_addr, u_int);
 void  in_socktrim(struct sockaddr_in *);
 char *inet_ntoa(struct in_addr);
Index: netinet/ip_output.c
===
RCS file: /cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.247
diff -u -p -u -p -r1.247 ip_output.c
--- netinet/ip_output.c 18 Oct 2013 09:04:03 -  1.247
+++ netinet/ip_output.c 18 Oct 2013 15:14:04 -
@@ -2050,34 +2050,35 @@ ip_mloopback(struct ifnet *ifp, struct m
  * Process a delayed payload checksum calculation.
  */
 void
-in_delayed_cksum(struct mbuf *m)
+in_delayed_cksum(struct mbuf *m, u_int8_t proto, u_int16_t p_off)
 {
struct ip *ip;
-   u_int16_t csum, offset;
+   u_int16_t csum = 0, hlen, *p = NULL;
 
ip = mtod(m, struct ip *);
-   offset = ip-ip_hl  2;
-   csum = in4_cksum(m, 0, offset, m-m_pkthdr.len - offset);
-   if (csum == 0  ip-ip_p == IPPROTO_UDP)
-   csum = 0x;
-
-   switch (ip-ip_p) {
-   case IPPROTO_TCP:
-   offset += offsetof(struct tcphdr, th_sum);
-   break;
-
-   case IPPROTO_UDP:
-   offset += offsetof(struct udphdr, uh_sum);
-   break;
-
-   default:
+   if (ip-ip_p != proto)
return;
+
+   hlen = ip-ip_hl  2;
+   p_off += hlen;
+   if ((p_off + sizeof(u_int16_t)) = m-m_len)
+   p = (u_int16_t *)(mtod(m, caddr_t) + p_off);
+
+   if (proto == IPPROTO_ICMP) {
+   if (p)
+   *p = 0;
+   else if (m_copyback(m, p_off, sizeof(csum), csum, M_NOWAIT))
+   return;
}
 
-   if ((offset + sizeof(u_int16_t))  m-m_len)
-   m_copyback(m, offset, sizeof(csum), csum, M_NOWAIT);
+   csum = in4_cksum(m, 0, hlen, m-m_pkthdr.len - hlen);
+   if (csum == 0  proto == IPPROTO_UDP)
+   csum = 0x;
+
+   if (p)
+   *p = csum;
else
-   *(u_int16_t *)(mtod(m, caddr_t) + offset) = csum;
+   m_copyback(m, p_off, sizeof(csum), csum, M_NOWAIT);
 }
 
 void
@@ -2086,25 +2087,20 @@ in_proto_cksum_out(struct mbuf *m, struc
if (m-m_pkthdr.csum_flags  M_TCP_CSUM_OUT) {
if (!ifp || !(ifp-if_capabilities  IFCAP_CSUM_TCPv4) ||
ifp-if_bridgeport != NULL) {
-   in_delayed_cksum(m);
+   in_delayed_cksum(m, IPPROTO_TCP,
+   offsetof(struct tcphdr, th_sum));
m-m_pkthdr.csum_flags = ~M_TCP_CSUM_OUT; /* Clear */
}
} else if (m-m_pkthdr.csum_flags  

unlimited HFSC v2: [part 1] rename pf_altq::altq_disc

2013-10-18 Thread Martin Pelikan
Hi.

After several suggestions from Henning I started working putting parts
of hfsc_if into ifaltq, where normally ALTQ bits would be (altq_flags
will have to stay outside of the union, because that's how you know if
altq has been enabled on that ifnet).  But making that union will mean
altq_disc as transition.altq.altq_disc will clash with pf_altq's
member.  This diff renames pf_altq::altq_disc to altq_disc_state.
(Ah, the good old C namespace problems! ;-))

It builds on amd64 and shouldn't make any difference.

ok?
--
Martin Pelikan


Index: altq/altq_cbq.c
===
RCS file: /cvs/src/sys/altq/altq_cbq.c,v
retrieving revision 1.26
diff -u -p -r1.26 altq_cbq.c
--- altq/altq_cbq.c 3 Jul 2011 23:59:43 -   1.26
+++ altq/altq_cbq.c 18 Oct 2013 16:49:09 -
@@ -189,10 +189,10 @@ cbq_pfattach(struct pf_altq *a)
struct ifnet*ifp;
int  s, error;
 
-   if ((ifp = ifunit(a-ifname)) == NULL || a-altq_disc == NULL)
+   if ((ifp = ifunit(a-ifname)) == NULL || a-altq_disc_state == NULL)
return (EINVAL);
s = splnet();
-   error = altq_attach(ifp-if_snd, ALTQT_CBQ, a-altq_disc,
+   error = altq_attach(ifp-if_snd, ALTQT_CBQ, a-altq_disc_state,
cbq_enqueue, cbq_dequeue, cbq_request, NULL, NULL);
splx(s);
return (error);
@@ -216,7 +216,7 @@ cbq_add_altq(struct pf_altq *a)
cbqp-ifnp.ifq_ = ifp-if_snd; /* keep the ifq */
 
/* keep the state in pf_altq */
-   a-altq_disc = cbqp;
+   a-altq_disc_state = cbqp;
 
return (0);
 }
@@ -226,9 +226,9 @@ cbq_remove_altq(struct pf_altq *a)
 {
cbq_state_t *cbqp;
 
-   if ((cbqp = a-altq_disc) == NULL)
+   if ((cbqp = a-altq_disc_state) == NULL)
return (EINVAL);
-   a-altq_disc = NULL;
+   a-altq_disc_state = NULL;
 
cbq_clear_interface(cbqp);
 
@@ -252,7 +252,7 @@ cbq_add_queue(struct pf_altq *a)
struct cbq_opts *opts;
int i;
 
-   if ((cbqp = a-altq_disc) == NULL)
+   if ((cbqp = a-altq_disc_state) == NULL)
return (EINVAL);
if (a-qid == 0)
return (EINVAL);
@@ -360,7 +360,7 @@ cbq_remove_queue(struct pf_altq *a)
cbq_state_t *cbqp;
int i;
 
-   if ((cbqp = a-altq_disc) == NULL)
+   if ((cbqp = a-altq_disc_state) == NULL)
return (EINVAL);
 
if ((cl = clh_to_clp(cbqp, a-qid)) == NULL)
Index: altq/altq_hfsc.c
===
RCS file: /cvs/src/sys/altq/altq_hfsc.c,v
retrieving revision 1.29
diff -u -p -r1.29 altq_hfsc.c
--- altq/altq_hfsc.c18 Sep 2011 20:34:29 -  1.29
+++ altq/altq_hfsc.c18 Oct 2013 16:49:09 -
@@ -134,10 +134,10 @@ hfsc_pfattach(struct pf_altq *a)
struct ifnet *ifp;
int s, error;
 
-   if ((ifp = ifunit(a-ifname)) == NULL || a-altq_disc == NULL)
+   if ((ifp = ifunit(a-ifname)) == NULL || a-altq_disc_state == NULL)
return (EINVAL);
s = splnet();
-   error = altq_attach(ifp-if_snd, ALTQT_HFSC, a-altq_disc,
+   error = altq_attach(ifp-if_snd, ALTQT_HFSC, a-altq_disc_state,
altq_hfsc_enqueue, altq_hfsc_dequeue, altq_hfsc_request, NULL,
NULL);
splx(s);
@@ -162,7 +162,7 @@ hfsc_add_altq(struct pf_altq *a)
hif-hif_ifq = ifp-if_snd;
 
/* keep the state in pf_altq */
-   a-altq_disc = hif;
+   a-altq_disc_state = hif;
 
return (0);
 }
@@ -172,9 +172,9 @@ hfsc_remove_altq(struct pf_altq *a)
 {
struct altq_hfsc_if *hif;
 
-   if ((hif = a-altq_disc) == NULL)
+   if ((hif = a-altq_disc_state) == NULL)
return (EINVAL);
-   a-altq_disc = NULL;
+   a-altq_disc_state = NULL;
 
(void)hfsc_clear_interface(hif);
(void)altq_hfsc_class_destroy(hif-hif_rootclass);
@@ -194,7 +194,7 @@ hfsc_add_queue(struct pf_altq *a)
struct hfsc_opts *opts;
struct service_curve rtsc, lssc, ulsc;
 
-   if ((hif = a-altq_disc) == NULL)
+   if ((hif = a-altq_disc_state) == NULL)
return (EINVAL);
 
opts = a-pq_u.hfsc_opts;
@@ -235,7 +235,7 @@ hfsc_remove_queue(struct pf_altq *a)
struct altq_hfsc_if *hif;
struct altq_hfsc_class *cl;
 
-   if ((hif = a-altq_disc) == NULL)
+   if ((hif = a-altq_disc_state) == NULL)
return (EINVAL);
 
if ((cl = clh_to_clp(hif, a-qid)) == NULL)
Index: altq/altq_priq.c
===
RCS file: /cvs/src/sys/altq/altq_priq.c,v
retrieving revision 1.24
diff -u -p -r1.24 altq_priq.c
--- altq/altq_priq.c3 Jul 2011 23:59:43 -   1.24
+++ altq/altq_priq.c18 Oct 2013 16:49:09 -
@@ -73,10 +73,10 @@ priq_pfattach(struct pf_altq *a)
struct ifnet *ifp;
int s, error;
 
-   if 

Re: Small binutils tweak

2013-10-18 Thread Landry Breuil
On Fri, Aug 23, 2013 at 10:40:22PM +0200, Landry Breuil wrote:
 On Sun, Apr 21, 2013 at 10:42:09AM -0400, Brian Callahan wrote:
  On 04/21/13 03:21, Jonathan Gray wrote:
  On Sat, Mar 02, 2013 at 10:36:50AM -0500, Brian Callahan wrote:
  Hi tech --
  
  While doing some ports testing with clang, I came across the
  binutils bug mentioned here:
  http://lists.gnu.org/archive/html/bug-binutils/2004-07/msg0.html
  
  Below is a backport of the commit mentioned later in the thread. It
  fixes the issue.
  I was able to rebuild working kernels and do a full 'make build' on
  amd64, loongson, and macppc with this patch. But since it affects
  all archs, testing on the archs I don't have access to will be
  needed.
  
  OK?
  This patch does not apply, it seems your mail client is wrapping lines.
  
  
  
  Below. Also attached as a tarball, in case Thunderbird really just hates me.
  
  miod told me about a month and a half ago to focus on moving to
  binutils-2.17 and not backport things to 2.15 so I never bothered to
  ping this.
 
 Bringing this back , since i'm facing issues with mozilla / icu linking
 with ld/building with clang. In my limited testing, instead of the big
 patch you were referring to, just using elflink.c r1.76 was enough to
 fix my issue.
 
 See https://bugzilla.mozilla.org/show_bug.cgi?id=908080 for the whole
 story, and
 http://www.sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=srcr1=1.75r2=1.76
 for the much smaller fix.
 
 Whatever was the reason for backing this out (iirc, xenocara blowed on
 ppc), this needs to be reconsidered, since we're not going to move to
 binutils 2.17 right now.

I know it still breaks stuff subtly on powerpc, but i stumbled upon this
again when trying to build mozilla trunk on i386 with clang. If we still
want to build next firefoxes (26 or 27, dont remember) with clang,
something has to move around this.

Landry