On Wed, 12 May 2021 17:26:51 +0300
Vitaliy Makkoveev <m...@openbsd.org> wrote:
> On Wed, May 12, 2021 at 07:11:09PM +0900, YASUOKA Masahiko wrote:
>> Radek reported a problem to misc@ that multiple Windows clients behind a NAT
>> cannot use a L2TP/IPsec server simultaneously.
>> 
>> https://marc.info/?t=160996816100001&r=1&w=2
>> 
>> There is two problems.  First is pipex(4) doesn't pass the proper
>> ipsecflowinfo to ip_output().  Second is the IPsec policy check which is
>> done by ipsp_spd_lookup() returns -1 (EINVAL) if the given tdb is not
>> cached.  This happens when its flow is shared by another tdb (for another
>> client of the same NAT).
>> 
>> The following 2 diffs fix these problem.
>> 
>> comment?
>> ok?
>> 
> 
> Hi.
> 
> I have two comments for the diff 1:
> 
> 1. You should add PACKET_TAG_IPSEC_FLOWINFO description to
>     m_tag_get(9).
> 2. You introduced mbuf(9) leak in pipex_l2tp_output() error path. I
>    pointed the place in your diff.

Good catch.  Thanks.


Let me update the diff.

Index: sys/net/pipex.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/net/pipex.c,v
retrieving revision 1.132
diff -u -p -r1.132 pipex.c
--- sys/net/pipex.c     10 Mar 2021 10:21:48 -0000      1.132
+++ sys/net/pipex.c     12 May 2021 15:33:33 -0000
@@ -1628,6 +1628,7 @@ pipex_l2tp_output(struct mbuf *m0, struc
 #ifdef INET6
        struct ip6_hdr *ip6;
 #endif
+       struct m_tag *mtag;
 
        hlen = sizeof(struct pipex_l2tp_header) +
            ((pipex_session_is_l2tp_data_sequencing_on(session))
@@ -1704,6 +1705,15 @@ pipex_l2tp_output(struct mbuf *m0, struc
                ip->ip_tos = 0;
                ip->ip_off = 0;
 
+               if (session->proto.l2tp.ipsecflowinfo > 0) {
+                       if ((mtag = m_tag_get(PACKET_TAG_IPSEC_FLOWINFO,
+                           sizeof(u_int32_t), M_NOWAIT)) == NULL)
+                               goto drop;
+                       *(u_int32_t *)(mtag + 1) =
+                           session->proto.l2tp.ipsecflowinfo;
+                       m_tag_prepend(m0, mtag);
+               }
+
                ip_send(m0);
                break;
 #ifdef INET6
@@ -1733,6 +1743,8 @@ pipex_l2tp_output(struct mbuf *m0, struc
 
        return;
 drop:
+       if (m0 != NULL)
+               m_freem(m0);
        session->stat.oerrors++;
 }
 
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/netinet/ip_input.c,v
retrieving revision 1.359
diff -u -p -r1.359 ip_input.c
--- sys/netinet/ip_input.c      30 Apr 2021 13:52:48 -0000      1.359
+++ sys/netinet/ip_input.c      12 May 2021 15:31:52 -0000
@@ -1790,6 +1790,8 @@ ip_send_do_dispatch(void *xmq, int flags
        struct mbuf_queue *mq = xmq;
        struct mbuf *m;
        struct mbuf_list ml;
+       struct m_tag *mtag;
+       u_int32_t ipsecflowinfo = 0;
 
        mq_delist(mq, &ml);
        if (ml_empty(&ml))
@@ -1797,7 +1799,12 @@ ip_send_do_dispatch(void *xmq, int flags
 
        NET_LOCK();
        while ((m = ml_dequeue(&ml)) != NULL) {
-               ip_output(m, NULL, NULL, flags, NULL, NULL, 0);
+               if ((mtag = m_tag_find(m, PACKET_TAG_IPSEC_FLOWINFO, NULL))
+                   != NULL) {
+                       ipsecflowinfo = *(u_int32_t *)(mtag + 1);
+                       m_tag_delete(m, mtag);
+               }
+               ip_output(m, NULL, NULL, flags, NULL, NULL, ipsecflowinfo);
        }
        NET_UNLOCK();
 }
Index: sys/sys/mbuf.h
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/sys/mbuf.h,v
retrieving revision 1.252
diff -u -p -r1.252 mbuf.h
--- sys/sys/mbuf.h      25 Feb 2021 02:43:31 -0000      1.252
+++ sys/sys/mbuf.h      12 May 2021 15:31:52 -0000
@@ -469,6 +469,7 @@ struct m_tag *m_tag_next(struct mbuf *, 
 /* Packet tag types */
 #define PACKET_TAG_IPSEC_IN_DONE       0x0001  /* IPsec applied, in */
 #define PACKET_TAG_IPSEC_OUT_DONE      0x0002  /* IPsec applied, out */
+#define PACKET_TAG_IPSEC_FLOWINFO      0x0004  /* IPsec flowinfo */
 #define PACKET_TAG_WIREGUARD           0x0040  /* WireGuard data */
 #define PACKET_TAG_GRE                 0x0080  /* GRE processing done */
 #define PACKET_TAG_DLT                 0x0100 /* data link layer type */
@@ -479,7 +480,7 @@ struct m_tag *m_tag_next(struct mbuf *, 
 #define PACKET_TAG_CARP_BAL_IP         0x4000  /* carp(4) ip balanced marker */
 
 #define MTAG_BITS \
-    ("\20\1IPSEC_IN_DONE\2IPSEC_OUT_DONE\3IPSEC_IN_CRYPTO_DONE" \
+    ("\20\1IPSEC_IN_DONE\2IPSEC_OUT_DONE\3IPSEC_FLOWINFO" \
     "\4IPSEC_OUT_CRYPTO_NEEDED\5IPSEC_PENDING_TDB\6BRIDGE\7WG\10GRE\11DLT" \
     "\12PF_DIVERT\14PF_REASSEMBLED\15SRCROUTE\16TUNNEL\17CARP_BAL_IP")
 
Index: share/man/man9/mbuf_tags.9
===================================================================
RCS file: /disk/cvs/openbsd/src/share/man/man9/mbuf_tags.9,v
retrieving revision 1.41
diff -u -p -r1.41 mbuf_tags.9
--- share/man/man9/mbuf_tags.9  21 Jun 2020 15:25:30 -0000      1.41
+++ share/man/man9/mbuf_tags.9  12 May 2021 15:33:33 -0000
@@ -122,6 +122,13 @@ The tag contains a
 identifying the security association applied to the packet.
 This tag is primarily used to detect and avoid loops in IPsec
 processing on output.
+.It PACKET_TAG_IPSEC_FLOWINFO
+Used by the IPv4 stack to specify the IPsec flow of an output IP packet.
+This is useful to specify the desired IPsec flow when there are multiple
+flows for multiple peers behind a same NAT with IPsec NAT-T.
+The tag contains a
+.Va u_int32_t
+identifying the IPsec flow.
 .It PACKET_TAG_WIREGUARD
 Used by the
 .Xr wg 4
@@ -152,12 +159,6 @@ The tag contains a
 .Va struct pf_divert
 identifying the port, address and routing domain the packet should be
 diverted to.
-.It PACKET_TAG_PIPEX
-Used by
-.Xr pipex 4
-to cache its session information.
-The tag contains a
-.Va struct pipex_tag .
 .It PACKET_TAG_PF_REASSEMBLED
 Used by
 .Xr pf 4
@@ -258,7 +259,6 @@ The tag-manipulating code is contained i
 .Xr gre 4 ,
 .Xr ipsec 4 ,
 .Xr pf 4 ,
-.Xr pipex 4 ,
 .Xr mbuf 9
 .Sh HISTORY
 The packet tags first appeared in

Reply via email to