Hello. This is more like a pull request. If the users mailing list is not the appropriate, I apologize and please tell me where should I submit it.
One big problem when using ifb (redirected) interfaces for download QoS control and NAT is that you can't usually create tcfilters based on a internal destination address. That's because when packets enter the outside interface, they are redirected to the ifb interface before reverse NAT or any other netfilter hooks. However, fairly recent kernels (at least the one that comes with RHEL/CentOS 7, which has now a few years) have a tc filter action named connmark that helps to create a workaround, but shorewall doesn't support it. Using the following (crude) patch I was able to take advantage of that feature: --- /root/Tc.pm.bkp 2020-07-07 17:26:27.329581191 +0100 +++ /usr/lib/perl5/site_perl/Shorewall/Tc.pm 2020-07-07 17:28:14.249592180 +0100 @@ -1865,7 +1865,7 @@ for my $rdev ( @{$devref->{redirected}} ) { my $phyrdev = physical_name( $rdev ); emit ( "run_tc qdisc add dev $phyrdev handle ffff: ingress" ); - emit( "run_tc filter add dev $phyrdev parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev $device > /dev/null" ); + emit( "run_tc filter add dev $phyrdev parent ffff: protocol all u32 match u32 0 0 action connmark action mirred egress redirect dev $device > /dev/null" ); } for my $class ( @tcclasses ) { Of course this should be optional. My suggestion is to have a new possible OPTION in tcdevices named "connmark", only valid when REDIRECTED INTERFACES is not empty. If present, the mirred filter is generated as above suggested, and if not present it stays as the current behaviour. Perhaps some extra code to determine if the tc filter action connmark is supported and set a new capability would be nice, but since it's already optional and should fail anyway if not supported, I don't think that would be really necessary.Please improve as needed - my proposed patch (against shorewall 5.2.5-2, and already with the option parsing) is attached in this message. A minimal example configuration using this suggested feature follows. For this scenario, there is a single 1 Gbps Internet connection. LAN users shouldn't use more than 50 mbps for upload and 100 for download. The rest should be available to our servers, who can also "borrow" bandwidth from the LAN network when it's not in use. Let's suppose that 10.100.100.0/24 corresponds to the lan network. Shorewall configuration files: /etc/shorewall/zones: #ZONE TYPE OPTIONS IN_OPTIONS OUT_OPTIONS fw firewall net ipv4 lan ipv4 routeback srv ipv4 routeback /etc/shorewall/interfaces: #ZONE INTERFACE OPTIONS net enp1s0 lan enp2s0 srv enp3s0 # our ifb interface, shouldn't be necessary to declare but doesn't hurt - ifb0 /etc/shorewall/policy: #SOURCE DEST POLICY LOGLEVEL RATE CONNLIMIT $FW all ACCEPT lan net ACCEPT srv net ACCEPT /etc/shorewall/rules: #ACTION SOURCE DEST PROTO DPORT SPORT ORIGDEST RATE USER MARK CONNLIMIT TIME HEADERS SWITCH HELPER ?SECTION NEW ACCEPT lan $FW tcp 22 (...) /etc/shorewall/snat: #ACTION SOURCE DEST PROTO PORT IPSEC MARK USER SWITCH ORIGDEST PROBABILITY MASQUERADE - enp1s0 /etc/shorewall/shorewall.conf: (...) TC_ENABLED=Internal /etc/shorewall/tcdevices: #NUMBER: IN-BANDWITH OUT-BANDWIDTH OPTIONS REDIRECTED #INTERFACE INTERFACES ## net upload 10:enp1s0 - 1000mbit htb ## net download 11:ifb0 - 1000mbit htb,connmark enp1s0 /etc/shorewall/tcclasses: #INTERFACE MARK RATE CEIL PRIO OPTIONS 10:5000 111 500kbit full 10 tcp-ack,tos-minimize-delay 11:5000 110 500kbit full 10 tcp-ack,tos-minimize-delay 10:1000 100 full-50500 full 20 default 11:1000 101 full-100500 full 20 default 10:50 10 50mbit 50mbit 101 flow=nfct-src 11:100 11 100mbit 100mbit 101 flow=dst /etc/shorewall/tcfilters: #INTERFACE: SOURCE DEST PROTO DEST SOURCE TOS LENGTH PRIORITY #CLASS PORT(S) PORT(S) ## limit LAN upload - works 10:50 10.100.100.0/24 ## limit LAN download - DOESN'T WORK BECAUSE OF MASQUERADE ON enp1s0 !!!! (snat file) #11:100 - 10.100.100.0/24 /etc/shorewall/mangle: #ACTION SOURCE DEST PROTO DPORT SPORT USER TEST LENGTH TOS CONNBYTES HELPER PROBABILITY DSCP SWITCH ## limit downloads of connections started by LAN users to the Internet ## this only works with the aforementioned conntrack filter action when setting up mirred ifb, as it restores the connmark to the mark ## and LAN users' download traffic will get the 11:100 class (defined in tcclasses) applied CONNMARK(11) 10.100.100.0/24 - Only problem I see is when using more than one Internet provider, having configured them in the /etc/shorewall/providers. Perhaps in that case one is able to use xmark masks to have the best of both worlds? Any ideas? Anyway, in hope that you also find this a useful feature... is there any chance that shorewall officially supports this in a near future release? :) Thanks in advance.
--- /root/Tc.pm.bkp 2020-07-07 17:26:27.329581191 +0100 +++ /usr/lib/perl5/site_perl/Shorewall/Tc.pm 2020-07-07 19:57:43.433513961 +0100 @@ -422,8 +422,8 @@ fatal_error "Duplicate INTERFACE ($device)" if $tcdevices{$device}; fatal_error "Invalid INTERFACE name ($device)" if $device =~ /[:+]/; - my ( $classify, $pfifo, $flow, $qdisc, $linklayer, $overhead, $mtu, $mpu, $tsize ) = - (0, 0, '', 'htb', '', 0, 0, 0, 0); + my ( $classify, $pfifo, $flow, $qdisc, $linklayer, $overhead, $mtu, $mpu, $tsize, $connmark ) = + (0, 0, '', 'htb', '', 0, 0, 0, 0, 0); if ( $options ne '-' ) { for my $option ( split_list1 $options, 'option' ) { @@ -458,6 +458,8 @@ $tsize = numeric_value( $1 ); fatal_error "Invalid tsize ($1)" unless defined $tsize; fatal_error q('tsize' requires 'linklayer') unless $linklayer; + } elsif ( $option eq 'connmark' ) { + $connmark = 1; } else { fatal_error "Unknown device option ($option)"; } @@ -478,6 +480,8 @@ fatal_error "REDIRECTED device ($rdevice) has not been defined in this file" unless $rdevref; fatal_error "IN-BANDWIDTH must be zero for REDIRECTED devices" if $rdevref->{in_bandwidth} != 0; } + } elsif ( $connmark ) { + fatal_error "Option connmark can only be used when setting up a IFB device"; } $inband = process_in_bandwidth( $inband ); @@ -503,6 +507,7 @@ mpu => $mpu, tsize => $tsize, filterpri => 0, + connmark => $connmark, } , push @tcdevices, $device; @@ -1865,7 +1870,7 @@ for my $rdev ( @{$devref->{redirected}} ) { my $phyrdev = physical_name( $rdev ); emit ( "run_tc qdisc add dev $phyrdev handle ffff: ingress" ); - emit( "run_tc filter add dev $phyrdev parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev $device > /dev/null" ); + emit( "run_tc filter add dev $phyrdev parent ffff: protocol all u32 match u32 0 0 ".($devref->{'connmark'} ? ' action connmark' : '')." action mirred egress redirect dev $device > /dev/null" ); } for my $class ( @tcclasses ) {
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Shorewall-users mailing list Shorewall-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/shorewall-users