Linux Vlan: Difference between revisions

From Leo's Notes
This page was last edited on 1 September 2019, at 06:21.
Created page with "You can make your linux box act like a smart switch by using this script: <syntaxhighlight lang="bash"> #!/bin/bash echo 0 > /proc/sys/net/ipv4/ip_forward modprobe 8021q ..."
 
m Text replacement - "Category:Linux{{Navbox Linux}}" to "{{Navbox Linux}}Category:Linux"
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
If an interface is trunked, you can 'untag' the traffic like so:
{{highlight|lang=terminal|code=
# 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:
You can make your linux box act like a smart switch by using this script:


Line 4: Line 15:
#!/bin/bash
#!/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"


echo 0 >  /proc/sys/net/ipv4/ip_forward
DryRun=0


modprobe 8021q
function Main() {
setup_requirements


# Uplink
add_vlan 911 "BuildNet"
Uplink="p4p2"
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
}


# Ports
function show_ports() {
Port1="p1p1"
echo "Network Interfaces Found:"
Port2="p1p2"
for i in "${!Ports[@]}" ; do
Port3="p4p1"
echo "$i: ${Ports[$i]}"
done
}


# Vlans
function show_config() {
Vlans="911 1010 7"
echo "Vlan Configuration:"
for i in "${!Ports[@]}" ; do
Vlan=${Config[$i]}
echo "$i: ${Ports[$i]} --> VLAN $Vlan (${Vlans[$Vlan]})"
done
}


# Make sure everything else is down until we reconfigure
function teardown_network() {
ifconfig $Uplink down
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' '`


ifconfig $Port1 down
brctl delif br$Vlan $Uplink.Vlan
ifconfig $Port2 down
brctl delbr br$Vlan
ifconfig $Port3 down


vconfig rem $Uplink.$Vlan
done
}


#
function setup_network() {
# Set up the vlans on the uplink port.
Interfaces=$(get_network_interfaces)
#
echo $Interfaces | grep $Uplink > /dev/null || die "Could not find $Uplink interface."
for Vlan in $Vlans ; do
# Add each port to the ports list excluding the uplink
vconfig add $Uplink $Vlan
for Port in $Interfaces ; do
brctl addbr br$Vlan
if [[ "$Port" != "$Uplink" ]] ; then
brctl addif br$Vlan $Uplink.$Vlan
Ports+=($Port)
done
fi
done


#
# Set up vlans on the uplink port
# Add our interfaces to the bridged VLANs
for i in "${!Vlans[@]}" ; do
#
Vlan=$i
brctl addif br911 $Port1
VlanName=${Vlans[$i]}
brctl addif br7 $Port2
brctl addif br1010 $Port3


# Check to see if it's already configured. Skip if it is.
grep "\b$Vlan\b" /proc/net/vlan/config > /dev/null && continue


# Start things up
# Add vlan to port. This creates $Uplink.$Vlan
ifconfig p4p1 up
vconfig add $Uplink $Vlan
for Vlan in $Vlans ; do
ifconfig p4p1.$Vlan up
ifconfig br$Vlan up
done


ifconfig $Port1 up
# Create bridge for each vlan
ifconfig $Port2 up
brctl addbr br$Vlan
ifconfig $Port3 up
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]}


# This machine is on deptnfs, so get an IP on this interface
# Add the port to the vlan bridge
#dhclient br1010
brctl addif br$Vlan $Port
ifconfig br1010 172.17.10.9 netmask 255.255.255.0
ifconfig $Port up
route add default gw 172.17.10.1
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 $@
</syntaxhighlight>
</syntaxhighlight>
{{Navbox Linux}}[[Category:Linux]]
[[Category:Networking]]
[[Category:Todo]]

Latest revision as of 06:21, 1 September 2019

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