Linux Vlan: Difference between revisions

From Leo's Notes
This page was last edited on 30 March 2015, at 17:53.
mNo edit summary
No edit summary
Line 3: Line 3:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
#!/bin/bash
#!/bin/bash
echo 0 >  /proc/sys/net/ipv4/ip_forward


modprobe 8021q
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
}


# Uplink
function show_ports() {
Uplink="p4p2"
echo "Network Interfaces Found:"
for i in "${!Ports[@]}" ; do
echo "$i: ${Ports[$i]}"
done
}


# Ports
function show_config() {
Port1="p1p1"
echo "Vlan Configuration:"
Port2="p1p2"
for i in "${!Ports[@]}" ; do
Port3="p4p1"
Vlan=${Config[$i]}
echo "$i: ${Ports[$i]} --> VLAN $Vlan (${Vlans[$Vlan]})"
done
}


# Vlans
function teardown_network() {
Vlans="911 1010 7"
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' '`


# Make sure everything else is down until we reconfigure
brctl delif br$Vlan $Uplink.Vlan
ifconfig $Uplink down
brctl delbr br$Vlan


ifconfig $Port1 down
vconfig rem $Uplink.$Vlan
ifconfig $Port2 down
done
ifconfig $Port3 down
}


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
# Set up the vlans on the uplink port.
for i in "${!Vlans[@]}" ; do
#
Vlan=$i
for Vlan in $Vlans ; do
VlanName=${Vlans[$i]}
vconfig add $Uplink $Vlan
brctl addbr br$Vlan
brctl addif br$Vlan $Uplink.$Vlan
done


#
# Check to see if it's already configured. Skip if it is.
# Add our interfaces to the bridged VLANs
grep "\b$Vlan\b" /proc/net/vlan/config > /dev/null && continue
#
brctl addif br911 $Port1
brctl addif br7 $Port2
brctl addif br1010 $Port3


# Add vlan to port. This creates $Uplink.$Vlan
vconfig add $Uplink $Vlan


# Start things up
# Create bridge for each vlan
ifconfig p4p1 up
brctl addbr br$Vlan
for Vlan in $Vlans ; do
brctl addif br$Vlan $Uplink.$Vlan
ifconfig p4p1.$Vlan up
ifconfig br$Vlan up
# Start the bridge and vlan uplink
done
ifconfig br$Vlan up
ifconfig $Uplink.$Vlan up
done
}


ifconfig $Port1 up
function configure_port_vlan() {
ifconfig $Port2 up
# Ensure everything is down.
ifconfig $Port3 up
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


# This machine is on deptnfs, so get an IP on this interface
# Start things up
#dhclient br1010
for Port in "${Ports[@]}" ; do
ifconfig br1010 172.17.10.9 netmask 255.255.255.0
ifconfig $Port up
route add default gw 172.17.10.1
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>



Revision as of 17:53, 30 March 2015

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