Firewall for bridge with hardware offload

Hi

I would like is someone could validate if what i want to do is possible:

Rb2011uias-in with routeros 6.32, ports from ether2 to ether8 bridged together with hardware offloading. i have one server (10.7.7.4) plugged into ether5, and one client (10.7.7.26) coming from a switch via ether2. I need to do some redirections, to put one as example:

traffic going to 10.7.7.4:80 from 10.7.7.0/24, should be redirected to 10.7.7.4:7080

I know that with hardware offloading those packets don’t see the cpu, and so don’t see the firewall, so i was looking in the “Switch > Rule” section, trying to make a rule that matches that scenario, with action being “Redirect to CPU”. I thought that with this, this packets would be processed by the cpu, and so they should be available to process from the firewall as usual. i put a passtrough rule to try to see the packets in the counters, but they don’t show up.

Is this scenario possible, maybe i’m missing something?

I don’t know how relevant may be, but i have also a “fasttrack connection” rule for established and related connections on top of the firewall rules.

Thank you

Bypassing the CPU is the essence of hardware offloading. So what you describe (using switch rules to redirect frames to CPU port) only makes sense if such handling would affect only a small subset of all frames, i.e. only frames matching some criteria. This may be especially important if we talk about stateful bi-directional connections (i.e. TCP ones) which can benefit from connection tracking, as it may not be easy to force both directions through the CPU.

In any case, i.e. regardless whether you disable hardware offloading for one or more switch ports or whether you use /interface ethernet switch rule to redirect matching frames to the CPU: if you want the IP firewall to handle bridged frames, you have to issue /interface bridge settings set use-ip-firewall=yes; if you don’t do that, the frames redirected using the switch rule will get to the CPU but will be processed there only by the software bridge and sent back to the switch chip without being seen by the IP firewall. This setting is a global one, so it will affect all bridges.

Thank you for the detailed answer.

Then the doubt that i have left is that, if activate the use-ip-firewall option for the bridges in my described scenario, will this disable “de facto” the hardware benefits of using the switch? Or it only will allow the selected packets go to the firewall, keeping the rest of packets skipping the cpu?

Due to (mainly) having a number of firewall rules, i’m in a very thin line regarding troughput, so if i lose performance because of enabling the use-ip-firewall, i may need to find another way (or upgrade to better hardware :slight_smile: )

Thanks

You think in the right way. Imagine you have two ports of the switch chip. A frame between them can take one of the following three paths, from the shortest/fastest one down to the longest/slowest one:

  • directly within the switch chip - this is the “bridging with hardware offload”
  • via bridge software module on CPU but without ip firewall handling - this is “bridging without hardware offload” (and you can use /interface bridge filter rules which are independent from the IP firewall)
  • via bridge and IP firewall software modules on CPU - this is the most CPU-intensive handling and the only one which can benefit from connection tracking

So the whole question is whether you can reduce the amount of traffic taking the long way, by using /interface ethernet switch rule or by choosing port(s) for which the HW offload would be disabled, and let the rest of the traffic take the shortest path within the switch chip alone, and whether the share of that “rest” on the total traffic is significant enough to justify the effort spent. It is hard to assess without knowledge of the actual use case.

I don’t know your budget, but hAP ac² has a very nice price to horsepower ratio.

That sounds perfect, so while i keep the matched packets in the bridge filter low (which will be the case), i won’t have any performance issues.

As a last request, as my first attempt on continuing with this didn’t succeed, i think i may be missing some step. Here is my relevant current switch and bridge config:

add dst-address=10.7.7.4/32 dst-port=80 ports=ether2,ether3,ether4,ether5 protocol=tcp \
    redirect-to-cpu=yes switch=switch1
    
    
/interface bridge port
add bridge=bridge1 interface=ether2 hw=yes
add bridge=bridge1 interface=ether3 hw=yes
add bridge=bridge1 interface=ether4 hw=yes
add bridge=bridge1 interface=ether5 hw=yes
/interface bridge settings
set use-ip-firewall=yes

/ip address
add address=10.7.7.1/24 comment=LAN interface=bridge1 network=10.7.7.0

To summarize, ether 5 has only the server connected, and ether2,3,4 have switches with all LAN clients that may be subject to redirect rules. So I’ve added all ports for this switch rule.
Next, there is the rule i added on the firewall that, altough I get hits, it doesn’t work.

add action=redirect chain=dstnat dst-address=10.7.7.4 dst-port=80 log=yes protocol=tcp to-ports=7080

I tried both redirect and dst-nat, giving “connect refused” and “Operation timed out” respectively in the client. Both outputs the same when logged:

09:29:51 firewall,info dstnat: in:bridge1(ether3) out:(unknown 0), src-mac 4c:e1:73:47:c8:0c, proto TCP (SYN), 10.7.7.26:53336->10.7.7.4:80, len 64

I have the feeling i’m almost there, but missing something very basic…

Thank you for your help

I’m afraid you’ve hit what I’ve announced in advance, the problem with forcing both directions of the connection through the IP firewall which is a pre-requisite for use of connection tracking, which in turn is a pre-requisite for any kind of NAT handling to work, because NAT handling requires to maintain a context for the connection, which is what connection tracking is all about.

Your only interface ethernet switch rule currently in place handles the client->server direction alone, so the redirect/dst-nat rule in ip firewall changes the destination TCP port from 80 to 7080 and forwards the frame to the server. The server responds from port 7080, but as the response doesn’t get to the CPU because there is no switch rule redirecting it there, the switch chip forwards it directly to the client as-is, so the client receives a packet from port 7080 which it doesn’t even expect, let alone that it would be able to match it to the connection establishment attempt. What you need is to force the response through the ip firewall too, so that the connection tracker could “un-dst-nat” the port back from 7080 to 80, so that the client could see the response to come from the same port to which it has sent the request before.

So I would use the following switch rules:
add dst-address=10.7.7.4/32 dst-port=80 ports=ether2,ether3,ether4,ether5 protocol=tcp redirect-to-cpu=yes switch=switch1
add src-port=7080 ports=ether5 protocol=tcp redirect-to-cpu=yes switch=switch1

In the first rule, you don’t need the ether5 in the list because switch rules only deal with ingress frames (wire → silicon).