Lab-38: Linux bridge with Linux containers (lxc)

This is a fun lab which involves Linux bridges, Linux containers and spanning tree protocol. I will create L2 switch network using three Linux bridges and three containers connected to bridges. It is going to be a ring network so we can test some basic  basic spanning tree function.

Prerequisite:

Install Linux containers using procedure in  Lab-36.

In this lab I am using Centos 7. We will be using brctl command to create bridge so Install bridge-utils if not already installed

#yum install bridge-utils

Procedure:

Create three Linux bridges, br0,br1 & br2 using brctl command.

sudo brctl addbr <bridge name>


[root@localhost]# sudo brctl addbr br0
[root@localhost]# sudo brctl addbr br1
[root@localhost]# sudo brctl addbr br2

//bring bridge up
[root@localhost]# ifconfig br0 up
[root@localhost]# ifconfig br0
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c0f6:91ff:fed2:38b0  prefixlen 64  scopeid 0x20
        ether c2:f6:91:d2:38:b0  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6  bytes 508 (508.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost]# ifconfig br2 up
[root@localhost]# ifconfig br1 up

Create virtual ethernet (veth) links and bring them up. veth created in pair, these will serve as trunk ports between bridges


//create veth with pair i.e. veth0 paired with veth1
[root@localhost ~]# ip link add veth0 type veth peer name veth1

[root@localhost ~]# ifconfig veth0 up
[root@localhost ~]# ifconfig veth1 up

//add veth to respective bridges (see topology diagram)
[root@localhost ~]# sudo brctl addif br0 veth0
[root@localhost ~]# sudo brctl addif br1 veth1
[root@localhost ~]# sudo brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.e274c68ffca6       no              veth0
br1             8000.d28623e04c88       no              veth1

//create veth2 paired with veth3, veth4 paired with veth5
[root@localhost ~]# ip link add veth2 type veth peer name veth3
[root@localhost ~]# ip link add veth4 type veth peer name veth5

//bring veth up
[root@localhost ~]# ifconfig veth2 up
[root@localhost ~]# ifconfig veth3 up
[root@localhost ~]# ifconfig veth4 up
[root@localhost ~]# ifconfig veth5 up

//add veth to respective bridges
[root@localhost ~]# sudo brctl addif br1 veth2
[root@localhost ~]# sudo brctl addif br2 veth3
[root@localhost ~]# sudo brctl addif br2 veth4
[root@localhost ~]# sudo brctl addif br0 veth5
//as can be seen veth interfaces are attached to bridges
[root@localhost ~]# sudo brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.c2f691d238b0       no              veth0
                                                        veth5
br1             8000.d28623e04c88       no              veth1
                                                        veth2
br2             8000.9a127ad7bf76       no              veth3
                                                        veth4

//check bridge and veth interfaces
[root@localhost ~]# ip addr
52: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether c2:f6:91:d2:38:b0 brd ff:ff:ff:ff:ff:ff
53: br1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether d2:86:23:e0:4c:88 brd ff:ff:ff:ff:ff:ff
54: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br1 state UP qlen 1000
    link/ether d2:86:23:e0:4c:88 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d086:23ff:fee0:4c88/64 scope link
       valid_lft forever preferred_lft forever
55: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP qlen 1000
    link/ether e2:74:c6:8f:fc:a6 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::e074:c6ff:fe8f:fca6/64 scope link
       valid_lft forever preferred_lft forever
56: veth3@veth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br2 state UP qlen 1000
    link/ether 9a:12:7a:d7:bf:76 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::9812:7aff:fed7:bf76/64 scope link
       valid_lft forever preferred_lft forever
57: veth2@veth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br1 state UP qlen 1000
    link/ether ee:bf:b0:92:54:a0 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::ecbf:b0ff:fe92:54a0/64 scope link
       valid_lft forever preferred_lft forever
58: veth5@veth4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP qlen 1000
    link/ether c2:f6:91:d2:38:b0 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::c0f6:91ff:fed2:38b0/64 scope link
       valid_lft forever preferred_lft forever
59: veth4@veth5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br2 state UP qlen 1000
    link/ether fe:fe:da:e0:3a:09 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fcfe:daff:fee0:3a09/64 scope link
       valid_lft forever preferred_lft forever
60: br2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 9a:12:7a:d7:bf:76 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]#

Create three Linux containers, c1,c2 & c3

#lxc-create -t ubuntu -n c1
#lxc-create -t ubuntu -n c2
#lxc-create -t ubuntu -n c3


