To read about an overview of how the policy module works,
see here.
Policy module type declarations
This is an internal node in a Patricia tree of policy expressions.
The tree is traversed based on a network address and mask. The node
contains the byte number within the address and the bit number within
the byte to test when the traversal reaches this node.
This structure is stored in a union in each
adv_entry
.
It is used to specify the destination address and mask that
matches a particular policy expression.
This structure forms part of each route entry,
rt_entry
.
This structure is used to doubly link together a number of different
route entries through this structure.
In addition, this structure is stored in each gw_entry
.
It is used as the head of a doubly linked list of route entries.
This structure forms part of a BGP peer descriptor block,
the bgpPeer
.
It contains most of the peer specific information, including
the peer's address, the peer AS numbers, the list of routes
received from the peer and the peer import and export policies.
This structure stores the results of a policy search and is part
of each control list element adv_entry
.
The values stored include a metric and a preference and some flags.
It is used as well as an in-out argument to the policy enforcement
routine to return the results of a policy check on a given route.
This structure, a list of which is contained in each control list element
adv_entry
, stores the configured
preference associated with a policy expression.
A singly-linked list of config_entry
elements.
This is a single control list element. A single route filter in the policy
expression language maps onto one adv_entry. A single adv_entry may specify
for example, that a route entry must match a destination and mask, and
an AS path and other AS specific data. The adv_list
field
specifies which of these conjunctive matches must hold for a match
to occur in a single adv_entry
.
Policy module macros
Perform a depth first search of the Patricia tree, storing untaken
branches in a stack and then unwinding the stack when a leaf node has
been reached. This macro is used to start a loop whenever a DFS traversal
of the tree is necessary.
End the loop started by DMI_WALK
.
Perform a depth first search of the Patricia tree, and in addition,
at each internal node, traverse the list of
adv_entries
.
End the loop started by DMI_WALK_ALL
.
This set of macros permits manipulation of the rtq_entry
s
and lists of such entries. Such manipulations include finding the
superstructure (e.g. rt_entry
) to which this entry belongs,
sequential traversal of such a list and so on.
Policy module function definitions
Called when the policy specifications are being parsed, to insert
a control list element into the Patricia tree. The basic algorithm is
as follows: search down the tree until we reach a dead-end or an internal
node with a bitmask greater than ours. If we reach a dead-end, we have
to create an internal node at the dead-end. If we have passed our appropriate
position in the tree, we create a split in the tree above the node where
we stopped.
Called when we need to locate the list of policies governing a particular
destination address and mask. Given a list of control list elements
(adv_entry
s), locate the root
of the Patricia tree corresponding to that list.
Search down the tree with the given destination and mask until
either the mask is exhausted or we have reached a dead-end. Store
all intermediate visited nodes in a stack. Depending on whether a
refined or exact match is to be performed, wrap back
the stack until the appropriate internal node is found. Return the
corresponding adv_entry
.
Called from rt_aggregate_match()
.
Given a route, traverse the Patricia tree to find out the longest match
on the routes destination and mask. Test to see if the route passes the
filters in the adv_entry
s. Such a route can probably be
aggregated into the less specific route.
Walk through the entire tree and from each internal node, delete every
element of the attached control list.
During configuration parsing, the list of adv_entry
s is built
up as is read from the configuration file. We actually want the
adv_entry
s to be listed in the order in which they appear
in the Patricia tree and for each adv_entry
to contain
a pointer to the root of the tree. This function, called at the
end of policy expression parsing, achieves that.
Do a complete tree traversal to compute the depth of each internal node
of the tree. Sore this depth value in the metric field of the associated
control list element adv_entry
.
Allocate a single adv_entry
with the specified protocol
and flags field.
Called during cleanup of different protocol adv lists. Free
each control list element and recursively, all its children (indicated
by the adv_list
field of the adv_entry
).
Repeatedly call adv_free_list()
on each of the specified lists.
Called when we want to verify if a route entry matches one of the export
filters specified in a adv_entry
list. For each element
in the control list (i.e. traversing down the adv_next
pointers
of the adv_entry
) check if the route's parameters
matches the adv_entry
's policy restrictions. We do this
by traversing the adv_list
pointers and checking for
a match along each restriction (e.g. AS match, AS path match etc).
Finally, the matching adv_list
element might have a
restriction on whether we are allowed to tell the peer this route's
destination. We do a Patricia tree search for this.
Called to verify if we can add an incoming route to the GateD database.
This code is similar to export()
, with the only difference
being that only a single level of lookup is necessary in the list
of adv_entry
s (figure out why).
The parser maintains a list of gateways or peers defined so far.
Given this list and an address and protocol, find
a matching gw_entry
in such a list of gateways.
Given a gw_entry
and a list of such entries, add this
entry to the end of the list. Appropriately initialize the list.
Find a matching gw_entry
in the specified list. If none
exists, create an entry and add it to the list.
In addition to the parser, some protocols (e.g. HELLO) maintain their
own list of gw_entry
s. Update the timer on the matching
gw_entry
.
Initialize a gw_entry
if we are given one, otherwise
create one.
Walk down the specified list and free each gw_entry
.
Functions related to config_entries
This code appears to be entirely used by the parser to store and
process interface specifications. To be documented later.