VRF on Linux using network namespaces

7,072

Starting with kernel version 4.3 Linux has a VRF implementation. Checkout: https://www.kernel.org/doc/Documentation/networking/vrf.txt.

Share:
7,072

Related videos on Youtube

user349251
Author by

user349251

Updated on September 18, 2022

Comments

  • user349251
    user349251 almost 2 years

    My ultimate goal is to implement Virtual Routing and Forwarding (VRF) in Linux. The method that seems to be most widely accepted is to set up different network name spaces (one for each separate routing table) and run a Quagga or BIRD daemon for each namespace/routing table. I'm not married to this method, so if anyone has any other suggestions, please let me know.

    The machine in question is running Debian 7 (wheezy) inside VMware workstation 12. It has always been a router and has been successfully routing for a while before I started this reconfiguration, so I know that the general routing setup is good.

    The immediate problem is that I cannot communicate through my network namespace. That is, veth1 (which is in my namespace as below) can ping ONLY veth0 and nothing else. There is no network communication between veth1 and the networks below it - not even ARPs. If I didn't know better, I'd say someone had pulled the cable from the switch (but it's kind of hard to do that in virtual environment). And yes, I checked that the vmnets were properly set up. The router works when restored to its old configuration. It just doesn't work in this new configuration.

    Anyone have any idea how to get veth1 communicating? Or even a wholly different method to get VRF working on Linux? Thanks in advance.

    I set up the new configuration as follows:

    add namespace

    ip netns add nsx
    

    add virtual interfaces

    ip link add veth0 type veth peer name veth1
    

    create a bridge

    ip link add name vbr0 type bridge
    

    add eth1 AND veth1 to the bridge

    ip link set dev eth1 master vbr0
    ip link set dev veth1 master vbr0
    

    Assign veth1 to the namespace

    ip link set veth1 netns nsx
    

    configure the veth's IPs

    ip addr add 10.0.2.10/24 dev vbr0
    ip addr add 10.0.2.1/24 dev veth0
    ip netns exec nsx ip addr add 10.0.2.2/24 dev veth1
    

    Bring the i/f's up

    ip link set dev vbr0 up
    ip link set dev veth0 up
    ip netns exec nsx ip link set dev veth1 up
    

    assign veth2 its own routing table

    ip netns exec nsx ip rule add dev veth1 table 1
    

    Set the default route for the vtable

    ip netns exec nsx ip route add default via 10.0.2.1 dev veth1
    

    You can see in the output of iptables-save that everything is set to ACCEPT or FORWARD as appropriate

    output of ip addr show:

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether 00:0c:29:10:e0:01 brd ff:ff:ff:ff:ff:ff
        inet 192.168.26.5/24 brd 192.168.26.255 scope global eth0
        inet 192.168.26.0/24 brd 192.168.26.255 scope global secondary eth0
        inet6 fe80::20c:29ff:fe10:e001/64 scope link
           valid_lft forever preferred_lft forever
    3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vbr0 state UP qlen 1000
        link/ether 00:0c:29:10:e0:ed brd ff:ff:ff:ff:ff:ff
        inet 10.0.0.1/24 brd 10.0.0.255 scope global eth1
        inet6 fe80::20c:29ff:fe10:e0ed/64 scope link
           valid_lft forever preferred_lft forever
    47: veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether ce:63:69:82:73:35 brd ff:ff:ff:ff:ff:ff
        inet 10.0.2.1/24 scope global veth0
        inet6 fe80::cc63:69ff:fe82:7335/64 scope link tentative
           valid_lft forever preferred_lft forever
    48: vbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
        link/ether 00:0c:29:10:e0:ed brd ff:ff:ff:ff:ff:ff
        inet 10.0.2.10/24 scope global vbr0
        inet6 fe80::20c:29ff:fe10:e0ed/64 scope link tentative
           valid_lft forever preferred_lft forever
    

    output of ip route show:

     default via 192.168.26.2 dev eth0
        10.0.0.0/24 dev eth1  proto kernel  scope link  src 10.0.0.1
        10.0.2.0/24 dev vbr0  proto kernel  scope link  src 10.0.2.10
        10.0.2.0/24 dev veth0  proto kernel  scope link  src 10.0.2.1
        192.168.26.0/24 dev eth0  proto kernel  scope link  src 192.168.26.5
    

    output of ip netns exec nsx ip addr show:

        45: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
            link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        46: veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
            link/ether b6:27:40:06:c2:de brd ff:ff:ff:ff:ff:ff
            inet 10.0.2.2/24 scope global veth1
            inet6 fe80::b427:40ff:fe06:c2de/64 scope link tentative
               valid_lft forever preferred_lft forever
    

    output of ip netns exec nsx ip route show

     default via 10.0.2.1 dev veth1
        10.0.2.0/24 dev veth1  proto kernel  scope link  src 10.0.2.2
    

    output of iptables-save

    # Generated by iptables-save v1.4.14 on Thu Apr 14 18:19:19 2016
    *nat
    :PREROUTING ACCEPT [36:3588]
    :INPUT ACCEPT [32:2540]
    :OUTPUT ACCEPT [51:3744]
    :POSTROUTING ACCEPT [55:4792]
    COMMIT
    # Completed on Thu Apr 14 18:19:19 2016
    # Generated by iptables-save v1.4.14 on Thu Apr 14 18:19:19 2016
    *filter
    :INPUT ACCEPT [3319:373389]
    :FORWARD ACCEPT [8:2004]
    :OUTPUT ACCEPT [3558:428447]
    COMMIT
    # Completed on Thu Apr 14 18:19:19 2016