# Wrong pf config crashing kernel on 9-STABLE



## bbzz (Nov 20, 2011)

My Internet router died on me, so I decided to replace it with one of FreeBSD servers and learn some new *pf* commands along the way.
The simplified version of network looks like this:


```
INTERNET<-----[R1]------192.168.1.0/24------(re0)[FreeBSD](vge1)----->INTERNET
						  (vge2)
						     |
						     |
						     |
						     |192.168.2.0/24
					   __________|__
					     |
					     |
				 	    PC1
```

I have two Internet connections.
Devices on 192.168.2.0 were using router that failed; FreeBSD machine in the middle (itself just a host on 192.168.1.0) should provide routing service for devices on 192.168.2.0 out to vge1 and to Internet. At the same it should allow connection between all other local LANs.

Since FreeBSD machine already has default route pointing to R1, I needed a policy routing inbound on vge2 to route to vge1.

Erroneously, the piece of configuration I used was (the only one that matters):


```
pass in on vge2 route-to vge1 from vge2:network to { !vge1:network !re0:network !vge3:network }
```

In other words, packets from vge2 going _not_ to LANs on re0, vge1, vge3 should be routed out of vge1.

Not only did I not include next-hop IP with vge1, the last part of configuration won't let me connect from internal devices to FreeBSD machine. Eventually I figured it out, but while doing so, I discovered that with configuration above I'm able to crash FreeBSD kernel every single time.

I tested this with other NICs I have and they all give exactly the same result.

The way to crash is to send ping from PC1, which is connected to LAN that FreeBSD is trying to route for, to its gateway IP (in this case 192.168.2.254).

All i get is:

```
kernel: Fatal trap 12: page fault while in kernel mode
kernel: cpuid = 0; apic id = 00
kernel: fault virtual address   = 0x0
kernel: instruction pointer     = 0x20:0xffffffff80940916
kernel: stack pointer           = 0x28:0xffffff8349eb7500
kernel: frame pointer           = 0x28:0xffffff8349eb7550
kernel: code segment            = base 0x0, limit 0xfffff, type 0x1b
kernel: = DPL 0, pres 1, long 1, def32 0, gran 1
kernel: processor eflags        = interrupt enabled, resume, IOPL = 0
kernel: current process         = 12 (irq19: vge2 fwohci+)
kernel: trap number             = 12
```
Like I said it will work for any NIC, just replace that "vge2" in message with NIC that's used.

What's _really_ interesting is that this only works if:
a) You try to ping FreeBSD IP address on that LAN. It won't work if you try to ping 192.168.1.5 which is it's IP on re0 LAN, etc. It also won't work if you try to ping any other address on Internet. BTW, to route to Internet I had to add next-hop next to vge1. Then it routes form vge2 to Internet but still crashes when I ping 192.168.2.254.
b) The interface connected to Internet, vge1, must be "UP". If it's down it won't crash. Funny.

I know the configuration above is wrong but it shouldn't crash the kernel.  
Btw, it's 9-STABLE and sources are maybe two weeks old if not less.

Anyone seen something like this?


----------



## _martin (Nov 20, 2011)

9.0-RELEASE is not there yet, so best you can have installed there is RC2. If you can reproduce this and didn't find any additional information on it, maybe it's worth sending a PR to FreeBSD. 

In my opinion, naming STABLE branch stable is confusing, but that can be just me. Have a look at FreeBSD handbook for a detail description.


----------



## bbzz (Nov 20, 2011)

Yes, technically, you are correct, although you can see it's also referred to it as 9-STABLE.


----------



## bbzz (Nov 20, 2011)

I can't reproduce same behavior on fresh sources as of today.
So thanks to ZFS rollback magic I quickly rerolled back to RC1 - and it's there, same crash. _Something_ has been changed in these couple of weeks, but I guess I won't find out what it is.

For someone out there still using RC1 with _lots_ of free time, maybe you could try to reproduce this.
This _might_ be relevant to those who won't update yet.


----------

