
                     Gated Configuration File Generator
                                User's Guide

Version:        4.11
Last updated:   10.21.97

Introduction

This program generates Gated configuration files for a variety of protocols
using a simple and flexible language.

This program became necessary from the sheer number of different gated.conf
files needed to test relatively simple configurations.  A basic four-machine
test using 12 slightly different networks and six sub-tests requires over
two hundred files which differ only slightly from each other.  To create
these files by hand is quite a chore:  to make even a minor change to the
underlying configuration requires editing many files, perhaps all of them.

Accordingly, the generator is designed to minimize the amount of work needed
to both create and modify all the configuration files needed for a given test.
It was designed both to be simple and straightforward to use, and yet flexible
enough to generate files for a wide variety of tests and conditions.

The author assumes the reader is familiar with what Gated is, the basic
protocols, and the basic concepts behind networking and using Gated to
establish machine-to-machine communications.

Definitions

CFG file
     Configuration File Generator file.  The file describing the
     network configurations (sequences) and routes and routing policy
     (test sets) which are used to generate a set of Gated configuration
     files.  By convention, this has the name, "[test name].cfg", but
     this is not required.

Configuration file
     A file which Gated uses to read in information about a
     particular machine - its peers, import and export policy,
     static routes, and operating parameters.  Usually named
     "gated.conf" or something similar.

Expected results file
     A file created by the configuration file generator
     containing the routes which are expected to be in
     the routing table following the processing of its
     related gated.conf file.

Sequence
     A particular network configuration of machines.  A sequence
     defines the routers used, internal and external peers for each
     one, and routing domain and RIB information.

Template
     A file used by the configuration file generator.  Templates supply
     the framework for configuration files, which are then filled in
     with user-defined variables and machine-specific information.
     By convention, template files have the suffix ".tpl".

Test set
     A particular set of routes and policy to apply to each sequence.
     Test sequences contain import and export information, and a set
     of static routes to use.

Configuration File Generator (CFG) Files

The CFG language is designed to describe physical machine layouts and test
conditions in a simple, straightforward manner, using names instead of numbers
and hard-coded addresses.

Each CFG file describes a particular set of test machines, communications,
and test conditions.  This file normally has the suffix ".cfg".  Some sample
CFG files are included in the examples directory.

A CFG file contains the following logical parts:

   <Name of test>
      <Global information>

      <Test set 1>
      .
      .
      .
      <Test set n>

      <Sequence 1>
      .
      .
      .
      <Sequence n>

Each sequence is a description of a network layout of machines and connections
among them.  Each test set is a set of conditions - static routes to include,
and import and export policy.

Note:  Sequence and test set IDs do not have to be numbers; they may be
       any string which uniquely identifies each sequence or test set.

A sequence has the following logical parts:

   <Sequence ID>
        <Routing Domain 1>
                <Protocol 1>
                        <Machine 1>
                                <peer/interface list>
                        .
                        .
                        .
                        <Machine n>
                                <peer/interface list>
                .
                .
                .
                <Protocol n>
        .
        .
        .
        <Routing Domain n>

A test set has the following logical parts:

   <Test set ID>
        <Static route set>
        <Import policy>
        <Export policy>

The complete set of CFG syntax is found in Appendix I of this guide.

Configuration files are generated from a cross-product of sequences and
test sets.  That is, a separate configuration file is generated for each
combination of sequence and test set.

The generated configuration file takes the following name:
   gated.conf.<test name>.<machine name>.<sequence name>.<test set name>

Thus the file name for test "basic_12", machine "ralph", sequence 1,
test set 5 would be:
   gated.conf.basic_12.ralph.1.5

Running the Program

Run the program "gated_setup.csh", first resetting any system-dependent values
in that script to appropriate values.  This script will set up the necessary
environment variables to run the generator.

The generator also uses a file to read in information about each machine.
This file must be edited to include all machines which will be referenced.
If the generator cannot find a machine mentioned in the CFG file in the
machine map, it will stop with an error message.  See the section below on
"The Machine Map File" for more information.

To run the generator, type "gen_config <options> <CFG filename>".  Use the
"-h" option to generate the usage message seen below.

