Fix IPsec NAT-T to work with pipex(4). Introduce a new packet tag
authoryasuoka <yasuoka@openbsd.org>
Sat, 15 May 2021 08:07:20 +0000 (08:07 +0000)
committeryasuoka <yasuoka@openbsd.org>
Sat, 15 May 2021 08:07:20 +0000 (08:07 +0000)
PACKET_TAG_IPSEC_FLOWINFO to specify the IPsec flow.

ok mvs

share/man/man9/mbuf_tags.9
sys/net/pipex.c
sys/netinet/ip_input.c
sys/sys/mbuf.h

index 424916d..a71e456 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: mbuf_tags.9,v 1.42 2021/05/12 23:17:30 yasuoka Exp $
+.\"    $OpenBSD: mbuf_tags.9,v 1.43 2021/05/15 08:07:20 yasuoka Exp $
 .\"
 .\" The author of this man page is Angelos D. Keromytis (angelos@cis.upenn.edu)
 .\"
@@ -15,7 +15,7 @@
 .\" MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
 .\" PURPOSE.
 .\"
-.Dd $Mdocdate: May 12 2021 $
+.Dd $Mdocdate: May 15 2021 $
 .Dt M_TAG_GET 9
 .Os
 .Sh NAME
@@ -122,6 +122,11 @@ 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.
+The tag contains a
+.Va u_int32_t
+identifying the IPsec flow.
 .It PACKET_TAG_WIREGUARD
 Used by the
 .Xr wg 4
index 83cafd0..a78cbd6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pipex.c,v 1.132 2021/03/10 10:21:48 jsg Exp $ */
+/*     $OpenBSD: pipex.c,v 1.133 2021/05/15 08:07:20 yasuoka Exp $     */
 
 /*-
  * Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -1628,6 +1628,7 @@ pipex_l2tp_output(struct mbuf *m0, struct pipex_session *session)
 #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, struct pipex_session *session)
                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,7 @@ pipex_l2tp_output(struct mbuf *m0, struct pipex_session *session)
 
        return;
 drop:
+       m_freem(m0);
        session->stat.oerrors++;
 }
 
index c2f63e7..2c09c32 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_input.c,v 1.359 2021/04/30 13:52:48 bluhm Exp $    */
+/*     $OpenBSD: ip_input.c,v 1.360 2021/05/15 08:07:20 yasuoka Exp $  */
 /*     $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $   */
 
 /*
@@ -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 4a590a0..488b75b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mbuf.h,v 1.252 2021/02/25 02:43:31 dlg Exp $  */
+/*     $OpenBSD: mbuf.h,v 1.253 2021/05/15 08:07:20 yasuoka Exp $      */
 /*     $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $       */
 
 /*
@@ -469,6 +469,7 @@ struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
 /* 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 *, struct m_tag *);
 #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")