# pf tracking state of ipsec connections



## adam2104 (Jul 18, 2012)

Does anyone know what information pf stores in its state table? How much of the "pass" criteria is stored? I ask because I'm having trouble with rules that match ipsec nat-t traffic that is marked with different TOS bits. More specifically, I have a device that creates an ipsec tunnel to a headend device. Through this tunnel different types of traffic flows. So, it looks like this:

headend --- freebsd router --- ipsec device --- phone

The phone behind the ipsec device marks its traffic with different tos values. tos 0x60 for signaling, tos 0xb8 for media. So, I've created the following rules:


```
local_nets = "{ 172.28.1.0/24, 172.28.10.0/24, 172.28.11.0/24 }"
work871 = "172.28.1.3"
pass in quick inet proto udp from $work871 tos 0xB8 tag VOIP-RTP
pass in quick inet proto udp from $work871 tos 0x60 tag VOIP-SIG
pass in quick inet proto { tcp, udp } from $local_nets
```

Unfortunately, it seems that PF creates a state entry first for the overall ipsec tunnel using the third rule. After the tunnel gets setup and the subsequent marked traffic goes through the tunnel, it hits the state entry and doesn't evaluate the rules. This leaves me to believe that pf isn't creating a state entry that contains the tos value.

I've confirmed the TOS bits are being carried through to the IP header of the IPSEC packets. Here's a tcpdump of the incoming packets from my LAN interface (vr0):


```
tcpdump: listening on vr0, link-type EN10MB (Ethernet), capture size 65535 bytes
21:37:39.464357 IP (tos 0xc0, ttl 255, id 848, offset 0, flags [none], proto UDP (17), length 144)
    172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x12e), length 116
21:37:39.483350 IP (tos 0xc0, ttl 255, id 1707, offset 0, flags [none], proto UDP (17), length 29)
    172.28.1.3.4500 > 64.102.7.50.4500: isakmp-nat-keep-alive
21:37:42.365389 IP (tos 0x0, ttl 255, id 849, offset 0, flags [none], proto UDP (17), length 152)
    172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x12f), length 124
21:37:45.465724 IP (tos 0xc0, ttl 255, id 850, offset 0, flags [none], proto UDP (17), length 144)
    172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x130), length 116
21:37:47.370081 IP (tos 0x0, ttl 255, id 851, offset 0, flags [none], proto UDP (17), length 152)
    172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x131), length 124
21:37:49.256302 IP (tos 0x60, ttl 255, id 852, offset 0, flags [none], proto UDP (17), length 120)
    172.28.1.3.4500 > 1.1.1.1.4500: UDP-encap: ESP(spi=0x32284280,seq=0x132), length 92
```

From this it's clear that the last packet has "tos 0x60" set. However, if I look at this particular rule, it doesn't have any matches or state entries:


```
pass in quick inet proto udp from 172.28.1.3 to any tos 0x60 keep state tag VOIP-SIG
  [ Evaluations: 34        Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 13666 State Creations: 0     ]
```

Instead, there's a state entry logged for this traffic under the third rule:

```
all udp 1.1.1.1:4500 <- 172.28.1.3:4500       MULTIPLE:MULTIPLE
   age 00:15:50, expires in 00:00:57, 394:196 pkts, 52356:39176 bytes, rule 37
all udp 2.2.2.2:65380 (172.28.1.3:4500) -> 1.1.1.1:4500       MULTIPLE:MULTIPLE
   age 00:15:50, expires in 00:00:57, 394:196 pkts, 52356:39176 bytes, rule 59
```

Note, the rule numbers don't match up exactly.
Rule 37 --> Rule 3 above
Rule 59 is my nat rule that's overloading on my external interface, IP 2.2.2.2.

Based on the above, it seems like the state entries don't include the tos information, and that's a problem, because rules like the above won't work, making it impossible to properly classify traffic that is encrypted with ipsec.

Am I missing something?


----------



## adam2104 (Jul 21, 2012)

This appears to be a pf limitation. I built a basic OpenBSD machine with version 5.1 and saw the same issue there. I guess most people don't have need to do different qos policies on traffic encrypted within a tunnel. This is a fairly standard practice for enterprise users where vpn technologies are employed. In any case, I'm willing to live with it as FreeBSD is actually stable on my alix 2d13 board and OpenWRT is not (crashes under high load).


----------