Usage: gen_config.perl [-EhILW] [-m machine_name] [-t test_name] <test config file>
Options:
   -m <machine_name> - Generate files only for that machine
   -t <test_name>    - Go to this test directory and make files
   -E                - Do not generate expected results files
   -h                - Print this usage and overview message
   -I                - Do not generate informational messages (do print errors)
   -L                - Do not generate export loop code
   -W                - Do not generate warning messages (do print errors)

"Export loop" means that in an export statement the current RDI is referenced
in a sub-statement.  Below is an example of export loop code generated for a
router in routing domain 0x490136:

# Export policy to another routing domain
export proto idrp rdi 0x490150
{
    # How to treat routes coming from our own RD
    proto idrp rdi 0x490136 {
        ip all;
        all;
    }
};

The Machine Map File

This file contains the necessary information on each machine which the
generator needs.  This file is of course site-specific and will need to
be edited by the user.  The file name is "machines.map" and is found in
the same directory as the generator.

Each entry in the machine map has the following fields:

Machine name
  A string, usually the machine's name.  This may differ based on the
  number of interfaces (see below).

AS number
  Autonomous System number - another type of domain identifier.
  Used by BGP.

RDI
  Routing domain identifier.  Used by IDRP.

IP global prefix
OSI global prefix
NLRI prefix
  (Network Layer Reachability Index)
  These are the prefixes to the static routes for a machine.
  Example:  if machine "ralph" has static OSI routes 49.0171-49.017f:
              "49.01" is the OSI global prefix
              "7"     is the NLRI prefix
NOTE: These three fields were once used to generate static route ranges, but
      since route sets were implemented, they are not used by the generator.

Capacity
IP address
OSI address
IP suffix - The suffix of a test route specific to this machine.
Default gateway

If a machine has more than one interface, it is recommended that the machine
be given a different name for each interface.  Thus if machine "ralph" has
two interfaces and both are used, the machine name fields could be "ralph1"
and "ralph2", each with a different IP and OSI addresses, with other fields
remaining the same.  Or each interface could be in a different routing domain.

Expected Results Files

For each configuration file, the generator also produces an "expected
results" file.  This is a list of routes which are expected to be in
a machine's kernel routing table after the configuration file is read
in and processed by Gated.

Lines in the expected results file take the form "<RIB>   <route>".
A set of routes is listed for every RIB which is supported by one or
more of the peers for that file.  The RIBs are checked against the
QOS file, which is generated by Gated.

A method for overriding the expected results is provided.  The keyword
"expected_file" takes as its argument a file name which is searched
for in the normal manner.  The contents of the file are as such:

        <machine> <test> <sequence>
        <expected results>
        end

        <machine> <test> <sequence>
        .
        .
        .

Built-in functions such as &ip_suffix(machine) and &ip(machine) may
be used in the expected results file.

If an entry is given for a specific machine,sequence,test the results
it specifies replaces the generated entries with the possible exception of a
direct route.  The direct route is added if not specified already by
the entry in the expected_file.

Comparison of the expected routes against the routes in the routing table
and the QOS table can be done using the script "cmp_results.perl".  This
script is used by the automated test program and is available there as a
menu selection.

CFG File commands

The commands listed here are in alphabetical order.  See Appendix I (CFG
file syntax) to view their proper scopes.

Comment lines (lines which have "#" as the first non-whitespace character
on the line), blank lines, and lines of all whitespace are ignored.

It should be noted that currently the parser is single pass and the result files
are generated at the end of a machine statement.  Thus the parser must
have all information required for the machine available at that point.
This is the motivation behind many commands like set_routing_domain,
rip_peers, ospf_peers and non_peer_routes.  These commands typically
provide information that would have been learned later in the
configuration file. This situation while not optimal in all situations
works well if the generator will not actually know the entire test
requirements (e.g., if another tool will be used in conjunction with gated.)

area <area name>[=<template>]
   Sets the current OSPF area to the given area name.  A template file
   is optional, although if it is not specified a default must exist
   through the use of the "area_template" command.  To include the OSPF
   backbone, define the backbone as an entry in the machine map file, then
   use the command "area <backbone name>=<backbone template>".

