[Ferm] ferm @if condition

Joel Johnson mrjoel at lixil.net
Mon Jan 6 18:30:00 CET 2014


I have a ferm ruleset where I want to restrict ICMP types allowed and 
apply it to both icmp and ipv6-icmp.  I'm trying to keep a single block 
with domain (ip ip6) to help ensure that similar rulesets are applied 
except a few specific differences (ipfilter on specific net ranges, 
etc.).

I have the below listed mostly duplicate blocks which works correctly, 
however I'm trying to figure out how to use @if to reduce the 
duplication, it doesn't seem to work unless the @if results in a 
complete statement.

The problem at first glance appears to be wanting to use the if as text 
substitution instead of generating an entire rule as a result of the 
single if. That also introduces ambiguity in the opening curly brace of 
the block following the @if as opposed to starting the block statement 
itself.

======== Existing ========
@if @eq($DOMAIN, ip) {
   proto icmp @subchain "icmp" {
     icmp-type (
       echo-reply
       echo-request
       destination-unreachable
       time-exceeded
     ) ACCEPT;
   }
}
@if @eq($DOMAIN, ip6) {
   proto ipv6-icmp @subchain "ipv6-icmp" {
     icmp-type (
       echo-reply
       echo-request
       destination-unreachable
       time-exceeded

       # IPv6 ICMP specific additions
       packet-too-big
       router-advertisement
     ) ACCEPT;
   }
}
======== End Existing ========

I'd like to get something like the following, where I can use the @if to 
only be used as a conditional on the differences.

======== Desired ========
@if @eq($DOMAIN, ip) {
   proto icmp @subchain "icmp"
}
@if @eq($DOMAIN, ip6) {
   proto ipv6-icmp @subchain "ipv6-icmp"
}
{
   icmp-type (
     # Common icmp type names
     echo-reply
     echo-request
     destination-unreachable
     time-exceeded

     @if @eq($DOMAIN, ip6) {
       # IPv6 ICMP specific additions
       packet-too-big
       router-advertisement
     }
     ) ACCEPT;
   }
}
======== End Desired ========


I've tried several variations on what I indicated, none of which I've 
been able to make work, including using conditionally set variables for 
the proto name, like:

@if @eq($DOMAIN, ip)
   @def $ICMP_PROTO = icmp;
@if @eq($DOMAIN, ip6)
   @def $ICMP_PROTO = ipv6-icmp;

proto $ICMP_PROTO subchain "$ICMP_PROTO" {}


I feel like there should be a straightforward way to do this, is there a 
syntax tweak I'm just missing? What makes it all a pain is the 
difference in name between icmp and ipv6-icmp/icmpv6. It would be useful 
if ferm would translate icmp in domain ip6 into ipv6-icmp, however icmp 
is valid for IPv6 in Linux, although not very useful, so that may block 
some unique requirement configs.

Thanks,
Joel Johnson



More information about the Ferm mailing list