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

De Le Wiki de Lug
Aller à la navigation Aller à la recherche
Ligne 89 : Ligne 89 :
== Installation du script ==
== Installation du script ==
  # mkdir -p /var/lib/vz/snippets
  # 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
  # wget -O /var/lib/vz/snippets/bridgefix.sh <nowiki>https://</nowiki>raw.githubusercontent.com/jdlayman/pve-hookscript-sriov/master/bridgefix.sh
  # chmod 755 /var/lib/vz/snippets/bridgefix.sh
  # chmod 755 /var/lib/vz/snippets/bridgefix.sh



Version du 11 avril 2026 à 13:59

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

Inscription du script

Pour les VM sans VF :

# qm set 100 --hookscript local:snippets/bridgefix.sh

Pour les conteneurs LXC :

# pct set 100 --hookscript local:snippets/bridgefix.sh