Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
labs
BIRD Internet Routing Daemon
Commits
6dc7a0cb
Commit
6dc7a0cb
authored
Nov 03, 1999
by
Pavel Machek
Browse files
Filters now do not allow function (int arg; int arg2; ).
parent
e5005be2
Changes
4
Hide whitespace changes
Inline
Side-by-side
bird.conf
View file @
6dc7a0cb
...
...
@@ -8,7 +8,9 @@ router id 62.168.0.1;
define
xyzzy
=
120
+
10
;
function
callme
(
int
arg1
;
int
arg2
;)
function
callme
(
int
arg1
;
int
arg2
)
int
local1
;
int
local2
;
{
print
"Function callme called arguments "
arg1
" and "
arg2
;
...
...
@@ -33,8 +35,8 @@ prefix px;
if
1
<=
1
then
printn
"."
;
else
{
print
"*** FAIL: test 3"
; }
if
1234
<
1234
then
{
print
"*** FAIL: test 4"
;
quitbird
; }
else
print
"ok"
;
print
" data types; must be true: "
1
.
2
.
3
.
4
=
1
.
2
.
3
.
4
","
1
~ [
1
,
2
,
3
]
","
5
~ [
1
..
20
]
","
2
~ [
1
,
2
,
3
]
","
5
~ [
4
..
7
]
","
1
.
2
.
3
.
4
~ [
1
.
2
.
3
.
3
..
1
.
2
.
3
.
5
];
print
" data types: must be false: "
1
~ [
2
,
3
,
4
]
","
5
~ [
2
,
3
,
4
,
7
..
11
]
","
1
.
2
.
3
.
4
~ [
1
.
2
.
3
.
3
,
1
.
2
.
3
.
5
]
","
(
1
,
2
) > (
2
,
2
)
","
(
1
,
1
) > (
1
,
1
);
print
" data types; must be true: "
1
.
2
.
3
.
4
=
1
.
2
.
3
.
4
","
1
~ [
1
,
2
,
3
]
","
5
~ [
1
..
20
]
","
2
~ [
1
,
2
,
3
]
","
5
~ [
4
..
7
]
","
1
.
2
.
3
.
4
~ [
1
.
2
.
3
.
3
..
1
.
2
.
3
.
5
]
","
1
.
2
.
3
.
4
~
1
.
2
.
3
.
4
/
8
","
1
.
2
.
3
.
4
/
8
~
1
.
2
.
3
.
4
/
8
","
1
.
2
.
3
.
4
/
8
~
1
.
2
.
3
.
4
/
8
+
","
1
.
2
.
3
.
4
/
16
~
1
.
2
.
3
.
4
/
8
{
15
,
16
}
;
print
" data types: must be false: "
1
~ [
2
,
3
,
4
]
","
5
~ [
2
,
3
,
4
,
7
..
11
]
","
1
.
2
.
3
.
4
~ [
1
.
2
.
3
.
3
,
1
.
2
.
3
.
5
]
","
(
1
,
2
) > (
2
,
2
)
","
(
1
,
1
) > (
1
,
1
)
","
1
.
2
.
3
.
4
/
8
~
1
.
2
.
3
.
4
/
8
-
","
1
.
2
.
3
.
4
/
17
~
1
.
2
.
3
.
4
/
8
{
15
,
16
}
;
px
=
1
.
2
.
3
.
4
/
18
;
print
"Testing prefixes: 1.2.3.4/18 = "
px
;
...
...
@@ -60,6 +62,8 @@ int j;
{
print
"Heya, filtering route to "
rta
.
net
.
ip
" prefixlen "
rta
.
net
.
len
;
print
"This route was from "
rta
.
from
;
j
=
7
;
j
=
17
;
accept
;
}
...
...
filter/config.Y
View file @
6dc7a0cb
...
...
@@ -6,11 +6,11 @@
* Can be freely distributed and used under the terms of the GNU GPL.
*
FIXME: define keyword
FIXME: make px+, px- px^pair work in prefix sets
FIXME: create ip.mask(x) function
FIXME: whole system of paths, path ~ string, path.prepend(), path.originate
FIXME: create community lists
FIXME: access to dynamic attributes
FIXME: local namespace for functions
*/
CF_HDR
...
...
@@ -30,18 +30,18 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, CONST,
INT, BOOL, IP, PREFIX, PAIR, SET, STRING,
IF, THEN, ELSE, CASE,
TRUE, FALSE,
RTA, FROM, GW, NET, MASK,
RTA, FROM, GW, NET, MASK,
RIP_METRIC, RIP_TAG,
LEN,
IMPOSSIBLE,
FILTER
)
%type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list
%type <x> term block cmds cmd function_body ifthen constant print_one print_list var_list
var_listn
%type <f> filter filter_body
%type <i> type break_command pair
%type <e> set_item set_items switch_body
%type <v> set_atom prefix prefix_s ipa
%type <s> decls function_params
%type <s> decls
declsn one_decl
function_params
CF_GRAMMAR
...
...
@@ -71,11 +71,11 @@ type:
}
;
decls: /* EMPTY */ { $$ = NULL; }
|
type SYM
';' decls
{
one_decl:
type SYM {
cf_define_symbol($2, SYM_VARIABLE | $1, NULL);
printf( "New variable %s type %x\n", $2->name, $1 );
$2->aux =
$4
;
$2->aux =
NULL
;
{
struct f_val * val;
val = cfg_alloc(sizeof(struct f_val));
...
...
@@ -86,6 +86,24 @@ decls: /* EMPTY */ { $$ = NULL; }
}
;
/* Decls with ';' at the end */
decls: /* EMPTY */ { $$ = NULL; }
| one_decl ';' decls {
$$ = $1;
$$->aux = $3;
}
;
/* Declarations that have no ';' at the end.
Ouch, this is responsible for 13 or so shift/reduce conflicts. */
declsn: one_decl { $$ = $1; }
| declsn ';' one_decl {
$$ = $3;
$$->aux = $1;
}
;
filter_body:
function_body {
struct filter *f = cfg_alloc(sizeof(struct filter));
...
...
@@ -104,7 +122,8 @@ filter:
;
function_params:
'(' decls ')' { printf( "Have function parameters\n" ); $$=$2; }
'(' declsn ')' { printf( "Have function parameters\n" ); $$=$2; }
| '(' ')' { $$=NULL; }
;
function_body:
...
...
@@ -166,11 +185,11 @@ prefix:
prefix_s { $$ = $1; }
| prefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
| prefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
/*
| prefix_s '{' NUM ',' NUM '}'
How should this be done? */
| prefix_s '{' NUM ',' NUM '}'
{ $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); }
;
ipa:
IPA { $$.type = T_IP; $$.val.ip = $1; }
IPA { $$.type = T_IP; $$.val.
px.
ip = $1; }
;
set_atom:
...
...
@@ -213,7 +232,8 @@ constant:
| TEXT { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_STRING; $$->a2.p = $1; }
| pair { $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_PAIR; $$->a2.i = $1; }
| ipa { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
| prefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
/* Replace with prefix_s to get rid of shift/reduce conflicts. */
| prefix {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
| '[' set_items ']' { printf( "We've got a set here..." ); $$ = f_new_inst(); $$->code = 'c'; $$->a1.i = T_SET; $$->a2.p = build_tree($2); printf( "ook\n" ); }
;
...
...
@@ -245,7 +265,9 @@ term:
| RTA '.' FROM { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, from); }
| RTA '.' GW { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_IP; $$->a2.i = OFFSETOF(struct rta, gw); }
| RTA '.' NET { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_PREFIX; $$->a2.i = 0x12345678; }
| RTA '.' NET { $$ = f_new_inst(); $$->code = 'a'; $$->a1.i = T_PREFIX; $$->a2.i = 0x12345678; }
| RTA '.' RIP_METRIC { $$ = f_new_inst(); $$->code = 'ea'; $$->a1.i = T_INT; $$->a2.i = EA_RIP_METRIC; }
| term '.' IP { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_IP; }
| term '.' LEN { $$ = f_new_inst(); $$->code = 'cp'; $$->a1.p = $1; $$->a2.i = T_INT; }
...
...
@@ -283,14 +305,14 @@ print_list: /* EMPTY */ { $$ = NULL; }
}
;
var_list: term {
var_list
n
: term {
$$ = f_new_inst();
$$->code = 's';
$$->a1.p = NULL;
$$->a2.p = $1;
$$->next = NULL;
}
| term ',' var_list {
| term ',' var_list
n
{
$$ = f_new_inst();
$$->code = 's';
$$->a1.p = NULL;
...
...
@@ -299,6 +321,10 @@ var_list: term {
}
;
var_list: /* EMPTY */ { $$ = NULL; }
| var_listn { $$ = $1; }
;
cmd:
ifthen {
$$ = $1;
...
...
filter/filter.c
View file @
6dc7a0cb
...
...
@@ -5,8 +5,6 @@
*
* Can be freely distributed and used under the terms of the GNU GPL.
*
* FIXME: local namespace for functions
*
* Notice that pair is stored as integer: first << 16 | second
*/
...
...
@@ -70,16 +68,55 @@ val_compare(struct f_val v1, struct f_val v2)
if
(
v1
.
val
.
i
<
v2
.
val
.
i
)
return
-
1
;
return
1
;
case
T_IP
:
return
ipa_compare
(
v1
.
val
.
ip
,
v2
.
val
.
ip
);
case
T_PREFIX
:
return
ipa_compare
(
v1
.
val
.
px
.
ip
,
v2
.
val
.
px
.
ip
);
default:
{
printf
(
"Error comparing
\n
"
);
return
CMP_ERROR
;
}
}
}
int
val_simple_in_range
(
struct
f_val
v1
,
struct
f_val
v2
)
{
if
((
v1
.
type
==
T_IP
)
&&
(
v2
.
type
==
T_PREFIX
))
return
!
(
ipa_compare
(
ipa_and
(
v2
.
val
.
px
.
ip
,
ipa_mkmask
(
v2
.
val
.
px
.
len
)),
ipa_and
(
v1
.
val
.
px
.
ip
,
ipa_mkmask
(
v2
.
val
.
px
.
len
))));
if
((
v1
.
type
==
T_PREFIX
)
&&
(
v2
.
type
==
T_PREFIX
))
{
ip_addr
mask
;
if
(
v1
.
val
.
px
.
len
&
(
LEN_PLUS
|
LEN_MINUS
|
LEN_RANGE
))
return
CMP_ERROR
;
mask
=
ipa_mkmask
(
v2
.
val
.
px
.
len
&
LEN_MASK
);
if
(
ipa_compare
(
ipa_and
(
v2
.
val
.
px
.
ip
,
mask
),
ipa_and
(
v1
.
val
.
px
.
ip
,
mask
)))
return
0
;
/* FIXME: read rpsl or better ask mj: is it really like this? */
if
((
v2
.
val
.
px
.
len
&
LEN_MINUS
)
&&
(
v1
.
val
.
px
.
len
<=
(
v2
.
val
.
px
.
len
&
LEN_MASK
)))
return
0
;
if
((
v2
.
val
.
px
.
len
&
LEN_PLUS
)
&&
(
v1
.
val
.
px
.
len
<
(
v2
.
val
.
px
.
len
&
LEN_MASK
)))
return
0
;
if
((
v2
.
val
.
px
.
len
&
LEN_RANGE
)
&&
((
v1
.
val
.
px
.
len
<
(
0xff
&
(
v2
.
val
.
px
.
len
>>
16
)))
||
(
v1
.
val
.
px
.
len
>
(
0xff
&
(
v2
.
val
.
px
.
len
>>
8
)))))
return
0
;
return
1
;
}
return
CMP_ERROR
;
}
int
val_in_range
(
struct
f_val
v1
,
struct
f_val
v2
)
{
if
(((
v1
.
type
==
T_INT
)
||
(
v1
.
type
==
T_IP
))
&&
(
v2
.
type
==
T_SET
))
return
!!
find_tree
(
v2
.
val
.
t
,
v1
);
int
res
;
res
=
val_simple_in_range
(
v1
,
v2
);
if
(
res
!=
CMP_ERROR
)
return
res
;
if
(((
v1
.
type
==
T_INT
)
||
(
v1
.
type
==
T_IP
))
&&
(
v2
.
type
==
T_SET
))
{
struct
f_tree
*
n
;
n
=
find_tree
(
v2
.
val
.
t
,
v1
);
if
(
!
n
)
return
0
;
return
!!
(
val_simple_in_range
(
v1
,
n
->
from
));
/* We turn CMP_ERROR into compared ok, and that's fine */
}
return
CMP_ERROR
;
}
...
...
@@ -108,7 +145,7 @@ val_print(struct f_val v)
case
T_BOOL
:
PRINTF
(
v
.
val
.
i
?
"TRUE"
:
"FALSE"
);
break
;
case
T_INT
:
PRINTF
(
"%d "
,
v
.
val
.
i
);
break
;
case
T_STRING
:
PRINTF
(
"%s"
,
v
.
val
.
s
);
break
;
case
T_IP
:
PRINTF
(
"%I"
,
v
.
val
.
ip
);
break
;
case
T_IP
:
PRINTF
(
"%I"
,
v
.
val
.
px
.
ip
);
break
;
case
T_PREFIX
:
PRINTF
(
"%I/%d"
,
v
.
val
.
px
.
ip
,
v
.
val
.
px
.
len
);
break
;
case
T_PAIR
:
PRINTF
(
"(%d,%d)"
,
v
.
val
.
i
>>
16
,
v
.
val
.
i
&
0xffff
);
break
;
case
T_SET
:
tree_print
(
v
.
val
.
t
);
PRINTF
(
"
\n
"
);
break
;
...
...
@@ -254,7 +291,7 @@ interpret(struct f_inst *what)
res
.
type
=
what
->
a1
.
i
;
switch
(
res
.
type
)
{
case
T_IP
:
res
.
val
.
ip
=
*
(
ip_addr
*
)
((
char
*
)
rta
+
what
->
a2
.
i
);
res
.
val
.
px
.
ip
=
*
(
ip_addr
*
)
((
char
*
)
rta
+
what
->
a2
.
i
);
break
;
case
T_PREFIX
:
/* Warning: this works only for prefix of network */
{
...
...
@@ -267,6 +304,9 @@ interpret(struct f_inst *what)
}
}
break
;
case
'
ea
'
:
/* Access to extended attributes [hmm, but we need it read/write, do we?] */
bug
(
"Implement me"
);
break
;
case
'
cp
'
:
/* Convert prefix to ... */
ONEARG
;
if
(
v1
.
type
!=
T_PREFIX
)
...
...
@@ -274,7 +314,7 @@ interpret(struct f_inst *what)
res
.
type
=
what
->
a2
.
i
;
switch
(
res
.
type
)
{
case
T_INT
:
res
.
val
.
i
=
v1
.
val
.
px
.
len
;
break
;
case
T_IP
:
res
.
val
.
ip
=
v1
.
val
.
px
.
ip
;
break
;
case
T_IP
:
res
.
val
.
px
.
ip
=
v1
.
val
.
px
.
ip
;
break
;
default:
bug
(
"Unknown prefix to conversion
\n
"
);
}
break
;
...
...
filter/filter.h
View file @
6dc7a0cb
...
...
@@ -32,17 +32,17 @@ struct prefix {
ip_addr
ip
;
int
len
;
#define LEN_MASK 0xff
#define LEN_PLUS 0x10000
#define LEN_MINUS 0x20000
#define LEN_RANGE 0x40000
/* If range then prefix must be in range (len >>
8
& 0xff, len & 0xff) */
#define LEN_PLUS 0x10000
00
#define LEN_MINUS 0x20000
00
#define LEN_RANGE 0x40000
00
/* If range then prefix must be in range (len >>
16
& 0xff, len
>> 8
& 0xff) */
};
struct
f_val
{
int
type
;
union
{
int
i
;
ip_addr
ip
;
/*
ip_addr ip;
Folded into prefix */
struct
prefix
px
;
char
*
s
;
struct
f_tree
*
t
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment