« NIC SR-IOV » : différence entre les versions

De Le Wiki de Lug
Aller à la navigation Aller à la recherche
Ligne 80 : Ligne 80 :
  systemctl enable sriov-x710
  systemctl enable sriov-x710
  systemctl start sriov-x710
  systemctl start sriov-x710
= Hookscript pour permettre au VF de communiquer entre elle =
[https://github.com/jdlayman/pve-hookscript-sriov Source github]
{{Méta bandeau
  | niveau = information
  | icône = loupe
  | texte  = Certaines cartes réseaux (exemple la Intel x710) empêchent les cartes réseaux virtuelles de communiquer avec les VF sur le même "bridge" réseau, ce script permet de contourner le problème en inscrivant les MAC adress sur le "bridge".
}}
== Installation du script ==
# mkdir -p /var/lib/vz/snippets
# wget -O /var/lib/vz/snippets/bridgefix.sh https://raw.githubusercontent.com/jdlayman/pve-hookscript-sriov/master/bridgefix.sh
# chmod 755 /var/lib/vz/snippets/bridgefix.sh
{| class="mw-collapsible mw-collapsed"
| '''Contenu du script'''
|-
|
<pre>
#!/bin/bash
# Hook script for PVE guests (hookscript config option)
# You can set this via pct/qm with
# pct set <vmid> -hookscript <volume-id>
# qm set <vmid> -hookscript <volume-id>
# where <volume-id> has to be an executable file in the snippets folder
# of any storage with directories e.g.:
# for KVM: qm set 100 -hookscript local:snippets/pf-bridge-fdb.sh
# or
# for CT: pct set 100 -hookscript local:snippets/pf-bridge-fdb.sh
#
# Modified from ctr's hookscript to add bridged CT and VM MAC addresses to the upstream PF interface.
# https://forum.proxmox.com/threads/communication-issue-between-sriov-vm-vf-and-ct-on-pf-bridge.68638/#post-435959
#
USAGE="Usage: $0 vmid phase"
if [ "$#" -ne "2" ]; then
  echo "$USAGE"
  exit 1
fi
echo "GUEST HOOK: $0 $*"
# First argument is the vmid
vmid=$1
if [[ $1 == ?(-)+([:digit:]) ]]; then
  echo "$USAGE"
  exit 1
fi
# Second argument is the phase
phase=$2
case "${phase}" in
  pre-start|post-start|pre-stop|post-stop) : ;;
  *)                                      echo "got unknown phase ${phase}"; exit 1 ;;
esac
function fixup_bridge_fdb {
  OPERATION=$1
  # Lookup Proxmox config for by vmid
  CONFFILE=$(find /etc/pve -type f -name ${vmid}.conf)
  if [ -f "${CONFFILE}" ]; then
    # get defined networks
    NETWORKS=$(egrep "^net" ${CONFFILE}| fgrep bridge= | awk '{print $2}')
    #echo $NETWORKS
    for i in ${NETWORKS}; do
      #echo $i
      declare macaddr=""
      declare bridge=""
      declare vlan=""
      IFS=\, read -a NETWORK <<<"$i"
      # get attributes for current network
      for item in "${NETWORK[@]}"; do
        IFS=\= read -a kv <<<"$item"
        case "${kv[0]}" in
          tag)    vlan=${kv[1]};;
          bridge)  bridge=${kv[1]};;
          virtio)  macaddr=${kv[1]};;
          hwaddr)  macaddr=${kv[1]};;
          vmxnet3) macaddr=${kv[1]};;
        esac
      done
      # special processing needed if member of vlan
      if [ ! -z "${vlan}" ]; then
        vlancheck=${vlan}
      else
        vlancheck="checking"
      fi
      # lookup member interfaces of defined bridge interface
      bridgeinterfaces=$(ls -1 /sys/class/net/${bridge}/brif/ 2>/dev/null)
      # for every member interface, if it is an SR-IOV PF then ...
      #echo $bridgeinterfaces
      for memberint in ${bridgeinterfaces}; do
        if [ -d "/sys/class/net/${memberint}/bonding" ]; then
          # find interfaces that are bonded
          IFS=' ' read -a bondedints <<< $(cat /sys/class/net/${memberint}/bonding/slaves 2>/dev/null)
          for bondedint in ${bondedints[@]}; do
            #echo $bondedint
            if [ -L "/sys/class/net/${bondedint}/device/virtfn0" ]; then
              # echo $memberint
              subint="${bondedint}"
              # check if entry in fdb and only execute when needed
              present=$(bridge fdb show dev ${subint} | fgrep -i ${macaddr})
              if [[ -z $present && $OPERATION == "add" ]] || [[ -n $present && $OPERATION == "del" ]]; then
                echo bridge fdb ${OPERATION} ${macaddr} dev ${subint}
                bridge fdb ${OPERATION} ${macaddr} dev ${subint}
              fi
            fi
          done
        fi
        # only proceed if memberinterface is PF with VF
        if [ -L "/sys/class/net/${memberint}/device/virtfn0" ]; then
          # echo $memberint
          subint="${memberint}"
          ## check if a vf is on the vlan
          #vf=$(ip link show dev ${memberint} 2>/dev/null |awk -v vlan="${vlancheck}" '{ if( $6 ~ vlan) print $2}')
          #if [ ! -z "${vf}" ]; then
          #  if [ ! -z "${vlan}" ]; then
          #    subint="${memberint}.${vlan}"
          #  else
          #    subint="${memberint}"
          #  fi
          #fi
          # check if entry in fdb and only execute when needed
          present=$(bridge fdb show dev ${subint} | fgrep -i ${macaddr})
          if [[ -z $present && $OPERATION == "add" ]] || [[ -n $present && $OPERATION == "del" ]]; then
            echo bridge fdb ${OPERATION} ${macaddr} dev ${subint}
            bridge fdb ${OPERATION} ${macaddr} dev ${subint}
          fi
        fi
      done
    done
  else
    echo "VM or CT does not exist, aborting"
  fi
}
case "${phase}" in
  pre-start)  echo "${vmid} is starting, doing bridge fdb setup." && fixup_bridge_fdb add ;;
  post-stop)  echo "${vmid} stopped. Doing bridge fdb cleanup." && fixup_bridge_fdb del ;;
