Re: Kill IN6_IFF_NODAD

2015-08-22 Thread Martin Pieuchot
On 19/08/15(Wed) 13:31, Martin Pieuchot wrote:
 KAME people chose to add states to the address descriptors in order
 to implement various IPv6 automagic features.  But IN6_IFF_NODAD is
 not a real state, it's just a hack for some spaghetti code.
 
 Diff belows get rids of this flag by shuffling some code around and
 only using the IN6_IFF_TENTATIVE flag.

Updated diff, this one contains a splsoftnet() missed in previous and
kindly reported by sthen@.


Index: net/if_spppsubr.c
===
RCS file: /cvs/src/sys/net/if_spppsubr.c,v
retrieving revision 1.136
diff -u -p -r1.136 if_spppsubr.c
--- net/if_spppsubr.c   18 Jul 2015 15:51:16 -  1.136
+++ net/if_spppsubr.c   22 Aug 2015 10:19:41 -
@@ -4790,9 +4790,6 @@ sppp_set_ip6_addr(struct sppp *sp, const
 */
ifra-ifra_prefixmask.sin6_family = AF_UNSPEC;
 
-   /* DAD is redundant after an IPv6CP exchange. */
-   ifra-ifra_flags |= IN6_IFF_NODAD;
-
task_add(systq, sp-ipv6cp.set_addr_task);
 }
 
