2015-06-29 11:14:42 +01:00
|
|
|
#!/bin/sh
|
|
|
|
|
#-------------------------------------------------------------------------+
|
|
|
|
|
# Copyright (C) 2015 Matt Churchyard (churchers@gmail.com)
|
|
|
|
|
# All rights reserved
|
|
|
|
|
#
|
|
|
|
|
# Redistribution and use in source and binary forms, with or without
|
|
|
|
|
# modification, are permitted providing that the following conditions
|
|
|
|
|
# are met:
|
|
|
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
|
|
|
# notice, this list of conditions and the following disclaimer.
|
|
|
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
|
|
|
# documentation and/or other materials provided with the distribution.
|
|
|
|
|
#
|
|
|
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
|
|
|
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
|
|
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
|
|
|
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
|
|
# create switches from rc list on init
|
2015-10-19 13:27:55 +01:00
|
|
|
# this should run once per boot to make sure switches from the
|
|
|
|
|
# configuration file have bridge interfaces. If any new switches are
|
|
|
|
|
# created, the bridge is done at the same time
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_init(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switchlist _switch _id
|
2016-04-07 11:25:11 +01:00
|
|
|
local _nat _havenat=0 _bridge _vale
|
2015-11-14 14:04:19 +00:00
|
|
|
|
|
|
|
|
__config_load "${vm_dir}/.config/switch"
|
|
|
|
|
__config_get "_switchlist" "switch_list"
|
|
|
|
|
|
|
|
|
|
# create bridges for each switch if they don't already exist
|
|
|
|
|
if [ -n "${_switchlist}" ]; then
|
|
|
|
|
for _switch in ${_switchlist}; do
|
|
|
|
|
__switch_get_ident "_id" "${_switch}"
|
|
|
|
|
[ -n "${_id}" ] && continue
|
|
|
|
|
|
|
|
|
|
__config_get "_nat" "nat_${_switch}"
|
|
|
|
|
__config_get "_bridge" "bridge_${_switch}"
|
|
|
|
|
|
2016-04-07 11:25:11 +01:00
|
|
|
# do nothing if it's a vale switch
|
|
|
|
|
__config_get "_vale" "vale_${_switch}"
|
|
|
|
|
__checkyesno "${_vale}" && continue
|
|
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
if [ -n "${_bridge}" ]; then
|
|
|
|
|
ifconfig "${_bridge}" description "vm-${_switch}" up >/dev/null 2>&1
|
|
|
|
|
else
|
|
|
|
|
_id=$(ifconfig bridge create)
|
|
|
|
|
[ $? -ne 0 ] && __err "failed to create bridge interface"
|
|
|
|
|
ifconfig "${_id}" description "vm-${_switch}" up
|
|
|
|
|
|
|
|
|
|
# add all member interfaces
|
|
|
|
|
__switch_add_allmembers "${_switch}" "${_id}"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
[ -n "${_nat}" ] &&_havenat="1"
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# only load dnsmasq/pf if we have a nat switch
|
|
|
|
|
[ "${_havenat}" = "1" ] && __switch_nat_init
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# list switches, currently just from stored configuration
|
2015-10-19 13:27:55 +01:00
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_list(){
|
2016-04-07 11:25:11 +01:00
|
|
|
local _switchlist _portlist _switch _port
|
|
|
|
|
local _vlan _nat _bridge _type _vale
|
2015-11-14 14:04:19 +00:00
|
|
|
local _id _format="%-15s %-10s %-11s %-9s %-12s %s\n"
|
|
|
|
|
|
|
|
|
|
__config_load "${vm_dir}/.config/switch"
|
|
|
|
|
__config_get "_switchlist" "switch_list"
|
|
|
|
|
|
|
|
|
|
printf "${_format}" "NAME" "TYPE" "IDENT" "VLAN" "NAT" "PORTS"
|
|
|
|
|
|
|
|
|
|
for _switch in ${_switchlist}; do
|
|
|
|
|
__switch_get_ident "_id" "${_switch}"
|
|
|
|
|
[ -z "${_id}" ] && _id="-"
|
|
|
|
|
|
|
|
|
|
__config_get "_portlist" "ports_${_switch}"
|
|
|
|
|
__config_get "_vlan" "vlan_${_switch}"
|
|
|
|
|
__config_get "_nat" "nat_${_switch}"
|
|
|
|
|
__config_get "_bridge" "bridge_${_switch}"
|
2016-04-07 11:25:11 +01:00
|
|
|
__config_get "_vale" "vale_${_switch}"
|
|
|
|
|
|
|
|
|
|
if __checkyesno "${_vale}"; then
|
|
|
|
|
_type="vale"
|
|
|
|
|
__switch_vale_id "_id" "${_switch}"
|
|
|
|
|
: ${_portlist:=n/a}
|
|
|
|
|
: ${_vlan:=n/a}
|
|
|
|
|
: ${_nat:=n/a}
|
|
|
|
|
elif [ -z "${_bridge}" ]; then
|
2015-11-14 14:04:19 +00:00
|
|
|
_type="auto"
|
|
|
|
|
: ${_portlist:=-}
|
|
|
|
|
: ${_vlan:=-}
|
|
|
|
|
: ${_nat:=-}
|
|
|
|
|
else
|
|
|
|
|
_type="manual"
|
|
|
|
|
_portlist="n/a"
|
|
|
|
|
_vlan="n/a"
|
|
|
|
|
_nat="n/a"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
printf "${_format}" "${_switch}" "${_type}" "${_id}" "${_vlan}" "${_nat}" "${_portlist}"
|
|
|
|
|
done
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# 'vm switch create'
|
2015-06-29 11:14:42 +01:00
|
|
|
# create a new virtual switch
|
2015-10-19 13:27:55 +01:00
|
|
|
#
|
|
|
|
|
# @param string _switch name of the switch to create
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_create(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _id _curr_list _curr
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-26 19:59:40 +00:00
|
|
|
echo "${_switch}" | egrep -iqs '^[a-z0-9][a-z0-9\_\-\.]{0,14}[a-z0-9]$'
|
2015-11-14 14:04:19 +00:00
|
|
|
[ $? -ne 0 ] && __err "invalid switch name"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
_curr_list=$(sysrc -inqf "${vm_dir}/.config/switch" switch_list)
|
2015-10-19 10:47:50 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
for _curr in $_curr_list; do
|
|
|
|
|
[ "${_switch}" = "${_curr}" ] && __err "switch ${_switch} already exists"
|
|
|
|
|
done
|
2015-10-19 10:47:50 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
__rc_append_string ".config/switch" "switch_list" "${_switch}"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
_id=$(ifconfig bridge create)
|
|
|
|
|
[ $? -ne 0 ] && __err "failed to create bridge interface"
|
|
|
|
|
ifconfig "${_id}" description "vm-${_switch}" up
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-11-09 10:11:28 +00:00
|
|
|
# 'vm switch import'
|
|
|
|
|
# use an existing manually configured bridge
|
|
|
|
|
#
|
|
|
|
|
# @param string _switch name of the switch to create
|
|
|
|
|
# @param string _bridge name of the bridge interface to import
|
|
|
|
|
#
|
|
|
|
|
__switch_import(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _bridge="$2"
|
|
|
|
|
local _exists
|
2015-11-09 10:11:28 +00:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
[ -z "${_switch}" -o -z "${_bridge}" ] && __usage
|
2015-11-09 10:11:28 +00:00
|
|
|
|
2015-11-26 19:59:40 +00:00
|
|
|
echo "${_switch}" | egrep -iqs '^[a-z0-9][a-z0-9\_\-\.]{0,14}[a-z0-9]$'
|
2015-11-09 10:11:28 +00:00
|
|
|
[ $? -ne 0 ] && __err "invalid switch name"
|
|
|
|
|
|
|
|
|
|
_curr_list=$(sysrc -inqf "${vm_dir}/.config/switch" switch_list)
|
|
|
|
|
|
|
|
|
|
for _curr in $_curr_list; do
|
|
|
|
|
[ "${_switch}" = "${_curr}" ] && __err "switch ${_switch} already exists"
|
|
|
|
|
done
|
|
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
_exists=$(ifconfig | grep "^${_bridge}: ")
|
|
|
|
|
[ -z "${_exists}" ] && __err "${_bridge} does not appear to be a valid existing bridge"
|
2015-11-09 10:11:28 +00:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
__rc_append_string ".config/switch" "switch_list" "${_switch}"
|
|
|
|
|
sysrc -inqf "${vm_dir}/.config/switch" "bridge_${_switch}"="${_bridge}" >/dev/null 2>&1
|
2015-11-09 10:11:28 +00:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
# attach our description to bridge
|
|
|
|
|
# this will allow vm-bhyve to find it and attach guests
|
|
|
|
|
ifconfig "${_bridge}" description "vm-${_switch}" up
|
2015-11-09 10:11:28 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# 'vm switch destroy'
|
2015-06-29 11:14:42 +01:00
|
|
|
# remove a virtual switch
|
2015-10-19 13:27:55 +01:00
|
|
|
#
|
|
|
|
|
# @param string _switch name of the switch
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_remove(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
2016-04-07 11:25:11 +01:00
|
|
|
local _id _nat _bridge _vale
|
2015-11-14 14:04:19 +00:00
|
|
|
|
|
|
|
|
__config_load "${vm_dir}/.config/switch"
|
|
|
|
|
__config_get "_bridge" "bridge_${_switch}"
|
|
|
|
|
__config_get "_nat" "nat_${_switch}"
|
2016-04-07 11:25:11 +01:00
|
|
|
__config_get "_vale" "vale_${_switch}"
|
2015-11-14 14:04:19 +00:00
|
|
|
|
|
|
|
|
# if manual, leave it there and just remove from our config
|
|
|
|
|
if [ -n "${_bridge}" ]; then
|
|
|
|
|
ifconfig "${_bridge}" description "" >/dev/null 2>&1
|
|
|
|
|
__rc_splice_string ".config/switch" "switch_list" "${_switch}"
|
|
|
|
|
sysrc -inxqf "${vm_dir}/.config/switch" "bridge_${_switch}"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
2016-04-07 11:25:11 +01:00
|
|
|
if [ -z "${_vale}" ]; then
|
|
|
|
|
__switch_get_ident "_id" "${_switch}"
|
|
|
|
|
__switch_remove_allmembers "${_switch}" "${_id}"
|
|
|
|
|
fi
|
|
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
__rc_splice_string ".config/switch" "switch_list" "${_switch}"
|
2016-04-07 11:25:11 +01:00
|
|
|
sysrc -inxqf "${vm_dir}/.config/switch" "ports_${_switch}" "vlan_${_switch}" \
|
|
|
|
|
"nat_${_switch}" "vale_${_switch}" >/dev/null 2>&1
|
2015-11-14 14:04:19 +00:00
|
|
|
|
2016-04-07 11:25:11 +01:00
|
|
|
if [ -z "${_vale}" ]; then
|
|
|
|
|
if [ -n "${_id}" ]; then
|
|
|
|
|
ifconfig "${_id}" destroy >/dev/null 2>&1
|
|
|
|
|
[ $? -ne 0 ] && __warn "removed configuration but failed to remove bridge"
|
|
|
|
|
else
|
|
|
|
|
__warn "removed configuration but failed to remove bridge"
|
|
|
|
|
fi
|
2015-11-14 14:04:19 +00:00
|
|
|
|
2016-04-07 11:25:11 +01:00
|
|
|
# reset nat if this switch had nat
|
|
|
|
|
[ -n "${_nat}" ] && __switch_nat_init
|
|
|
|
|
fi
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# 'vm switch vlan'
|
2015-06-29 11:14:42 +01:00
|
|
|
# set vlan number for a switch
|
2015-10-19 13:27:55 +01:00
|
|
|
# all interfaces will be removed, vlan interfaces created, then re-added
|
|
|
|
|
#
|
|
|
|
|
# @param string _switch name of the switch
|
|
|
|
|
# @param int _vlan vlan number (or 0 to switch vlan off)
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_vlan(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _vlan="$2"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
[ -z "${_switch}" -o -z "${_vlan}" ] && __usage
|
|
|
|
|
__switch_auto "${_switch}"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
echo "${_vlan}" | egrep -qs '^[0-9]{1,4}$'
|
|
|
|
|
[ $? -ne 0 ] && __err "invalid vlan number"
|
|
|
|
|
[ ${_vlan} -ge 4095 ] && __err "invalid vlan number"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
# we need to remove everything and re-add as raw interfaces will
|
|
|
|
|
# change to vlan or visa-versa
|
|
|
|
|
__switch_remove_allmembers "${_switch}"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
if [ "${_vlan}" = "0" ]; then
|
|
|
|
|
sysrc -inxqf "${vm_dir}/.config/switch" "vlan_${_switch}" >/dev/null 2>&1
|
|
|
|
|
else
|
|
|
|
|
sysrc -inqf "${vm_dir}/.config/switch" "vlan_${_switch}"="${_vlan}" >/dev/null 2>&1
|
|
|
|
|
fi
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
# put interfaces back in
|
|
|
|
|
__switch_add_allmembers "${_switch}"
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# physically add switch member interfaces
|
|
|
|
|
# this will add all configured interfaces to the bridge
|
|
|
|
|
# if vlan specified, each real interface will be assigned to a vlan interface
|
|
|
|
|
#
|
|
|
|
|
# @private
|
|
|
|
|
# @param string _switch the switch to configure
|
|
|
|
|
# @param optional string _id switch id (eg bridge0) if already known
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_add_allmembers(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _id="$2"
|
|
|
|
|
local _portlist _port
|
|
|
|
|
|
|
|
|
|
if [ -z "${_id}" ]; then
|
|
|
|
|
__switch_get_ident "_id" "${_switch}"
|
|
|
|
|
[ -z "${_id}" ] && __err "failed to get switch id while adding members"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
_portlist=$(sysrc -inqf "${vm_dir}/.config/switch" "ports_${_switch}")
|
|
|
|
|
|
|
|
|
|
if [ -n "${_portlist}" ]; then
|
|
|
|
|
for _port in ${_portlist}; do
|
|
|
|
|
__switch_configure_port "${_switch}" "${_id}" "${_port}"
|
|
|
|
|
done
|
|
|
|
|
fi
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# physically remove all configured members from a switch
|
|
|
|
|
#
|
|
|
|
|
# @private
|
|
|
|
|
# @param string _switch name of the switch
|
|
|
|
|
# @param optional string _id switch id if already known
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_remove_allmembers(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _id="$2"
|
|
|
|
|
local _portlist _port
|
|
|
|
|
|
|
|
|
|
if [ -z "${_id}" ]; then
|
|
|
|
|
__switch_get_ident "_id" "${_switch}"
|
|
|
|
|
[ -z "${_id}" ] && __err "failed to get switch id while removing members"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
_portlist=$(sysrc -inqf "${vm_dir}/.config/switch" "ports_${_switch}")
|
|
|
|
|
|
|
|
|
|
if [ -n "${_portlist}" ]; then
|
|
|
|
|
for _port in ${_portlist}; do
|
|
|
|
|
__switch_unconfigure_port "${_switch}" "${_id}" "${_port}"
|
|
|
|
|
done
|
|
|
|
|
fi
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# physically adds a port to a virtual switch
|
2015-08-12 15:11:44 +01:00
|
|
|
# if vlan is configured, we need to create the relevant vlan interface first,
|
|
|
|
|
# then add that to the bridge
|
2015-10-19 13:27:55 +01:00
|
|
|
#
|
|
|
|
|
# @private
|
|
|
|
|
# @param string _switch the switch to add port to
|
|
|
|
|
# @param string _id the switch id
|
|
|
|
|
# @param string _member name of the member interface to add
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_configure_port(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _id="$2"
|
|
|
|
|
local _member="$3"
|
|
|
|
|
local _vlan _vid
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
_vlan=$(sysrc -inqf "${vm_dir}/.config/switch" "vlan_${_switch}")
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
if [ -n "${_vlan}" ]; then
|
|
|
|
|
__switch_get_ident "_vid" "vlan-${_member}-${_vlan}"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
if [ -z "${_vid}" ]; then
|
|
|
|
|
_vid=$(ifconfig vlan create)
|
|
|
|
|
[ $? -ne 0 ] && __err "failed to create vlan interface"
|
|
|
|
|
ifconfig "${_vid}" vlandev "${_member}" vlan "${_vlan}" description "vm-vlan-${_member}-${_vlan}"
|
|
|
|
|
fi
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
ifconfig ${_id} addm ${_vid} >/dev/null 2>&1
|
|
|
|
|
else
|
|
|
|
|
ifconfig ${_id} addm ${_member} >/dev/null 2>&1
|
|
|
|
|
fi
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
[ $? -ne 0 ] && __err "failed to add member to the virtual switch"
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# 'vm switch add'
|
2015-06-29 11:14:42 +01:00
|
|
|
# configure a member interface to a "switch"
|
2015-10-19 13:27:55 +01:00
|
|
|
# add the interface to bridge and update switch configuration
|
|
|
|
|
#
|
|
|
|
|
# @param string _switch name of the switch
|
|
|
|
|
# @param string _member name of the interface to add
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_add_member(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _member="$2"
|
|
|
|
|
local _id
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
[ -z "${_switch}" -o -z "${_member}" ] && __usage
|
2015-11-09 10:11:28 +00:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
__switch_auto "${_switch}"
|
|
|
|
|
__switch_get_ident "_id" "${_switch}"
|
|
|
|
|
[ -z "${_id}" ] && __err "unable to locate virtual switch ${_id}"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
__switch_configure_port "${_switch}" "${_id}" "${_member}"
|
|
|
|
|
__rc_append_string ".config/switch" "ports_${_switch}" "${_member}"
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# physically remove a port from a virtual switch / bridge
|
2015-10-19 13:27:55 +01:00
|
|
|
#
|
|
|
|
|
# @private
|
|
|
|
|
# @param string _switch the switch to update
|
|
|
|
|
# @param string _id the switch id
|
|
|
|
|
# @param string _member the interface to remove
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_unconfigure_port(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _id="$2"
|
|
|
|
|
local _member="$3"
|
|
|
|
|
local _id _vlan _vid _usage
|
|
|
|
|
|
|
|
|
|
_vlan=$(sysrc -inqf "${vm_dir}/.config/switch" "vlan_${_switch}")
|
|
|
|
|
|
|
|
|
|
if [ -n "${_vlan}" ]; then
|
|
|
|
|
__switch_get_ident "_vid" "vlan-${_member}-${_vlan}"
|
|
|
|
|
[ -z "${_vid}" ] && __err "unable to find relevent vlan interface for ${_member}"
|
|
|
|
|
|
|
|
|
|
ifconfig ${_id} deletem ${_vid} >/dev/null 2>&1
|
|
|
|
|
else
|
|
|
|
|
ifconfig ${_id} deletem ${_member} >/dev/null 2>&1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
[ $? -ne 0 ] && __err "failed to remove member from the virtual switch"
|
|
|
|
|
|
|
|
|
|
# it's possible a vlan interface may be assigned to multiple switches
|
|
|
|
|
# we want to remove the vlan interface if possible, but not if it's
|
|
|
|
|
# still assigned to another switch
|
|
|
|
|
if [ -n "${_vlan}" -a -n "${_vid}" ]; then
|
|
|
|
|
_usage=$(ifconfig -a |grep "member: vm-vlan-${_member}-${_vlan}\$")
|
|
|
|
|
[ -z "${_usage}" ] && ifconfig "${_vid}" destroy >/dev/null 2>&1
|
|
|
|
|
fi
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# 'vm switch remove'
|
2015-06-29 11:14:42 +01:00
|
|
|
# remove a member interface from a switch configuration
|
2015-10-19 13:27:55 +01:00
|
|
|
# update configuration then remove device from bridge
|
|
|
|
|
#
|
|
|
|
|
# @param string _switch the switch to update
|
|
|
|
|
# @param string _member the interface to remove
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_remove_member(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _member="$2"
|
|
|
|
|
local _id
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
[ -z "${_switch}" -o -z "${_member}" ] && __usage
|
2015-11-09 10:11:28 +00:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
__switch_auto "${_switch}"
|
|
|
|
|
__switch_get_ident "_id" "${_switch}"
|
|
|
|
|
[ -z "${_id}" ] && __err "unable to locate virtual switch ${_id}"
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
__rc_splice_string ".config/switch" "ports_${_switch}" "${_member}"
|
|
|
|
|
__switch_unconfigure_port "${_switch}" "${_id}" "${_member}"
|
2015-06-29 11:14:42 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-19 13:27:55 +01:00
|
|
|
# 'vm switch nat'
|
2015-08-07 16:52:07 +01:00
|
|
|
# configure nat on a switch
|
2015-08-12 15:11:44 +01:00
|
|
|
# this function just deals with the vm-bhyve configuration
|
2015-10-19 13:27:55 +01:00
|
|
|
#
|
|
|
|
|
# @param string _switch the name of the switch
|
|
|
|
|
# @param string _nat=on|off whether to switch it on or off
|
|
|
|
|
#
|
2015-08-07 16:52:07 +01:00
|
|
|
__switch_nat(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
|
|
|
|
local _nat="$2"
|
|
|
|
|
|
|
|
|
|
[ -z "${_switch}" ] && __usage
|
|
|
|
|
__switch_auto "${_switch}"
|
|
|
|
|
|
|
|
|
|
case "${_nat}" in
|
|
|
|
|
off)
|
|
|
|
|
sysrc -inxqf "${vm_dir}/.config/switch" "nat_${_switch}"
|
|
|
|
|
;;
|
|
|
|
|
on)
|
|
|
|
|
if ! checkyesno pf_enable; then
|
|
|
|
|
__err "pf needs to be enabled for nat functionality"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
sysrc -inqf "${vm_dir}/.config/switch" "nat_${_switch}=yes" >/dev/null 2>&1
|
|
|
|
|
[ $? -ne 0 ] && __err "failed to store nat configuration"
|
|
|
|
|
|
|
|
|
|
echo "******"
|
|
|
|
|
echo " NAT has been enabled on the specified switch"
|
|
|
|
|
echo " A sample dnsmasq configuration has been created in /usr/local/etc/dnsmasq.conf.bhyve"
|
|
|
|
|
echo " To enable DHCP on this switch, please install the dnsmasq confguration or merge with your existing."
|
|
|
|
|
echo "******"
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
__err "last option should either be 'on' or 'off' to enable/disable nat functionality"
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
# reset nat configuration
|
|
|
|
|
__switch_nat_init
|
2015-08-07 16:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# set the system up for nat usage
|
2015-08-12 15:11:44 +01:00
|
|
|
# do the actual nat work
|
|
|
|
|
# we completely take over dnsmasq and assign it to the required interfaces
|
|
|
|
|
# /etc/pf.conf gets an include statement added pointing to a file in
|
|
|
|
|
# out .config directory. This file contains a nat rule for each nat switch
|
2015-10-19 13:27:55 +01:00
|
|
|
#
|
|
|
|
|
# @private
|
|
|
|
|
#
|
2015-08-08 12:21:01 +01:00
|
|
|
__switch_nat_init(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _pf_rules="${vm_dir}/.config/pf-nat.conf"
|
|
|
|
|
local _havenat=0
|
|
|
|
|
local _grep _switchlist _nat _net24 _if
|
|
|
|
|
local _gw _bnum
|
|
|
|
|
|
|
|
|
|
# get default gateway
|
2016-02-01 17:40:48 +01:00
|
|
|
_gw=$(netstat -4rn | grep default | awk '{print $4}')
|
2015-11-14 14:04:19 +00:00
|
|
|
|
|
|
|
|
# basic dnsmasq settings
|
|
|
|
|
echo "# vm-bhyve dhcp" > /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "port=0" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "domain-needed" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "no-resolv" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "except-interface=lo0" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "bind-interfaces" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "local-service" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "dhcp-authoritative" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
|
|
|
|
|
# reset our pf config and create /etc/pf.conf if needed
|
|
|
|
|
echo "# vm-bhyve nat" > "${vm_dir}/.config/pf-nat.conf"
|
|
|
|
|
[ ! -e "/etc/pf.conf" ] && touch /etc/pf.conf
|
|
|
|
|
|
|
|
|
|
# only add our include statement to /etc/pf.conf if it's not already in there somwhere
|
|
|
|
|
_grep=$(grep "${_pf_rules}" /etc/pf.conf)
|
|
|
|
|
[ -z "${_grep}" ] && echo "include \"${_pf_rules}\"" >> /etc/pf.conf
|
|
|
|
|
|
|
|
|
|
_switchlist=$(sysrc -inqf "${vm_dir}/.config/switch" switch_list)
|
|
|
|
|
|
|
|
|
|
# add each nat switch to dnsmasq.conf and .config/pf-nat.conf
|
|
|
|
|
for _switch in ${_switchlist}; do
|
|
|
|
|
_nat=$(sysrc -inqf "${vm_dir}/.config/switch" "nat_${_switch}")
|
|
|
|
|
__switch_get_ident "_id" "${_switch}"
|
|
|
|
|
|
|
|
|
|
if [ "${_nat}" = "yes" -a -n "${_id}" ]; then
|
|
|
|
|
_bnum=$(echo "${_id}" |awk -F'bridge' '{print $2}')
|
|
|
|
|
_net24="172.16.${_bnum}"
|
|
|
|
|
|
|
|
|
|
echo "nat on ${_gw} from {${_net24}.0/24} to any -> (${_gw})" >> "${vm_dir}/.config/pf-nat.conf"
|
|
|
|
|
echo "" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "interface=${_id}" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
echo "dhcp-range=${_net24}.10,${_net24}.254" >> /usr/local/etc/dnsmasq.conf.bhyve
|
|
|
|
|
|
|
|
|
|
# make sure interface has an ip
|
|
|
|
|
# this doesn't get removed when nat disabled but not a major issue
|
|
|
|
|
ifconfig "${_id}" ${_net24}.1/24
|
|
|
|
|
|
|
|
|
|
_havenat="1"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# make sure forwarding enabled if we have any nat
|
|
|
|
|
[ "${_havenat}" = "1" ] && sysctl net.inet.ip.forwarding=1 >/dev/null 2>&1
|
|
|
|
|
|
|
|
|
|
# restart services regardless
|
|
|
|
|
# still need to restart if _havenat=0, in case we've just removed last nat switch
|
|
|
|
|
__restart_service "pf"
|
2015-08-07 16:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
2016-04-05 10:29:47 +01:00
|
|
|
# check if a switch is a vale switch
|
|
|
|
|
# if so, we don't need to actually create anything.
|
|
|
|
|
# interfaces are created on demand when starting guests,
|
|
|
|
|
# and vale switches are dynamic
|
|
|
|
|
#
|
|
|
|
|
__switch_is_vale(){
|
|
|
|
|
local _switch="$1"
|
|
|
|
|
local _is_vale=$(sysrc -inqf "${vm_dir}/.config/switch" "vale_${_switch}")
|
|
|
|
|
|
|
|
|
|
[ -z "${_is_vale}" ] && return 1
|
|
|
|
|
|
|
|
|
|
if __checkyesno "${_is_vale}"; then
|
|
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# gets a unique port name for a vale interface
|
|
|
|
|
# we need to make sure vale switch name is the same
|
|
|
|
|
# for all interfaces on the same switch, but port is
|
|
|
|
|
# different
|
|
|
|
|
#
|
|
|
|
|
# @param string _var name of variable to put port name into
|
|
|
|
|
# @param string _switch the name of the switch
|
|
|
|
|
# @param string _port unique port identifier (usually mac address)
|
|
|
|
|
#
|
2016-04-07 11:25:11 +01:00
|
|
|
__switch_vale_id(){
|
2016-04-05 10:29:47 +01:00
|
|
|
local _var="$1"
|
2016-04-07 11:25:11 +01:00
|
|
|
local _switch="$2"
|
|
|
|
|
local _port="$3"
|
2016-04-05 10:29:47 +01:00
|
|
|
local _id_s _id_p
|
|
|
|
|
|
2016-04-07 11:25:11 +01:00
|
|
|
# get a switch id
|
2016-04-05 10:29:47 +01:00
|
|
|
_id_s=$(md5 -qs "${_switch}" | awk '{print substr($0,0,5)}')
|
|
|
|
|
|
2016-04-07 11:25:11 +01:00
|
|
|
# given port?
|
|
|
|
|
if [ -n "${_port}" ]; then
|
|
|
|
|
_id_p=$(md5 -qs "${_port}" | awk '{print substr($0,0,5)}')
|
|
|
|
|
setvar "${_var}" "vale${_id_s}:${_id_p}"
|
|
|
|
|
else
|
|
|
|
|
setvar "${_var}" "vale${_id_s}"
|
|
|
|
|
fi
|
2016-04-05 10:29:47 +01:00
|
|
|
}
|
|
|
|
|
|
2015-11-09 10:11:28 +00:00
|
|
|
# produce an error if the listed switch is not managed by vm-bhyve.
|
|
|
|
|
# we allow users to import existing bridges which they configure themselves.
|
|
|
|
|
# we don't allow vm-bhyve to mess with these, it's all up to the user
|
2016-04-07 11:25:11 +01:00
|
|
|
# also don't mess with vale switches
|
2015-11-09 10:11:28 +00:00
|
|
|
#
|
|
|
|
|
# @param string _switch the name of the switch
|
|
|
|
|
#
|
|
|
|
|
__switch_auto(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _switch="$1"
|
2016-04-07 11:25:11 +01:00
|
|
|
local _bridge _vale
|
2015-11-09 10:11:28 +00:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
_bridge=$(sysrc -inqf "${vm_dir}/.config/switch" "bridge_${_switch}")
|
2016-04-07 11:25:11 +01:00
|
|
|
_vale=$(sysrc -inqf "${vm_dir}/.config/switch" "vale_${_switch}")
|
2015-11-14 14:04:19 +00:00
|
|
|
[ -n "${_bridge}" ] && __err "this is a manual switch that is managed outside of vm-bhyve"
|
2016-04-07 11:25:11 +01:00
|
|
|
[ -n "${_vale}" ] && __err "this command is not currently supported on vale switches"
|
2015-11-09 10:11:28 +00:00
|
|
|
}
|
|
|
|
|
|
2015-06-29 11:14:42 +01:00
|
|
|
# get the interface name for a switch
|
2015-10-19 13:27:55 +01:00
|
|
|
# the id will be the name of the bridge interface (eg. "bridge0")
|
|
|
|
|
# ifconfig will have "description: vm-switchname" directly below the first interface line
|
|
|
|
|
#
|
2015-10-19 16:26:20 +01:00
|
|
|
# @param string _var variable to put id into
|
2015-10-19 13:27:55 +01:00
|
|
|
# @param string _switch the switch to look for
|
|
|
|
|
#
|
2015-06-29 11:14:42 +01:00
|
|
|
__switch_get_ident(){
|
2015-11-14 14:04:19 +00:00
|
|
|
local _var="$1"
|
|
|
|
|
local _switch="$2"
|
|
|
|
|
local _c_id
|
2015-06-29 11:14:42 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
# search ifconfig for our switch id, and pull bridge interface name from preceeding line
|
|
|
|
|
# we've got rid of trailing '-' on switch names but on vm-bhyve upgrade, before host reboot, users may still have them
|
|
|
|
|
_c_id=$(ifconfig -a | grep -B 1 "vm-${_switch}\$" | head -n 1 | awk -F: '{print $1}')
|
|
|
|
|
[ -z "${_c_id}" ] && _c_id=$(ifconfig -a | grep -B 1 "vm-${_switch}-\$" | head -n 1 | awk -F: '{print $1}')
|
2015-10-19 10:47:50 +01:00
|
|
|
|
2015-11-14 14:04:19 +00:00
|
|
|
setvar "${_var}" "${_c_id}"
|
2015-06-30 10:21:30 +01:00
|
|
|
}
|