pf table cannot contain multiple PFRKE_ROUTE to same IP on different interfaces

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
NOP
Reply | Threaded
Open this post in threaded view
|

pf table cannot contain multiple PFRKE_ROUTE to same IP on different interfaces

NOP
Dear OpenBSD developers,

In packet filter, it is not possible to define a "route-to" rule with
multiple destinations having the same IP address but on different
interfaces.

Minimal example to reproduce the problem:

# cat /etc/hostname.lo5
rdomain 5
inet 127.0.0.1 255.0.0.0
# cat /etc/hostname.lo6
rdomain 6
inet 127.0.0.1 255.0.0.0
# cat /etc/pf.conf
pass in on vio0 to 123.123.123.123 route-to { (lo5 127.0.10.1), (lo6
127.0.10.1) } round-robin
# pfctl -f /etc/pf.conf -v
table <__automatic_5854be65_0> const { 127.0.10.1@lo5 127.0.10.1@lo6 }
pass in on vio0 inet from any to 123.123.123.123 flags S/SA route-to
<__automatic_5854be65_0> round-robin
# pfctl -T show -t __automatic_5854be65_0
   127.0.10.1@lo5

In practice, I need this for routing traffic to several OpenVPN tunnels
in a round-robin fashion. Unfortunately, my VPN provider uses the same
gateway IP for all their servers.

pass in on vlan123 route-to { (tun0 tun0:peer), (tun1 tun1:peer) }
round-robin


The second address is not added because of this:
- In /sys/net/pf_table.c:1653, in the pfr_ina_define function, the call
to pfr_lookup_addr returns non NULL
- In /sys/net/pf_table.c:815, in the pfr_lookup_addr function, rn_match
returns non NULL
- In /sys/net/radix.c:263-265, in the rn_match function, the for loops
checks for differences in the IP prefix, does not find any and returns
the existing node in the tree.

The problem is that only the IP address and mask are taken into
consideration when searching a node in the radix tree, the interface is
ignored. Therefore it's not possible to store two nodes with the same IP
but different interfaces (127.0.10.1@lo5 and 127.0.10.1@lo6).

Unfortunately, I did not manage to understand in details how the radix
tree worked, especially the nodes ordering so I was not able to patch it
to add the interface information.

Can someone who knows this code better try to fix this problem or point
me in the right direction?

Thanks a lot for all your work on OpenBSD and thank you in advance for
your help.

Kind regards,

NOP

Reply | Threaded
Open this post in threaded view
|

Re: pf table cannot contain multiple PFRKE_ROUTE to same IP on different interfaces

Stuart Henderson
When I used route-to with pppoe before, it didn't matter what IP address
was used (as a point-to-point interface, no link layer address is needed,
only the interface). It might have changed now (it definitely has changed
for normal routing, but perhaps not with route-p), but it's worth a try.

Specifically just try it with different dummy addresses for each interface
(e.g. 10.0.0.100@tun0, 10.0.0.101@tun1) and see if that works.

--
  Sent from a phone, apologies for poor formatting.



On 30 January 2018 05:25:28 NOP <[hidden email]> wrote:

> Dear OpenBSD developers,
>
> In packet filter, it is not possible to define a "route-to" rule with
> multiple destinations having the same IP address but on different
> interfaces.
>
> Minimal example to reproduce the problem:
>
> # cat /etc/hostname.lo5
> rdomain 5
> inet 127.0.0.1 255.0.0.0
> # cat /etc/hostname.lo6
> rdomain 6
> inet 127.0.0.1 255.0.0.0
> # cat /etc/pf.conf
> pass in on vio0 to 123.123.123.123 route-to { (lo5 127.0.10.1), (lo6
> 127.0.10.1) } round-robin
> # pfctl -f /etc/pf.conf -v
> table <__automatic_5854be65_0> const { 127.0.10.1@lo5 127.0.10.1@lo6 }
> pass in on vio0 inet from any to 123.123.123.123 flags S/SA route-to
> <__automatic_5854be65_0> round-robin
> # pfctl -T show -t __automatic_5854be65_0
>    127.0.10.1@lo5
>
> In practice, I need this for routing traffic to several OpenVPN tunnels
> in a round-robin fashion. Unfortunately, my VPN provider uses the same
> gateway IP for all their servers.
>
> pass in on vlan123 route-to { (tun0 tun0:peer), (tun1 tun1:peer) }
> round-robin
>
>
> The second address is not added because of this:
> - In /sys/net/pf_table.c:1653, in the pfr_ina_define function, the call
> to pfr_lookup_addr returns non NULL
> - In /sys/net/pf_table.c:815, in the pfr_lookup_addr function, rn_match
> returns non NULL
> - In /sys/net/radix.c:263-265, in the rn_match function, the for loops
> checks for differences in the IP prefix, does not find any and returns
> the existing node in the tree.
>
> The problem is that only the IP address and mask are taken into
> consideration when searching a node in the radix tree, the interface is
> ignored. Therefore it's not possible to store two nodes with the same IP
> but different interfaces (127.0.10.1@lo5 and 127.0.10.1@lo6).
>
> Unfortunately, I did not manage to understand in details how the radix
> tree worked, especially the nodes ordering so I was not able to patch it
> to add the interface information.
>
> Can someone who knows this code better try to fix this problem or point
> me in the right direction?
>
> Thanks a lot for all your work on OpenBSD and thank you in advance for
> your help.
>
> Kind regards,
>
> NOP
>


NOP
Reply | Threaded
Open this post in threaded view
|

Re: pf table cannot contain multiple PFRKE_ROUTE to same IP on different interfaces

NOP
Dear Stuart,

> When I used route-to with pppoe before, it didn't matter what IP address
> was used (as a point-to-point interface, no link layer address is
> needed, only the interface). It might have changed now (it definitely
> has changed for normal routing, but perhaps not with route-p), but it's
> worth a try.
>
> Specifically just try it with different dummy addresses for each
> interface (e.g. 10.0.0.100@tun0, 10.0.0.101@tun1) and see if that works.

That worked perfectly, thank you so much! My only use case is for tun
interfaces so for me this can be considered as solved.

Kind regards,

NOP