I'm running OpenBSD 6.6 operating as an inter-VLAN and border router using pf. Recently I wanted to use a nondefault state timeout for some UDP traffic traversing from my voip subnet to a provider off site.

Within pf, there are three rules involved. The first is for traffic coming from the voip subnet, which gets a six minute state timeout and a tag:

pass in quick on vlan110 proto udp from any to port = 9430 tag VOIP_UDP keep state (udp.multiple 360)

Then there is a NAT rule:

match out on $ext_if from 10.128.0.0/16 nat-to { $ext_vip } sticky-address

And a rule giving the traffic going out to the Internet a six minute timeout as well:

pass out quick on $ext_if proto udp tagged VOIP_UDP keep state (udp.multiple 360)


This initially looks like it worked; after the initial connection:

bash-5.0# pfctl -v -s state | grep -A1 '110.73:9430'
all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
   age 00:00:00, expires in 00:06:00, 7:5 pkts, 4451:2203 bytes, rule 63
all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:00:00, expires in 00:06:00, 7:5 pkts, 4451:2203 bytes, rule 48, source-track

There are two states, one with the internal addressing and one for the NAT translation, both with six minute timeouts. As time goes by:

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:00:08, expires in 00:05:54, 31:31 pkts, 16469:18285 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:00:08, expires in 00:05:54, 31:31 pkts, 16469:18285 bytes, rule 48, source-track

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:00:20, expires in 00:05:42, 31:31 pkts, 16469:18285 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:00:20, expires in 00:05:42, 31:31 pkts, 16469:18285 bytes, rule 48, source-track

More packets are seen, resetting the timeout:

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:00:23, expires in 00:05:58, 32:32 pkts, 16872:19073 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:00:23, expires in 00:05:58, 32:32 pkts, 16872:19073 bytes, rule 48, source-track

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:00:38, expires in 00:05:43, 32:32 pkts, 16872:19073 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:00:38, expires in 00:05:43, 32:32 pkts, 16872:19073 bytes, rule 48, source-track

again:

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:00:41, expires in 00:06:00, 33:33 pkts, 17275:19931 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:00:41, expires in 00:06:00, 33:33 pkts, 17275:19931 bytes, rule 48, source-track

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:00:58, expires in 00:05:43, 33:33 pkts, 17275:19931 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:00:58, expires in 00:05:43, 33:33 pkts, 17275:19931 bytes, rule 48, source-track

etc, etc:

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:02:26, expires in 00:05:52, 37:37 pkts, 18863:23594 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:02:26, expires in 00:05:52, 37:37 pkts, 18863:23594 bytes, rule 48, source-track

Until finally, there are no more packets for a while:

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:02:36, expires in 00:05:54, 47:46 pkts, 24551:29876 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:02:36, expires in 00:05:54, 47:46 pkts, 24551:29876 bytes, rule 48, source-track

all udp 198.148.6.55:9430 <- 10.128.110.73:9430       MULTIPLE:MULTIPLE
age 00:03:31, expires in 00:04:59, 47:46 pkts, 24551:29876 bytes, rule 63 all udp 96.251.22.157:55202 (10.128.110.73:9430) -> 198.148.6.55:9430 MULTIPLE:MULTIPLE age 00:03:31, expires in 00:04:59, 47:46 pkts, 24551:29876 bytes, rule 48, source-track

After this, the next time I look a couple seconds later, the state is gone? It reproducibly seems to disappear a minute after the last traffic is seen on the connection. Yet the timeout says 5 minutes are left?

Why would the state be removed when it still had five minutes left before it expired? I know if it were a TCP state, it might go away before the timeout expires if the connection is shut down. But this is a UDP state. What would cause it to go away before the timeout expiration? Is there something wrong with my initial rules?

Thanks much for any thoughts on this issue…

Reply via email to