Route BGP with BIRD

    Bird is an open source routing daemon for Unix-like systems. It can be used to establish bgp sessions between client instances and the packet network.

    An elastic IP address can simply be announced via Bird from the instance that is currently using it, thereby making it easy to freely move the IP from one instance to another within the same project.

    Getting Started

    If you haven't already requested that BGP be added to your account you'll need to get that sorted before continuing with this guide - see more info about getting started here.

    Choose an IP to Broadcast

    Navigate over to IPs & Networks in your BGP enabled project and click on Manage Block for the IPv4 block in the data center location that corresponds with your server deployment. Choose an available IP that will act as your broadcast IP. In this guide, we'll be using

    manage-ips manage-ips-2

    Update Network Interface

    Update the network interfaces with a virtual loopback interface.

    cat >>/etc/network/interfaces <<EOF
    auto lo:0
    iface lo:0 inet static

    Bring Up the Interface

    ifup lo:0


    First install system dependencies. On Ubuntu 18.04 this looks like:

    apt -y update && apt -y install python3.6 python3-pip git bird

    Now clone the repo and install remaining python dependencies:

    cd /opt
    git clone
    cd network-helpers
    pip3 install jmespath
    pip3 install -e .

    Now use the script to configure bird:

    ./ -r bird | tee /etc/bird/bird.conf
    filter packet_bgp {
      # the IP range(s) to announce via BGP from this machine
      # these IP addresses need to be bound to the lo interface
      # to be reachable; the default behavior is to accept all
      # prefixes bound to interface lo
      # if net = A.B.C.D/32 then accept;
    router id;
    protocol direct {
      interface "lo"; # Restrict network interfaces BIRD works with
    protocol kernel {
      persist; # Don't remove routes on bird shutdown
      scan time 20; # Scan kernel routing table every 20 seconds
      import all; # Default is import all
      export all; # Default is export none
    # This pseudo-protocol watches all interface up/down events.
    protocol device {
      scan time 10; # Scan interfaces every 10 seconds
    protocol bgp neighbor_v4_1 {
      export filter packet_bgp;
      local as 65000;
      neighbor as 65530;
      password "somepassword";

    Check that the config looks correct, then restart bird:

    systemctl restart bird

    And verify:

    bird> show protocols all neighbor_v4_1
    name     proto    table    state  since       info
    neighbor_v4_1 BGP      master   up     15:20:31    Established   
      Preference:     100
      Input filter:   ACCEPT
      Output filter:  packet_bgp
      Routes:         0 imported, 1 exported, 0 preferred
      Route change stats:     received   rejected   filtered    ignored   accepted
        Import updates:              0          0          0          0          0
        Import withdraws:            0          0        ---          0          0
        Export updates:              1          0          0        ---          1
        Export withdraws:            0        ---        ---        ---          0
      BGP state:          Established
        Neighbor address:
        Neighbor AS:      65530
        Neighbor ID:
        Neighbor caps:    refresh restart-aware AS4
        Session:          external AS4
        Source address:
        Hold timer:       66/90
        Keepalive timer:  18/30

    In this case we only have a single elastic IP bound to interface lo, and we see the prefix is being exported and accepted so we are done.

    Note: Bird uses separate daemons for IPv4 and IPv6 routing. To configure bgp over IPv6 using bird, the process will be the same as above, except that the configuration command you will use will be:

    ./ -r bird6 | tee /etc/bird/bird6.conf


    systemctl restart bird6

    In this case we only have a single elastic IP bound to interface lo, and we see the prefix is being exported and accepted so we are done.

    To test, you can ping the IP address in a command line - ping Remember, Local BGP is announcing a private IP address, so you'll have to be connected to the private network for the data center you're running Local BGP in. You can do that by SSHing into another server in that data center or by connected to Doorman, Packet's private VPN.

    Congratulations! You've just configured a BGP routing protocol.

    Alternative Method

    For those interested, bird can also be automatically deployed via docker. See more here.

    Was it helpful?