Category Archives: Ubuntu

Configuring a Dual Stacked DHCP Server

Reading Time: 4 minutes

As part of my IPv6 Testing, I needed to test whether we would either use SLAAC or DHCPv6 in a particular situation. Having never setup a DHCP server before, of course, I had to write a post on how I did it 😀

Dynamic Host Configuration Protocol or DHCP is defined in RFC2131:

The Dynamic Host Configuration Protocol (DHCP) provides configuration parameters to Internet hosts. DHCP consists of two components: a protocol for delivering host-specific configuration parameters from a DHCP server to a host and a mechanism for allocation of network addresses to hosts.

DHCP supports three mechanisms of IP address allocation; Automatic, Dynamic and Manual allocation. RFC2131: describes how each of these mechanisms works within the DHCP process

Dynamic allocation is the only one of the three mechanisms that allows automatic reuse of an address that is no longer needed by the client to which it was assigned. Thus, dynamic allocation is particularly useful for assigning an address to a client that will be connected to the network only temporarily or for sharing a limited pool of IP addresses among a group of clients that do not need permanent IP addresses. Dynamic allocation may also be a good choice for assigning an IP address to a new client being permanently connected to a network where IP addresses are sufficiently scarce that it is important to reclaim them when old clients are retired. Manual allocation allows DHCP to be used to eliminate the error-prone process of manually configuring hosts with IP addresses in environments where (for whatever reasons) it is desirable to manage IP address assignment outside of the DHCP mechanisms.

In a nutshell:

  • Automatic allocation; the DHCP process will assign a permanent IP address to the host/device.
  • Dynamic allocation; the DHCP assigns an IP address to a client for a limited period of time or until the client release the address.
  • Manual allocation; the a client’s IP address is assigned by the network administrator, and DHCP is used simply to convey the assigned address to the client.

With DHCPv6 the communication process between server and client is a little different compared DHCPv4, as explained in RFC3315:

Clients and servers exchange DHCP messages using UDP. The client uses a link-local address or addresses determined through other mechanisms for transmitting and receiving DHCP messages. DHCP servers receive messages from clients using a reserved, link-scoped multicast address. A DHCP client transmits most messages to this reserved multicast address, so that the client need not be configured with the address or addresses of DHCP servers.

To allow a DHCP client to send a message to a DHCP server that is not attached to the same link, a DHCP relay agent on the client’s link will relay messages between the client and server. The operation of the relay agent is transparent to the client and the discussion of message exchanges in the remainder of this section will omit the description of message relaying by relay agents. Once the client has determined the address of a server, it may under some circumstances send messages directly to the server using unicast.

NOTE
For more in-depth detail about the DHCP and DHCPv6, I would suggest looking into RFC2131 and RFC3315 respectfully.

For this testing, I used a two ESXi Ubuntu 14.04LTS Hosts, one as the DHCP server and client, and the other was a Juniper EX4200 connecting them together. The switch configuration is extremely basic, both devices are in the same Vlan and the Vlan has a layer-3 interface IPv4: 192.168.1.1/24 and IPv6: 2001:192:168:1::1/64.

With all the talk out of way.. Let’s get cracking 🙂

You will need to have sudo or root privileges

Firstly, a static IPv4 and IPv6 will need to be set on the interface that will be advertising the DHCP to the LAN. For my example I’m using eth1

[email protected]:~$ ifconfig -a eth1
eth1      Link encap:Ethernet  HWaddr 00:0c:29:d3:ac:77  
          inet addr:192.168.1.2  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fed3:ac77/64 Scope:Link
          inet6 addr: 2001:192:168:1::2/64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:43 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1308 (1.3 KB)  TX bytes:4204 (4.2 KB)

The DHCP package is available via the apt-get repository

sudo apt-get install isc-dhcp-server

You will need to edit /etc/default/isc-dhcp-server and set the NIC that you want to run DHCP from. In addition, you need to set options with “-6” flag to tell the package we’ll be running IPv6. For my server, I’ll be using interface “eth1”. Make you use the appropriate NIC in your configuration.

[email protected]:~$ cat /etc/default/isc-dhcp-server 
# Defaults for isc-dhcp-server initscript
# sourced by /etc/init.d/isc-dhcp-server
# installed at /etc/default/isc-dhcp-server by the maintainer scripts

#
# This is a POSIX shell fragment
#

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPD_CONF=/etc/dhcp/dhcpd.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPD_PID=/var/run/dhcpd.pid

# Additional options to start dhcpd with.
#    Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
OPTIONS="-6"

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#    Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth1"

From doing some digging, unfortunately the original isc-dhcp-server doesn’t allow you to run IPv4 and IPv6 under the same config file. I had to create a new file and edit it to be IPv6 specific. I backed the original dhcpd.conf file and created a new dhcpd6.conf file; the two files should look similar to the below if you have a simple set up like myself.

