pipex hook in udp_usrreq() mistakenly assumed that `inp' is
connected. The hook could not use the destination address properly,
so it failed to find the pipex session. This bug caused LCP keepalive
failures on L2TP from client that does LCP keepalive and uses sequence
number on the L2TP data channel (xl2tpd + pppd).
The diff includes kernel header file changes.
ok?
Index: sys/net/pipex.c
===================================================================
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.25
diff -u -p -r1.25 pipex.c
--- sys/net/pipex.c 23 Jan 2012 03:36:21 -0000 1.25
+++ sys/net/pipex.c 30 Jan 2012 12:11:16 -0000
@@ -2210,7 +2210,7 @@ pipex_l2tp_userland_lookup_session_ipv6(
}
#endif
-Static struct pipex_session *
+struct pipex_session *
pipex_l2tp_userland_lookup_session(struct mbuf *m0, struct sockaddr *sa)
{
struct pipex_l2tp_header l2tp;
Index: sys/net/pipex.h
===================================================================
RCS file: /cvs/src/sys/net/pipex.h,v
retrieving revision 1.11
diff -u -p -r1.11 pipex.h
--- sys/net/pipex.h 23 Jan 2012 03:36:21 -0000 1.11
+++ sys/net/pipex.h 30 Jan 2012 12:11:16 -0000
@@ -210,6 +210,7 @@ struct pipex_session *pipex_pptp_lookup
struct mbuf *pipex_pptp_input (struct mbuf *, struct pipex_session
*);
struct pipex_session *pipex_pptp_userland_lookup_session_ipv4 (struct mbuf *,
struct in_addr);
struct pipex_session *pipex_pptp_userland_lookup_session_ipv6 (struct mbuf *,
struct in6_addr);
+struct pipex_session *pipex_l2tp_userland_lookup_session(struct mbuf *,
struct sockaddr *);
struct mbuf *pipex_pptp_userland_output (struct mbuf *, struct
pipex_session *);
struct pipex_session *pipex_l2tp_lookup_session (struct mbuf *, int);
struct mbuf *pipex_l2tp_input (struct mbuf *, int off, struct
pipex_session *);
Index: sys/net/pipex_local.h
===================================================================
RCS file: /cvs/src/sys/net/pipex_local.h,v
retrieving revision 1.14
diff -u -p -r1.14 pipex_local.h
--- sys/net/pipex_local.h 25 Nov 2011 13:05:06 -0000 1.14
+++ sys/net/pipex_local.h 30 Jan 2012 12:11:16 -0000
@@ -406,7 +406,6 @@ Static struct pipex_session *pipex_pptp
#ifdef PIPEX_L2TP
Static void pipex_l2tp_output (struct mbuf *, struct
pipex_session *);
-Static struct pipex_session *pipex_l2tp_userland_lookup_session(struct mbuf
*, struct sockaddr *);
#endif
#ifdef PIPEX_MPPE
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.145
diff -u -p -r1.145 udp_usrreq.c
--- sys/netinet/udp_usrreq.c 8 Jul 2011 18:30:17 -0000 1.145
+++ sys/netinet/udp_usrreq.c 30 Jan 2012 12:11:17 -0000
@@ -1198,6 +1198,12 @@ udp_usrreq(struct socket *so, int req, s
#ifdef PIPEX
if (inp->inp_pipex) {
struct pipex_session *session;
+
+ if (addr != NULL)
+ session =
+ pipex_l2tp_userland_lookup_session(m,
+ mtod(addr, struct sockaddr *));
+ else
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
session =