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
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 $@