esac
exit 0
</pre>
|}

Version du 11 avril 2026 à 13:18

Voir le nombre MAX de VF supportées

root@proxmox:~# cat /sys/class/net/enp8s0f1np1/device/sriov_totalvfs

Voir combien de VF sont actives actuellement

root@proxmox:~# cat /sys/class/net/enp8s0f1np1/device/sriov_numvfs

Créer des VF temporaire

Exemple : créer 4 VF

root@proxmox:~# echo 4 > /sys/class/net/enp8s0f1np1/device/sriov_numvfs

Créer des VF

On crée un service :

root@proxmoxve:~# vi /etc/systemd/system/sriov-x710.service

Contenu :

[Unit]
Description=Enable SR-IOV on Intel X710
After=systemd-modules-load.service
Before=pve-guests.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo 4 > /sys/class/net/enp8s0f1np1/device/sriov_numvfs'
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Puis on active le service ;

systemctl daemon-reload
systemctl enable sriov-x710
systemctl start sriov-x710

Créer des VF avec adresses MAC fixes

On crée un service :

root@proxmoxve:~# vi /etc/systemd/system/sriov-x710.service

Contenu :

[Unit]
Description=Enable SR-IOV on Intel X710 (fixed VF MACs)
After=systemd-modules-load.service
Before=pve-guests.service

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'set -e; \
DEV=enp8s0f1np1; \
for i in {1..20}; do [ -e /sys/class/net/$DEV ] && break; sleep 0.2; done; \
echo 0 > /sys/class/net/$DEV/device/sriov_numvfs; \
sleep 1; \
echo 4 > /sys/class/net/$DEV/device/sriov_numvfs; \
sleep 1; \
ip link set $DEV vf 0 mac 02:00:00:10:01:00; \
ip link set $DEV vf 1 mac 02:00:00:10:01:01; \
ip link set $DEV vf 2 mac 02:00:00:10:01:02; \
ip link set $DEV vf 3 mac 02:00:00:10:01:03'
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Puis on active le service ;

systemctl daemon-reload
systemctl enable sriov-x710
systemctl start sriov-x710

Hookscript pour permettre au VF de communiquer entre elle

Source github

Installation du script

# mkdir -p /var/lib/vz/snippets
# wget -O /var/lib/vz/snippets/bridgefix.sh https://raw.githubusercontent.com/jdlayman/pve-hookscript-sriov/master/bridgefix.sh
# chmod 755 /var/lib/vz/snippets/bridgefix.sh
Contenu du script
#!/bin/bash

# Hook script for PVE guests (hookscript config option)
# You can set this via pct/qm with
# pct set <vmid> -hookscript <volume-id>
# qm set <vmid> -hookscript <volume-id>
# where <volume-id> has to be an executable file in the snippets folder
# of any storage with directories e.g.:
# for KVM: qm set 100 -hookscript local:snippets/pf-bridge-fdb.sh
# or
# for CT: pct set 100 -hookscript local:snippets/pf-bridge-fdb.sh

