Solved [Solved] ipfw not matching decapsulated ipsec traffic

I think this is a bug:
On the 10.0-RELEASE I set up an ipsec server using ipsec-tools and compiling the corresponding custom kernel with IPSEC_NAT_T support.
I can connect normally (through NAT-T) and when ipfw is set to "allow all" the tunnel works.

However, when I set net.inet.ipsec.filtertunnel=1 and ipfw rules like: ipfw allow ip from any to any via bge0.2 ipsec keep-state the rules are getting no traffic, indicating that the ipfw has a problem matching the decapsulated traffic.

Has anyone observed the same?
 
Re: ipfw not matching decapsulated ipsec traffic

Same here.
After I upgraded to 10.0-RELEASE, pf, ipfw cannot control or NAT over ipsec tunnel.
I tried set net.inet.ipsec.filtertunnel=1, or remove IPSEC_NAT_T, not work.

Before upgrade, FreeBSd 9.2 works fine.
 
Re: ipfw not matching decapsulated ipsec traffic

I can confirm this case. I'm using my machine as L2TP/IPSec VPN gate with NAT. Since upgrade to release 10.0 it's broken on this matter.
 
Re: ipfw not matching decapsulated ipsec traffic

Reversing revision 254519 on 10-STABLE resolves the problem. Because there is a conflict on sys/sys/mbuf.h with svn when applying
Code:
svn merge -c -254519
I used the following patch:

Code:
--- sys/sys/mbuf.h      (revision 262373)
+++ sys/sys/mbuf.h      (working copy)
@@ -221,6 +221,7 @@
 #define        M_MCAST         0x00000020 /* send/received as link-level multicast */
 #define        M_PROMISC       0x00000040 /* packet was not for us */
 #define        M_VLANTAG       0x00000080 /* ether_vtag is valid */
+#define       M_SKIP_FIREWALL 0x01000000
 #define        M_FLOWID        0x00000100 /* deprecated: flowid is valid */
 #define        M_NOFREE        0x00000200 /* do not free mbuf, embedded in cluster */
 


@@ -248,7 +249,7 @@
  * Flags preserved when copying m_pkthdr.
  */
 #define M_COPYFLAGS \
