On Monday, January 30, 2012 15:43 CET, YASUOKA Masahiko <[email protected]>
wrote:
> On Mon, 30 Jan 2012 22:49:22 +0900 (JST)
> YASUOKA Masahiko <[email protected]> wrote:
> > 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?
>
> Oops. Let me update the diff.
>
> The given struct sockaddr object of
> pipex_l2tp_userland_lookup_session() became passed from the userland,
> so its address family must be checked.
>
> ok?
tested IPSec/L2TP with xl2tpd, strongswan client. I did setup the tunnel
yesterday
evening, and its still alive this morning. Without the patch, the tunnel
usually died after
a couple of minutes.
So this definitely works for me, but I'm probably not the right guy to OK that
in this phase of
release cycle.
I'll now try with Android phone, since I've seen the same problems with dying
tunnel too.
Sebastian
>
> 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 14:37:31 -0000
> @@ -2210,13 +2210,16 @@ 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;
> struct pipex_hash_head *list;
> struct pipex_session *session;
> uint16_t session_id, tunnel_id, flags;
> +
> + if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
> + return (NULL);
>
> /* pullup */
> if (m0->m_pkthdr.len < sizeof(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 14:37:31 -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 14:37:31 -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 14:37:32 -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 =