BGP Update Processing type declarations


BGP Update Processing module macros

macro BGPM_*

BGP metrics are stored in a bgp_metrics structure. Routes with the same metric share the same structure. These structures are all stored in a Patricia tree and are indexed by the contents of the metrics structure itself. The tree node contains a reference count and the bit within the metrics structure which is used to perform the traversal test. These macros are used to update the node reference count as well as traverse the tree.

macro BRT_*

The BGP TSI structure (the protocol specific information that is associated with every rt_head structure) contains either a metrics structure or a BGP outgoing route (bgp_rto). These macros read or write a TSI structure and update the specified rt_head value appropriately.

macro BGP_ASPL_*

Recall that a BGP ASP list contains the queue head for a linked list of bgp_rto_entrys and bgp_grto_entrys. This set of macros inserts one such entry into the head or tail of this list.

BGP Update Processing module function definitions

function bgp_rt_metrics_add

Called from the BGPM_FIND macro when tree traversal found that a matching metrics structure does not exist. Given the node which has the longest similar prefix to the specified metrics structure. Allocate a new internal node and find out at which bit the supplied metrics structure and the other one don't match. Locate the position of this in the tree and splice the new node in there.

function bgp_rt_metrics_free

Given a metrics node, decrement its reference count. Locate its position in the radix tree and splice the elements of the tree to reflect the new structure.

function bgp_rt_unsync

A peer is said to be synchronized if it is ready to write (that is, if nothing is spooled on the write buffer). The group structure has a per peer bit to indicate if a peer is synchronized or not. A peer is allocated this from a bit mask maintained in the group structure. We simply reset the peer's sync bit in the group structure.

function bgp_rt_sync

Called when a peer's write buffer is flushed. Simply set the peer's sync bit in the group structure so we can quickly determine which peer is in sync to send data.

function bgp_rt_send_v4_message_attr

While processing a BGP message for send, the message is constructed in pieces. This function places the specified attributes in the outgoing buffer (BGP maintains a single outgoing buffer; actually GateD maintains a single send buffer common to all protocols). Make sure there is enough space in the buffer. If we already have some unreachables, put the attributes after the unreachables, otherwise put it at the head of the packet.

function bgp_rt_send_v4_unreachable_init

Initialize the global send buffer so that we can write unreachable information onto it.

function bgp_rt_send_message

BGP update send processing builds up a message piecemeal. When the message is completely formulated, this routine is called to dispatch the message to the peer. Simply calls bgp_send(), which if the write was partially completed, spools the message into the peer's write buffer.

function bgp_rt_send_v4_message_adjust

Called from bgp_rt_send_v4_flush() when the caller of that function indicates that there may be more routes to send to the same peer. This function moves up the attributes, removing any unreachables that might have been there (why?).

function bgp_rt_send_v4_prepare

This is called just before a prepared message is flushed out to a peer. Set the total message length and the message type. Two pathological cases might arise. If the message consists only of unreachables, set the unreachable length portion as well. If the message has attributes but no NLRI information, zero out the attributes portion and send the unreachables only (if any).

function bgp_rt_send_v4_flush

Called when a version 4 message has been completely formulated in the task buffer. Simply call the send routine and adjust the attributes portion of the message if more data is to follow.

function bgp_rt_send_v4_group_flush

Called when a version 4 message has been completely formulated in the task buffer and must be sent to each peer specified in the sendbits parameter. Scan through the list of established peers and, for peers specified in sendbits, fill in the nexthop attribute (to either the specified nexthop or the address of the local interface), then send out the message. Adjust the attributes part of the message if more data is to be sent.

function bgp_rt_send_peer

Each peer structure holds (in its bgp_asp_queue) the list of routes to be advertised to the (external) peer. This list is created in the following manner: whenever an update is received, the advertised route is tested against import policy and then stored in the routing database. This may cause changes to our FIB. We flash the kernel routing table with the new FIB and then process the resulting updates to be sent to the peers. These are stored in the peer structure. When it comes time for these updates to be sent out, this function is called.

The bgp_asp_queue attached to the bgpPeer structure contains a list of AS paths, and, for each AS path it has NLRI information stored in a bgp_rto_entry. At the head of this list is a list of NLRIs which have become unreachable (for these, the AS path is NULL). First put each unreachable NLRI into the message being created. Then free the bgp_rto_entry and any associated information (e.g., TSI fields allocated in the rt_entry). If, while filling in the unreachables, the packet size was exceeded, send the packet formed so far.

Now we process remaining AS paths. For each AS path, we attempt to pair each unique (metric, nexthop) tuple with the list of NLRIs that have the same AS path, metric and nexthop. We bundle each such combination into one update and send it off. (AS path, metric, nexthop) triple. This gives us a single update message, which we can then flush to the peer. We repeat this process for other

function bgp_rt_send_group_peer

Called to send updates for a specified peer in a non-external group. We do this if the peer was earlier blocked or if the peer is just starting up. Almost identical to bgp_rt_send_peer() above, except that we process the list of AS paths in the bgpPeerGroup structure. One difference is that each bgp_rto_entry contains an additional bgp_rtinfo_entry. Another is that metrics processing is different.

