XORP Logo

Getting Started with XORP

This short guide is aimed at people new to XORP understand what XORP does and how to use it. It's a work in progress - please let us know what additional help you would find useful.

Getting XORP

There are three ways to try out XORP.

If you want to develop new functionality for XORP, you'll obviously need to compile from source, but the live CD provides a way to try XORP out without needing to worry about having the right compilers or operating system installed.

Supported Operating Systems

XORP should be fairly portable. At the present time, the main development platforms for XORP are FreeBSD and Linux. XORP should run on all recent versions of FreeBSD, and on most versions of Linux with a 2.4.x or 2.6.x kernel.

XORP also appears to work on DragonFlyBSD, NetBSD, OpenBSD, MacOS X (10.2 or later), and on Windows Server 2003, but if you want to use it for multicast routing make sure that the kernel has the appropriate support (not available for MacOS X and Windows at this time). If you try XORP on another platform, let us know how you fare. See porting if you're interested in porting XORP to a new platform.

Compiling XORP from source

XORP is written in C++. We've endeavoured to comply as far as possible with the ANSI standards, but currently XORP has only been compiled with variants of gcc. XORP is known to compile on gcc 2.95.x, 2.96, 3.2.x, 3.3.x, 3.4.x, 4.0.x, 4.1.x, and experimental releases of 4.2.0 and 4.3.0.

We run a tinderbox that checks daily that XORP still compiles and passes its unit tests with 2.95.4, 2.96, 3.3.x, 3.4.x, and 4.1.1. The aim is that you should always be able to check out a current source snapshot from CVS, compile it, and have it pass all the internal validation tests. We don't always succeed, but failures identified by the tinderbox are always fixed very rapidly.

To compile XORP requires nearly 1.4GB of free disk space, and up to an hour depending on your CPU speed and the version of the compiler you're using. Much of this is spent compiling the validation tests, which are always built by default.

To compile XORP, you will need gmake installed. This is the default on Linux but not on BSD-derived systems (including MacOS X).

To build XORP with SNMP support, you need net-snmp installed (details here).

Assuming you have a checked out copy of the XORP source, you should be able to compile XORP by typing the following in the top-level XORP source directory where file "VERSION" is located:

# ./configure
# gmake
Note that "gmake" may be installed as "make" on some platforms. Then go away and have a coffee or two.