#
# Modified from ctr's hookscript to add bridged CT and VM MAC addresses to the upstream PF interface.
# https://forum.proxmox.com/threads/communication-issue-between-sriov-vm-vf-and-ct-on-pf-bridge.68638/#post-435959
#

USAGE="Usage: $0 vmid phase"

if [ "$#" -ne "2" ]; then
  echo "$USAGE"
  exit 1
fi

echo "GUEST HOOK: $0 $*"

# First argument is the vmid

vmid=$1
if [[ $1 == ?(-)+([:digit:]) ]]; then
  echo "$USAGE"
  exit 1
fi

# Second argument is the phase

phase=$2
case "${phase}" in
  pre-start|post-start|pre-stop|post-stop) : ;;
  *)                                       echo "got unknown phase ${phase}"; exit 1 ;;
esac


function fixup_bridge_fdb {
  OPERATION=$1
  # Lookup Proxmox config for by vmid
  CONFFILE=$(find /etc/pve -type f -name ${vmid}.conf)
  if [ -f "${CONFFILE}" ]; then
    # get defined networks
    NETWORKS=$(egrep "^net" ${CONFFILE}| fgrep bridge= | awk '{print $2}')
    #echo $NETWORKS
    for i in ${NETWORKS}; do
      #echo $i
      declare macaddr=""
      declare bridge=""
      declare vlan=""
      IFS=\, read -a NETWORK <<<"$i"
      # get attributes for current network
      for item in "${NETWORK[@]}"; do
        IFS=\= read -a kv <<<"$item"
        case "${kv[0]}" in
          tag)     vlan=${kv[1]};;
          bridge)  bridge=${kv[1]};;
          virtio)  macaddr=${kv[1]};;
          hwaddr)  macaddr=${kv[1]};;
          vmxnet3) macaddr=${kv[1]};;
        esac
      done
      # special processing needed if member of vlan
      if [ ! -z "${vlan}" ]; then
        vlancheck=${vlan}
      else
        vlancheck="checking"
      fi
      # lookup member interfaces of defined bridge interface
      bridgeinterfaces=$(ls -1 /sys/class/net/${bridge}/brif/ 2>/dev/null)
      # for every member interface, if it is an SR-IOV PF then ...
      #echo $bridgeinterfaces
      for memberint in ${bridgeinterfaces}; do
        if [ -d "/sys/class/net/${memberint}/bonding" ]; then
          # find interfaces that are bonded
          IFS=' ' read -a bondedints <<< $(cat /sys/class/net/${memberint}/bonding/slaves 2>/dev/null)
          for bondedint in ${bondedints[@]}; do
            #echo $bondedint
            if [ -L "/sys/class/net/${bondedint}/device/virtfn0" ]; then
              # echo $memberint
              subint="${bondedint}"
              # check if entry in fdb and only execute when needed
              present=$(bridge fdb show dev ${subint} | fgrep -i ${macaddr})
              if [[ -z $present && $OPERATION == "add" ]] || [[ -n $present && $OPERATION == "del" ]]; then
                echo bridge fdb ${OPERATION} ${macaddr} dev ${subint}
                bridge fdb ${OPERATION} ${macaddr} dev ${subint}
              fi
            fi
          done
        fi
        # only proceed if memberinterface is PF with VF
        if [ -L "/sys/class/net/${memberint}/device/virtfn0" ]; then
          # echo $memberint
          subint="${memberint}"
          ## check if a vf is on the vlan
          #vf=$(ip link show dev ${memberint} 2>/dev/null |awk -v vlan="${vlancheck}" '{ if( $6 ~ vlan) print $2}')
          #if [ ! -z "${vf}" ]; then
          #  if [ ! -z "${vlan}" ]; then
          #    subint="${memberint}.${vlan}"
          #  else
          #    subint="${memberint}"
          #  fi
          #fi
          # check if entry in fdb and only execute when needed
          present=$(bridge fdb show dev ${subint} | fgrep -i ${macaddr})
          if [[ -z $present && $OPERATION == "add" ]] || [[ -n $present && $OPERATION == "del" ]]; then
            echo bridge fdb ${OPERATION} ${macaddr} dev ${subint}
            bridge fdb ${OPERATION} ${macaddr} dev ${subint}
          fi
        fi
      done
    done
  else
    echo "VM or CT does not exist, aborting"
  fi
}

case "${phase}" in
  pre-start)  echo "${vmid} is starting, doing bridge fdb setup." && fixup_bridge_fdb add ;;
  post-stop)  echo "${vmid} stopped. Doing bridge fdb cleanup." && fixup_bridge_fdb del ;;
esac

exit 0