aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSepherosa Ziehau <sephe@FreeBSD.org>2017-07-31 07:18:15 +0000
committerSepherosa Ziehau <sephe@FreeBSD.org>2017-07-31 07:18:15 +0000
commitc685956956793831f724177309eace82c4b347b9 (patch)
tree53cd18159e9f305b09c931c0be9927f7932a7ced
parent4c0c8a36da0bda1ade0f4d0a56599360df302b57 (diff)
downloadsrc-c685956956793831f724177309eace82c4b347b9.tar.gz
src-c685956956793831f724177309eace82c4b347b9.zip
Notes
-rw-r--r--contrib/hyperv/tools/scripts/hyperv_vfattach79
-rw-r--r--contrib/hyperv/tools/scripts/hyperv_vfup119
-rw-r--r--etc/devd/hyperv.conf73
-rw-r--r--libexec/hyperv/Makefile1
4 files changed, 272 insertions, 0 deletions
diff --git a/contrib/hyperv/tools/scripts/hyperv_vfattach b/contrib/hyperv/tools/scripts/hyperv_vfattach
new file mode 100644
index 000000000000..e1ed1849f98f
--- /dev/null
+++ b/contrib/hyperv/tools/scripts/hyperv_vfattach
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+#
+# If transparent VF is enabled, don't do anything.
+#
+
+sysctl -n hw.hn.vf_transparent > /dev/null 2>&1
+if [ $? -ne 0 ]
+then
+ # Old kernel; no transparent VF.
+ vf_transparent=0
+else
+ vf_transparent=`sysctl -n hw.hn.vf_transparent`
+fi
+
+if [ $vf_transparent -ne 0 ]
+then
+ # Transparent VF; done!
+ exit 0
+fi
+
+iface=$1
+delay=$2
+
+if [ $delay -gt 0 ]
+then
+ #
+ # Delayed VF up.
+ #
+ sleep $delay
+ ifconfig $iface up
+ # Done!
+ exit $?
+fi
+
+#
+# Check to see whether $iface is a VF or not.
+# If $iface is a VF, bring it up now.
+#
+
+# for hyperv_vf_delay
+. /etc/rc.conf
+
+sysctl -n hw.hn.vflist > /dev/null 2>&1
+if [ $? -ne 0 ]
+then
+ # Old kernel; nothing could be done properly.
+ exit 0
+fi
+vf_list=`sysctl -n hw.hn.vflist`
+
+for vf in $vf_list
+do
+ if [ $vf = $iface ]
+ then
+ #
+ # Linger a little bit (at least 2 seconds) mainly to
+ # make sure that $iface is fully attached.
+ #
+ # NOTE:
+ # In Azure hyperv_vf_delay should be configured to a
+ # large value, e.g. 120 seconds, to avoid racing cloud
+ # agent goofs.
+ #
+ test $hyperv_vf_delay -ge 2 > /dev/null 2>&1
+ if [ $? -ne 0 ]
+ then
+ hyperv_vf_delay=2
+ fi
+ #
+ # NOTE:
+ # "(sleep ..; ifconfig .. up) > /dev/null 2>&1 &"
+ # does _not_ work.
+ #
+ daemon -f /usr/libexec/hyperv/hyperv_vfattach \
+ $iface $hyperv_vf_delay
+ break
+ fi
+done
diff --git a/contrib/hyperv/tools/scripts/hyperv_vfup b/contrib/hyperv/tools/scripts/hyperv_vfup
new file mode 100644
index 000000000000..7a2bc595c212
--- /dev/null
+++ b/contrib/hyperv/tools/scripts/hyperv_vfup
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+. /etc/rc.subr
+. /etc/network.subr
+
+load_rc_config netif
+
+#
+# Customized per-interface setup, e.g. hyperv_vfup.hn1
+#
+# NOTE-CUSTOMIZE:
+# Comment this out, if this script is used as template
+# for the customized per-interface setup.
+#
+if [ -f /usr/libexec/hyperv/hyperv_vfup.$1 ]
+then
+ /usr/libexec/hyperv/hyperv_vfup.$1
+ exit $?
+fi
+
+# NOTE-CUSTOMIZE:
+#hn=${0##*.}
+hn=$1
+hn_unit=`echo $hn | sed 's/[^0-9]*//g'`
+
+vf=`sysctl -n dev.hn.$hn_unit.vf`
+if [ ! $vf ]
+then
+ # Race happened; VF was removed, before we ran.
+ echo "$hn: VF was detached"
+ exit 0
+fi
+
+#
+# Create laggX for hnX.
+# Add VF and hnX to laggX.
+#
+
+lagg=lagg$hn_unit
+
+ifconfig $lagg > /dev/null 2>&1
+if [ $? -ne 0 ]
+then
+ #
+ # No laggX, create it now.
+ #
+ ifconfig $lagg create > /dev/null 2>&1
+ if [ $? -ne 0 ]
+ then
+ echo "$lagg creation failed"
+ exit 1
+ fi
+
+ #
+ # Configure laggX (failover), add hnX and VF to it.
+ #
+ ifconfig $lagg laggproto failover laggport $hn laggport $vf
+ ifconfig $lagg inet6 no_dad
+
+ #
+ # Stop dhclient on hnX, if any.
+ #
+ pidfile=/var/run/dhclient.$hn.pid
+ if [ -f $pidfile ]
+ then
+ kill -TERM `cat $pidfile`
+ fi
+
+ #
+ # Remove all configured IPv4 addresses on hnX, e.g.
+ # configured by dhclient. laggX will take over the
+ # network operations.
+ #
+ while true
+ do
+ ifconfig $hn -alias > /dev/null 2>&1
+ if [ $? -ne 0 ]
+ then
+ break
+ fi
+ done
+
+ # TODO: Remove IPv6 addresses on hnX
+
+ #
+ # Use hnX's configuration for laggX
+ #
+ # NOTE-CUSTOMIZE:
+ # If this script is used as template for the customized
+ # per-interface setup, replace this with whatever you
+ # want to do with the laggX.
+ #
+ if dhcpif $hn;
+ then
+ ifconfig $lagg up
+ if syncdhcpif $hn;
+ then
+ dhclient $lagg
+ else
+ dhclient -b $lagg
+ fi
+ else
+ ifconfig_args=`ifconfig_getargs $hn`
+ if [ -n "$ifconfig_args" ]
+ then
+ ifconfig $lagg $ifconfig_args
+ fi
+ fi
+else
+ #
+ # laggX exists. Check whether VF was there or not.
+ # If VF was not added to laggX, add it now.
+ #
+ ifconfig $lagg | grep "laggport: $vf" > /dev/null 2>&1
+ if [ $? -ne 0 ]
+ then
+ ifconfig $lagg laggport $vf
+ fi
+fi
diff --git a/etc/devd/hyperv.conf b/etc/devd/hyperv.conf
index 0abf284a9ce0..10a4e2b9e5ce 100644
--- a/etc/devd/hyperv.conf
+++ b/etc/devd/hyperv.conf
@@ -33,3 +33,76 @@ notify 11 {
match "cdev" "hv_fsvss_dev";
action "pkill -x hv_vss_daemon";
};
+
+#
+# Rules for non-transparent network VF.
+#
+# How network VF works with hn(4) on Hyper-V in non-transparent mode:
+#
+# - Each network VF has a cooresponding hn(4).
+# - The network VF and the it's cooresponding hn(4) have the same hardware
+# address.
+# - Once the network VF is up, e.g. ifconfig VF up:
+# o All of the transmission should go through the network VF.
+# o Most of the reception goes through the network VF.
+# o Small amount of reception may go through the cooresponding hn(4).
+# This reception will happen, even if the the cooresponding hn(4) is
+# down. The cooresponding hn(4) will change the reception interface
+# to the network VF, so that network layer and application layer will
+# be tricked into thinking that these packets were received by the
+# network VF.
+# o The cooresponding hn(4) pretends the physical link is down.
+# - Once the network VF is down or detached:
+# o All of the transmission should go through the cooresponding hn(4).
+# o All of the reception goes through the cooresponding hn(4).
+# o The cooresponding hn(4) fallbacks to the original physical link
+# detection logic.
+#
+# All these features are mainly used to help live migration, during which
+# the network VF will be detached, while the network communication to the
+# VM must not be cut off. In order to reach this level of live migration
+# transparency, we use failover mode lagg(4) with the network VF and the
+# cooresponding hn(4) attached to it.
+#
+# To ease user configuration for both network VF and non-network VF, the
+# lagg(4) will be created by the following rules, and the configuration
+# of the cooresponding hn(4) will be applied to the lagg(4) automatically.
+#
+# NOTE:
+# If live migration is not needed at all, the following rules could be
+# commented out, and the network VF interface could be used exclusively.
+# Most often the cooresponding hn(4) could be completely ignored.
+#
+#
+# Default workflow for the network VF bringup:
+# 1) ETHERNET/IFATTACH -> VF interface up (delayed by rc.conf hyperv_vf_delay
+# seconds). This operation will trigger HYPERV_NIC_VF/VF_UP.
+# 2) HYPERV_NIC_VF/VF_UP:
+# a) Create laggX coresponding to hnX.
+# b) Add hnX and VF to laggX.
+# c) Whack all previous network configuration on hnX, including stopping
+# dhclient.
+# d) Apply rc.conf ifconfig_hnX to laggX; i.e. including starting dhclient.
+#
+# NOTE:
+# HYPERV_NIC_VF/VF_UP action script could be customized per-interface by
+# adding /usr/libexec/hyperv/hyperv_vfup.hnX script.
+# /usr/libexec/hyperv/hyperv_vfup could be used as the template for the
+# customized per-interface script.
+#
+# NOTE:
+# For transparent network VF, hyperv_vfattach does nothing and
+# HYPERV_NIC_VF/VF_UP will not be triggered at all.
+#
+
+notify 10 {
+ match "system" "HYPERV_NIC_VF";
+ match "type" "VF_UP";
+ action "/usr/libexec/hyperv/hyperv_vfup $subsystem";
+};
+
+notify 10 {
+ match "system" "ETHERNET";
+ match "type" "IFATTACH";
+ action "/usr/libexec/hyperv/hyperv_vfattach $subsystem 0";
+};
diff --git a/libexec/hyperv/Makefile b/libexec/hyperv/Makefile
index a89b7435d2e5..6e251b24faa7 100644
--- a/libexec/hyperv/Makefile
+++ b/libexec/hyperv/Makefile
@@ -5,5 +5,6 @@
BINDIR= ${LIBEXECDIR}/hyperv
SCRIPTS= hv_set_ifconfig hv_get_dns_info hv_get_dhcp_info
+SCRIPTS+= hyperv_vfattach hyperv_vfup
.include <bsd.prog.mk>