function bgp_rt_send_v4_group

Called for non-external groups from a flash routing when some updates have to be sent to each peer in the group. The general structure is similar to bgp_rt_send_peer.

For each AS path and for each bgpg_rto_entry entry in the AS path, we find out which peers we should be advertising this route to. To each such peer, first formulate a message containing unreachables, followed by the AS path info and the NLRI information. As before, find any other bgpg_rto_entry in the list which has to be advertised to the same set of peers and with the same metric information. Add its NLRI to the end of the message (at each step, of course, check that we haven't exceeded the BGP packet size). When we have a message with the maximal set of NLRI information to a given set of peers, we send the message.

function bgp_get_asp_list

Recall that a peer structure contains a list of bgp_asp_list entries chained through the bgp_rt_queue of the latter structure. The head of this list contains the AS path hash table. Lookup the specified AS path in this list. If no AS path is specified, we create one and add it to the list head. Otherwise, we look in the hash table to see if the AS path already exists; if so, we return a pointer to that. Otherwise, we create a bgp_asp_list structure and insert that into the list head.

function bgp_rt_add_policy_group_peer

When a new peer comes up in a non-external group, we need to advertize to the peer the last set of routes advertised to other peers in the same group. For this reason, groups maintain a list of bgp_adv_entry structs (recall that a bgp_rto_entry also contains a pointer to the bgp_adv_entry). In each group, the list of advertised routes may contain all the routes that the group is allowed to send to its peers. But only a subset of these is actually queued for flushing to a peer (e.g. because of holddown times?).

This function builds this queue for the new peer as follows. Sequentially traverse the list of bgp_adv_entrys in the group structure, and finds the corresponding outgoing route structure in which this resides (from the TSI information in the route list head). If such an entry does not exist, create a new outgoing route entry (bgp_grto_entry), find a corresponding AS path list entry to add the route entry to.

function bgp_rt_policy_init_group_peer

This complements the previous function, which is called when a peer with the same or better version is up already in a group. This function is called for the first peer to come up in a group or the first v4 peer. Instead of looking at the list of routes already advertised, here we must determine anew what routes this peer can advertise.

Find all active routes in the routing database and determine for each whether another peer in the group has already advertised this. If not, we create a new bgp_adv_entry and add it to the list of routes advertised by the group. Also, if the route does not belong to the send list yet, we need to create and add a group outgoing route structure. Otherwise, we need to set bits so that the route gets advertised to this peer as well.

function bgp_rt_policy_group

Called from the flash routine for non-external groups. Given a change list of routes that have changed, we run the export policy on these to create an advertised routes list. We also queue up data to be sent to the group peers. The (rather complicated) processing occurs as follows. For each route that has changed, first find if a route to the same destination has already been announced. On the changed (new) route, do a policy test to see if we can announce the route to our peer. If we can, and the old route is different from the new, find the metrics structure corresponding to the new route and queue up the new in the group "advertised list". Now, unannounce the old route. To do this, reset all the peer bits bgp_rtinfo_entrys in the old route's outgoing route entry. Then, remove the old group outgoing route entry structure and requeue the new route's structure in the send list.

function bgp_rt_policy_peer

Almost identical to above code. Minor differences owing to the fact that a peer's outgoing route entry does not have an "info" structure.

function bgp_rt_if_terminate

When all peers in an internal group running on a particular interface have terminated, we are called. Traverse the list of advertised routes to see if any of them have third party nexthops through the deceased interface. Change these nexthop values.

function bgp_rt_peer_update

This is the peer flash routine. After update processing has caused the kernel routing tables to change, this function is called to update the peer's send list. First run the policy code to decide which of the changed routes the peer should export. If anything has been queued up on the send list, try to flush some of that right away.

function bgp_rt_peer_flush

A peer may have been blocked in the write queue waiting for a previous write to complete. Alternately, everything in the send queue may be on holddown and we may have set a timer for this time to elapse. This function is called to try and flush anything pending in the send list at the end of such a wait or timer expiry.

function bgp_rt_group_update

The corresponding group flash routine for non-external groups. Slightly different logic. If there is one peer, flush directly by calling bgp_rt_send_group_peer. Otherwise, do the version 4 peers first followed by the version 3 peers.

function bgp_recv_v4_update

Called from the task select loop when data has arrived on a peer's socket. This routine tries to read as many complete BGP messages as possible, terminating only when incomplete message remains in the input buffer. For each message, check to see that the right sized message is available in the buffer. Process the unreachables first. Check if the unreachable route was indeed advertised by the peer and has not already been deleted. If so, delete it. Then, if there are any attributes (including the AS path), parse the attributes section of the message. Test for sanity in the value of the path attributes, including metric/preference, whether the AS path contains our AS, and so on. Now process the NLRI information. For each such NLRI destination and prefix, check if import policy would allow us to install that route. If so, and if a route already exists, just change the AS path, otherwise install the route in the GateD database. Repeat this for all the NLRI in the update message. Try to read as many BGP messages as possible before giving up.