Add new global counter for stats channel
New symbol is added for each stats protocol channel, the symbol is accessed by
same name as the underlying channel. Symbols evaluate to the sum of all routes
exported from connected table with generation less than max generation of
particular channel. Default max generation is 16.
Beware you shouldn't make cyclic references as the behavior of such
configuration is not defined!
Add static route attribute to set onlink flag for route next hop. Can be
used to build a dynamically routed IP-in-IP overlay network. Usage:
ifname = "tunl0";
onlink = true;
gw = bgp_next_hop;
Most branching instructions (FI_CONDITION, FI_AND, FI_OR) linearize its
branches in a recursive way, while FI_SWITCH branches are linearized
from parser even before the switch instruction is allocated.
Change linearization of FI_SWITCH branches to make it similar to other
branching instructions. This also fixes an issue with constant
switch evaluation, where linearized branch is mistaken for
non-linearized during switch construction.
Thanks to Jiten Kumar Pathy for the bugreport.
Define scope for anonymous filters, and also explicitly distinguish block
scopes and function/filter scopes instead of using anonymous / named
distinction.
Anonymous filters forgot to push scope, so variables for them were in
fact defined in the top scope and therefore they shared a frame. This got
broken after rework of variables, which assumed that there is a named
scope for every function/filter.
After flattening the route attribute structure, the ea_list ** is derivable
from rte * by arithmetics. Caching the derived value doesn't help performance
and therefore is removed as unnecessary.
For loops allow to iterate over elements in compound data like BGP paths
or community lists. The syntax is:
for [ <type> ] <variable> in <expr> do <command-body>
Allow variable declarations mixed with code, also in nested blocks with
proper scoping, and with variable initializers. E.g:
function fn(int a)
{
int b;
int c = 10;
if a > 20 then
{
b = 30;
int d = c * 2;
print a, b, c, d;
}
string s = "Hello";
}
When f_line is done, we have to pop the stack frame. The old code just
removed nominal number of args/vars. Change it to use stored ventry value
modified by number of returned values. This allows to allocate variables
on a stack frame during execution of f_lines instead of just at start.
But we need to know the number of returned values for a f_line. It is 1
for term, 0 for cmd. Store that to f_line during linearization.
When a new variable used the same name as an existing symbol in an outer
scope, then offset number was defined based on a scope of the existing
symbol ($3) instead of a scope of the new symbol (sym_). That can lead
to two variables sharing the same memory slot.
Direct recursion almost worked, just crashed on function signature check.
Split function parsing such that function signature is saved before
function body is processed. Recursive calls are marked so they can be
avoided during f_same() and similar code walking.
Also, include tower of hanoi solver as a test case.
Add literal for empty set [], which works both for tree-based sets
and prefix sets by using existing constant promotion mechanism.
Minor changes by committer.
All instructions with a return value (i.e. expressions, ones with
non-zero outval, third argument in INST()) should declare their return
type. Check that automatically by M4 macros.
Set outval of FI_RETURN to 0. The instruction adds one value to stack,
but syntactically it is a statement, not an expression.
Add fake return type declaration to FI_CALL, otherwise the automatic
check would fail builds.
Pass instructions of function call arguments as vararg arguments to
FI_CALL instruction constructor and move necessary magic from parser
code to interpreter / instruction code.