diff --git a/lib/vm-info b/lib/vm-info index c84cc2d..b694924 100644 --- a/lib/vm-info +++ b/lib/vm-info @@ -96,7 +96,7 @@ info::switch(){ # info::switch_show(){ local _switch="$1" - local _type _bridge _vale _id + local _type _bridge _vale _netgraph, _id local _INDENT=" " [ -z "${_switch}" ] && return 1 @@ -104,6 +104,8 @@ info::switch_show(){ config::get "_type" "type_${_switch}" "standard" config::get "_bridge" "bridge_${_switch}" config::get "_vale" "vale_${_switch}" + config::get "_netgraph" "netgraph_${_switch}" + echo "------------------------" echo "Virtual Switch: ${_switch}" @@ -112,8 +114,8 @@ info::switch_show(){ echo "${_INDENT}type: ${_type}" switch::id "_id" "${_switch}" - # we don't have a bridge for vale switches - [ "${_type}" != "vale" ] && _bridge="${_id}" + # we don't have a bridge for vale and netgraph switches + [ "${_type}" != "vale" ] && [ "${_type}" != "netgraph" ] && _bridge="${_id}" echo "${_INDENT}ident: ${_id:--}" diff --git a/lib/vm-run b/lib/vm-run index 7febda7..fadd4e3 100644 --- a/lib/vm-run +++ b/lib/vm-run @@ -586,6 +586,15 @@ vm::bhyve_device_networking(){ _devices="${_devices} -s ${_slot}:${_func},${_type},${_tap}" [ -n "${_mac}" ] && _devices="${_devices},mac=${_mac}" + _func=$((_func + 1)) + elif [ "${_sw_type}" = "netgraph" ]; then + # create a netgraph peer + switch::netgraph::id "_path" "${_switch}" + + util::log "guest" "${_name}" "adding netgraph interface ${_path} (${_switch})" + _devices="${_devices} -s ${_slot}:${_func},${_type},${_path}" + [ -n "${_mac}" ] && _devices="${_devices},mac=${_mac}" + _func=$((_func + 1)) else # create interface diff --git a/lib/vm-switch b/lib/vm-switch index 2f25884..f7367ec 100644 --- a/lib/vm-switch +++ b/lib/vm-switch @@ -26,6 +26,7 @@ # switch libraries # +. "${LIB}/vm-switch-netgraph" . "${LIB}/vm-switch-manual" . "${LIB}/vm-switch-standard" . "${LIB}/vm-switch-vale" @@ -50,6 +51,7 @@ switch::init(){ vxlan) switch::vxlan::init "${_switch}" ;; manual) switch::manual::init "${_switch}" ;; vale) ;; + netgraph) ;; *) switch::standard::init "${_switch}" ;; esac done @@ -73,6 +75,7 @@ switch::list(){ config::core::get "_type" "type_${_switch}" case "${_type}" in + netgraph) switch::netgraph::show "${_switch}" "${_format}" ;; vale) switch::vale::show "${_switch}" "${_format}" ;; vxlan) switch::vxlan::show "${_switch}" "${_format}" ;; manual) switch::manual::show "${_switch}" "${_format}" ;; @@ -143,6 +146,7 @@ switch::create(){ case "${_type}" in standard) switch::standard::create ;; manual) switch::manual::create ;; + netgraph) switch::netgraph:create ;; vale) switch::vale::create ;; vxlan) switch::vxlan::create ;; *) util::err "invalid switch type - '${_type}'" ;; @@ -166,6 +170,7 @@ switch::remove(){ case "${_type}" in standard) switch::standard::remove "${_switch}" ;; manual) switch::manual::remove "${_switch}" ;; + netgraph) switch::netgraph::remove "${_switch}" ;; vale) switch::vale::remove "${_switch}" ;; vxlan) switch::vxlan::remove "${_switch}" ;; *) util::err "unable to remove switch of unknown type" ;; @@ -203,6 +208,7 @@ switch::add_member(){ case "${_type}" in standard) switch::standard::add_member "${_switch}" "${_if}" ;; manual) switch::manual::add_member "${_switch}" "${_if}" ;; + netgraph) switch::netgraph::add_member "${_switch}" "${_if}" ;; vale) switch::vale::add_member "${_switch}" "${_if}" ;; vxlan) switch::vxlan::add_member "${_switch}" "${_if}" ;; *) util::err "unable to configure switch of unknown type" ;; @@ -227,6 +233,7 @@ switch::remove_member(){ case "${_type}" in standard) switch::standard::remove_member "${_switch}" "${_if}" ;; manual) switch::manual::remove_member "${_switch}" "${_if}" ;; + netgraph) switch::netgraph::remove_member "${_switch}" "${_if}" ;; vale) switch::vale::remove_member "${_switch}" "${_if}" ;; vxlan) switch::vxlan::remove_member "${_switch}" "${_if}" ;; *) util::err "unable to configure switch of unknown type" ;; @@ -256,6 +263,7 @@ switch::vlan(){ case "${_type}" in standard) switch::standard::vlan "${_switch}" "${_vlan}" ;; manual) switch::manual::vlan "${_switch}" "${_vlan}" ;; + netgraph) switch::netgraph::vlan "${_switch}" "${_vlan}" ;; vale) switch::vale::vlan "${_switch}" "${_vlan}" ;; vxlan) switch::vxlan::vlan "${_switch}" "${_vlan}" ;; *) util::err "unable to configure switch of unknown type" ;; @@ -287,6 +295,9 @@ switch::private(){ config::core::set "private_${_switch}" "no" fi ;; + netgraph) + util::err "unable to configure private mode on netgraph switches" + ;; vale) util::err "unable to configure private mode on vale switches" ;; @@ -331,6 +342,7 @@ switch::address(){ case "${_type}" in standard) switch::standard::address "${_switch}" "${_addr}" ;; manual) ;& + netgraph) ;& vale) ;& vxlan) util::err "feature not currently supported on switches of this type" ;; *) util::err "unable to configure switch of unknown type" ;; @@ -380,6 +392,7 @@ switch::id(){ case "${_type}" in vale) switch::vale::id "${_var}" "${_switch}" ;; + netgraph) switch::netgraph::id "${_var}" "${_switch}" ;; manual) switch::manual::id "${_var}" "${_switch}" ;; *) switch::standard::id "${_var}" "${_switch}" ;; esac diff --git a/lib/vm-switch-netgraph b/lib/vm-switch-netgraph new file mode 100644 index 0000000..bf0e378 --- /dev/null +++ b/lib/vm-switch-netgraph @@ -0,0 +1,101 @@ +#!/bin/sh +#-------------------------------------------------------------------------+ +# Copyright (C) 2021 Benoit Chesneau (bchesneau@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. + + +# show the configuration details for a netgraph switch +# +# @param string _name the switch name +# @param string _format output format +# +switch::netgraph::show(){ + local _name="$1" + local _format="$2" + local _id + + switch::netgraph::id "_id" "${_name}" + printf "${_format}" "${_name}" "netraph" "${_id}" "n/a" "n/a" "n/a" "n/a" "n/a" +} + +# create a netgraph switch +# +# @param string _switch the name of the switch +# +switch::netgraph::create(){ + config::core::set "switch_list" "${_switch}" "1" + config::core::set "type_${_switch}" "netgraph" +} + +# remove a netgraph switch +# +switch::netgraph::remove(){ } + +# add a new interface to this switch +# at the moment we require the user to manually +# set up any netgraph switches +# +# @param string _switch name of the switch +# @param string _if the interface to add +# +switch::netgraph::add_member(){ + util::err "physical interfaces must be added to the netgraph switch manually" +} + +# remove an interface +# +# @param string _switch name of the switch +# @param string _if the interface to remove +# +switch::netgraph::remove_member(){ + util::err "physical interfaces must be removed from the netgraph switch manually" +} + +# set vlan id +# +# @param string _switch name of switch +# @param int _vlan vlan id to set +# +switch::netgraph::vlan(){ + util::err "vlan support is not currently implemented for netgraph switches" +} +# gets a unique linkname name for a ng_bridge interface +# we need to make sure the link is unique and the last one +# +# @param string _var name of variable to put port name into +# @param string _switch the name of the switch +# +switch::netgraph::id(){ + local _var="$1" + local _switch="$2" + + # Create a new interface to the bridge + num=2 + while ngctl msg "${_switch}:" getstats $num > /dev/null 2>&1 + do + num=$(( $num + 1 )) + done + setvar "${_var}" "netgraph,path=${_switch}:,peerhook=link$num" +} + diff --git a/vm.8 b/vm.8 index cfa2782..7c2cc61 100644 --- a/vm.8 +++ b/vm.8 @@ -457,6 +457,7 @@ There are currently 4 types of virtual switch that can be created. These are .Sy standard , .Sy manual , +.Sy netgraph , .Sy vale and .Sy vxlan . @@ -468,6 +469,9 @@ interface and bridges clients to it. .Sy manual allows you to attach guests to a bridge that you have created and configured manually. +.Sy netgraph +switches use the netgraph ng_bridg esystem to create a virtual switch connecting +guests. .Sy vale switches use the netmap VALE system to create a virtual switch connecting guests.