Gated Configuration File Generator User's Guide

Version: 4.10 Last updated: 7.30.96

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 If a machine has more than one interface, it is recommeded 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. Support has been added for "template" based generation of expected route files. This allows for complete user-definition of expected routes, and is especially useful in import/export tests and "next-hop" situations. The expected-route template to be used for all sequences must be specified globally. In order to invoke generation in this fashion, the variables in the template must be defined as follows: sequence x machine yyy expected_routes setvar $variable1 = ... setvar $variable2 = ... setvar $variableN = ... end Without using the template feature, the expected routes will be created as derived from a full-mesh configuration. 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. 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_template <template_file> Specifies a template filename to be used in processing the expected route files. 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. 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. peer_template <template> Sets the default template to use when processing peers. Can be overriden 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. 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". 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 overriden 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 statment 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. 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 currnet 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 substatement $$PEER_AS AS number of current import/export substatement $$PEER_NET NET (OSI address) of current import/export substatement $$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 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" 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> routing_domain <RD name> mesh <peer_type>=<machine list> machine <machine name> setvar <variable>=<var value> rib <RIB>=<template> protocol <protocol> 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> routing_domain <RD name> mesh <peer_type>=<machine list> machine <machine name> setvar <variable>=<var value> rib <RIB>=<template> protocol <protocol> 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> 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> 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> ] <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 <test name> ::= STRING = name of this test <test set name> ::= STRING = name of this test set