LDP

Label Distribution Protocol (LDP) is a protocol in which routers capable of Multiprotocol Label Switching (MPLS) exchange label mapping information. Two routers with an established session are called LDP peers and the exchange of information is bi-directional. LDP is used to build and maintain LSP databases that are used to forward traffic through MPLS networks.

LDP discovery runs on UDP port 646 and the session is built on TCP port 646. During the discovery phase hello packets are sent on UDP port 646 to the ‘all routers on this subnet’ group multicast address (224.0.0.2).

LDP is defined by the IETF (RFC 5036).

Configuration

Following an example LDP configuration with one instance attached to a network interface function.

{
    "interfaces": {
        "network": [
            {
                "interface": "eth1",
                "address": "10.0.1.2/24",
                "gateway": "10.0.1.1",
                "ldp-instance-id": 1,
            }
        ]
    },
    "ldp": [
        {
            "instance-id": 1,
            "lsr-id": "10.10.10.11"
        }
    ]
}
{ "ldp": {} }

Attribute

Description

instance-id

LDP instance identifier.

keepalive-time

LDP session keepalive time in seconds.
The keepalive-time defines the local LDP session
keepalive timeout. Each LDP peer must calculate the
effective keepalive timeout by using the smaller of its
locally defined and received timeout in the PDU. The
value chosen indicates the maximum number of seconds
that may elapse between the receipt of successive PDUs
from the LDP peer on the session TCP connection. The
keepalive timeout is reset each time a PDU arrives. The
BNG Blaster will send keepalive messages at an interval
calculated by using the effective keepalive time divided
by 3. Assuming an effective keepalive time of of 15
seconds results in a keepalive interval of 5 seconds.
Default: 15 Range: 0 - 65535

hold-time

LDP hello hold time in seconds.
Default: 15 Range: 0 - 65535

teardown-time

LDP teardown time in seconds.
Default: 5 Range: 0 - 65535

hostname

LDP hostname.
Default: bngblaster

lsr-id

LDP LSR identifier.
Default: 10.10.10.10

ipv6-transport-address

LDP transport IPv6 address.
Setting a valid IPv6 address here enables LDP IPv6
hello and transport.

ipv4-transport-address

LDP transport IPv4 address.
Default: lsr-id

no-ipv4-transport

Disable/discard IPv4 LDP hello messages.

prefer-ipv4-transport

According to RFC7552, IPv6 is preferred over IPv4 which
can be changed with this option to prefer IPv4 transport
even if IPv6 is enabled.
Default: false

raw-update-file

LDP RAW update file.

Limitations

The following LDP functionalities are currently not supported:

  • Targeted LDP

  • LDP TCP authentication

  • Multiple links between LDP instance and DUT (ECMP)

LDP Adjacencies

When the BNG Blaster receives an LDP discovery hello message, an LDP adjacency is set up between the two peers.

$ sudo bngblaster-cli run.sock ldp-adjacencies

{
    "status": "ok",
    "code": 200,
    "ldp-adjacencies": [
        {
            "ldp-instance-id": 1,
            "interface": "eth0",
            "state": "up"
        }
    ]
}

LDP Sessions

LDP peers exchange messages over a TCP session which is initiated by the peer with the larger transport IP address (active peer).

The LDP transport IP address can be explicitly configured for the LDP instance using the option ipv4-transport-address. The lsr-id is used as a transport IP address if not explicitly configured.

Note

It is currently not supported to setup multiple links between a single LDP instance and the device under test (ECMP).

$ sudo bngblaster-cli run.sock ldp-sessions

{
    "status": "ok",
    "code": 200,
    "ldp-sessions": [
        {
            "ldp-instance-id": 1,
            "interface": "eth0",
            "local-address": "10.2.3.1",
            "local-identifier": "10.2.3.1:0",
            "peer-address": "10.2.3.2",
            "peer-identifier": "10.2.3.2:0",
            "state": "operational",
            "raw-update-state": "done",
            "raw-update-file": "out.ldp",
            "stats": {
                "pdu-rx": 23,
                "pdu-tx": 32,
                "messages-rx": 24,
                "messages-tx": 34,
                "keepalive-rx": 21,
                "keepalive-tx": 21
            }
        }
    ]
}