[root@localhost ~]# lxc-create -t ubuntu -n c1
Checking cache download in /var/cache/lxc/precise/rootfs-amd64 ...
Copy /var/cache/lxc/precise/rootfs-amd64 to /var/lib/lxc/c1/rootfs ...
Copying rootfs to /var/lib/lxc/c1/rootfs ...
Generating locales...
  en_US.UTF-8... up-to-date
Generation complete.
Creating SSH2 RSA key; this may take some time ...
Creating SSH2 DSA key; this may take some time ...
Creating SSH2 ECDSA key; this may take some time ...
Timezone in container is not configured. Adjust it manually.

##
# The default user is 'ubuntu' with password 'ubuntu'!
# Use the 'sudo' command to run tasks as root in the container.
##

[root@localhost ~]# lxc-create -t ubuntu -n c2
Checking cache download in /var/cache/lxc/precise/rootfs-amd64 ...
Copy /var/cache/lxc/precise/rootfs-amd64 to /var/lib/lxc/c2/rootfs ...
Copying rootfs to /var/lib/lxc/c2/rootfs ...
Generating locales...
  en_US.UTF-8... up-to-date
Generation complete.
Creating SSH2 RSA key; this may take some time ...
Creating SSH2 DSA key; this may take some time ...
Creating SSH2 ECDSA key; this may take some time ...
Timezone in container is not configured. Adjust it manually.

##
# The default user is 'ubuntu' with password 'ubuntu'!
# Use the 'sudo' command to run tasks as root in the container.
##

[root@localhost ~]# lxc-create -t ubuntu -n c3
Checking cache download in /var/cache/lxc/precise/rootfs-amd64 ...
Copy /var/cache/lxc/precise/rootfs-amd64 to /var/lib/lxc/c3/rootfs ...
Copying rootfs to /var/lib/lxc/c3/rootfs ...
Generating locales...
  en_US.UTF-8... up-to-date
Generation complete.
Creating SSH2 RSA key; this may take some time ...
Creating SSH2 DSA key; this may take some time ...
Creating SSH2 ECDSA key; this may take some time ...
Timezone in container is not configured. Adjust it manually.

##
# The default user is 'ubuntu' with password 'ubuntu'!
# Use the 'sudo' command to run tasks as root in the container.
##

Edit container config file to create veth network types. Container config files for my system is located at /var/lib/lxc/<container name>/config

Container c1 attached to bridge br0, c2 to br1 and c3 to br2

Below sample container c1 config file /var/lib/lxc/c1/config


# Network configuration
lxc.network.type = veth
lxc.network.hwaddr = 00:16:3e:80:81:03
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.2.1/24

below sample container c2 config file /var/lib/lxc/c2/config


# Network configuration
lxc.network.type = veth
lxc.network.hwaddr = 00:16:3e:6e:70:a7
lxc.network.flags = up
lxc.network.link = br1
lxc.network.ipv4 = 192.168.2.2/24

Below sample container c3 config file /var/lib/lxc/c3/config


# Network configuration
lxc.network.type = veth
lxc.network.hwaddr = 00:16:3e:18:56:d5
lxc.network.flags = up
lxc.network.link = br2
lxc.network.ipv4 = 192.168.2.3/24

Check container network interface. Use lxc-attach command to list ip interfaces

#lxc-attach -n <container name> /sbin/ip addr


//container c1 assigned with ip address 192.168.2.1
[root@localhost]# lxc-attach -n c1 /sbin/ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
67: eth0@if68: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 00:16:3e:80:81:03 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.1/24 brd 192.168.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fe80:8103/64 scope link
       valid_lft forever preferred_lft forever
//container c2 assigned ip address 192.168.2.2
[root@localhost]# lxc-attach -n c2 /sbin/ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
69: eth0@if70: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 00:16:3e:6e:70:a7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fe6e:70a7/64 scope link
       valid_lft forever preferred_lft forever

//container c3 assigned ip address 192.168.2.3
[root@localhost]# lxc-attach -n c3 /sbin/ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
71: eth0@if72: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 00:16:3e:18:56:d5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.3/24 brd 192.168.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fe18:56d5/64 scope link
       valid_lft forever preferred_lft forever

Check bridge status. As can be seen three virtual ethernet interfaces are attached to each bridge


[root@localhost]# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.c2f691d238b0       no              veth0
                                                        veth5
                                                        vethOC0NPG
br1             8000.d28623e04c88       no              veth1
                                                        veth2
                                                        vethSQUCH3
br2             8000.9a127ad7bf76       no              veth3
                                                        veth4
                                                        veth577WF3

At this point we have created this topology. Containers c1,c2 & c3 attached to respective bridges and all bridges connected in a ring. Our L2 network is ready for testing

stp_1

Check spanning tree (stp) status on bridges. As can be seen stp is disabled on all bridges as every bridge is a designated root bridge