area_template
   Sets the default template file to use when processing OSPF areas.
   Can be overridden by specifying a template file on an "area" command.

bgp_test <peer list>[=<template>]
   Identifies the list of machines which follow as internal BGP "test" peers
   of the current machine.  A template file is optional, although if it is
   not specified a default must exist through the use of the "peer_template"
   command or $$PEER_LOOP directive.

configuration
   Identical to the "sequence" command (see below).

end [comment]
   Ends a sequence, test set, machine, or route-set variable declaration set.
   When encountered after a set of statements for a single machine, the "end"
   statement invokes generation of configuration (and in some cases, expected
   route) files for that machine.  May also be used to end a test set
   (one possible use for this:  subsequent setvar statements can be done in
   global scope).  Required in all cases except when using the 'mesh'
   statement; in this case, a single 'end' at the end of the sequence is
   sufficient.

expected_file <expected results file>
   Indicates file to check for specific overrides of generated results.

export <template>,
export_all <template>
   Specifies the export policy structure to use in the generated configuration
   file, and the template to use.
   - "export"     exports to a specific RDI (defined using a setvar).
   - "export_all" exports to all the RDI of the defined peers of a machine.

external <peer list>[=<template>]
   Identifies the list of machines which follow as external neighbors of
   the current machine.  A template file is optional, although if it is
   not specified a default must exist through the use of the "peer_template"
   command or $$PEER_LOOP directive.

generate <sequence>, <test_set> | "all"
   Adds a restriction to sequence/test set generation.  The wildcard "*"
   matches everything.  "all" is equivalent to "*,*".  More than one
   generate command may be used.  Not using the "generate" command at
   all in the CFG file is equivalent to "generate all".

   The generate list uses the most inclusive set:  thus with the commands
      generate 1,*
      generate 2,2
      generate all
   every combination will be generated.  Without the "all", every test set
   would be generated with sequence 1, but with sequence 2 only test set 2
   would be generated.

group_template [<protocol>=]<template>
   Specifies the template to use when generating BGP and IDRP "group"
   statements.  A different template can be specified for each protocol.
   If no protocol is specified, it becomes a "general" group template used
   for protocols which have no specific group template defined.

igp <peer list>[=<template>]
   Identifies the list of machines which follow as internal IGP peers of
   the current machine.  A template file is optional, although if it is
   not specified a default must exist through the use of the "peer_template"
   command or $$PEER_LOOP directive.

import <template>,
import_all <template>
   Specifies the import policy structure to use in the generated configuration
   file, and template to use.
   - "import"     imports from a specific RDI (defined using a setvar).
   - "import_all" imports from the RDI of all defined peers of a machine.

interface <interface name> | "all" [=<template>]
   Sets the current interface to the specified name.  A template file
   is optional, although if it is not specified a default must exist
   through the use of the "intf_template" command.  Interface names are
   entries in the machine map file (treated the same as machine names)
   and are translated by the generator into the appropriate IP addresses.
   The keyword "all", which refers to "all available interfaces", passes
   through to the generated files untranslated.

internal <peer list>[=<template>]
   Identifies the list of machines which follow as internal neighbors of
   the current machine.  A template file is optional, although if it is
   not specified a default must exist through the use of the "peer_template"
   command or $$PEER_LOOP directive.

intf_template  <template>
   Sets the default template file to use when processing interfaces.
   Can be overridden by specifying a template file on an "interface" command.

ip_gateway <machine>=<IP address>
   The value of the variable $IP_Gateway for the given machine.  This
   value is used normally when processing route sets where the gateway
   for a specific route is given as $IP_Gateway.  By having different
   values for each machine the next hop can be checked to determine
   where the route originated most of the time.

machine <machine name>
   Identifies a particular machine as part of the physical configuration
   of a sequence.  After the machine configuration is complete, the
   machine set *MUST* be terminated with an 'end' to invoke generation
   of config and expected route files.

main_template <template>
   Sets the file name of the main template for this test.  This command
   is optional; the default main template will be used if the command is
   not specified.

