diff --git a/hv-rhel6.x/hv/hyperv_net.h b/hv-rhel6.x/hv/hyperv_net.h index e2789f4b1..c45144b3d 100644 --- a/hv-rhel6.x/hv/hyperv_net.h +++ b/hv-rhel6.x/hv/hyperv_net.h @@ -147,7 +147,6 @@ struct hv_netvsc_packet { struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; - bool link_state; /* 0 - link up, 1 - link down */ int ring_size; u32 max_num_vrss_chns; u32 num_chn; @@ -169,7 +168,7 @@ struct rndis_device { struct net_device *ndev; enum rndis_device_state state; - bool link_state; + atomic_t new_req_id; spinlock_t request_lock; @@ -177,6 +176,8 @@ struct rndis_device { struct work_struct mcast_work; + bool link_state; /* 0 - link up, 1 - link down */ + u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; u16 ind_table[ITAB_NUM]; diff --git a/hv-rhel6.x/hv/rndis_filter.c b/hv-rhel6.x/hv/rndis_filter.c index 43acfc6fc..a83b491cf 100644 --- a/hv-rhel6.x/hv/rndis_filter.c +++ b/hv-rhel6.x/hv/rndis_filter.c @@ -1223,11 +1223,9 @@ int rndis_filter_device_add(struct hv_device *dev, rndis_filter_query_device_link_status(rndis_device); - device_info->link_state = rndis_device->link_state; - netdev_dbg(net, "Device MAC %pM link state %s\n", rndis_device->hw_mac_adr, - device_info->link_state ? "down" : "up"); + rndis_device->link_state ? "down" : "up"); if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) return 0; diff --git a/hv-rhel7.x/hv/hyperv_net.h b/hv-rhel7.x/hv/hyperv_net.h index 86cebe4a0..fc64b8fd7 100644 --- a/hv-rhel7.x/hv/hyperv_net.h +++ b/hv-rhel7.x/hv/hyperv_net.h @@ -149,7 +149,6 @@ struct hv_netvsc_packet { struct netvsc_device_info { unsigned char mac_adr[ETH_ALEN]; - bool link_state; /* 0 - link up, 1 - link down */ int ring_size; u32 max_num_vrss_chns; u32 num_chn; @@ -168,7 +167,6 @@ struct rndis_device { struct net_device *ndev; enum rndis_device_state state; - bool link_state; atomic_t new_req_id; spinlock_t request_lock; @@ -176,6 +174,8 @@ struct rndis_device { struct work_struct mcast_work; + bool link_state; /* 0 - link up, 1 - link down */ + u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; u16 ind_table[ITAB_NUM]; @@ -719,6 +719,9 @@ struct net_device_context { u32 vf_alloc; /* Serial number of the VF to team with */ u32 vf_serial; + + bool datapath; /* 0 - synthetic, 1 - VF nic */ + /* * Tracks the current data path; initially the data path is set * to deliver packets on the synthetic path. diff --git a/hv-rhel7.x/hv/netvsc.c b/hv-rhel7.x/hv/netvsc.c index 8f9ef8269..95c58cd99 100644 --- a/hv-rhel7.x/hv/netvsc.c +++ b/hv-rhel7.x/hv/netvsc.c @@ -56,6 +56,8 @@ void netvsc_switch_datapath(struct net_device *ndev, bool vf) sizeof(struct nvsp_message), (unsigned long)init_pkt, VM_PKT_DATA_INBAND, 0); + + net_device_ctx->datapath = vf; } static struct netvsc_device *alloc_net_device(void) diff --git a/hv-rhel7.x/hv/netvsc_drv.c b/hv-rhel7.x/hv/netvsc_drv.c index 1b423fee8..10e83fc7f 100644 --- a/hv-rhel7.x/hv/netvsc_drv.c +++ b/hv-rhel7.x/hv/netvsc_drv.c @@ -69,7 +69,8 @@ static void netvsc_set_multicast_list(struct net_device *net) static int netvsc_open(struct net_device *net) { - struct netvsc_device *nvdev = net_device_to_netvsc_device(net); + struct net_device_context *ndev_ctx = netdev_priv(net); + struct netvsc_device *nvdev = ndev_ctx->nvdev; struct rndis_device *rdev; int ret = 0; @@ -85,7 +86,7 @@ static int netvsc_open(struct net_device *net) netif_tx_wake_all_queues(net); rdev = nvdev->extension; - if (!rdev->link_state) + if (!rdev->link_state && !ndev_ctx->datapath) netif_carrier_on(net); return ret; @@ -1374,7 +1375,8 @@ static void netvsc_link_change(struct work_struct *w) case RNDIS_STATUS_MEDIA_CONNECT: if (rdev->link_state) { rdev->link_state = false; - netif_carrier_on(net); + if (!ndev_ctx->datapath) + netif_carrier_on(net); netif_tx_wake_all_queues(net); } else { notify = true; diff --git a/hv-rhel7.x/hv/rndis_filter.c b/hv-rhel7.x/hv/rndis_filter.c index 9906e83c8..9cb6189a8 100644 --- a/hv-rhel7.x/hv/rndis_filter.c +++ b/hv-rhel7.x/hv/rndis_filter.c @@ -1197,11 +1197,9 @@ int rndis_filter_device_add(struct hv_device *dev, rndis_filter_query_device_link_status(rndis_device); - device_info->link_state = rndis_device->link_state; - netdev_dbg(net, "Device MAC %pM link state %s\n", rndis_device->hw_mac_adr, - device_info->link_state ? "down" : "up"); + rndis_device->link_state ? "down" : "up"); if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5) return 0; diff --git a/tools/sriov/configure_hv_sriov.sh b/tools/sriov/configure_hv_sriov.sh new file mode 100644 index 000000000..084f99e4e --- /dev/null +++ b/tools/sriov/configure_hv_sriov.sh @@ -0,0 +1,184 @@ +#!/bin/bash + +######################################################################## +# +# Linux on Hyper-V and Azure Test Code, ver. 1.0.0 +# Copyright (c) Microsoft Corporation +# +# All rights reserved. +# Licensed under the Apache License, Version 2.0 (the ""License""); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS +# OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +# ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR +# PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. +# +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# +######################################################################## + +######################################################################## +# +# This is a script to configure SRIOV for Linux VMs on Azure. +# +# How to use this: +# $sudo ./configure_hv_sriov.sh +# Logging: +# See log: "/var/log/configure_hv_sriov.log" +# +######################################################################## + +log_file="/var/log/configure_hv_sriov.log" + +######################################## +# Detect Distro +######################################## +if [ -f /etc/redhat-release ]; +then + cfgdir="/etc/sysconfig/network-scripts" + distro=redhat +elif grep -q 'Ubuntu' /etc/issue +then + cfgdir="/etc/network" + distro=ubuntu +elif grep -q 'SUSE' /etc/issue +then + cfgdir="/etc/sysconfig/network" + distro=suse +else + echo "Unsupported Distro" + exit 1 +fi + +function LOG() { + echo "`date`: $1" + echo "`date`: $1" >> $log_file +} + +LOG "---------------------------------------" +LOG "Configure SRIOV for $distro" + +######################################## +# Write configuration for: +# vf, synthetic NIC, bond interfaces +######################################## +if [ $distro == 'ubuntu' ]; then + default_net_config=$cfgdir/interfaces + + LOG "Running on Ubuntu: making change to ${default_net_config} ..." + sed -i 's/^source/#source/' $default_net_config + echo "allow-hotplug vf1" >> $default_net_config + echo "iface vf1 inet manual" >> $default_net_config + echo "bond-master bond0" >> $default_net_config + echo "bond-primary vf1" >> $default_net_config + echo "" >> $default_net_config + echo "auto eth0" >> $default_net_config + echo "iface eth0 inet manual" >> $default_net_config + echo "bond-master bond0" >> $default_net_config + echo "" >> $default_net_config + echo "auto bond0" >> $default_net_config + echo "iface bond0 inet dhcp" >> $default_net_config + echo "bond-mode active-backup" >> $default_net_config + echo "bond-miimon 100" >> $default_net_config + echo "bond-slaves none" >> $default_net_config + + n_line1=`cat $default_net_config | grep "allow-hotplug" | grep "vf1" | wc -l` + if [ $n_line1 -ne 1 ]; then + LOG "[Failed] allow-hotplug vf1: was defined multiple times in ${default_net_config}" + exit + fi + + n_line2=`cat $default_net_config | grep "auto" | grep "eth0" | wc -l` + if [ $n_line2 -ne 1 ]; then + LOG "[Failed] auto eth0: was defined multiple times in ${default_net_config}" + exit + fi + + n_line3=`cat $default_net_config | grep "auto" | grep "bond0" | wc -l` + if [ $n_line3 -ne 1 ]; then + LOG "[Failed] auto bond0: was defined multiple times in ${default_net_config}" + exit + fi +elif [ $distro == 'suse' ]; then + ifcfg_bond0_cfg=$cfgdir/ifcfg-bond0 + ifcfg_eth0_cfg=$cfgdir/ifcfg-eth0 + ifcfg_eth0_old_cfg=$cfgdir/old.ifcfg-eth0.backup + ifcfg_vf1_cfg=$cfgdir/ifcfg-vf1 + + LOG "Running on Suse: making change to:" + LOG "${ifcfg_bond0_cfg} ..." + echo "BOOTPROTO=dhcp" > $ifcfg_bond0_cfg + echo "STARTMODE=auto" >> $ifcfg_bond0_cfg + echo "BONDING_MASTER=yes" >> $ifcfg_bond0_cfg + echo "BONDING_SLAVE_0=vf1" >> $ifcfg_bond0_cfg + echo "BONDING_SLAVE_1=eth0" >> $ifcfg_bond0_cfg + echo "BONDING_MODULE_OPTS='mode=active-backup miimon=100 primary=vf1'" >> $ifcfg_bond0_cfg + + LOG "${ifcfg_eth0_cfg} ..." + mv $ifcfg_eth0_cfg $ifcfg_eth0_old_cfg + echo "BOOTPROTO=none" > $ifcfg_eth0_cfg + echo "STARTMODE=auto" >> $ifcfg_eth0_cfg + + LOG "${ifcfg_vf1_cfg} ..." + echo "BOOTPROTO=none" > $ifcfg_vf1_cfg + echo "STARTMODE=hotplug" >> $ifcfg_vf1_cfg +else + echo "Unsupported distro. Exiting." + exit 1 +fi + +######################################## +# Download files +######################################## +bin_folder="/usr/sbin/" +udev_folder="/etc/udev/rules.d/" +udev_file="60-hyperv-vf-name.rules" +hv_vf_name_file="hv_vf_name" +bondvf_sh_file="bondvf.sh" +all_files_downloaded=true + +LOG "Start downloading udev rule and config scripts ..." +cd /tmp +wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/${udev_file}" +wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/${hv_vf_name_file}" +wget "https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/plain/tools/hv/${bondvf_sh_file}" + +LOG "Move configuration to the destination folder ..." +mv -f $udev_file $udev_folder +chmod +x $hv_vf_name_file $bondvf_sh_file +mv -f $hv_vf_name_file $bin_folder +mv -f $bondvf_sh_file $bin_folder + +######################################## +# Check downloaded files +######################################## +LOG "Check downloaded files ..." +if [ ! -f ${udev_folder}${udev_file} ]; then + all_files_downloaded=false + LOG "${udev_file} is not found in ${udev_folder}!" +fi + +if [ ! -f ${bin_folder}${hv_vf_name_file} ]; then + all_files_downloaded=false + LOG "${hv_vf_name_file} is not found in ${bin_folder}!" +fi + +if [ ! -f ${bin_folder}${bondvf_sh_file} ]; then + all_files_downloaded=false + LOG "${bondvf_sh_file} is not found in ${bin_folder}!" +fi + +if [ $all_files_downloaded == false ]; then + LOG "[Failed] Some files are missing; please download them again." + exit +else + LOG "This system will reboot within 60 seconds ..." + sleep 60 + LOG "Rebooting now." + reboot +fi + diff --git a/tools/sriov/configure_sriov_ubuntu1604.sh b/tools/sriov/configure_sriov_ubuntu1604.sh deleted file mode 100644 index e6cf5abfb..000000000 --- a/tools/sriov/configure_sriov_ubuntu1604.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/bash - -######################################################################## -# -# Linux on Hyper-V and Azure Test Code, ver. 1.0.0 -# Copyright (c) Microsoft Corporation -# -# All rights reserved. -# Licensed under the Apache License, Version 2.0 (the ""License""); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# -# THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS -# OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION -# ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR -# PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. -# -# See the Apache Version 2.0 License for specific language governing -# permissions and limitations under the License. -# -######################################################################## - -######################################################################## -# -# This is a script to configure SRIOV for Ubuntu 1604 VM on Azure. -# -# How to use this: -# $sudo ./configure_sriov_ubuntu1604.sh -# Logging: -# See log: "/var/log/configure_sriov_ubuntu1604.log" -# -######################################################################## - -log_file="/var/log/configure_sriov_ubuntu1604.log" -bin_folder="/usr/sbin/" -udev_folder="/etc/udev/rules.d/" -udev_file="60-hyperv-sriov.rules" -hv_vf_name_file="hv_vf_name" -bondvf_lock_file="bondvf_lock" -bondvf_sh_file="bondvf.sh" -default_net_config="/etc/network/interfaces" -eth0_dhcp_config_line1="auto eth0" -eth0_dhcp_config_line2="iface eth0 inet dhcp" -all_files_downloaded=true - - -function LOG() { - echo "`date`: $1" - echo "`date`: $1" >> $log_file -} - -LOG "---------------------------------------" - -######################################## -# Download files -######################################## -LOG "Start downloading configuration files ..." -cd /tmp -wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/60-hyperv-sriov.rules" -wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/hv_vf_name" -wget "https://raw.githubusercontent.com/LIS/lis-next/master/tools/sriov/bondvf_lock" -wget "https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/plain/tools/hv/bondvf.sh" - -LOG "Move configuration to the destination folder ..." -mv -f $udev_file $udev_folder -chmod +x $hv_vf_name_file $bondvf_lock_file $bondvf_sh_file -mv -f $hv_vf_name_file $bin_folder -mv -f $bondvf_lock_file $bin_folder -mv -f $bondvf_sh_file $bin_folder - -if [ ! -f ${udev_folder}${udev_file} ]; then - all_files_downloaded=false - LOG "${udev_file} is not found in ${udev_folder}!" -fi - -if [ ! -f ${bin_folder}${hv_vf_name_file} ]; then - all_files_downloaded=false - LOG "${hv_vf_name_file} is not found in ${bin_folder}!" -fi - -if [ ! -f ${bin_folder}${bondvf_lock_file} ]; then - all_files_downloaded=false - LOG "${bondvf_lock_file} is not found in ${bin_folder}!" -fi - -if [ ! -f ${bin_folder}${bondvf_sh_file} ]; then - all_files_downloaded=false - LOG "${bondvf_sh_file} is not found in ${bin_folder}!" -fi - -######################################## -# Change eth0 DHCP configuration -######################################## -LOG "Make change to the eth0 DHCP configuration ..." -sed -i 's/^source/#source/' $default_net_config -echo "$eth0_dhcp_config_line1" >> $default_net_config -echo "$eth0_dhcp_config_line2" >> $default_net_config - -LOG "Check files ..." -n_line1=`cat $default_net_config | grep "$eth0_dhcp_config_line1" | wc -l` -if [ $n_line1 -ne 1 ]; then - LOG "[Failed] $n_line1 line(s) of '${eth0_dhcp_config_line1}' in $default_net_config" - exit -fi - -n_line2=`cat $default_net_config | grep "$eth0_dhcp_config_line2" | wc -l` -if [ $n_line2 -ne 1 ]; then - LOG "[Failed] $n_line2 line(s) of '${eth0_dhcp_config_line2}' in $default_net_config" - exit -fi - - -if [ $all_files_downloaded == false ]; then - LOG "[Failed] Some files are missing; please download them again." - exit -else - LOG "This system will reboot within 60 seconds ..." - sleep 60 - LOG "Rebooting now." - reboot -fi -