[root@localhost]# brctl showstp br0
br0
 bridge id              8000.c2f691d238b0
 designated root        8000.c2f691d238b0
 root port                 0                    path cost                  0
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               1.66                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                  53.31
 flags


veth0 (1)
 port id                8001                    state                forwarding
 designated root        8000.c2f691d238b0       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer          0.00
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.66
 flags

veth5 (2)
 port id                8002                    state                forwarding
 designated root        8000.c2f691d238b0       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer          0.00
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.66
 flags

vethOC0NPG (3)
 port id                8003                    state                forwarding
 designated root        8000.c2f691d238b0       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.66
 flags

[root@localhost]# brctl showstp br1
br1
 bridge id              8000.d28623e04c88
 designated root        8000.d28623e04c88
 root port                 0                    path cost                  0
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               1.04                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                  45.06
 flags


veth1 (1)
 port id                8001                    state                forwarding
 designated root        8000.d28623e04c88       path cost                  2
 designated bridge      8000.d28623e04c88       message age timer          0.00
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.04
 flags

veth2 (2)
 port id                8002                    state                forwarding
 designated root        8000.d28623e04c88       path cost                  2
 designated bridge      8000.d28623e04c88       message age timer          0.00
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.04
 flags

vethSQUCH3 (3)
 port id                8003                    state                forwarding
 designated root        8000.d28623e04c88       path cost                  2
 designated bridge      8000.d28623e04c88       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.04
 flags

[root@localhost]# brctl showstp br2
br2
 bridge id              8000.9a127ad7bf76
 designated root        8000.9a127ad7bf76
 root port                 0                    path cost                  0
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               1.07                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                  16.98
 flags


veth3 (1)
 port id                8001                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer          0.00
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.07
 flags

veth4 (2)
 port id                8002                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer          0.00
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.07
 flags

veth577WF3 (3)
 port id                8003                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.07
 flags

Login to container c2 and ping to container c1 (192.168.2.1). Because of loop in the topology network will experience broadcast storm and create congestion. Ping will intermittently pass.

You can confirm the broadcast storm by checking packet counts on bridges. You will see packet counts increment at very high rate