mesh <peer type>=<machine list>
   Sets up a full mesh of the specified peer type among the listed machines.
   For internal mesh types (internal, igp, routing> a routing domain must
   have been specified beforehand.  "End" keywords are not required when
   using a mesh.

non_peer_routes <machine> <...>=<gateway>
   Indicates that we expect to receive route sets for the given machines
   through the given gateway.

ospf_peers <test list>=<machine> <machine> <...>
   Indicates that the machine expects to be direct peers with the given
   machines.  This information is used to determine which machines
   we expect to receive route sets for.  The next hop is determined
   by checking to see if the current machine is directly connected to
   the same network as the given peer machines ip_gateway value.
   If a test list is not given the information applies to all tests otherwise
   it is limited to the given tests.

peer_template <template>
   Sets the default template to use when processing peers.  Can be
   overridden by specifying a template file on a peer command (such as
   "internal" or "external">.

protocol "bgp" | "idrp" | "ospf" | "rip"
   Sets the current protocol.  For CFG files dealing with only one protocol,
   this command can be used just once at the top of the file.  For multiple
   protocols, it is used before peer/interface statements in this form:
   ...
        machine ralph
             protocol bgp
                  internal alice,norton
             protocol idrp
                  external fred
             protocol rip
                  interface ralph2
   ...

rib <RIB>[=<template>]
   Defines a RIB id and specifies the template to use to generate it.
   Can be set at global, sequence, or machine scope.  A template file
   is optional, although if it is not specified a default must exist
   through the use of the "rib_template" command.

rib_template <template>
   Sets the default template file to use when processing RIB commands.
   Can be overridden by specifying a template file on a "rib" command.

ribs-supported <RIB list>
   Indicates the RIBs supported by the current peer(s).  This list will be
   added to the "neighbor" statement for the peer in the configuration file.

rip_peers <test list>=<machine> <machine> <...>
ripv2_peers <test list>=<machine> <machine> <...>
   Indicates that the machine expects to be direct peers with the given
   machines.  This information is used to determine which machines
   we expect to receive route sets for.  The next hop is determined
   by checking to see if the current machine is directly connected to
   the same network as the given peer machines ip_gateway value.
   rip_peers always use the machine the route is received from as the
   next hop whereas ripv2 will use the actual gateway value if it
   has an interface on the same network.
   If a test list is not given the information applies to all tests otherwise
   it is limited to the given tests.

route_set [<machine name> | "default"=]<route set name>
   Specifies a set of static routes to use in a given test set.  The
   route sets are defined in the route set file.  If no machine name is
   specified (e.g. "route_set 3") that route set will be used for every
   machine.  The route set which contains the "default" routes is
   identified by using "route_set default=<route set>."

routing <peer list>[=<template>]
   Identifies the list of machines which follow as internal BGP "routing"
   peers of the current machine.  A template file is optional, although
   if it is not specified a default must exist through the use of the
   "peer_template" command or $$PEER_LOOP directive.

routing_domain <rdi>
   Identifies the routing domain of the subsequent machines.  The <rdi>
   identifier must have an entry in the machine map file.

sequence <sequence name>
   Defines a new sequence.  Must be terminated with an "end".

set_routing_domain <machine> <machine>=<routing domain>
   Sets the routing domain of the given machines to the specified value.
   This should be done when machines are in routing domains other than
   their own (as specified in the machine map file.)

setvar <variable>=<var value>
   Creates a user-defined variable.  Can be set at many different scopes
   (see section on "Variables").

socket <socket type>
   Defines the socket type to use.  Current valid choices are "idrp" and "ip".

test <test name>
   Establishes a new test.

test_set <test set name>
   Defines a new test set.  May be terminated by an optional "end".

Templates

Predefined templates are located in a "templates" subdirectory.  In addition
to these, the user may define as many other templates as needed.  When making
configuration files, the generator uses the following search path when looking
for templates:
   1 - the current directory
   2 - the test subdirectory
   3 - the template directory

If a directory specification is included with the template name (for example,
"/usr/barney/gated/bgp_peer.tpl"), the search path is not used.

The default main template is "main_template.tpl".  This contains the framework
for the main body of a configuration file.  This can be overridden by specifying
a different file using the "main_template" command.

Import and export statements use other templates.  These are specified by
the user, as they can take many and varied forms.  In turn, these can reference
sub-templates for multiple peers.  The $$LOOP directive (used in export), for
example, takes a sub-template as an argument; it loops through all defined
peers for a given machine and sequence, using the sub-template for each peer
in the loop.  RIB statements also use templates.  Each RIB statement may use
a separate template.

All templates may contain user-defined variables.  See the section below on
"Variables" for more information.

Variables

Variables in the configuration file generator come in two forms:  predefined
and user-defined.  Predefined variables have values established by the program
and begin with "$$".  User-defined variables should begin with a single "$",
and are defined using the "setvar" command in the CFG file.

For example, if a variable is defined in the CFG file as follows:
                  setvar $routes=128.1 128.2 128.3;

and the string "$routes" is placed in a template file:
                  import proto idrp rdi $$PEER_RDI
                  {
                       $routes
                  }

the RDI of the current peer would be substituted in place of "$$PEER_RDI" and
the value "128.1 128.2 128.3;" would be printed in place of "$routes" in
the generated configuration file.  However, there is currently no variable
substitution inside the "setvar" statement itself, so a statement in the
CFG file like
                  setvar $line=proto idrp rdi $my_rdi

would print "$my_rdi" as a literal string and would not attempt to look for
a variable with that name.

Variable names are case-sensitive, so "$ROUTE", "$Route",  and "$route" are
three different variables.

Some predefined variables are actually template directives.  Rather
than being a simple substitution, they instruct the generator to produce a
set of code or perform some other specific action.

The term "current machine" used below refers to the machine for which a
configuration file is being generated at the time of reference.  For example,
if a configuration file is currently being generated for machine "ralph",
$$RDI_NUMBER will be translated as the RDI of machine ralph.

   Directive                    Do
----------------------------------------------------------------------------

   $$INCLUDE <template>         Read and process the specified template
   $$RIB_LOOP                   RIB statements (as many as defined)
   $$AREAS                      OSPF area statements
   $$GROUPS                     BGP/IDRP "group" statements
   $$PEER_LOOP                  Individual peer statements within a group
   $$INTERFACES                 Interfaces for current area or peer
   $INTERNAL_NEIGHBORS          Internal peers of current machine/sequence
   $EXTERNAL_NEIGHBORS          External peers of current machine/sequence
   $STATIC_ROUTES               Current machine's static routes
   $IMPORT_STATEMENTS           Import policy statements
   $EXPORT_STATEMENTS           Export policy statements
   $$LOOP <template>            export sub-statements (all external peers)

   $$LOOP is used inside an import/export template and indicates the sub-
   template to use for the loop (specified by the "import_all" or "export_all"
   commands).  Thus an import_all command specifies the main import template,
   while the $$LOOP inside that template specifies the sub-template.

The following are usually placed in the header of the main template.

   Predefined
   Variable                     Becomes
----------------------------------------------------------------------------

   $$HOST_NAME                  Name of the machine this file is generated for.
   $$PROGRAM_NAME               Name of the configuration file generator.
   $$PROGRAM_VERSION            Configuration file generator version.
   $$DATE                       Date and time file was generated.
   $$SEQUENCE                   Sequence represented by this file.
   $$TEST_SET                   Test set represented by this file.
   $$HOST_IP                    IP address of current machine.

The following are usually placed in a protocol-specific template.

   Predefined
   Variable                     Becomes
----------------------------------------------------------------------------

   $$TRACEOPTIONS               Log file directory/filename
   $$RDI_NUMBER                 RDI of the current machine
   $$AS_NUMBER                  AS number of the current machine
   $$NET                        NET (OSI address) of the current machine
   $$CAPACITY                   Capacity of current machine (from machine map)

The following are usually placed in the peer or area templates.

   Predefined
   Variable                     Becomes
----------------------------------------------------------------------------

   $$PROTO-SOCK                 Value of the "socket" command
   $$RIBS-SUPPORTED             Value of the "ribs-supported" command
   $$GROUP_TYPE                 BGP group type - internal/external, etc.
   $$PEER_NAME                  Peer machine name
   $$AREA_NAME                  Name of current area
   $$HOST_IP                    IP address of current machine
   $$PEER_IP                    IP address of peer

The following variable should be placed in the RIB template(s) to identify
the ID of each RIB.

   Predefined
   Variable                     Becomes
----------------------------------------------------------------------------

   $$RIB                        ID of each RIB in the loop

The following are usually placed in the import/export template(s).  Which ones
are used depends on how the user wants to create import and export policy:

   Predefined
   Variable                     Becomes
----------------------------------------------------------------------------

   $$PEER_RDI                   RDI of current import/export peer sub-statement
   $$PEER_AS                    AS number of current import/export sub-statement
   $$PEER_NET                   NET (OSI address) of current import/export
                                sub-statement
   $$HOST_RDI                   RDI of current machine
   $$HOST_AS                    AS number of current machine
   $$HOST_NET                   NET (OSI address) of current machine

   $$PEER_RDI, etc.  can be used for the export sub-template (for inside
   the loop) or can be put into the top level template.  For example:

   import proto idrp rdi $$PEER_RDI
   {
      <routes & policy>
   };

   To process a specific number of RDI without using the loop of all peers,
   use user-defined variables and built-in functions:

   (in CFG file)
   setvar $rdi_1=&rdi(ralph)
   setvar $rdi_2=&rdi(norton)
   (later on...)
   setvar $rdi_1=&rdi(fred)
   setvar $rdi_2=&rdi(wilma)

   (in export template)
   #  We want to specify policy for routes imported from two external RDI
   export proto idrp rdi $PEER_RDI
   {
      # Policy for routes coming in from first specific RDI
      proto idrp rdi $rdi_1
      {
         <routes & policy>
      }

      # Policy for routes coming in from second specific RDI
      proto idrp rdi $rdi_2
      {
         <routes & policy>
      }
   };

User variables can be defined in several different scopes.  If a variable
is defined in multiple scopes, the value of the innermost active scope is
used.  Thus a variable defined inside a sequence statement would use the
value defined in the sequence, and revert to its global value (if any)
outside of that sequence.  The scopes are listed below:

Global scope - variable value used throughout entire test
   Sequence scope - value used throughout current sequence
      Machine scope - value used for this machine in current sequence
         Peer/interface scope - value used for this peer or interface
                                of current machine in current sequence
Test set scope - value used for this test set (overrides others)

Test set scope is special in that it is not actually "inner" to peer scope, but
separate.  However, a variable defined inside a test set will override all
other definitions for that variable when that test set is part of the file
currently being generated.

Built-in Functions

These are useful for putting machine-specific information into a general
statement.  Built-in functions are interpreted only in "setvar" statements;
they cannot be put into a template like user variables.  However, you can
have as many built-ins as you want in any given setvar statement, and they
may be located among other text.

The defined built-in functions are:
   &as(machine)  - returns the AS number of the specified machine
   &rdi(machine) - returns the RDI value of the specified machine
   &net(machine) - returns the NET (OSI address) of the specified machine
   &ip(machine)  - returns the IP address of the specified machine
   &ip_suffix(machine) - returns the IP suffix (as specified in machines.map) of the specified machine

Leaving the machine parameter blank returns the value for the current machine.
Thus if a file is currently being generated for machine "ralph", a call to
&net() would return ralph's NET.

Examples:
   setvar $rdi_1=&rdi(ralph)
   setvar $local_net=local-net &net()
   setvar $ip_list=ip &ip(ralph), &ip(norton), &ip(alice)

>Author: Jeff Jackson
        Merit Network, Inc.
        jeff@merit.edu

----------------------------------------------------------------------------

                                 Appendix I
                Configuration File Generator Language Syntax

# comment ("#" must be first non-whitespace character on line)

test <test name>
   generate <sequence>, <test set> | "all"
   protocol <protocol>
   rib <RIB>=<template>
   socket "ip" | "idrp"

   expected_file  <expected results file>

   area_template  <template>
   intf_template  <template>
   group_template <template>
   main_template  <template>
   peer_template  <template>
   rib_template   <template>

   setvar <variable>=<var value>

test_set <test set name>
        route_set default=<default route set>
        route_set <route set>

        import <template>
        import_all <template>

        export <template>
        export_all <template>

        setvar <variable>=<var value>
[end [comment]]
# NOTE: "end" on a test set is optional; it re-establishes global scope
#       for subsequent variable declarations.

.
.
.

# IDRP sequences
sequence <sequence name>
        rib <RIB>=<template>
        setvar <variable>=<var value>
        mesh external=<machine list>
        set_routing_domain <machine> ...=<RD name>
        routing_domain <RD name>
                mesh <peer_type>=<machine list>
                machine <machine name>
                        setvar <variable>=<var value>
                        rib <RIB>=<template>
                        protocol <protocol>
                                non_peer_routes <peer list>=<machine_name>
                                internal <peer list>[=<template>]
                                        ribs-supported <RIB list>
                                        setvar <variable>=<var value>
                                external <peer list>[=<template>]
                                        ribs-supported <RIB list>
                                        setvar <variable>=<var value>
end [comment]
.
.
.

# BGP sequences
sequence <sequence name>
        rib <RIB>=<template>
        setvar <variable>=<var value>
        mesh external=<machine list>
        set_routing_domain <machine> ...=<RD name>
        routing_domain <RD name>
                mesh <peer_type>=<machine list>
                machine <machine name>
                        setvar <variable>=<var value>
                        rib <RIB>=<template>
                        protocol <protocol>
                                non_peer_routes <peer list>=<machine_name>
                                internal <peer list>[=<template>]
                                        ribs-supported <RIB list>
                                        setvar <variable>=<var value>
                                igp <peer list>[=<template>]
                                        ribs-supported <RIB list>
                                        setvar <variable>=<var value>
                                routing <peer list>[=<template>]
                                        ribs-supported <RIB list>
                                        setvar <variable>=<var value>
                                bgp_test <peer list>[=<template>]
                                        ribs-supported <RIB list>
                                        setvar <variable>=<var value>
                                external <peer list>[=<template>]
                                        ribs-supported <RIB list>
                                        setvar <variable>=<var value>
end [comment]
.
.
.

# OSPF sequences
sequence <sequence name>
        setvar <variable>=<var value>
        routing_domain <RD name>
                machine <machine name>
                        setvar <variable>=<var value>
                        protocol <protocol>
                                ospf_peers <test list>=<peer list>
                                non_peer_routes <peer list>=<machine_name>
                                area <area name>
                                        interface <interface>[=<template>]
                                                setvar <variable>=<var value>
end [comment]
.
.
.

# RIP sequences
sequence <sequence name>
        setvar <variable>=<var value>
        routing_domain <RD name>
                machine <machine name>
                        protocol <protocol>
                                rip_peers <test list>=<peer list>
                                ripv2_peers <test list>=<peer list>
                                non_peer_routes <peer list>=<machine_name>
                                interface <interface>[=<template>]
end [comment]

<built-in>     ::= "&"<built-in name>"<" <machine name> ">"
<machine list> ::= <machine name> [ , <machine name> ] ... [ , <machine name> ]
<peer list>    ::= <machine name> [ , <machine name> ] ... [ , <machine name> ]
<rdi>          ::= <machine name>
<RIB list>     ::= "all" | <RIB> [ <RIB> ... <RIB> ]
<test list>    ::= <test set name> [ , <test set name> ] ... [ , <test set name> ]

<variable>     ::= "$"<string>
<var value>    ::= <string> | <built-in> [ <string> | <built-in> ] ...

<built-in name> ::= "rdi" | "net" | "ip"
<peer_type>     ::= "internal" | "external" | "igp" | "routing" | "bgp_test"
<machine name>  ::= ATOM     = name of a machine in the machine map file
<protocol>      ::= STRING   = name of a supported protocol
<RIB>           ::= INTEGER  = ID of a specific RIB
<RD name>       ::= STRING   = name of a routing domain in machine map file
<sequence name> ::= STRING   = name of this sequence
<template>      ::= FILENAME = name of a file to use as a template
<expected results file>  ::= FILENAME = name of file to get overrides from
<test name>     ::= STRING   = name of this test
<test set name> ::= STRING   = name of this test set
