diff options
-rw-r--r-- | doc/bird.sgml | 3 | ||||
-rw-r--r-- | filter/config.Y | 4 | ||||
-rw-r--r-- | filter/filter.c | 7 | ||||
-rw-r--r-- | filter/test.conf | 3 |
4 files changed, 15 insertions, 2 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index 761c5396..b10b1a21 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1186,7 +1186,8 @@ foot). <tag><label id="type-ip">ip</tag> This type can hold a single IP address. Depending on the compile-time configuration of BIRD you are using, it is either an IPv4 or IPv6 - address. IP addresses are written in the standard notation + address; this may be checked by <cf>.is_ip4</cf> which returns <cf/bool/. + IP addresses are written in the standard notation (<cf/10.20.30.40/ or <cf/fec0:3:4::1/). You can apply special operator <cf>.mask(<M>num</M>)</cf> on values of type ip. It masks out all but first <cf><M>num</M></cf> bits from the IP address. So diff --git a/filter/config.Y b/filter/config.Y index f84360ff..2864d290 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -400,6 +400,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, PREFERENCE, ROA_CHECK, ASN, + IS_V4, IS_V6, LEN, MAXLEN, DEFINED, ADD, DELETE, CONTAINS, RESET, @@ -890,7 +891,8 @@ term: | rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); } - | term '.' TYPE { $$ = f_new_inst(); $$->code = 'T'; $$->a1.p = $1; } + | term '.' IS_V4 { $$ = f_new_inst(); $$->code = P('I','i'); $$->a1.p = $1; } + | term '.' TYPE { $$ = f_new_inst(); $$->code = 'T'; $$->a1.p = $1; } | term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; } | term '.' RD { $$ = f_new_inst(); $$->code = P('R','D'); $$->a1.p = $1; $$->aux = T_RD; } | term '.' LEN { $$ = f_new_inst(); $$->code = 'L'; $$->a1.p = $1; } diff --git a/filter/filter.c b/filter/filter.c index 616f9e2a..9f6c2cdd 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -829,6 +829,13 @@ interpret(struct f_inst *what) runtime( "Can't determine type of this item" ); } break; + case P('I','i'): + ONEARG; + if (v1.type != T_IP) + runtime( "IP version check needs an IP address" ); + res.type = T_BOOL; + res.val.i = ipa_is_ip4(v1.val.ip); + break; /* Set to indirect value, a1 = variable, a2 = value */ case 's': diff --git a/filter/test.conf b/filter/test.conf index 89c882ae..dedad1d8 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -312,15 +312,18 @@ function t_ip() ip p; { p = 127.1.2.3; + bt_assert(p.is_v4); bt_assert(p.mask(8) = 127.0.0.0); bt_assert(1.2.3.4 = 1.2.3.4); bt_assert(1.2.3.4 = onetwo); bt_assert(format(p) = "127.1.2.3"); p = ::fffe:6:c0c:936d:88c7:35d3; + bt_assert(!p.is_v4); bt_assert(format(p) = "::fffe:6:c0c:936d:88c7:35d3"); p = 1234:5678::; + bt_assert(!p.is_v4); bt_assert(p.mask(24) = 1234:5600::); } |