Note
With a DHCP server you can have the server configured to set DNS, hostnames and other administrative settings. You can see examples of this if you look at the full original dhcpd.conf file. This is out of scope of what I was testing currently, but with knowing what else I’ll be testing in the future I’ll likely shown how in a future post 🙂
dhcpd6.confdhcpd.conf
[email protected]:~$ cat /etc/dhcp/dhcpd6.conf 
# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed.
ddns-update-style none;

# Option definitions common to all supported networks...
default-lease-time 600; 
max-lease-time 7200; 

# This DHCP server is the official DHCP server for the local network
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;
 
# Subnet declaration
subnet6 2001:192:168:1::/64  {
    range6 2001:192:168:1::110 2001:192:168:1::120;
}
[email protected]:~$ cat /etc/dhcp/dhcpd.conf 
#
# Sample configuration file for ISC dhcpd for Debian
#
# Attention: If /etc/ltsp/dhcpd.conf exists, that will be used as
# configuration file instead of this file.
#
#

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# This is a very basic subnet declaration.

subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.110 192.168.1.120;
}

An DHCPv6 lease file will need to be created because, unlike IPv4, there isn’t a predefined file. In addition this file will need to have its owner changed to dhcpd daemon. This is because the daemon will need write, read and execute permissions

sudo touch /var/lib/dhcp/dhcpd6.leases
sudo chown dhcpd:dhcpd /var/lib/dhcp/dhcpd6.leases

To finish up on the server, we will need to start the DCHP processes

sudo service isc-dhcp-server start
sudo service isc-dhcp-server6 start

Once this has been done, the server is configured. Next we will hop to the other VM to see if we can get some IP addresses assigned!

Once on the client, we have to set its interface to listening for DHCP packets. Under /etc/network/interfaces both for IPv4 and IPv6 we will need to DHCP.

[email protected]:~$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
{...}
auto eth1
iface eth1 inet dhcp

# This is an autoconfigured IPv6 interface
iface eth0 inet6 auto

auto eth1
iface eth1 inet6 dhcp

Once this has been set, the interface will automatically pick up an address. If you’re like me and want to see everything, you can manually release any addresses learnt by using the following commands: for IPv6 dhclient -6 -v -r eth1 and for IPv4 dhclient -v -r eth1

dhclient -v -r eth1dhclient -6 -v -r eth1
[email protected]:~$ sudo dhclient -v -r eth1
[sudo] password for marquk01: 
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth1/00:0c:29:4f:26:c5
Sending on   LPF/eth1/00:0c:29:4f:26:c5
Sending on   Socket/fallback
DHCPRELEASE on eth1 to 192.168.1.2 port 67 (xid=0x45baa909)
[email protected]:~$ sudo dhclient -6 -v -r eth1
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Bound to *:546
Listening on Socket/eth1
Sending on   Socket/eth1
RTNETLINK answers: Cannot assign requested address
XMT: Forming Release, 0 ms elapsed.
XMT:  X-- IA_NA 29:4f:26:c5
XMT:  | X-- Release Address 2001:192:168:1::111
XMT:  V IA_NA appended.
XMT: Release on eth1, interval 1000ms.
RCV: Reply message on eth1 from fe80::20c:29ff:fed3:ac77.
RCV:  X-- Server ID: 00:01:00:01:1d:dc:60:db:00:0c:29:d3:ac:77
message status code Success: "Release received."

Running an ifconfig will show that eth1 has no IP addresses set (except for its link-local address)

[email protected]:~$ ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 00:0c:29:4f:26:c5  
          inet6 addr: fe80::20c:29ff:fe4f:26c5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3487 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1272 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:501952 (501.9 KB)  TX bytes:267192 (267.1 KB)

Now we can request addresses from DHCP server to bind the next available IP addresses to km-vm1 by using the command for IPv4 dhclient -v eth1 and for IPv6 dhclient -6 -v eth1 respectfully.