LDP Traffic Streams

Traffic streams send from network interface functions (downstream) can be configured to dynamically resolve the outer MPLS label using the learned label mappings.

The traffic stream configuration options ldp-ipv4-lookup-address and ldp-ipv6-lookup-address specifies the lookup IPv4 or IPv6 address. This means that traffic will not start until this address is found in the corresponding label database of the sending network interface function.

{
    "streams": [
        {
            "name": "S1",
            "type": "ipv4",
            "direction": "downstream",
            "priority": 128,
            "network-interface": "eth1",
            "destination-ipv4-address": "10.0.0.1",
            "ldp-ipv4-lookup-address": "13.37.0.1",
            "pps": 1
        }
    ]
}

$ sudo bngblaster-cli run.sock ldp-database instance 1

{
    "status": "ok",
    "code": 200,
    "ldp-database": [
        {
            "direction": "ipv4",
            "prefix": "10.0.0.0/24",
            "label": 3,
            "source-identifier": "10.2.3.1:0"
        },
        {
            "direction": "ipv4",
            "prefix": "13.37.0.0/32",
            "label": 10000,
            "source-identifier": "10.2.3.1:0"
        },
        {
            "direction": "ipv4",
            "prefix": "13.37.0.1/32",
            "label": 10001,
            "source-identifier": "10.2.3.1:0"
        }
    ]
}

The ldp-ipv4-lookup-address and ldp-ipv6-lookup-address are mutually exclusive and must exactly match the prefix address as shown in the LDP database. This means that if the prefix is 10.0.0.0/24, the lookup address should be 10.0.0.0.

Note

There is currently no longest prefix match supported, meaning that the actual prefix length is ignored!

RAW Update Files

The BNG Blaster can inject LDP PDU from a pre-compiled RAW update file into the defined sessions. A RAW update file is not more than a pre-compiled binary stream of LDP PDU.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Version                      |         PDU Length            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         LDP Identifier                        |
+                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                         LDP Messages
.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Version                      |         PDU Length            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         LDP Identifier                        |
+                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                         LDP Messages
.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Those files can be created using the included LDP RAW update generator script ldpupdate or manually using libraries like scapy.

The configured raw-update-file under the LDP instance is loaded during BNG Blaster startup phase and send it as soon as the session is established.

The ldp-raw-update command allows to send further updates during the session lifetime.

$ sudo bngblaster-cli run.sock ldp-raw-update file update1.ldp

This allows loading label mappings after the LDP session has started and manually trigger a series of changes using incremental updates files.

All LDP RAW update files are loaded once and can then be used for multiple sessions. Meaning if two or more sessions reference the same file identified by file name, this file is loaded once into memory and used by multiple sessions.

LDP RAW Update Generator

The LDP RAW update generator is a simple tool to generate LDP RAW update streams for use with the BNG Blaster.

$ ldpupdate --help
usage: ldpupdate [-h] -l ADDRESS [-i N] [-w] [-a ADDRESS] [-A N] [-p PREFIX] [-P N] [-m LABEL] [-M N] [-f FILE] [--append] [--pcap FILE] [--log-level {warning,info,debug}]

The LDP RAW update generator is a simple tool to generate LDP RAW update streams for use with the BNG Blaster.

optional arguments:
-h, --help            show this help message and exit
-l ADDRESS, --lsr-id ADDRESS
                        LSR identifier
-i N, --message-id-base N
                        message identifier base
-w, --withdraw        withdraw
-a ADDRESS, --address-base ADDRESS
                        address message base
-A N, --address-num N
                        address message count
-p PREFIX, --prefix-base PREFIX
                        label mapping base prefix
-P N, --prefix-num N  label mapping prefix count
-m LABEL, --label-base LABEL
                        label base
-M N, --label-num N   label count
-f FILE, --file FILE  output file
--append              append to file if exist
--pcap FILE           write LDP updates to PCAP file
--log-level {warning,info,debug}
                        logging Level

The python LDP RAW update generator is a python script that uses scapy to build LDP PDU. Therefore this tool can be easily modified, extend or used as a blueprint for your own tools to generate valid LDP update streams.