Index: netinet6/in6.c
===
RCS file: /cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.165
diff -u -p -r1.165 in6.c
--- netinet6/in6.c  19 Aug 2015 13:27:38 -  1.165
+++ netinet6/in6.c  22 Aug 2015 10:25:19 -
@@ -468,11 +468,19 @@ in6_control(struct socket *so, u_long cm
/* reject read-only flags */
if ((ifra-ifra_flags  IN6_IFF_DUPLICATED) != 0 ||
(ifra-ifra_flags  IN6_IFF_DETACHED) != 0 ||
-   (ifra-ifra_flags  IN6_IFF_NODAD) != 0 ||
(ifra-ifra_flags  IN6_IFF_DEPRECATED) != 0 ||
(ifra-ifra_flags  IN6_IFF_AUTOCONF) != 0) {
return (EINVAL);
}
+
+   /*
+* Make the address tentative before joining multicast
+* addresses, so that corresponding MLD responses would
+* not have a tentative source address.
+*/
+   if ((ia6 == NULL)  in6if_do_dad(ifp))
+   ifra-ifra_flags |= IN6_IFF_TENTATIVE;
+
/*
 * first, make or update the interface address structure,
 * and link it to the list. try to enable inet6 if there
@@ -497,6 +505,11 @@ in6_control(struct socket *so, u_long cm
break;
}
 
+   /* Perform DAD, if needed. */
+   if (ia6-ia6_flags  IN6_IFF_TENTATIVE)
+   nd6_dad_start(ia6-ia_ifa);
+
+
plen = in6_mask2len(ifra-ifra_prefixmask.sin6_addr, NULL);
if (plen == 128) {
dohooks(ifp-if_addrhooks, 0);
@@ -753,15 +766,6 @@ in6_update_ifa(struct ifnet *ifp, struct
 * configure address flags.
 */
ia6-ia6_flags = ifra-ifra_flags;
-   /*
-* Make the address tentative before joining multicast addresses,
-* so that corresponding MLD responses would not have a tentative
-* source address.
-*/
-   ia6-ia6_flags = ~IN6_IFF_DUPLICATED;  /* safety */
-   if (hostIsNew  in6if_do_dad(ifp) 
-   (ifra-ifra_flags  IN6_IFF_NODAD) == 0)
-   ia6-ia6_flags |= IN6_IFF_TENTATIVE;
 
/*
 * We are done if we have simply modified an existing address.
@@ -906,17 +910,6 @@ in6_update_ifa(struct ifnet *ifp, struct
if (!imm)
goto cleanup;
LIST_INSERT_HEAD(ia6-ia6_memberships, imm, i6mm_chain);
-   }
-
-   /*
-* Perform DAD, if needed.
-* XXX It may be of use, if we can administratively
-* disable DAD.
-*/
-   if (hostIsNew  in6if_do_dad(ifp) 
-   (ifra-ifra_flags  IN6_IFF_NODAD) == 0)
-   {
-   nd6_dad_start(ia6-ia_ifa, NULL);
}
 
return (error);
Index: netinet6/in6_ifattach.c
===
RCS file: /cvs/src/sys/netinet6/in6_ifattach.c,v
retrieving revision 1.91
diff -u -p -r1.91 in6_ifattach.c
--- netinet6/in6_ifattach.c 17 Aug 2015 10:57:24 -  1.91
+++ netinet6/in6_ifattach.c 22 Aug 2015 10:19:41 -
@@ -292,7 +292,6 @@ success:
 int
 in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid)
 {
-   struct in6_ifaddr *ia6;
struct in6_aliasreq ifra;
int  s, error;
 
@@ -332,12 +331,6 @@ in6_ifattach_linklocal(struct ifnet *ifp
ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
 
/*
-* Do not let in6_update_ifa() do DAD, since we need a random delay
-* before sending an NS at the first time the interface becomes up.
-*/
-   ifra.ifra_flags |= IN6_IFF_NODAD;
-
-   /*
 * Now call in6_update_ifa() to do a bunch of procedures to configure
 * a link-local address. In the case of CARP, we may be 

Re: Fix ndp -p unaligned access (kernel and userland)

2015-08-22 Thread Martin Pieuchot
On 20/08/15(Thu) 17:48, Christian Weisgerber wrote:
 Currently, ndp -p will trigger unaligned accesses in the kernel and
 userland on architectures that require strict alignment for 64-bit
 types (e.g. sparc64).
 
 This is actually fallout from the time_t change.
 
 The sysctl used to pass the prefix list uses a packed format:
   one struct in6_prefix, several struct sockaddr_in6,
   one struct in6_prefix, several struct sockaddr_in6,
   ...
 This worked dandily when both structs had the same alignment
 requirement (int32_t).  However, there's a time_t in in6_prefix
 which pushed that struct's alignment to int64_t... boom!
 
 The patches below are taken from NetBSD (Martin Husemann):
 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netinet6/nd6.c.diff?r1=1.145r2=1.146
 http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.sbin/ndp/ndp.c.diff?r1=1.41r2=1.42
 
 Use simple byte pointer arithmetic and memcpy from/to aligned stack
 variables to handle the packed binary format passed out to userland
 when querying the prefix/router list.
 
 OK?

ok mpi@

 
 Index: sys/netinet6/nd6.c
 ===
 RCS file: /cvs/src/sys/netinet6/nd6.c,v
 retrieving revision 1.143
 diff -u -p -r1.143 nd6.c
 --- sys/netinet6/nd6.c16 Jul 2015 15:31:35 -  1.143
 +++ sys/netinet6/nd6.c20 Aug 2015 14:36:19 -
 @@ -1877,45 +1877,43 @@ fill_prlist(void *oldp, size_t *oldlenp,
  {
   int error = 0, s;
   struct nd_prefix *pr;
 - struct in6_prefix *p = NULL;
 - struct in6_prefix *pe = NULL;
 + char *p = NULL, *ps = NULL;
 + char *pe = NULL;
   size_t l;
  
   s = splsoftnet();
  
   if (oldp) {
 - p = (struct in6_prefix *)oldp;
 - pe = (struct in6_prefix *)((caddr_t)oldp + *oldlenp);
 + ps = p = (char *)oldp;
 + pe = (char *)oldp + *oldlenp;
   }
   l = 0;
  
   LIST_FOREACH(pr, nd_prefix, ndpr_entry) {
   u_short advrtrs;
 - size_t advance;
 - struct sockaddr_in6 *sin6;
 - struct sockaddr_in6 *s6;
 + struct sockaddr_in6 sin6;
   struct nd_pfxrouter *pfr;
 + struct in6_prefix pfx;
   char addr[INET6_ADDRSTRLEN];
  
 - if (oldp  p + 1 = pe)
 - {
 - bzero(p, sizeof(*p));
 - sin6 = (struct sockaddr_in6 *)(p + 1);
 -
 - p-prefix = pr-ndpr_prefix;
 - if (in6_recoverscope(p-prefix,
 - p-prefix.sin6_addr, pr-ndpr_ifp) != 0)
 + if (oldp  p + sizeof(struct in6_prefix) = pe) {
 + memset(pfx, 0, sizeof(pfx));
 + ps = p;
 +
 + pfx.prefix = pr-ndpr_prefix;
 + if (in6_recoverscope(pfx.prefix,
 + pfx.prefix.sin6_addr, pr-ndpr_ifp) != 0)
   log(LOG_ERR,
   scope error in prefix list (%s)\n,
 - inet_ntop(AF_INET6, p-prefix.sin6_addr,
 + inet_ntop(AF_INET6, pfx.prefix.sin6_addr,
   addr, sizeof(addr)));
 - p-raflags = pr-ndpr_raf;
 - p-prefixlen = pr-ndpr_plen;
 - p-vltime = pr-ndpr_vltime;
 - p-pltime = pr-ndpr_pltime;
 - p-if_index = pr-ndpr_ifp-if_index;
 + pfx.raflags = pr-ndpr_raf;
 + pfx.prefixlen = pr-ndpr_plen;
 + pfx.vltime = pr-ndpr_vltime;
 + pfx.pltime = pr-ndpr_pltime;
 + pfx.if_index = pr-ndpr_ifp-if_index;
   if (pr-ndpr_vltime == ND6_INFINITE_LIFETIME)
 - p-expire = 0;
 + pfx.expire = 0;
   else {
   time_t maxexpire;
  
 @@ -1924,40 +1922,44 @@ fill_prlist(void *oldp, size_t *oldlenp,
   ((sizeof(maxexpire) * 8) - 1));
   if (pr-ndpr_vltime 
   maxexpire - pr-ndpr_lastupdate) {
 - p-expire = pr-ndpr_lastupdate +
 + pfx.expire = pr-ndpr_lastupdate +
   pr-ndpr_vltime;
   } else
 - p-expire = maxexpire;
 + pfx.expire = maxexpire;
   }
 - p-refcnt = pr-ndpr_refcnt;
 - p-flags = pr-ndpr_stateflags;
 - p-origin = PR_ORIG_RA;
 + pfx.refcnt = pr-ndpr_refcnt;
 + pfx.flags = pr-ndpr_stateflags;
 + pfx.origin = PR_ORIG_RA;
 +
 + 

Re: tap-and-drag on ALPS touchpads

2015-08-22 Thread Martin Pieuchot
On 15/08/15(Sat) 01:32, Ulf Brosziewski wrote:
 
 The tap-and-drag gesture doesn't work reliably with the ALPS touchpads
 supported by pms. To make it work, it is necessary to start dragging
 immediately with the second touch, which doesn't always succeed.
 Increasing the tap timeout helps, but doesn't change the principle. The
 patch below solves that problem. Tests and comments would be welcome.
 
 In case someone is interested in the background: I have observed the
 same problem with a Linux installation on a machine with an ALPS
 touchpad; however, increasing the tap timeout to a sufficiently high
 value (= 260ms) makes it work normally. The somewhat special behaviour
 of those ALPS models is described in this LKML posting:
 https://lkml.org/lkml/2004/7/28/210
 The approach put forward there - which is partially reproduced in the
 current version of pms - is improved by the patch as follows: When the
 hardware signals a tap, the handler does nothing. The missing events
 will be emulated when the next packet arrives, which either signals the
 end of the gesture, or the start of a drag action. No timeout will occur
 even if the hardware introduces a long delay between the first and the
 second packet (which just happens when the finger is resting after the
 second contact).

This looks good to me.

Did you get reports from other ALPS users?

 Index: dev/pckbc/pms.c
 ===
 RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
 retrieving revision 1.64
 diff -u -p -r1.64 pms.c
 --- dev/pckbc/pms.c   20 Jul 2015 00:55:06 -  1.64
 +++ dev/pckbc/pms.c   14 Aug 2015 18:27:57 -
 @@ -120,7 +120,8 @@ struct alps_softc {
 
   int min_x, min_y;
   int max_x, max_y;
 - int old_fin;
 +
 + u_int gesture;
 
   u_int sec_buttons;  /* trackpoint */
 
 @@ -1521,8 +1522,7 @@ pms_proc_alps(struct pms_softc *sc)
  {
   struct alps_softc *alps = sc-alps;
   int x, y, z, w, dx, dy;
 - u_int buttons;
 - int fin, ges;
 + u_int buttons, gesture;
 
   if ((alps-model  ALPS_DUALPOINT)  alps_sec_proc(sc))
   return;
 @@ -1557,28 +1557,44 @@ pms_proc_alps(struct pms_softc *sc)
   y = ALPS_YMAX_BEZEL - y + ALPS_YMIN_BEZEL;
 
   if (alps-wsmode == WSMOUSE_NATIVE) {
 - ges = sc-packet[2]  0x01;
 - fin = sc-packet[2]  0x02;
 + if (alps-gesture == ALPS_TAP) {
 + /* Report a touch with the tap coordinates. */
 + wsmouse_input(sc-sc_wsmousedev, buttons,
 + alps-old_x, alps-old_y, ALPS_PRESSURE, 4,
 + WSMOUSE_INPUT_ABSOLUTE_X
 + | WSMOUSE_INPUT_ABSOLUTE_Y
 + | WSMOUSE_INPUT_ABSOLUTE_Z
 + | WSMOUSE_INPUT_ABSOLUTE_W);
 + if (z  0) {
 + /*
 +  * The hardware doesn't send a null pressure
 +  * event when dragging starts.
 +  */
 + wsmouse_input(sc-sc_wsmousedev, buttons,
 + alps-old_x, alps-old_y, 0, 0,
 + WSMOUSE_INPUT_ABSOLUTE_X
 + | WSMOUSE_INPUT_ABSOLUTE_Y
 + | WSMOUSE_INPUT_ABSOLUTE_Z
 + | WSMOUSE_INPUT_ABSOLUTE_W);
 + }
 + }
 
 - /* Simulate click (tap) */
 - if (ges  !fin)
 - z = 35;
 -
 - /* Generate a null pressure event (needed for tap  drag) */
 - if (ges  fin  !alps-old_fin)
 - z = 0;
 -
 - /* Generate a width value corresponding to one finger */
 - if (z  0)
 - w = 4;
 - else
 - w = 0;
 + gesture = sc-packet[2]  0x03;
 + if (gesture != ALPS_TAP) {
 + w = z ? 4 : 0;
 + wsmouse_input(sc-sc_wsmousedev, buttons, x, y, z, w,
 + WSMOUSE_INPUT_ABSOLUTE_X
 + | WSMOUSE_INPUT_ABSOLUTE_Y
 + | WSMOUSE_INPUT_ABSOLUTE_Z
 + | WSMOUSE_INPUT_ABSOLUTE_W);
 + }
 
 - wsmouse_input(sc-sc_wsmousedev, buttons, x, y, z, w,
 - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
 - WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W);
 + if (alps-gesture != ALPS_DRAG || gesture != ALPS_TAP)
 + alps-gesture = gesture;
 +
 + alps-old_x = x;
 + alps-old_y = y;
 
 - alps-old_fin = fin;
   } else {
   dx = dy = 0;
   if (z  ALPS_PRESSURE) {
 Index: dev/pckbc/pmsreg.h
 

Re: v6 autoconf, where have my connected routes gone?

2015-08-22 Thread Martin Pieuchot
On 20/08/15(Thu) 19:32, Sebastian Reitenbach wrote:
 On 08/19/15 17:51, Martin Pieuchot wrote:
 [...]
 With the patch below, together with the other patch you mention above,
 my problem is gone, network works as I expect it.

Thanks for testing, I'd appreciate reviews and oks for the first diff I
sent then.

M.



Re: tap-and-drag on ALPS touchpads

2015-08-22 Thread Ulf Brosziewski

On 08/22/2015 12:35 PM, Martin Pieuchot wrote:

On 15/08/15(Sat) 01:32, Ulf Brosziewski wrote:


The tap-and-drag gesture doesn't work reliably with the ALPS touchpads
supported by pms. To make it work, it is necessary to start dragging
immediately with the second touch, which doesn't always succeed.
Increasing the tap timeout helps, but doesn't change the principle. The
patch below solves that problem. Tests and comments would be welcome.

In case someone is interested in the background: I have observed the
same problem with a Linux installation on a machine with an ALPS
touchpad; however, increasing the tap timeout to a sufficiently high
value (= 260ms) makes it work normally. The somewhat special behaviour
of those ALPS models is described in this LKML posting:
 https://lkml.org/lkml/2004/7/28/210
The approach put forward there - which is partially reproduced in the
current version of pms - is improved by the patch as follows: When the
hardware signals a tap, the handler does nothing. The missing events
will be emulated when the next packet arrives, which either signals the
end of the gesture, or the start of a drag action. No timeout will occur
even if the hardware introduces a long delay between the first and the
second packet (which just happens when the finger is resting after the
second contact).


This looks good to me.

Did you get reports from other ALPS users?



No, I haven't received any reports.


Index: dev/pckbc/pms.c
===
RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.64
diff -u -p -r1.64 pms.c
--- dev/pckbc/pms.c 20 Jul 2015 00:55:06 -  1.64
+++ dev/pckbc/pms.c 14 Aug 2015 18:27:57 -
@@ -120,7 +120,8 @@ struct alps_softc {

int min_x, min_y;
int max_x, max_y;
-   int old_fin;
+
+   u_int gesture;

u_int sec_buttons;  /* trackpoint */

@@ -1521,8 +1522,7 @@ pms_proc_alps(struct pms_softc *sc)
  {
struct alps_softc *alps = sc-alps;
int x, y, z, w, dx, dy;
-   u_int buttons;
-   int fin, ges;
+   u_int buttons, gesture;

if ((alps-model  ALPS_DUALPOINT)  alps_sec_proc(sc))
return;
@@ -1557,28 +1557,44 @@ pms_proc_alps(struct pms_softc *sc)
y = ALPS_YMAX_BEZEL - y + ALPS_YMIN_BEZEL;

if (alps-wsmode == WSMOUSE_NATIVE) {
-   ges = sc-packet[2]  0x01;
-   fin = sc-packet[2]  0x02;
+   if (alps-gesture == ALPS_TAP) {
+   /* Report a touch with the tap coordinates. */
+   wsmouse_input(sc-sc_wsmousedev, buttons,
+   alps-old_x, alps-old_y, ALPS_PRESSURE, 4,
+   WSMOUSE_INPUT_ABSOLUTE_X
+   | WSMOUSE_INPUT_ABSOLUTE_Y
+   | WSMOUSE_INPUT_ABSOLUTE_Z
+   | WSMOUSE_INPUT_ABSOLUTE_W);
+   if (z  0) {
+   /*
+* The hardware doesn't send a null pressure
+* event when dragging starts.
+*/
+   wsmouse_input(sc-sc_wsmousedev, buttons,
+   alps-old_x, alps-old_y, 0, 0,
+   WSMOUSE_INPUT_ABSOLUTE_X
+   | WSMOUSE_INPUT_ABSOLUTE_Y
+   | WSMOUSE_INPUT_ABSOLUTE_Z
+   | WSMOUSE_INPUT_ABSOLUTE_W);
+   }
+   }

-   /* Simulate click (tap) */
-   if (ges  !fin)
-   z = 35;
-
-   /* Generate a null pressure event (needed for tap  drag) */
-   if (ges  fin  !alps-old_fin)
-   z = 0;
-
-   /* Generate a width value corresponding to one finger */
-   if (z  0)
-   w = 4;
-   else
-   w = 0;
+   gesture = sc-packet[2]  0x03;
+   if (gesture != ALPS_TAP) {
+   w = z ? 4 : 0;
+   wsmouse_input(sc-sc_wsmousedev, buttons, x, y, z, w,
+   WSMOUSE_INPUT_ABSOLUTE_X
+   | WSMOUSE_INPUT_ABSOLUTE_Y
+   | WSMOUSE_INPUT_ABSOLUTE_Z
+   | WSMOUSE_INPUT_ABSOLUTE_W);
+   }

-   wsmouse_input(sc-sc_wsmousedev, buttons, x, y, z, w,
-   WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
-   WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W);
+   if (alps-gesture != ALPS_DRAG || gesture != ALPS_TAP)
+   alps-gesture = gesture;
+
+   alps-old_x = x;
+   alps-old_y = y;

-   alps-old_fin = fin;
} else {
dx = dy = 0;