ubuntu@c1:~$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:16:3e:80:81:03
          inet addr:192.168.2.1  Bcast:192.168.2.255  Mask:255.255.255.0
          inet6 addr: fe80::216:3eff:fe80:8103/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:87 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:648 (648.0 B)  TX bytes:18666 (18.6 KB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:56 errors:0 dropped:0 overruns:0 frame:0
          TX packets:56 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:5440 (5.4 KB)  TX bytes:5440 (5.4 KB)

ubuntu@c1:~$ ip route
192.168.2.0/24 dev eth0  proto kernel  scope link  src 192.168.2.1
ubuntu@c1:~$ ping 192.168.2.2
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_req=13 ttl=64 time=4009 ms
64 bytes from 192.168.2.2: icmp_req=19 ttl=64 time=3007 ms
64 bytes from 192.168.2.2: icmp_req=20 ttl=64 time=2005 ms

[root@localhost ~]# ifconfig br0
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c0f6:91ff:fed2:38b0  prefixlen 64  scopeid 0x20<link>
        ether c2:f6:91:d2:38:b0  txqueuelen 1000  (Ethernet)
        RX packets 233826705  bytes 49096357638 (45.7 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]# ifconfig br0
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c0f6:91ff:fed2:38b0  prefixlen 64  scopeid 0x20<link>
        ether c2:f6:91:d2:38:b0  txqueuelen 1000  (Ethernet)
        RX packets 233921147  bytes 49127334614 (45.7 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Stop ping and check bridge packet count again. As can be seen packets counts are are still incrementing at a very high rate. Packets are circulating in the network due to topology loop


[root@localhost]# ifconfig br0
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c0f6:91ff:fed2:38b0  prefixlen 64  scopeid 0x20
        ether c2:f6:91:d2:38:b0  txqueuelen 1000  (Ethernet)
        RX packets 158174506  bytes 28354814180 (26.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost]# ifconfig br0
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c0f6:91ff:fed2:38b0  prefixlen 64  scopeid 0x20
        ether c2:f6:91:d2:38:b0  txqueuelen 1000  (Ethernet)
        RX packets 159069415  bytes 28530733852 (26.5 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost]# ifconfig br1
br1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::d086:23ff:fee0:4c88  prefixlen 64  scopeid 0x20
        ether d2:86:23:e0:4c:88  txqueuelen 1000  (Ethernet)
        RX packets 160435925  bytes 28800879432 (26.8 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3  bytes 258 (258.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost]# ifconfig br1
br1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::d086:23ff:fee0:4c88  prefixlen 64  scopeid 0x20
        ether d2:86:23:e0:4c:88  txqueuelen 1000  (Ethernet)
        RX packets 161046481  bytes 28923084308 (26.9 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3  bytes 258 (258.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost]# ifconfig br2
br2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::9812:7aff:fed7:bf76  prefixlen 64  scopeid 0x20
        ether 9a:12:7a:d7:bf:76  txqueuelen 1000  (Ethernet)
        RX packets 162073378  bytes 29129182172 (27.1 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost]# ifconfig br2
br2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::9812:7aff:fed7:bf76  prefixlen 64  scopeid 0x20
        ether 9a:12:7a:d7:bf:76  txqueuelen 1000  (Ethernet)
        RX packets 162616331  bytes 29238047188 (27.2 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Enable spanning tree on all bridges, br0,br1 & br2.

As can be seen bridge br2 is elected as designated root bridge by spanning tree protocol. This is because the mac address of br2 is lower then br0 & br1

Bridge br1 port veth1(1) blocked by stp to break the loop and now there is no broadcast storm. The new topology after stp enabled should look like this

You ask why veth1 blocked this is because spanning tree packets received on this port has higher path cost than packet received on veth2 which is directly connected to root bridge

stp_2

Another logical view

stp_3


[root@localhost]# brctl stp br0 on
[root@localhost]# brctl stp br1 on
[root@localhost]# brctl stp br2 on

[root@localhost]# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.c2f691d238b0       yes             veth0
                                                        veth5
                                                        vethOC0NPG
br1             8000.d28623e04c88       yes             veth1
                                                        veth2
                                                        vethSQUCH3
br2             8000.9a127ad7bf76       yes             veth3
                                                        veth4
  
                                                      veth577WF3
//all ports in bridge br0 are in forwarding state
[root@localhost]# brctl showstp br0
br0
 bridge id              8000.c2f691d238b0
 designated root        8000.9a127ad7bf76
 root port                 2                    path cost                  2
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               0.00                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                  62.44
 flags                  TOPOLOGY_CHANGE


veth0 (1)
 port id                8001                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer          0.00
 designated port        8001                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.00
 flags

veth5 (2)
 port id                8002                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer         18.79
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

vethOC0NPG (3)
 port id                8003                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.00
 flags

//port veth1(1) is in blocking state
[root@localhost]# brctl showstp br1
br1
 bridge id              8000.d28623e04c88
 designated root        8000.9a127ad7bf76
 root port                 2                    path cost                  2
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               0.00                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                  73.66
 flags


veth1 (1)
 port id                8001                    state                  blocking
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer         19.64
 designated port        8001                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.00
 flags

veth2 (2)
 port id                8002                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer         19.64
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

vethSQUCH3 (3)
 port id                8003                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.d28623e04c88       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.57
 flags

//all ports in bridge br2 are in forwarding state
[root@localhost]# brctl showstp br2
br2
 bridge id              8000.9a127ad7bf76
 designated root        8000.9a127ad7bf76
 root port                 0                    path cost                  0
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               1.68                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                  66.65
 flags


veth3 (1)
 port id                8001                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer          0.00
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.68
 flags

veth4 (2)
 port id                8002                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer          0.00
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.68
 flags

veth577WF3 (3)
 port id                8003                    state                forwarding
 designated root        8000.9a127ad7bf76       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.68
 flags

Let’s try to change the root bridge selection. The easiest way to do is by changing bridge priority

Change bridge br2  priority to make it root bridge. Bridge with lower priority become root. In this case I am reducing bridge priority just by one 7999.

As can be seen port veth5(2) on bridge br0 transition to block state to break loop. Bridge br1 elected as root bridge


[root@localhost ~]# sudo brctl setbridgeprio br1 7999

[root@localhost]# brctl showstp br1
br1
 bridge id              1f3f.d28623e04c88
 designated root        1f3f.d28623e04c88
 root port                 0                    path cost                  0
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               1.30                 tcn timer                  0.00
 topology change timer    19.86                 gc timer                 243.09
 flags                  TOPOLOGY_CHANGE TOPOLOGY_CHANGE_DETECTED


veth1 (1)
 port id                8001                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      1f3f.d28623e04c88       message age timer          0.00
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.30
 flags

veth2 (2)
 port id                8002                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      1f3f.d28623e04c88       message age timer          0.00
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.30
 flags

vethSQUCH3 (3)
 port id                8003                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      1f3f.d28623e04c88       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.30
 flags

[root@localhost ns]# brctl showstp br0
br0
 bridge id              8000.c2f691d238b0
 designated root        1f3f.d28623e04c88
 root port                 1                    path cost                  2
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               0.00                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                 223.34
 flags                  TOPOLOGY_CHANGE


veth0 (1)
 port id                8001                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      1f3f.d28623e04c88       message age timer         19.57
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

veth5 (2)
 port id                8002                    state                  blocking
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer         19.57
 designated port        8002                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.00
 flags

vethOC0NPG (3)
 port id                8003                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.55
 flags

[root@localhost]# brctl showstp br2
br2
 bridge id              8000.9a127ad7bf76
 designated root        1f3f.d28623e04c88
 root port                 1                    path cost                  2
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               0.00                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                   0.32
 flags                  TOPOLOGY_CHANGE


veth3 (1)
 port id                8001                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      1f3f.d28623e04c88       message age timer         18.34
 designated port        8002                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

veth4 (2)
 port id                8002                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer          0.00
 designated port        8002                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.00
 flags

veth577WF3 (3)
 port id                8003                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.00
 flags

The new topology should look like this

stp_4

Let’s change the root port on  br0 from veth0 to veth5. The easiest way to do that is by changing the port cost on veth0. Edit port cost on veth0 to 10. This will cause veth5 to move to forwarding state and veth0 to blocking.

As can be seen port veth0 transitioned to blocking state


[root@localhost ~]# brctl setpathcost br0 veth0 10
[root@localhost ~]# brctl showstp br0
br0
 bridge id              8000.c2f691d238b0
 designated root        1f3f.d28623e04c88
 root port                 2                    path cost                  4
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               0.00                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                 226.87
 flags                  TOPOLOGY_CHANGE


veth0 (1)
 port id                8001                    state                  blocking
 designated root        1f3f.d28623e04c88       path cost                 10
 designated bridge      1f3f.d28623e04c88       message age timer         18.81
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

veth5 (2)
 port id                8002                    state                 listening
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer         18.81
 designated port        8002                    forward delay timer       12.41
 designated cost           2                    hold timer                 0.00
 flags

vethOC0NPG (3)
 port id                8003                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           4                    hold timer                 0.78
 flags

[root@localhost ~]# brctl showstp br0
br0
 bridge id              8000.c2f691d238b0
 designated root        1f3f.d28623e04c88
 root port                 2                    path cost                  4
 max age                  20.00                 bridge max age            20.00
 hello time                2.00                 bridge hello time          2.00
 forward delay            15.00                 bridge forward delay      15.00
 ageing time             300.00
 hello timer               0.00                 tcn timer                  0.00
 topology change timer     0.00                 gc timer                  32.26
 flags


veth0 (1)
 port id                8001                    state                  blocking
 designated root        1f3f.d28623e04c88       path cost                 10
 designated bridge      1f3f.d28623e04c88       message age timer         19.07
 designated port        8001                    forward delay timer        0.00
 designated cost           0                    hold timer                 0.00
 flags

veth5 (2)
 port id                8002                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      8000.9a127ad7bf76       message age timer         19.01
 designated port        8002                    forward delay timer        0.00
 designated cost           2                    hold timer                 0.00
 flags

vethOC0NPG (3)
 port id                8003                    state                forwarding
 designated root        1f3f.d28623e04c88       path cost                  2
 designated bridge      8000.c2f691d238b0       message age timer          0.00
 designated port        8003                    forward delay timer        0.00
 designated cost           4                    hold timer                 0.00
 flags

Other useful command is to check mac table


[root@localhost ~]# brctl showmacs br0
port no mac addr                is local?       ageing timer
  2     00:16:3e:18:56:d5       no                10.04
  2     00:16:3e:6e:70:a7       no                12.00
  3     00:16:3e:80:81:03       no                17.73
  2     c2:f6:91:d2:38:b0       yes                0.00
  1     e2:74:c6:8f:fc:a6       yes                0.00
  1     e2:74:c6:8f:fc:a6       yes                0.00
  3     fe:0e:18:bc:7e:e3       yes                0.00
  3     fe:0e:18:bc:7e:e3       yes                0.00
  2     fe:fe:da:e0:3a:09       no                 0.81

You can dump packets on virtual interfaces and bridge


[root@localhost ~]# tcpdump -i veth5 -XX
tcpdump: WARNING: veth5: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth5, link-type EN10MB (Ethernet), capture size 65535 bytes
22:03:48.738230 STP 802.1d, Config, Flags [none], bridge-id 8000.9a:12:7a:d7:bf:76.8002, length 35
        0x0000:  0180 c200 0000 fefe dae0 3a09 0026 4242  ..........:..&BB
        0x0010:  0300 0000 0000 1f3f d286 23e0 4c88 0000  .......?..#.L...
        0x0020:  0002 8000 9a12 7ad7 bf76 8002 0001 1400  ......z..v......
        0x0030:  0200 0f00                                ....
22:03:50.738236 STP 802.1d, Config, Flags [none], bridge-id 8000.9a:12:7a:d7:bf:76.8002, length 35
        0x0000:  0180 c200 0000 fefe dae0 3a09 0026 4242  ..........:..&BB
        0x0010:  0300 0000 0000 1f3f d286 23e0 4c88 0000  .......?..#.L...
        0x0020:  0002 8000 9a12 7ad7 bf76 8002 0001 1400  ......z..v......
        0x0030:  0200 0f00

 

 

 

Lab-15:Linux bridge with basic firewall

Almost all Linux distributions are shipped with Linux bridge. In this lab I will demonstrate how to setup a Linux bridge with VMs attached to it simulating as hosts.  I will also show how to add basic firewall rule to bridge

Topology:

My test bridge mapped to physical interface and two virtual interfaces. VMs are connected to virtual interfaces on bridge. I am using Linux Mint on VMs. Please note that mapping to physical interface is optional it is required only if you need external connectivity for your VMs

linux_bridge_5
Linux bridge topology

Pre-condition:

  • Linux bridge package (able to run brctl command), virtual box and your favorite VM image. I like Linux Mint because it is light weight and boots fast
  • sudo apt-get install uml-utilities bridge-utils

Procedure:

  • Try bridge command
sjakhwal@rtxl3rld05:~$ sudo brctl --help
Usage: brctl [commands]
commands:
        addbr           <bridge>                add bridge
        delbr           <bridge>                delete bridge
        addif           <bridge> <device>       add interface to bridge
        delif           <bridge> <device>       delete interface from bridge
        hairpin         <bridge> <port> {on|off}        turn hairpin on/off
        setageing       <bridge> <time>         set ageing time
        setbridgeprio   <bridge> <prio>         set bridge priority
        setfd           <bridge> <time>         set bridge forward delay
        sethello        <bridge> <time>         set hello time
        setmaxage       <bridge> <time>         set max message age
        setpathcost     <bridge> <port> <cost>  set path cost
        setportprio     <bridge> <port> <prio>  set port priority
        show            [ <bridge> ]            show a list of bridges
        showmacs        <bridge>                show a list of mac addrs
        showstp         <bridge>                show bridge stp info
        stp             <bridge> {on|off}       turn stp on/off
  • Create a test bridge. Note: virbr0 is a default bridge created by Linux
sjakhwal@rtxl3rld05:~$ sudo brctl addbr testBr
sjakhwal@rtxl3rld05:~$ sudo brctl show
bridge name     bridge id               STP enabled     interfaces
testBr          8000.000acd27b824       no              
virbr0          8000.000000000000       yes
sjakhwal@rtxl3rld05:~$ ip addr
10: testBr: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
    link/ether 00:0a:cd:27:b8:24 brd ff:ff:ff:ff:ff:ff
  • Bring the test bridge to UP state
sjakhwal@rtxl3rld05:~$ sudo ip link set testBr up
sjakhwal@rtxl3rld05:~$ ip addr
10: testBr: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 00:0a:cd:27:b8:24 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::20a:cdff:fe27:b824/64 scope link
       valid_lft forever preferred_lft forever
  • Attach a physical port to test bridge. In this case I am using eth3 physical port. Note: This step is needed only if you are planning to have external connectivity to your bridge, otherwise you can skip it
sjakhwal@rtxl3rld05:~$ ifconfig eth3
eth3      Link encap:Ethernet  HWaddr 00:0a:cd:27:b8:24
          inet6 addr: fe80::20a:cdff:fe27:b824/64 Scope:Link
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:3413 errors:0 dropped:283 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1352737 (1.3 MB)  TX bytes:648 (648.0 B)

sjakhwal@rtxl3rld05:~$
sjakhwal@rtxl3rld05:~$ sudo brctl addif testBr eth3
sjakhwal@rtxl3rld05:~$ sudo brctl show
bridge name     bridge id               STP enabled     interfaces
testBr          8000.000acd27b824       no              eth3
virbr0          8000.000000000000       yes
  • To make setting persistent we need to update interfaces file.
    • I am using Ubuntu so my changes are in /etc/network/interfaces, in case of Centos you need to create ifcfg-testBr file under /etc/sysconfig/network-scripts.
    • restart network manager to activate changes $sudo service network-manager restart

Please note that IP address has moved from physical interface to bridge. There is no IP address provisioned on physical interface

sjakhwal@rtxl3rld05:~$cat interfaces
auto eth3
iface eth3 inet manual
pre-up ifconfig eth3 up

## test bridge
auto testBr
iface testBr inet static
bridge_ports eth3
bridge_stp off
bridge_fd 0.0
address 192.168.10.100
netmask 255.255.255.0
network 192.168.10.0
broadcast 192.168.10.255
  • Make sure bridge gets the IP address and UP & RUNNING
sjakhwal@rtxl3rld05:/etc/network$ ifconfig testBr
testBr    Link encap:Ethernet  HWaddr 00:0a:cd:27:b8:24
          inet addr:192.168.10.100  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: fe80::20a:cdff:fe27:b824/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:64 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:11747 (11.7 KB)  TX bytes:648 (648.0 B)

sjakhwal@rtxl3rld05:~$ ip addr
5: testBr: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 00:0a:cd:27:b8:24 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.100/24 brd 192.168.10.255 scope global testBr
       valid_lft forever preferred_lft forever
    inet6 fe80::20a:cdff:fe27:b824/64 scope link
       valid_lft forever preferred_lft forever

sjakhwal@rtxl3rld05:~$ ifconfig eth3
eth3      Link encap:Ethernet  HWaddr 00:0a:cd:27:b8:24
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:15 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2330 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1206 (1.2 KB)  TX bytes:447039 (447.0 KB)
  • Create two virtual interfaces and connect them to test bridge.
sjakhwal@rtxl3rld05:~$ sudo tunctl
Set 'tap0' persistent and owned by uid 0
sjakhwal@rtxl3rld05:$ sudo tunctl
Set 'tap1' persistent and owned by uid 0

sjakhwal@rtxl3rld05:/sbin$ ip addr
16: tap0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 500
    link/ether de:57:03:0e:b7:ba brd ff:ff:ff:ff:ff:ff
17: tap1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 500
    link/ether 22:f8:6e:cf:0e:7a brd ff:ff:ff:ff:ff:ff

sjakhwal@rtxl3rld05:$ sudo ip link set tap0 up
sjakhwal@rtxl3rld05:$ sudo ip link set tap1 up

sjakhwal@rtxl3rld05:~$ sudo brctl addif testBr tap0
sjakhwal@rtxl3rld05:~$ sudo brctl addif testBr tap1
sjakhwal@rtxl3rld05:$ sudo brctl show
bridge name     bridge id               STP enabled     interfaces
testBr          8000.000acd27b824       no              eth3
                                                        tap0
                                                        tap1
virbr0          8000.000000000000       yes
  • At this point we have 3 ports bridge. We need host to connect to bridge ports so we can test our bridge. Below step is to simulate virtual host using VMs.
  • On the virtual box start two VMs. I am using Linux mint for my VMs. In the virtual box under setting select ‘Attached to’ as Bridge Adopter and under name drop down select ‘tap0’ for first VM and ‘tap1’ for second VM. Set promiscuous mode to ‘allow all’

linux_bridge_3

linux_bridge_4

  • Setup IP addresses on VMs
    • VM1: sudo ifconfig eth0 192.168.10.1 up
    • VM2:sudo ifconfig eth0 192.168.10.2 up
  • Ping from VM1 to VM2. Ping is successful
  • Ping to VMs from host machine. Ping is successful
sjakhwal@rtxl3rld05:/etc/network$ ip addr
24: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master testBr state UP group default qlen 500
    link/ether ce:b5:77:bd:f5:79 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::ccb5:77ff:febd:f579/64 scope link
       valid_lft forever preferred_lft forever
25: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master testBr state UP group default qlen 500
    link/ether 9e:53:00:9c:cb:c7 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::9c53:ff:fe9c:cbc7/64 scope link
       valid_lft forever preferred_lft forever

sjakhwal@rtxl3rld05:/etc/network$ ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.506 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.352 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=0.340 ms
64 bytes from 192.168.10.1: icmp_seq=4 ttl=64 time=0.334 ms
64 bytes from 192.168.10.1: icmp_seq=5 ttl=64 time=0.397 ms
^C
--- 192.168.10.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3998ms
  • Just to prove that our VMs are in fact connected to tap interfaces lets try some tests. Disable tap interface and check ping connectivity to VM
sjakhwal@rtxl3rld05:/etc/network$ ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.162 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.211 ms
^C
--- 192.168.10.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.162/0.186/0.211/0.028 ms

#disable tap interface
sjakhwal@rtxl3rld05:/etc/network$ sudo ip link set tap0 down
[sudo] password for sjakhwal:
sjakhwal@rtxl3rld05:/etc/network$ ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
^C
--- 192.168.10.1 ping statistics ---
6 packets transmitted, 0 received, 100% packet loss, time 5039ms

sjakhwal@rtxl3rld05:/etc/network$ ip addr
24: tap0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master testBr state DOWN group default qlen 500
    link/ether ce:b5:77:bd:f5:79 brd ff:ff:ff:ff:ff:ff
25: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master testBr state UP group default qlen 500
    link/ether 9e:53:00:9c:cb:c7 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::9c53:ff:fe9c:cbc7/64 scope link
       valid_lft forever preferred_lft forever

#enable tap interface
sjakhwal@rtxl3rld05:/etc/network$ sudo ip link set tap0 up
sjakhwal@rtxl3rld05:/etc/network$ ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.405 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.165 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=0.234 ms
64 bytes from 192.168.10.1: icmp_seq=4 ttl=64 time=0.299 ms
^C
--- 192.168.10.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.165/0.275/0.405/0.090 ms

Firewalling to Linux bridge is provided by ebtables. Ebtables firewall applies to Link layer so filtering is based on MAC only.  Lets try some basic rules

  • FORWARD chain: Forward chain applied when traffic goes from one port to another port in a bridge, in our case between VMs
  • Add MAC filter rule so traffic from VM1 to VM2 dropped, I am using VM1 source MAC to filter the traffic. run ping from VM1 to VM2 make sure ping dropped
sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -A FORWARD -s 8:0:27:aa:7:b2 -j DROP
sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -L
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 1, policy: ACCEPT
-s 8:0:27:aa:7:b2 -j DROP
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -L --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 1, policy: ACCEPT
-s 8:0:27:aa:7:b2 -j DROP , pcnt = 0 -- bcnt = 0

Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -L --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 1, policy: ACCEPT
-s 8:0:27:aa:7:b2 -j DROP , pcnt = 5 -- bcnt = 420
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -L --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 1, policy: ACCEPT
-s 8:0:27:aa:7:b2 -j DROP , pcnt = 11 -- bcnt = 756
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
sjakhwal@rtxl3rld05:/etc/network$
  • INPUT chain: Input chain applied to incoming traffic  to local host. In our case bridge (192.178.10.100) is local host
  • Add MAC filter rule so traffic from VM1 to bridge dropped. run ping from VM1 to bridge IP, make sure ping dropped
sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -A INPUT -s 8:0:27:aa:7:b2 -j DROP
sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -L
Bridge table: filter
Bridge chain: INPUT, entries: 1, policy: ACCEPT
-s 8:0:27:aa:7:b2 -j DROP
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -L --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 1, policy: ACCEPT
-s 8:0:27:aa:7:b2 -j DROP , pcnt = 11 -- bcnt = 418
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -L --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 1, policy: ACCEPT
-s 8:0:27:aa:7:b2 -j DROP , pcnt = 14 -- bcnt = 502
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT

sjakhwal@rtxl3rld05:/etc/network$ sudo ebtables -L --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 1, policy: ACCEPT
-s 8:0:27:aa:7:b2 -j DROP , pcnt = 17 -- bcnt = 586
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
sjakhwal@rtxl3rld05:/etc/network$
  • OUTPUT chain: Output chain applied to outgoing traffic from local host. In our case bridge (192.168.10.100) is the local host
  • Add MAC filter rule so traffic from bridge to VM1 dropped, –Lc option gives the count when rule get hit
sjakhwal@rtxl3rld05:~$ sudo ebtables -A OUTPUT -d 8:0:27:aa:7:b2 -j DROP
sjakhwal@rtxl3rld05:~$ sudo ebtables -L
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 1, policy: ACCEPT
-d 8:0:27:aa:7:b2 -j DROP
sjakhwal@rtxl3rld05:~$ ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
^C
--- 192.168.10.1 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3024ms
sjakhwal@rtxl3rld05:~$ sudo ebtables -L --Lc
Bridge table: filter
Bridge chain: INPUT, entries: 0, policy: ACCEPT
Bridge chain: FORWARD, entries: 0, policy: ACCEPT
Bridge chain: OUTPUT, entries: 1, policy: ACCEPT
-d 8:0:27:aa:7:b2 -j DROP , pcnt = 7 -- bcnt = 420

You can delete bridge using these commands

sjakhwal@rtxl3rld05:~$ brctl show
bridge name    bridge id        STP enabled    interfaces
testBr        8000.000acd27b824    no        eth3
                            tap0
                            tap1
virbr0        8000.000000000000    yes   

#edit bridge to down state 
sjakhwal@rtxl3rld05:~$ sudo ip link set testBr down
[sudo] password for sjakhwal: 
sjakhwal@rtxl3rld05:~$ sudo brctl delbr testBr
sjakhwal@rtxl3rld05:~$ sudo brctl show
bridge name    bridge id        STP enabled    interfaces
virbr0        8000.000000000000    yes        
sjakhwal@rtxl3rld05:~$

 

References:

Ebtables documentation