Brian Candler wrote:
Hmm, I think this syntax is obscure. Here the == operator is being changed to mean "is this IP address contained within that prefix"? They're not equal to each other. Perhaps something like =~ would be clearer?
=~ already has a meaning as a regex operator. So I'd like to avoid using that.
I'm also not sure that casting the LHS to <cidr> is a clear way of achieving this. The LHS is, and remains, a single IP address. The RHS is a CIDR prefix.
The issue is that the code does type-specific comparisons. It's hard to know what's right for inter-type comparisons. if (127.0.0.1 < 2) ???
So I'd rather see:
if (Framed-IP-Address =~ <cidr>192.168.0.0/24) { ... }
That could work (maybe) with some changes.
since the unquoted RHS literal can be unambiguously parsed as a CIDR prefix anyway,
Well... maybe. What about: if (Framed-IP-Address =~ "%{sql: ...") { Is the RHS a regex? A CIDR comparison? An IP address comparison? I'm trying to say that the code needs *unambiguous* rules. Ad-hoc rules work in some cases, and don't work in others. So they can't be used. The casting, however, is always unambiguous. Cast both sides to a type, and do type-specific comparions.
and a comparison of IP value with CIDR value have the obvious semantics.
"obvious"? What happens when an IP address is smaller than the CIDR range? Or greater than it? For CIDRs, we need at least a "contains" operator. As in "does CIDR 1 contain CIDR 2".
Maybe the reason for casting the LHS to <cidr> so that you can go a general comparison of (CIDR) to (CIDR) rather than (IP) within (CIDR). In that case, the rules for comparing two (CIDR) values need to be clear.
See Wikipedia for "range comparison" (IIRC). There are 20+ types of possible relationships for two ranges. In contrast, integers just have 3 (and their negations). ==, <, > (and !=, >=, <=) It's much easier to just say define a "contains" operator for CIDRs. That way you can't even *express* the other types of relationships. Because they're not needed 99.999% of the time. And if they are needed, use Perl.
Finally, there is a problem of what to do with modules like rlm_sql and rlm_files. These are already restricted to returning LHS=attribute name, RHS=string literal. Unfortunately we can't use the =~ operator here because people may already be doing things like
("Framed-IP-Address", "=~", "^192\.168\.")
So maybe it makes sense for these to return
("<cidr>Framed-IP-Address", "=~", "192.168.0.0/24")
but this still doesn't feel quite right to me.
That will probably *not* happen.
Aside: if this is going to be done, I have a much more pressing need for being able to qualify the attribute with the list name:
("reply:Framed-IP-Address", "=*", "present")
At the moment I have to copy a bunch of attributes from the reply list to the request list, just so that rlm_sql can match them.
Adding a list qualifier is probably easy. It's on the "to do" items for v3. Alan DeKok.