dhclient -v eth1dhclient -6 -v eth1
[email protected]:~$ sudo dhclient -v eth1
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth1/00:0c:29:4f:26:c5
Sending on   LPF/eth1/00:0c:29:4f:26:c5
Sending on   Socket/fallback
DHCPDISCOVER on eth1 to 255.255.255.255 port 67 interval 3 (xid=0x7cae5613)
DHCPREQUEST of 192.168.1.112 on eth1 to 255.255.255.255 port 67 (xid=0x1356ae7c)
DHCPOFFER of 192.168.1.112 from 192.168.1.2
DHCPACK of 192.168.1.112 from 192.168.1.2
bound to 192.168.1.112 -- renewal in 230 seconds.
[email protected]:~$ sudo dhclient -6 -v eth1
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Bound to *:546
Listening on Socket/eth1
Sending on   Socket/eth1
PRC: Soliciting for leases (INIT).
XMT: Forming Solicit, 0 ms elapsed.
XMT:  X-- IA_NA 29:4f:26:c5
XMT:  | X-- Request renew in  +3600
XMT:  | X-- Request rebind in +5400
XMT:  | X-- Request address 2001:192:168:1::111.
XMT:  | | X-- Request preferred in +7200
XMT:  | | X-- Request valid in     +10800
XMT: Solicit on eth1, interval 1050ms.
RCV: Advertise message on eth1 from fe80::20c:29ff:fed3:ac77.
RCV:  X-- IA_NA 29:4f:26:c5
RCV:  | X-- starts 1447710742
RCV:  | X-- t1 - renew  +0
RCV:  | X-- t2 - rebind +0
RCV:  | X-- [Options]
RCV:  | | X-- IAADDR 2001:192:168:1::111
RCV:  | | | X-- Preferred lifetime 7200.
RCV:  | | | X-- Max lifetime 43200.
RCV:  X-- Server ID: 00:01:00:01:1d:dc:60:db:00:0c:29:d3:ac:77
RCV:  Advertisement recorded.
PRC: Selecting best advertised lease.
PRC: Considering best lease.
PRC:  X-- Initial candidate 00:01:00:01:1d:dc:60:db:00:0c:29:d3:ac:77 (s: 153, p: 0).
XMT: Forming Request, 0 ms elapsed.
XMT:  X-- IA_NA 29:4f:26:c5
XMT:  | X-- Requested renew  +3600
XMT:  | X-- Requested rebind +5400
XMT:  | | X-- IAADDR 2001:192:168:1::111
XMT:  | | | X-- Preferred lifetime +7200
XMT:  | | | X-- Max lifetime +7500
XMT:  V IA_NA appended.
XMT: Request on eth1, interval 1040ms.
RCV: Reply message on eth1 from fe80::20c:29ff:fed3:ac77.
RCV:  X-- IA_NA 29:4f:26:c5
RCV:  | X-- starts 1447710744
RCV:  | X-- t1 - renew  +0
RCV:  | X-- t2 - rebind +0
RCV:  | X-- [Options]
RCV:  | | X-- IAADDR 2001:192:168:1::111
RCV:  | | | X-- Preferred lifetime 7200.
RCV:  | | | X-- Max lifetime 43200.
RCV:  X-- Server ID: 00:01:00:01:1d:dc:60:db:00:0c:29:d3:ac:77
PRC: Bound to lease 00:01:00:01:1d:dc:60:db:00:0c:29:d3:ac:77.

We can confirm by using ifconfig again:

[email protected]:~$ ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 00:0c:29:4f:26:c5  
          inet addr:192.168.1.110  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe4f:26c5/64 Scope:Link
          inet6 addr: 2001:192:168:1::111/64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3647 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1365 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:519662 (519.6 KB)  TX bytes:292435 (292.4 KB)

And with that, we now have a Dual Stacked DHCP server! Although this looks quite straightforward, now I’ll tell you that it took me a few days to get understand and get the IPv6 side of things working as expected. There was plenty of googling, troubleshooting, screen staring and frustration with this one, but I have to give major props to a great page by Jochen Kirstätter on how the IPv6 side of install was done if I hadn’t have found it, I would still be poking in the dark *covers face*! You will find some great nuggets on Jochen’s blog here 🙂

Share this:
Share

IPv6 and Junos – Stateless Address Autoconfiguration (SLAAC)

Reading Time: 3 minutes

From my research and testing, I’ve notice there are a few ways you can set IPv6 addresses to hosts. Essentially you have 3 methods; manually setting a Static IP address, Using Stateful Dynamic Address allocation via a DHCPv6 server, or by using Stateless Dynamic Address allocation. The first two methods are pretty standard as addressing with IPv4 is done this way however, the last method is new method that comes with IPv6 and this is actually known as Stateless Address Autoconfiguration (SLAAC). SLAAC, as its name suggestions, allows a host to auto configure itself without any manual intervention.

RFC4862 describe the SLAAC as

The IPv6 stateless autoconfiguration mechanism requires no manual configuration of hosts, minimal (if any) configuration of routers, and no additional servers. The stateless mechanism allows a host to generate its own addresses using a combination of locally available information and information advertised by routers. Routers advertise prefixes that identify the subnet(s) associated with a link, while hosts generate an “interface identifier” that uniquely identifies an interface on a subnet. An address is formed by combining the two. In the absence of routers, a host can only generate link-local addresses. However, link-local addresses are sufficient for allowing communication among nodes attached to the same link.

In essence, when using SLAAC to get the full 128-bit IPv6 address, it uses the 64-bit prefix that is advertised by the host or router for the first half, then in conjunction with the EUI-64 process, is able to allocation the second 64-bit of the address.

Note
The EUI-64 process in a nutshell, is the method of extending the 48-bit MAC Address and making it into a 64-bit value. This is done by splitting the 48-bit address into two 24-bit halves and adding the 16-bit hex value 0xFFFE in middle to create the last 64-bits

