Linux Vlan
From Leo's Notes
Last edited on 1 September 2019, at 06:21.
If an interface is trunked, you can 'untag' the traffic like so:
# ip link add link enp3s0f1 name enp3s0f1.1012 type vlan id 1012
You can then assign an IP address to the interface enp3s0f1.1012.
Linux Switch[edit | edit source]
You can make your linux box act like a smart switch by using this script:
#!/bin/bash
declare -a Ports # List of ports
declare -A Config # Vlan ID for each port
declare -A Vlans # key=>value | vlanid=>vlan name
Uplink="p4p2"
DryRun=0
function Main() {
setup_requirements
add_vlan 911 "BuildNet"
add_vlan 912 "BuildNet2"
add_vlan 1010 "DeptNFS"
add_vlan 7 "WildWest"
add_vlan 1012 "AdminNet"
add_vlan 915 "OS-Int"
# add_vlan 916 "OS-VM"
# Interfaces are sorted. Run `get_network_interfaces` to see the mapping.
# eth2 p1p1 p1p2 p4p2
config_port 0 911
config_port 1 911
config_port 2 7
# config_port 3 trunked
setup_network
show_ports
configure_port_vlan
show_config
# Give this machine an IP address through a bridge.
# ifconfig br1010 172.17.10.9 netmask 255.255.255.0
# route add default gw 172.17.10.1
# Statically configure the network for this machine on the trunked bridge
# p4p2 (the uplink) at 1010 is our interface.
ifconfig br1010 172.17.10.9 netmask 255.255.255.0
route add default gw 172.17.10.1
# dhclient br1010
}
function setup_requirements() {
echo 1 > /proc/sys/net/ipv4/ip_forward
modprobe 8021q
}
function get_network_interfaces() {
# Get all interfaces except bridges and vlan interfaces and loopback
/sbin/ip a \
| /bin/grep -E '^[0-9]+' \
| cut -f2 -d' ' \
| grep -vE '(br|@)' \
| tr : ' ' \
| grep -v lo \
| sort
}
function config_port() {
Config[$1]="$2"
}
function add_vlan() {
Vlans[$1]="$2"
}
function die() {
echo $@
exit
}
function show_ports() {
echo "Network Interfaces Found:"
for i in "${!Ports[@]}" ; do
echo "$i: ${Ports[$i]}"
done
}
function show_config() {
echo "Vlan Configuration:"
for i in "${!Ports[@]}" ; do
Vlan=${Config[$i]}
echo "$i: ${Ports[$i]} --> VLAN $Vlan (${Vlans[$Vlan]})"
done
}
function teardown_network() {
ifconfig $Uplink down
for Port in "${Ports[@]}" ; do
ifconfig $Port down
done
cat /proc/net/vlan/config | tail -n+3 | cut -f1 -d' '|tr . ' ' | while read line ; do
Port=`echo $line | cut -f1 -d' '`
Vlan=`echo $line | cut -f2 -d' '`
brctl delif br$Vlan $Uplink.Vlan
brctl delbr br$Vlan
vconfig rem $Uplink.$Vlan
done
}
function setup_network() {
Interfaces=$(get_network_interfaces)
echo $Interfaces | grep $Uplink > /dev/null || die "Could not find $Uplink interface."
# Add each port to the ports list excluding the uplink
for Port in $Interfaces ; do
if [[ "$Port" != "$Uplink" ]] ; then
Ports+=($Port)
fi
done
# Set up vlans on the uplink port
for i in "${!Vlans[@]}" ; do
Vlan=$i
VlanName=${Vlans[$i]}
# Check to see if it's already configured. Skip if it is.
grep "\b$Vlan\b" /proc/net/vlan/config > /dev/null && continue
# Add vlan to port. This creates $Uplink.$Vlan
vconfig add $Uplink $Vlan
# Create bridge for each vlan
brctl addbr br$Vlan
brctl addif br$Vlan $Uplink.$Vlan
# Start the bridge and vlan uplink
ifconfig br$Vlan up
ifconfig $Uplink.$Vlan up
done
}
function configure_port_vlan() {
# Ensure everything is down.
for i in "${!Ports[@]}" ; do
Vlan=${Config[$i]}
Port=${Ports[$i]}
# Add the port to the vlan bridge
brctl addif br$Vlan $Port
ifconfig $Port up
done
# Start things up
for Port in "${Ports[@]}" ; do
ifconfig $Port up
done
}
function ifconfig() {
echo ifconfig $@
if [ $DryRun -eq 0 ] ; then
/sbin/ifconfig $@
fi
}
function brctl() {
echo brctl $@
if [ $DryRun -eq 0 ] ; then
/sbin/brctl $@
fi
}
function vconfig() {
echo vconfig $@
if [ $DryRun -eq 0 ] ; then
/sbin/vconfig $@
fi
}
function dhclient() {
echo dhclient $@
if [ $DryRun -eq 0 ] ; then
/sbin/dhclient $@
fi
}
Main $@