This will build XORP "in place". That is, the bgp binary (xorp_bgp) will be left in the bgp subdirectory, the XORP shell binary (xorpsh) will be left in the rtrmgr directory, and so on. This default can be overridden (for example, if you're cross-compiling multiple platforms from the same source), but there's no need to if you're just starting out.

To compile XORP on Windows see file "BUILD_NOTES" in the top-level XORP source directory.

XORP can be cross-compiled for a variety of processors. Currently it is known to cross-compile for IA-64, MIPS, PowerPC-603, Sparc64, and XScale. See file "BUILD_NOTES" in the top-level XORP source directory for details and instructions.

Validating a XORP Compilation

Assuming the compilation completed without errors, you should now validate that the build actually runs correctly. First, make sure that "bash" and "python" are installed. Then type the following in the top-level directory:

# gmake check
This will run all the internal validation tests for all the XORP modules. This is a rather lengthy procedure (nearly an hour), but it's a good idea to be sure that everything is working.

The debugging output can sometimes be a little excessive, but what you're looking for is lines like:

PASS: test_trie
which indicates that a particular test program completed successfully. Hopefully you won't see any lines like:
FAIL: test_peering1.sh
which indicates a particular validation test failed.

There can be warnings such as:

[ 2004/04/22 00:48:57 WARNING coord BGP ] TCP connection 
from test_peer: peer1 to localhost closed
Unless these result in a FAIL message, they are typically transient artifacts of the testing methodology, and can safely be ignored.

Running XORP

XORP tries to hide from the operator the internal structure of the software, so that the operator only needs to know the right commands to use to configure the router. The operator should not need to know that XORP is internally composed of multiple processes, nor what those processes do. All the operator needs to see is a single router configuration file that determines the startup configuration, and a single command line interface that can be used to configure XORP.

There is a single XORP process that manages the whole XORP router - this is called xorp_rtrmgr (short for XORP Router Manager). If you built XORP from source using the defaults, the xorp_rtrmgr binary will be in the rtrmgr subdirectory.

xorp_rtrmgr will expect to find a configuration file in the same directory it is started from. By default this configuration file is called config.boot. There are several sample configuration files in the rtrmgr/config directory - please do not use these without tailoring the IP addresses, interfaces and routing protocols to match your local network environment. You can specify a different filename for the configuration file using the -b command line flag. The -N "no execute" flag will cause xorp_rtrmgr to startup and pretend the router is operating normally, but to not actually start any processes. This can be used to check configuration files.

Typically xorp_rtrmgr must be run as root. This is because it starts up processes that need privileged access to insert routes into the forwarding path in the kernel.

If you are using the live CD, then xorp_rtrmgr should start by default after the OS has booted, and read the config.boot file from the floppy drive.

To interact with the router via the command line interface, the operator uses the XORP command shell xorpsh. If you compiled from source, this should also be in the rtrmgr subdirectory. Xorpsh should not normally be run as root, but if a user is going to change the configuration of the router (as opposed to simply monitor the router's operation) then they need to be in the "xorp" Unix group. If you are using the live CD then, by default, logging in as username xorp should cause the user's login shell to be xorpsh.

The "help" command provides basic online help. The XORP user manual (PDF) provides more detailed information about how to use xorpsh, as well as information on how to configure specific routing protocols, interface IP addresses, and so forth.

Configuring XORP

A XORP router must be configured to perform the desired operations. The configuration information can be provided in one of the two ways:

A mixture of both methods is permissible. For example, a configuration file can also be loaded from within the xorpsh.

Network Interfaces

A XORP router will only use interfaces that it has been explicitly configured to use. Even for protocols such as BGP that are agnostic to interfaces, if the next-hop router for a routing entry is not through a configured interface routes the route will not be installed. For protocols that are explicitly aware of interfaces only configured interfaces will be used.

Every physical network device in the system is considered to be an "interface". Every interface can contain a number of virtual interfaces ("vif"s). In the majority of cases the interface name and vif name will be identical and will map to the name given to the interface by the operating system. A virtual interface is configured with the address or addresses that should be used. At each level in the configuration hierarchy ("interface", "vif" and "address") this part of the configuration is implicitly enabled.

interfaces {
    restore-original-config-on-shutdown: false
    interface dc0 {
	description: "data interface"
	disable: false
	/* default-system-config */
	vif dc0 {
	    disable: false
	    address 10.10.10.10 {
		prefix-length: 24
		broadcast: 10.10.10.255
		disable: false
	    }
/*
	    address 2001:DB8:10:10:10:10:10:10 {
		prefix-length: 64
		disable: false
	    }
*/
	}
    }
}

Note: Prior to XORP Release-1.1, the "enabled" flag was used instead of "disable".

We recommend that you select the interfaces that you want to use on your system and configure them as above. If you are configuring an interface that is currently being used by the the system make sure that there is no mismatch in the "address", "prefix-length" and "broadcast" arguments. If the "default-system-config" statement is used, it instructs the FEA that the interface should be configured by using the existing interface information from the underlying system. In that case, the "vif"s and "address"es must not be configured.

Forwarding Engine Abstraction

It is a requirement to explicitly enable forwarding for each protocol family.
fea {
    unicast-forwarding4 {
        disable: false
    }

    unicast-forwarding6 {
        disable: false
    }
}
If IPv4 and IPv6 forwarding are required you will require the configuration above.

Note: Prior to XORP Release-1.1, the "enable-unicast-forwarding4" and "enable-unicast-forwarding6" flags were used instead to enable or disable the IPv4 and IPv6 forwarding.

Now that we have configured the interfaces and enabled forwarding we need to configure some routing protocols.

Protocols

Static Routes

This is the simplest routing protocol in XORP. It allows the installation of unicast or multicast static routes (either IPv4 or IPv6). Note that in case of multicast the routes are installed only in the user-level Multicast Routing Information Base and are used for multicast-specific reverse-path information by multicast routing protocols such as PIM-SM.
protocols {
    static {
	route 10.20.0.0/16 {
	    next-hop: 10.10.10.20
	    metric: 1
	}
	mrib-route 10.20.0.0/16 {
	    next-hop: 10.10.10.30
	    metric: 1
	}
/*
	route 2001:DB8:AAAA:20::/64 {
	    next-hop: 2001:DB8:10:10:10:10:10:20
	    metric: 1
	}
	mrib-route 2001:DB8:AAAA:20::/64 {
	    next-hop: 2001:DB8:10:10:10:10:10:30
	    metric: 1
	}
*/
    }
}

Note: Prior to XORP Release-1.3, the "route4" and "route6" statements were used instead of "route". Also, "mrib-route4" and "mrib-route6" statements were used instead of "mrib-route".

Routing Information Protocol

In order to run RIP it is sufficient to specify the "interface"s, "vif"s and "address"es on which RIP is enabled. Remember that each "address" must be explicitly configured.

If you wish to announce routes then it is necessary to "export" the routes that are to be announced. For example, "connected" and "static".

Note: Starting with XORP Release-1.2 policy is used to export routes into RIP with the "export" statement. Prior to XORP Release-1.2 the "export" statement was used with a different syntax.

policy {
    /* Describe connected routes for redistribution */
    policy-statement connected {
	term export {
	    from {
		protocol: "connected"
	    }
	}
    }
}

policy {
    /* Describe static routes for redistribution */
    policy-statement static {
	term export {
	    from {
		protocol: "static"
	    }
	}
    }
}

protocols {
    rip {
/* Redistribute routes for connected interfaces */
/*
	export: "connected"
*/
/* Redistribute static routes */
/*
	export: "static"
*/
/* Redistribute connected and static routes */
/*
	export: "connected,static"
*/

/* Run on specified network interface addresses */
/*
	interface dc0 {
	    vif dc0 {
		address 10.10.10.10 {
		    disable: false
		}
	    }
	}
*/
    }
}

Note: Prior to XORP Release-1.1, the "enabled" flag was used instead of "disable".

Open Shortest Path First

In order to run OSPF Version 2 or 3 the "router-id" must be specified, it is a unique IPv4 address within the Autonomous System. The smallest IP address of an interface belonging to the router is a good choice.

OSPF splits networks into areas so an "area" must be configured.

Configure one or more of the routers configured interface/vif/address in this area. In the OSPF Version 3 case an address is not required.

Note: The 4 in "ospf4" refers to the IPv4 address family.

protocols {
    ospf4 {
	router-id: 10.10.10.10

	area 0.0.0.0 {
	    interface dc0 {
		vif dc0 {
		    address 10.10.10.10 {
		    }
		}
	    }
	}
    }
}

Note: The 6 in "ospf6" refers to the IPv6 address family. OSPFv3 may run multiple instances of OSPF in the same process, therefore the "ospf6" keyword must be followed by an integer instance ID.

protocols {
    ospf6 0 {
	router-id: 10.10.10.10

	area 0.0.0.0 {
	    interface dc0 {
		vif dc0 {
		}
	    }
	}
    }
}

Border Gateway Protocol

In order to run BGP the "bgp-id" (BGP Identifier) and "local-as" (Autonomous System number) must be specified.

The "peer" statement specifies a peering. The argument to the peer statement is the IP address of the peer. The "local-ip" is the IP address that TCP should use. The "as" is the Autonomous System Number of the peer.

protocols {
    bgp {
	bgp-id: 10.10.10.10
	local-as: 65002

	peer 10.30.30.30 {
	    local-ip: 10.10.10.10
	    as: 65000
	    next-hop: 10.10.10.20
/*
	    local-port: 179
	    peer-port: 179
*/
	    /* holdtime: 120 */
	    /* disable: false */

	    /* IPv4 unicast is enabled by default */
	    /* ipv4-unicast: true */

	    /* Optionally enable other AFI/SAFI combinations */
	    /* ipv4-multicast: true */
            /* ipv6-unicast: true */
            /* ipv6-multicast: true */
	}
    }
}

Note: Prior to XORP Release-1.1, the "enabled" flag was used instead of "disable".

Multicast Forwarding Engine Abstraction

The MFEA must be configured if the XORP router is to be used for multicast routing. The MFEA for IPv4 and IPv6 are configured separately.

In the configuration we must explicitly configure the entity itself, and each "vif". The "traceoptions" section is used to explicitly enable log information that can be used for debugging purpose.

plumbing {
    mfea4 {
	disable: false
	interface dc0 {
	    vif dc0 {
		disable: false
	    }
	}
	interface register_vif {
	    vif register_vif {
		/* Note: this vif should be always enabled */
		disable: false
	    }
	}
	traceoptions {
	    flag all {
		disable: false
	    }
	}
    }
}

plumbing {
    mfea6 {
	disable: false
	interface dc0 {
	    vif dc0 {
		disable: false
	    }
	}
	interface register_vif {
	    vif register_vif {
		/* Note: this vif should be always enabled */
		disable: false
	    }
	}
	traceoptions {
	    flag all {
		disable: false
	    }
	}
    }
}

Note: Prior to XORP Release-1.1, the "enabled" flag was used instead of "disable".

Note that the interface/vif named "register_vif" is special. If PIM-SM is configured, then "register_vif" must be enabled in the MFEA.

Internet Group Management Protocol/Multicast Listener Discovery

IGMP/MLD should be configured if the XORP router is to be used for multicast routing and if we want to track multicast group membership for directly connected subnets. Typically this is the case for a multicast router, therefore it should be enabled. IGMP and MLD are configured separately: IGMP is used for tracking IPv4 multicast members; MLD is used for tracking IPv6 multicast members.

In the configuration we must explicitly configure each entity and each "vif". The "traceoptions" section is used to explicitly enable log information that can be used for debugging purpose.

protocols {
    igmp {
	disable: false
	interface dc0 {
	    vif dc0 {
		disable: false
		/* version: 2 */
		/* enable-ip-router-alert-option-check: false */
		/* query-interval: 125 */
		/* query-last-member-interval: 1 */
		/* query-response-interval: 10 */
		/* robust-count: 2 */
	    }
	}
	traceoptions {
	    flag all {
		disable: false
	    }
	}
    }
}

protocols {
    mld {
	disable: false
	interface dc0 {
	    vif dc0 {
		disable: false
		/* version: 1 */
		/* enable-ip-router-alert-option-check: false */
		/* query-interval: 125 */
		/* query-last-member-interval: 1 */
		/* query-response-interval: 10 */
		/* robust-count: 2 */
	    }
	}
	traceoptions {
	    flag all {
		disable: false
	    }
	}
    }
}

Note: Prior to XORP Release-1.1, the "enabled" flag was used instead of "disable".

Note: The "version", "enable-ip-router-alert-option-check", "query-interval", "query-last-member-interval", "query-response-interval", and "robust-count" statements appeared after XORP Release-1.1. A number of parameters have default values, therefore they don't have to be configured (those parameters are commented-out in the above sample configuration).

The "version" parameter is used to configure the MLD/IGMP protocol version per virtual interface.

The "enable-ip-router-alert-option-check" parameter is used to enable the IP Router Alert option check per virtual interface.

The "query-interval" parameter is used to configure (per virtual interface) the interval (in seconds) between general queries sent by the querier.

The "query-last-member-interval" parameter is used to configure (per virtual interface) the maximum response time (in seconds) inserted into group-specific queries sent in response to leave group messages. It is also the interval between group-specific query messages.

The "query-response-interval" parameter is used to configure (per virtual interface) the maximum response time (in seconds) inserted into the periodic general queries.

The "robust-count" parameter is used to configure the robustness variable count that allows tuning for the expected packet loss on a subnet.

Note that in case of IGMP each enabled interface must have a valid IPv4 address. In case of MLD each enabled interface must have a valid link-local IPv6 address.

Protocol Independent Multicast - Sparse Mode

PIM-SM should be configured if the XORP router is to be used for multicast routing in PIM-SM domain. PIM-SM for IPv4 and IPv6 are configured separately. At minimum, the entity itself and the virtual interfaces should be configured, as well as the mechanism for obtaining the Candidate-RP set (either the Bootstrap mechanism, or a static-RP set).
protocols {
    pimsm4 {
	disable: false
	interface dc0 {
	    vif dc0 {
		disable: false
		/* enable-ip-router-alert-option-check: false */
		/* dr-priority: 1 */
		/* hello-period: 30 */
		/* hello-triggered-delay: 5 */
		/* alternative-subnet 10.40.0.0/16 */
	    }
	}
	interface register_vif {
	    vif register_vif {
		/* Note: this vif should be always enabled */
		disable: false
	    }
	}

	static-rps {
	    rp 10.60.0.1 {
		group-prefix 224.0.0.0/4 {
		    /* rp-priority: 192 */
		    /* hash-mask-len: 30 */
		}
	    }
	}

	bootstrap {
	    disable: false
	    cand-bsr {
		scope-zone 224.0.0.0/4 {
		    /* is-scope-zone: false */
		    cand-bsr-by-vif-name: "dc0"
		    /* cand-bsr-by-vif-addr: 10.10.10.10 */
		    /* bsr-priority: 1 */
		    /* hash-mask-len: 30 */
		}
	    }

	    cand-rp {
		group-prefix 224.0.0.0/4 {
		    /* is-scope-zone: false */
		    cand-rp-by-vif-name: "dc0"
		    /* cand-rp-by-vif-addr: 10.10.10.10 */
		    /* rp-priority: 192 */
		    /* rp-holdtime: 150 */
		}
	    }
	}

	switch-to-spt-threshold {
	    /* approx. 1K bytes/s (10Kbps) threshold */
	    disable: false
	    interval: 100
	    bytes: 102400
	}

	traceoptions {
	    flag all {
		disable: false
	    }
	}
    }
}

protocols {
    pimsm6 {
	disable: false
	interface dc0 {
	    vif dc0 {
		disable: false
		/* enable-ip-router-alert-option-check: false */
		/* dr-priority: 1 */
		/* hello-period: 30 */
		/* hello-triggered-delay: 5 */
		/* alternative-subnet 2001:DB8:40:40::/64 */
	    }
	}
	interface register_vif {
	    vif register_vif {
		/* Note: this vif should be always enabled */
		disable: false
	    }
	}

	static-rps {
	    rp 2001:DB8:50:50:50:50:50:50 {
		group-prefix ff00::/8 {
		    /* rp-priority: 192 */
		    /* hash-mask-len: 126 */
		}
	    }
	}

	bootstrap {
	    disable: false
	    cand-bsr {
		scope-zone ff00::/8 {
		    /* is-scope-zone: false */
		    cand-bsr-by-vif-name: "dc0"
		    /* cand-bsr-by-vif-addr: 2001:DB8:10:10:10:10:10:10 */
		    /* bsr-priority: 1 */
		    /* hash-mask-len: 126 */
		}
	    }

	    cand-rp {
		group-prefix ff00::/8 {
		    /* is-scope-zone: false */
		    cand-rp-by-vif-name: "dc0"
		    /* cand-rp-by-vif-addr: 2001:DB8:10:10:10:10:10:10 */
		    /* rp-priority: 192 */
		    /* rp-holdtime: 150 */
		}
	    }
	}

	switch-to-spt-threshold {
	    /* approx. 1K bytes/s (10Kbps) threshold */
	    disable: false
	    interval: 100
	    bytes: 102400
	}

	traceoptions {
	    flag all {
		disable: false
	    }
	}
    }
}

Note: Prior to XORP Release-1.1, the "enabled" flag was used instead of "disable".

Note: The "enable-ip-router-alert-option-check", "cand-bsr-by-vif-addr", "cand-rp-by-vif-addr", "hello-period" and "hello-triggered-delay" statements appeared after XORP Release-1.1.

Note: Prior to XORP Release-1.3, the "interval-sec" statement was used instead of "interval".

A number of parameters have default values, therefore they don't have to be configured (those parameters are commented-out in the above sample configuration).

Note that the interface/vif named "register_vif" is special If PIM-SM is configured, then "register_vif" must be enabled.

The "enable-ip-router-alert-option-check" parameter is used to enable the IP Router Alert option check per virtual interface.

The "dr-priority" parameter is used to configure the Designated Router priority per virtual interface (note that in case of "register_vif" it is not used).

The "hello-period" parameter is used to configure the PIM Hello messages period (in seconds) per virtual interface. It must be an integer between 1 and 18724.

The "hello-triggered-delay" parameter is used to configure the randomized triggered delay of PIM Hello messages (in seconds) per virtual interface. It must be an integer between 1 and 255.

The "alternative-subnet" statement is used to add "alternative subnets" to a network interface. For example, if you want to make incoming traffic with a non-local source address appear as it is coming from a local subnet, then "alternative-subnet" can be used. Typically, this is needed as a work-around solution when we use uni-directional interfaces for receiving traffic (e.g., satellite links). Note: use "alternative-subnet" with extreme care, only if you know what you are really doing!

If PIM-SM uses static RPs, those can be configured within the "static-rps" section. For each RP, an "rp" section is needed, and each section should contain the multicast prefix address the static RP is configured with. The RP priority can be modified with the "rp-priority" parameter.

If PIM-SM uses the Bootstrap mechanism to obtain the Candidate-RP set, that can be configured in the "bootstrap" section. If the XORP router is to be used as a Candidate-BSR, this should be specified in the "cand-bsr" section. For a router to be a Candidate-BSR it must advertise for each zone (scoped or non-scoped) the associated multicast prefix address. The "cand-bsr" section should contain "scope-zone" statements for each multicast prefix address. The vif name with the address that is to be used as the Candidate-BSR is specified by the "cand-bsr-by-vif-name" statement. The particular vif's address can be specified by the "cand-bsr-by-vif-addr" statement. If the "cand-bsr-by-vif-addr" statement is omitted, a domain-wide address (if exists) that belongs to that interface is chosen by the router itself. The Candidate-BSR priority can be modified with the "bsr-priority" parameter.

If the XORP router is to be a Candidate-RP, this should be specified in the "cand-rp" section. For a router to be a Candidate-RP it must advertise for each zone (scoped or non-scoped) the associated multicast prefix address. The "cand-rp" section should contain "group-prefix" statements for each multicast prefix address. The vif name with the address that is to be used as the Candidate-RP is specified by the "cand-rp-by-vif-name" statement. The particular vif's address can be specified by the "cand-rp-by-vif-addr" statement. If the "cand-rp-by-vif-addr" statement is omitted, a domain-wide address (if exists) that belongs to that interface is chosen by the router itself. The Candidate-RP priority can be modified with the "rp-priority" parameter; the Candidate-RP holdtime can be modified with the "rp-holdtime" parameter.

The "is-scope-zone" parameter is used to specify whether a Candidate-BSR "scope-zone" or a Candidate-RP "group-prefix" is scoped. Currently, scoped zones are not well tested, hence it is recommended "scope-zone" is always set to "false". Note that typically the "hash-mask-len" should not be modified; if you don't know what "hash-mask-len" is used for, don't modify it!

The "switch-to-spt-threshold" section can be used to specify the multicast data bandwidth threshold used by the last-hop PIM-SM routers and the RPs to initiate shortest-path switch toward the multicast source. Parameter "interval" is used to specify the periodic measurement interval; parameter "bytes" is used to specify the threshold in number of bytes within the measurement interval. It is recommended that the measurement interval is not too small, and should be on the order of tens of seconds. The smallest accepted value is 3 seconds. If the shortest-path switch should happen right after the first packet is forwarded, then "bytes" should be set to 0.

The "traceoptions" section is used to explicitly enable log information that can be used for debugging purpose.

Note that in case of PIM-SM for IPv4 each enabled interface must have a valid IPv4 address. In case of PIM-SM for IPv6 each enabled interface must have a valid link-local and a valid domain-wide IPv6 addresses.

FIB2MRIB

The FIB2MRIB module is used to obtain the Forwarding Information Base information from the underlying system (via the FEA), and to propagate it to the MRIB, so it can be used by multicast routing protocols such as PIM-SM. Typically, it is needed only if the unicast routing protocols (if any) on that router do not inject routes into the MRIB.
protocols {
    fib2mrib {
	disable: false
    }
}

Note: Prior to XORP Release-1.1, the "enabled" flag was used instead of "disable".