Configuring SLAAC

Enabling SLAAC with Junos is pretty straightforward. For my example, I’ve got an EX4200 connected to an Ubuntu 14.04LTS ESXi host in Vlan 200.

Before enabling the switch, the host’s interface has to be set to auto

[email protected]:~$ cat /etc/network/interfaces
{...}
# This is an autoconfigured IPv6 interface
iface eth0 inet6 auto

auto eth1
iface eth1 inet6 auto

Once that’s done, to make sure no address was learnt as I configured the switch, the interface was disabled using ifdown.

With the switch configuration, under the protocol router-advertisement stanza, the interface and the prefix (first 64-bits) that will be advertised need to be set. Additionally I enabled a traceoption to see the process from the switch’s perspective.

Interface ConfigurationEnabling SLAAC
{master:0}[edit]
[email protected]# show interfaces vlan unit 200 
family inet6 {
    address 2001:192:168:2::1/64;
}
{master:0}[edit protocols router-advertisement]
[email protected]# show 
traceoptions {
    file RA.log;
    flag all;
}
interface vlan.200 {
    prefix 2001:192:168:2::/64;
}

Verification

With that SLAAC has been enabled, simple isn’t it 🙂

Now, back on the host, I re-enabled the interface using ifup. By using ifconfig we can see that the IPv6 address has been auto configured onto the host.

[email protected]:~$ ifconfig -a eth1
eth1      Link encap:Ethernet  HWaddr 00:0c:29:4f:26:c5  
          inet addr:192.31.1.2  Bcast:192.31.1.255  Mask:255.255.255.0
          inet6 addr: 2001:192:168:2:20c:29ff:fe4f:26c5/64 Scope:Global
          inet6 addr: fe80::20c:29ff:fe4f:26c5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:40 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:563 (563.0 B)  TX bytes:2334 (2.3 KB)

By looking closer at the ifconfig output, we can see how the EUI-64 process has been used to allocate the IPv6 address, as well as its link-local address:

eth1      Link encap:Ethernet  HWaddr 00:0c:29:4f:26:c5  
          inet6 addr: 2001:192:168:2:20c:29ff:fe4f:26c5/64 Scope:Global
          inet6 addr: fe80::20c:29ff:fe4f:26c5/64 Scope:Link

On the switch, by running the commands: show ipv6 neighbours, we can see the hosts’ link-local and SLAAC allocated addresses, both discovered by the Neighbour Discovery Protocol (NDP). And show ipv6 router-advertisement, which shows how many RA’s and RS’ have been sent and received by the switch.

IPv6 NeighborsRouter Advertisements
{master:0}
[email protected]> show ipv6 neighbors 
IPv6 Address                 Linklayer Address  State       Exp Rtr Secure Interface
2001:192:168:2:20c:29ff:fe4f:26c5
                             00:0c:29:4f:26:c5  stale       1110 no no      vlan.200    
fe80::20c:29ff:fe4f:26c5     00:0c:29:4f:26:c5  stale       1039 no no      vlan.200
{master:0}
[email protected]> show ipv6 router-advertisement 
Interface: vlan.200
  Advertisements sent: 4, last sent 00:04:45 ago
  Solicits received: 2, last received 00:04:46 ago
  Advertisements received: 0

When we look further at the traceoption, we can see the request from the host sent out Router Solicitation (RS) via its link-local address, to the destination of ff02::2 for the presence of routers (in this case a switch) on the link. The switch replies by sending a Router Advertisement (RA) to ff02::1 with the Router’s presence and link prefixes, MTU, and hop limits.