-    (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
+    (M_PKTHDR|M_EOR|M_RDONLY|M_SKIP_FIREWALL|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
      M_PROTOFLAGS)
 
 /*
 
Re: ipfw not matching decapsulated ipsec traffic

What about for 10.0-RELEASE?
The patch can not compiled with 10.0-RELEASE src, M_SKIP_FIREWALL redefined.
 
Re: ipfw not matching decapsulated ipsec traffic

For the 10.0-RELEASE the following patch should do it:

Code:
Index: sys/netinet/ip_var.h
===================================================================
--- sys/netinet/ip_var.h        (revision 260789)
+++ sys/netinet/ip_var.h        (working copy)
@@ -163,12 +163,10 @@
 #define IP_ALLOWBROADCAST      SO_BROADCAST    /* 0x20 can send broadcast packets */
 
 /*
- * IPv4 protocol layer specific mbuf flags.
+ * mbuf flag used by ip_fastfwd
  */
 #define        M_FASTFWD_OURS          M_PROTO1        /* changed dst to local */
 #define        M_IP_NEXTHOP            M_PROTO2        /* explicit ip nexthop */
-#define        M_SKIP_FIREWALL         M_PROTO3        /* skip firewall processing,
-                                                  keep in sync with IP6 */
 #define        M_IP_FRAG               M_PROTO4        /* fragment reassembly */
 
 #ifdef __NO_STRICT_ALIGNMENT
Index: sys/netinet6/ip6_var.h
===================================================================
--- sys/netinet6/ip6_var.h      (revision 260789)
+++ sys/netinet6/ip6_var.h      (working copy)
@@ -293,12 +293,7 @@
 #define        IPV6_FORWARDING         0x02    /* most of IPv6 header exists */
 #define        IPV6_MINMTU             0x04    /* use minimum MTU (IPV6_USE_MIN_MTU) */
 
-/*
- * IPv6 protocol layer specific mbuf flags.
- */
-#define        M_IP6_NEXTHOP           M_PROTO2        /* explicit ip nexthop */
-#define        M_SKIP_FIREWALL         M_PROTO3        /* skip firewall processing,
-                                                  keep in sync with IPv4 */
+#define        M_IP6_NEXTHOP           M_PROTO7        /* explicit ip nexthop */
 
 #ifdef __NO_STRICT_ALIGNMENT
 #define IP6_HDR_ALIGNED_P(ip)  1
Index: sys/sys/mbuf.h
===================================================================
--- sys/sys/mbuf.h      (revision 260789)
+++ sys/sys/mbuf.h      (working copy)
@@ -221,6 +221,7 @@
 #define        M_MCAST         0x00000020 /* send/received as link-level multicast */
 #define        M_PROMISC       0x00000040 /* packet was not for us */
 #define        M_VLANTAG       0x00000080 /* ether_vtag is valid */
+#define M_SKIP_FIREWALL        0x01000000
 #define        M_FLOWID        0x00000100 /* deprecated: flowid is valid */
 #define        M_NOFREE        0x00000200 /* do not free mbuf, embedded in cluster */
 
@@ -248,7 +249,7 @@
  * Flags preserved when copying m_pkthdr.
  */
 #define M_COPYFLAGS \
-    (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
+    (M_PKTHDR|M_EOR|M_RDONLY|M_SKIP_FIREWALL|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
      M_PROTOFLAGS)
 
 /*
 
Re: ipfw not matching decapsulated ipsec traffic

patch for 10.0-RELEASE src

Code:
diff -urN sys/netinet/ip_var.h /tmp/sys/netinet/ip_var.h
--- sys/netinet/ip_var.h        2014-02-24 04:12:49.000000000 +0000
+++ /tmp/sys/netinet/ip_var.h   2014-02-24 05:14:23.000000000 +0000
@@ -163,12 +163,10 @@
 #define IP_ALLOWBROADCAST      SO_BROADCAST    /* 0x20 can send broadcast packets */
 
 /*
- * IPv4 protocol layer specific mbuf flags.
+ * mbuf flag used by ip_fastfwd
  */
 #define        M_FASTFWD_OURS          M_PROTO1        /* changed dst to local */
 #define        M_IP_NEXTHOP            M_PROTO2        /* explicit ip nexthop */
-#define        M_SKIP_FIREWALL         M_PROTO3        /* skip firewall processing,
-                                                  keep in sync with IP6 */
 #define        M_IP_FRAG               M_PROTO4        /* fragment reassembly */
 
 #ifdef __NO_STRICT_ALIGNMENT
diff -urN sys/netinet6/ip6_var.h /tmp/sys/netinet6/ip6_var.h
--- sys/netinet6/ip6_var.h      2014-02-24 04:12:48.000000000 +0000
+++ /tmp/sys/netinet6/ip6_var.h 2014-02-24 05:10:11.000000000 +0000
@@ -293,12 +293,7 @@
 #define        IPV6_FORWARDING         0x02    /* most of IPv6 header exists */
 #define        IPV6_MINMTU             0x04    /* use minimum MTU (IPV6_USE_MIN_MTU) */
 
-/*
- * IPv6 protocol layer specific mbuf flags.
- */
-#define        M_IP6_NEXTHOP           M_PROTO2        /* explicit ip nexthop */
-#define        M_SKIP_FIREWALL         M_PROTO3        /* skip firewall processing,
-                                                  keep in sync with IPv4 */
+#define        M_IP6_NEXTHOP           M_PROTO7        /* explicit ip nexthop */
 
 #ifdef __NO_STRICT_ALIGNMENT
 #define IP6_HDR_ALIGNED_P(ip)  1
diff -urN sys/sys/mbuf.h /tmp/sys/sys/mbuf.h
--- sys/sys/mbuf.h      2014-02-24 04:12:35.000000000 +0000
+++ /tmp/sys/sys/mbuf.h 2014-02-24 05:12:37.000000000 +0000
@@ -221,6 +221,7 @@
 #define        M_MCAST         0x00000020 /* send/received as link-level multicast */
 #define        M_PROMISC       0x00000040 /* packet was not for us */
 #define        M_VLANTAG       0x00000080 /* ether_vtag is valid */
+#define        M_SKIP_FIREWALL 0x01000000
 #define        M_FLOWID        0x00000100 /* deprecated: flowid is valid */
 #define        M_NOFREE        0x00000200 /* do not free mbuf, embedded in cluster */
 
@@ -248,7 +249,7 @@
  * Flags preserved when copying m_pkthdr.
  */
 #define M_COPYFLAGS \
-    (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
+    (M_PKTHDR|M_EOR|M_RDONLY|M_SKIP_FIREWALL|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
      M_PROTOFLAGS)
 
 /*
 
Re: ipfw not matching decapsulated ipsec traffic

This is somewhat nicer.

Code:
diff -urN sys/netinet/ip_var.h /tmp/sys/netinet/ip_var.h
--- sys/netinet/ip_var.h        2014-02-24 04:12:49.000000000 +0000
+++ /tmp/sys/netinet/ip_var.h   2014-02-24 05:14:23.000000000 +0000
@@ -163,12 +163,10 @@
 #define IP_ALLOWBROADCAST      SO_BROADCAST    /* 0x20 can send broadcast packets */
 
 /*
- * IPv4 protocol layer specific mbuf flags.
+ * mbuf flag used by ip_fastfwd
  */
 #define        M_FASTFWD_OURS          M_PROTO1        /* changed dst to local */
 #define        M_IP_NEXTHOP            M_PROTO2        /* explicit ip nexthop */
-#define        M_SKIP_FIREWALL         M_PROTO3        /* skip firewall processing,
-                                                  keep in sync with IP6 */
 #define        M_IP_FRAG               M_PROTO4        /* fragment reassembly */
 
 #ifdef __NO_STRICT_ALIGNMENT
diff -urN sys/netinet6/ip6_var.h /tmp/sys/netinet6/ip6_var.h
--- sys/netinet6/ip6_var.h      2014-02-24 04:12:48.000000000 +0000
+++ /tmp/sys/netinet6/ip6_var.h 2014-02-24 05:10:11.000000000 +0000
@@ -293,12 +293,7 @@
 #define        IPV6_FORWARDING         0x02    /* most of IPv6 header exists */
 #define        IPV6_MINMTU             0x04    /* use minimum MTU (IPV6_USE_MIN_MTU) */
 
-/*
- * IPv6 protocol layer specific mbuf flags.
- */
-#define        M_IP6_NEXTHOP           M_PROTO2        /* explicit ip nexthop */
-#define        M_SKIP_FIREWALL         M_PROTO3        /* skip firewall processing,
-                                                  keep in sync with IPv4 */
+#define        M_IP6_NEXTHOP           M_PROTO7        /* explicit ip nexthop */
 
 #ifdef __NO_STRICT_ALIGNMENT
 #define IP6_HDR_ALIGNED_P(ip)  1
diff -urN sys/sys/mbuf.h /tmp/sys/sys/mbuf.h
--- sys/sys/mbuf.h      2014-02-24 04:12:35.000000000 +0000
+++ /tmp/sys/sys/mbuf.h 2014-02-24 05:12:37.000000000 +0000
@@ -235,7 +235,7 @@
 #define        M_PROTO9        0x00100000 /* protocol-specific */
 #define        M_PROTO10       0x00200000 /* protocol-specific */
 #define        M_PROTO11       0x00400000 /* protocol-specific */
-#define        M_PROTO12       0x00800000 /* protocol-specific */
+#define        M_SKIP_FIREWALL 0x00800000
 
 /*
  * Flags to purge when crossing layers.
@@ -242,13 +242,13 @@
  */
 #define        M_PROTOFLAGS \
     (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8|\
-     M_PROTO9|M_PROTO10|M_PROTO11|M_PROTO12)
+     M_PROTO9|M_PROTO10|M_PROTO11)
 
 /*
  * Flags preserved when copying m_pkthdr.
  */
 #define M_COPYFLAGS \
-    (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
+    (M_PKTHDR|M_EOR|M_RDONLY|M_SKIP_FIREWALL|M_BCAST|M_MCAST|M_VLANTAG|M_PROMISC| \
      M_PROTOFLAGS)
 
 /*
@@ -255,12 +255,12 @@
  * Mbuf flag description for use with printf(9) %b identifier.
  */
 #define        M_FLAG_BITS \
-    "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY\5M_BCAST\6M_MCAST" \
-    "\7M_PROMISC\10M_VLANTAG\11M_FLOWID"
+    "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY\5M_SKIP_FIREWALL\6M_BCAST\7M_MCAST" \
+    "\8M_PROMISC\10M_VLANTAG\11M_FLOWID"
 #define        M_FLAG_PROTOBITS \
     "\15M_PROTO1\16M_PROTO2\17M_PROTO3\20M_PROTO4\21M_PROTO5" \
     "\22M_PROTO6\23M_PROTO7\24M_PROTO8\25M_PROTO9\26M_PROTO10" \
-    "\27M_PROTO11\30M_PROTO12"
+    "\27M_PROTO11"
 #define        M_FLAG_PRINTF (M_FLAG_BITS M_FLAG_PROTOBITS)
 
 /*
 
After a little more testing it seems it has to do with the definition of M_PROTO3. Applying the following minimalistic patch resolves the issue.

Code:
Index: netinet/ip_var.h
===================================================================
--- netinet/ip_var.h    (revision 262470)
+++ netinet/ip_var.h    (working copy)
@@ -167,7 +167,7 @@
  */
 #define        M_FASTFWD_OURS          M_PROTO1        /* changed dst to local */
 #define        M_IP_NEXTHOP            M_PROTO2        /* explicit ip nexthop */
-#define        M_SKIP_FIREWALL         M_PROTO3        /* skip firewall processing,
+#define        M_SKIP_FIREWALL         M_PROTO5        /* skip firewall processing,
                                                   keep in sync with IP6 */
 #define        M_IP_FRAG               M_PROTO4        /* fragment reassembly */

Index: netinet6/ip6_var.h
===================================================================
--- netinet6/ip6_var.h  (revision 262470)
+++ netinet6/ip6_var.h  (working copy)
@@ -297,7 +297,7 @@
  * IPv6 protocol layer specific mbuf flags.
  */
 #define        M_IP6_NEXTHOP           M_PROTO2        /* explicit ip nexthop */
-#define        M_SKIP_FIREWALL         M_PROTO3        /* skip firewall processing,
+#define        M_SKIP_FIREWALL         M_PROTO5        /* skip firewall processing,
                                                   keep in sync with IPv4 */

 #ifdef __NO_STRICT_ALIGNMENT

The question is why isn't M_PROTO3 functioning. I am guessing that it's being set by another protocol but it isn't properly cleared.
 
The culprit is the #define M_DECRYPTED M_PROTO3 in netinet6/in6.h (that is regardless of whether or not INET6 has been set). It gets mixed up and so when the M_DECRYPTED flag is set, M_SKIP_FIREWALL flag is also set.

The following patch resolves it (it has to be tested thoroughly).

Code:
Index: netipsec/xform_ipip.c
===================================================================
--- netipsec/xform_ipip.c       (revision 262492)
+++ netipsec/xform_ipip.c       (working copy)
@@ -181,6 +181,7 @@
        IPIPSTAT_INC(ipips_ipackets);
 
        m_copydata(m, 0, 1, &v);
+       m_clrprotoflags(m);
 
        switch (v >> 4) {
 #ifdef INET

Edit: This one doesn't resolve it correctly, i.e. not all ipsec packets are captured. Furthermore the captured packets have both directions (in and out).
 
Back
Top