{Apr  7 06:29:13.002388 background dispatch running job ipv6_ra_delete_interface_config_job for task Router-Advertisement
Apr  7 06:29:13.002436 task_job_delete: delete background job ipv6_ra_delete_interface_config_job for task Router-Advertisement
Apr  7 06:29:13.002473 background dispatch completed job ipv6_ra_delete_interface_config_job for task Router-Advertisement
Apr  7 06:29:48.645889 ipv6_ra_receive_solicit: received solicit from fe80::20c:29ff:fe4f:26c5
Apr  7 06:29:48.646013 ipv6_ra_receive_solicit: task Router-Advertisement src fe80::20c:29ff:fe4f:26c5 dst ff02::2 hdr 0x26fc000 count 16 intf 0x283c0e8
Apr  7 06:29:48.646086 task_timer_reset: reset Router-Advertisement_ipv6ra
Apr  7 06:29:48.646137 task_timer_set_oneshot_latest: timer Router-Advertisement_ipv6ra interval set to 0.426219
Apr  7 06:29:49.073743 task_job_create_foreground: create job ipv6 ra for task Router-Advertisement
Apr  7 06:29:49.073857 foreground dispatch running job ipv6 ra for task Router-Advertisement
Apr  7 06:29:49.073978 ipv6_ra_send_advertisement: sending advertisement for ifl 73 to ff02::1
Apr  7 06:29:49.074018 (519322) sending advertisement for ifl 73
Apr  7 06:29:49.074106 	ifa 0x28383f0 2001:192:168:2::1/64
Apr  7 06:29:49.074942 	--> sent 56 bytes
Note
The ff02::1 and ff02::2 addresses are well-known IPv6 Multicast addresses that a host sends out to a RS, to all devices within the all-host multicast group for ff02::2, and for a router, the address ff02::1 is used to reply RS with RA. Although this process could be compared to the IPv4 broadcast address 255.255.255.255, its important to remember that broadcasts are not accepted by any IPv6 protocol.

SLAAC is a really useful way of easily enabling IPv6 across your network and let the host and devices auto configure themselves. In addition, as the EUI-64 process is key to SLAAC, as long as you keep a record of the MAC Addresses of each device, you’ll always be able to know what address goes with what device. Of course, there will be situations where Static or DHCP addressing will be more suitable however; if you need to quickly enable your network with IPv6 then SLAAC is the way to go!

Share this:
Share

Configuring BGP using Bird on Ubuntu 14.04LTS

Reading Time: 3 minutes

As part of the QFX testing I’ve been doing at work, I’ve had to do the testing of running BGP between a switch and server. Although one of my seniors advised I could just test BGP between two switches, as BGP is BGP, and should work whether it’s a switch or server, the protocol is the same and should simply work. However, given the chance to learn something new, I went with it and thought this would be the perfect chance for a new post! I found out that our production servers use EXaBGP daemon. I looked into the configuration and the specs for EXaBGP…. Let just say was pretty lost very quickly (being polite)! I then started looking into alternative daemons and found BIRD. I had heard of BIRD before and from my research it didn’t look as complex as EXaBGP.

The BIRD project was developed as a school project at the Faculty of Mathematics and Physics at Charles University in Prague, with major contributions from developers Martin Mares, Pavel Machek, Ondrej Zajicek, Libor Forst and Ondrej Filip. Designed for a UNIX based system, BIRD is an open source daemon that runs an Internet protocol suite. It can run a number of Dynamic Routing Protocols: BGP, OSPF, RIP, Static Routing, Both IPv4 and IPv6 and can hold Multiple Routing Tables.

I had found a perfect post from mindless.gr that went into detail on how to configure a simple IPv4/IPv6 BGP session using BIRD, which was exactly what I needed.

With that in mind, this post will detail how to configure a simple IPv4 BGP session using BIRD on Ubuntu 14.04LTS

Let’s get Cracking 😛

You will need sudo and root privileges

You will be able to make the changes here with sudo privileges. You need to install the BIRD package, which is nicely available via Ubuntu’s Advanced Packaging Tool apt-get install bird

[email protected]:~$ apt-get install bird6

By default any modern Linux distribution will have IP Forwarding disabled; we’ll need the server to basically act as a router and we’ll need to have IP Forwarding enabled. Running the command sysctl net.ipv4.ip_forward=1 will enable IPv4 forwarding. You can also make this a permanent change so that on boot, IP forwarding will always been enabled. You will need to edit /etc/sysctl.conf file. Check below for what you need to look out for and uncomment:

[email protected]:~$ cat /etc/sysctl.conf
{...}
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#  Enabling this option disables Stateless Address Autoconfiguration
#  based on Router Advertisements for this host
#net.ipv6.conf.all.forwarding=1
{...}

Backup the original bird.conf by running something like cp bird.conf bird.old.conf (always need to cover your ass :p lol)

The config file looks quite complex at first appearance (when this was written I didn’t have a clue about any of it!!). If you want more detailed information about the config file and the different options available you can find them on the Bird Internet Routing Daemon: User’s Guide Page

For my example, I needed a simple configuration that had the server advertise 4 routes (3 x /24 and /22) and accept all routes. This was the same setup on the switch side, which is a Juniper QFX5100.

To edit the bird.conf file, you’ll need it to be root. I tried a sudo nano however I got Permission Denied! So I sudo -s down to root and edited the conf file

[email protected]:~$ sudo -s
[sudo] password for marquk01: 
[email protected]:~# nano /etc/bird/bird.conf
Bird.confSwitch Configuration
[email protected]:~$ sudo cat /etc/bird/bird.conf
[sudo] password for marquk01: 
/*
 *	This is an example configuration file.
 */

# Yes, even shell-like comments work...

# Configure logging
log syslog all;

# Override router ID
router id 192.31.1.3;

# This pseudo-protocol performs synchronization between BIRD's routing
# tables and the kernel. If your kernel supports multiple routing tables
# (as Linux 2.2.x does), you can run multiple instances of the kernel
# protocol and synchronize different kernel tables with different BIRD tables.
protocol kernel {
#	learn;			# Learn all alien routes from the kernel
	persist;		# Don't remove routes on bird shutdown
	scan time 20;		# Scan kernel routing table every 20 seconds
#	import none;		# Default is import all
	export all;		# Default is export none
#	kernel table 5;		# Kernel table to synchronize with (default: main)
}

# This pseudo-protocol watches all interface up/down events.
protocol device {
	scan time 10;		# Scan interfaces every 10 seconds
}

# Static routes (again, there can be multiple instances, so that you
# can disable/enable various groups of static routes on the fly).
protocol static static_bgp {
	route 192.70.0.0:255.255.252.0 via 192.31.1.3;
	route 192.70.1.0:255.255.255.0 via 192.31.1.3;
	route 192.70.1.0:255.255.255.0 via 192.31.1.3;
	route 192.70.2.0:255.255.255.0 via 192.31.1.3;
	route 192.70.3.0:255.255.255.0 via 192.31.1.3;
}

#BGP Configuration
protocol bgp {
        import all;
        export where proto = "static_bgp";

        local as 3000;
        neighbor 192.31.1.2 as 4000;
}
set interfaces xe-0/0/4 description "km-vm3 10GB"
set interfaces xe-0/0/4 enable
set interfaces xe-0/0/4 unit 0 family inet address 192.31.1.2/31
set routing-options static route 192.69.0.0/24 reject
set routing-options static route 192.69.1.0/24 reject
set routing-options static route 192.69.2.0/24 reject
set routing-options static route 192.69.3.0/24 reject
set routing-options autonomous-system 4000
set protocols bgp enable
set protocols bgp local-as 4000
set protocols bgp group test local-address 192.31.1.2
set protocols bgp group test family inet unicast
set protocols bgp group test neighbor 192.31.1.3 export BGP-Export
set protocols bgp group test neighbor 192.31.1.3 peer-as 3000
set policy-options policy-statement BGP-Export from protocol static
set policy-options policy-statement BGP-Export then accept

Having configured the switch and the server, I needed to enable to the bird daemon. This was done by running the command invoke-rc.d bird start

[email protected]:~$ invoke-rc.d bird start

To enter the bird client, you will need to run the command birdc and from there you’re able to run a verification command to check that routes are being advertised and received from server to the switch.

[email protected]:~$ sudo birdc
[sudo] password for marquk01: 
BIRD 1.4.0 ready.
bird>

From the bird client, you can run show route to see the RIB table and to check the BGP status you will run show protocols all bgp1

show routeshow protocols all bgp1
bird> show route 
192.69.0.0/24      via 192.31.1.2 on eth1 [bgp1 11:35:14] * (100) [AS4000i]
192.69.1.0/24      via 192.31.1.2 on eth1 [bgp1 11:35:14] * (100) [AS4000i]
192.69.2.0/24      via 192.31.1.2 on eth1 [bgp1 11:35:14] * (100) [AS4000i]
192.69.3.0/24      via 192.31.1.2 on eth1 [bgp1 11:35:14] * (100) [AS4000i]
192.70.0.0/22      via 192.31.1.3 on eth1 [static_bgp 13:50:05] ! (200)
192.70.1.0/24      via 192.31.1.3 on eth1 [static_bgp 11:35:09] ! (200)
192.70.2.0/24      via 192.31.1.3 on eth1 [static_bgp 11:35:09] ! (200)
192.70.3.0/24      via 192.31.1.3 on eth1 [static_bgp 11:35:09] ! (200)
bird> show protocols all bgp1
name     proto    table    state  since       info
bgp1     BGP      master   up     11:35:14    Established   
  Preference:     100
  Input filter:   ACCEPT
  Output filter:  (unnamed)
  Routes:         4 imported, 4 exported, 4 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:              4          0          0          0          4
    Import withdraws:            0          0        ---          0          0
    Export updates:              9          4          0        ---          5
    Export withdraws:            0        ---        ---        ---          0
  BGP state:          Established
    Neighbor address: 192.31.1.2
    Neighbor AS:      4000
    Neighbor ID:      10.1.0.241
    Neighbor caps:    refresh AS4
    Session:          external AS4
    Source address:   192.31.1.3
    Hold timer:       52/90
    Keepalive timer:  18/30

On the switch, we can check when the BGP session is up and can see what routes that are being adverted and what routes are being received:

show bgp summaryshow route advertising-protocol bgpshow route receive-protocol bgp
{master:0}
[email protected]> show bgp summary group test    
Groups: 1 Peers: 1 Down peers: 0
Table          Tot Paths  Act Paths Suppressed    History Damp State    Pending
inet.0               
                       4          4          0          0          0          0
Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
192.31.1.3             3000         79         79       0       1       33:43 4/4/4/0              0/0/0/0
{master:0}
[email protected]> show route advertising-protocol bgp 192.31.1.3

inet.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
* 192.69.0.0/24           Self                                    I
* 192.69.1.0/24           Self                                    I
* 192.69.2.0/24           Self                                    I
* 192.69.3.0/24           Self                                    I
{master:0}
[email protected]> show route receive-protocol bgp 192.31.1.3                                                          

inet.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
* 192.70.0.0/22           192.31.1.3                              3000 I
* 192.70.1.0/24           192.31.1.3                              3000 I
* 192.70.2.0/24           192.31.1.3                              3000 I
* 192.70.3.0/24           192.31.1.3                              3000 I

You can enable BIRD for IPv6 as well. The editing and process is exactly the same however you’ll need to edit the /etc/bird/bird6.conf file with the appropriate IPv6 addressing. To enter the IPv6 BIRD client you’ll use the command birdc6.

Being able to spin up VMs and have them configured as “dumb” BGP nodes is such a useful thing to have in a lab when you don’t have as many switches/routers as you need. From what I can see Bird can be a extremely useful tool for connecting BGP routes and I see that many Internet Exchange Points (IXPs) such as London Internet Exchange (LINX), London Network Access Point (LONAP), Deutscher Commercial Internet Exchange (DE-CIX), Amsterdam Internet Exchange (AMS-IX) and many more use BIRD for their Route Server. When I get a chance I will defiantly look into how to get the most out of BIRD!

You can find all the documentation and user guides on BIRD on the official website here

Share this:
Share

Manually changing an Active Slave in a Bond-Type 1 Configuration

Reading Time: 2 minutes

As I was doing testing in my previous post, I ran into an issue where I had configured bond-type 1 (Active-Backup) interface however Active Slave never failed over when I disconnected the interface. For the life of me, I didn’t have a clue why! Subsequently, I found out that the configuration I had on ESXi host’s vSwitch was wrong and this is why the failover never happened.

Before I told about the ESXi vSwitch, I was looking at a number of different ways to fix this issue. From my searching I found a great article written by Ivan Erben on how you can manually fail over active slave in bond-type 1 configuration

It was quite straightforward, as I like it :p

Firstly, check to see what the active slave is by using the command cat /proc/net/bonding/bond0

[email protected]:~$ cat /proc/net/bonding/bond0 
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth1
MII Status: up
MII Polling Interval (ms): 0
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth1
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:4f:26:c5
Slave queue ID: 0

Slave Interface: eth2
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:4f:26:cf
Slave queue ID: 0

Having seen that eth1 is the active slave, we can remove the interface from the bond, by running echo -eth1 > /sys/class/net/bond0/bonding/slaves

Note
You will need to sudo root to make this change.
[email protected]:~$ sudo -s
[sudo] password for marquk01: 
[email protected]:~# echo -eth1 > /sys/class/net/bond0/bonding/slaves

We can see that the eth1 has been removed from bond configuration

[email protected]:~# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth2
MII Status: up
MII Polling Interval (ms): 0
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth2
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:4f:26:cf
Slave queue ID: 0

The bond will still pass traffic and work as expected to add the interface back into the bond, we would need to run echo +eth1 > /sys/class/net/bond0/bonding/slaves

As we can see, eth1 has been added back into the bond and eth2 has become the active slave.

[email protected]:~# echo +eth1 > /sys/class/net/bond0/bonding/slaves
[email protected]:~# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth2
MII Status: up
MII Polling Interval (ms): 0
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eth2
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:4f:26:cf
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:4f:26:c5
Slave queue ID: 0

This is very useful, if you know you have planned maintenance or need a quick failover of interfaces and you don’t have link detection enabled. Definitely a great find and post by Ivan! You can check out his blog here

Share this:
Share

Installing LLDP on Ubuntu

Reading Time: 2 minutes

LLDP (Link Local Discovery Protocol) is an Open Standard Layer-2 protocol that is used by servers and network devices to advertise their identity and capabilities to other device, by directly connected devices. This standard is defined in IEEE 802.1AB. The information is sent via lldp-enabled interfaces, as Ethernet frame, over fixed interval. These frames contain LLDPDS (Link Local Discovery Protocol Data Unit) in a Type-Length-Value (TLV) format.

LLPDS include a wide range of information from hostname, description, and port name etc. Using LLPD can be very useful as you will be able to find out what devices are directly connected to a switch without having the joy of going cable tracking, and it’s useful for troubleshooting. With that in mind, this post will go into how you would enable LLDP on a Juniper and Cisco switch, and how to enable on Ubuntu 14.04LTS.

Let’s get cracking!

For my set up I’ve got ESXi host running Ubuntu 14.04LTS. It has three vNICs; one is connected to the OOB Cisco 3750G switch and other two connections go into a Virtual Chassis Juniper EX4200

Firstly enable lldp on your network device:

For a Juniper device set protocols lldp interface all and for a Cisco device lldp run or for CDP, under the interface you will need to run cdp enable (CDP is Cisco’s proprietary link discovery protocol)

You’ll need to install the LLDP and SNMP packages onto the server:

[email protected]:~$ sudo apt-get install lldpd snmp

You’ll need to start both of the processes to get them up and running:

[email protected]:~$ sudo service lldpd restart
[email protected]:~$ sudo service snmpd restart

Once you’ve started these you’ll have both enabled on your server, and you’ll have LLDP configured! Nice and simple 🙂

To confirm everything is working as expected, you can run a show command on switches and the server for verification:

On the Juniper EX4200 show lldp neighbors, shows the 2 server NICs connected to each member

show lldp neighbors
[email protected]> show lldp neighbors 
Local Interface    Parent Interface    Chassis Id          Port info          System Name
ge-0/0/2.0         -                   00:0c:29:4f:26:bb   eth1               km-vm1              
ge-1/0/2.0         -                   00:0c:29:4f:26:bb   eth2               km-vm1              
vme.0              -                   00:19:06:cd:8f:80   GigabitEthernet1/0/36 oob-sw0-10.lab

On the Cisco 3750G show lldp neighbors, show the 2 ESXi hosts connected using the switch for Out of Band.

show lldp neighbors g1/0/48
oob-sw0-10.lab#show lldp neighbors g1/0/48
Capability codes:
    (R) Router, (B) Bridge, (T) Telephone, (C) DOCSIS Cable Device
    (W) WLAN Access Point, (P) Repeater, (S) Station, (O) Other

Device ID           Local Intf     Hold-time  Capability      Port ID
km-vm2              Gi1/0/48       120                        000c.29d3.ac6d
km-vm1              Gi1/0/48       120                        000c.294f.26bb

On the server, lldpcli show neighbors, shows all Cisco and Juniper switches and the other ESXi host shared the OOB NIC

lldpcli show neighbors
[email protected]:~$ lldpcli show neighbors
-------------------------------------------------------------------------------
LLDP neighbors:
-------------------------------------------------------------------------------
Interface:    eth0, via: LLDP, RID: 1, Time: 0 day, 22:19:29
  Chassis:     
    ChassisID:    mac 00:0c:29:d3:ac:77
    SysName:      km-vm2
    SysDescr:     Ubuntu 14.04.2 LTS Linux 3.16.0-30-generic #40~14.04.1-Ubuntu SMP Thu Jan 15 17:43:14 UTC 2015 x86_64
    MgmtIP:       10.1.0.141
    MgmtIP:       2001:41c1:4:8040:20c:29ff:fed3:ac6d
    Capability:   Bridge, off
    Capability:   Router, off
    Capability:   Wlan, off
  Port:        
    PortID:       mac 00:0c:29:d3:ac:6d
    PortDescr:    eth0
-------------------------------------------------------------------------------
Interface:    eth0, via: LLDP, RID: 2, Time: 0 day, 22:19:11
  Chassis:     
    ChassisID:    mac 00:19:06:cd:8f:80
    SysName:      oob-sw0-10.lab
    SysDescr:     Cisco IOS Software, C3750 Software (C3750-IPSERVICESK9-M), Version 15.0(1)SE, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2011 by Cisco Systems, Inc.
Compiled Wed 20-Jul-11 09:32 by prod_rel_team
    MgmtIP:       10.1.0.4
    Capability:   Bridge, on
    Capability:   Router, off
  Port:        
    PortID:       ifname Gi1/0/48
    PortDescr:    GigabitEthernet1/0/48
-------------------------------------------------------------------------------
Interface:    eth1, via: LLDP, RID: 6, Time: 0 day, 00:02:58
  Chassis:     
    ChassisID:    mac 40:a6:77:5f:60:00
    SysName:      EX4200-A
    SysDescr:     Juniper Networks, Inc. ex4200-48t , version 12.3R5.7 Build date: 2013-12-18 03:01:12 UTC 
    MgmtIP:       10.1.0.243
    Capability:   Bridge, on
    Capability:   Router, on
  Port:        
    PortID:       local 503
    PortDescr:    KM-VM-1
-------------------------------------------------------------------------------
Interface:    eth2, via: LLDP, RID: 6, Time: 0 day, 00:03:01
  Chassis:     
    ChassisID:    mac 40:a6:77:5f:60:00
    SysName:      EX4200-A
    SysDescr:     Juniper Networks, Inc. ex4200-48t , version 12.3R5.7 Build date: 2013-12-18 03:01:12 UTC 
    MgmtIP:       10.1.0.243
    Capability:   Bridge, on
    Capability:   Router, on
  Port:        
    PortID:       local 661
    PortDescr:    KM-VM-1
-------------------------------------------------------------------------------

You can see detailed information and additional commands that can be run using lldpcli, on the man pages or via Ubuntu documentation

Share this:
Share