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

De Le Wiki de Lug
Aller à la navigation Aller à la recherche
 
(8 versions intermédiaires par le même utilisateur non affichées)
Ligne 12 : Ligne 12 :
  }}
  }}
=Créer des VF=
=Créer des VF=
{{Méta bandeau
  | niveau = information
  | icône = loupe
  | texte  = Exemple avec 4 VF.
}}
{{Méta bandeau
  | niveau = modéré
  | icône = modéré
  | texte  = Il est préférable d'utiliser [[#Créer_des_VF_avec_adresses_MAC_fixes|le service de création de VF avec MAC adress assignées]] pour plus de stabiliter.
}}
On crée un service :
On crée un service :
  root@proxmoxve:~# vi /etc/systemd/system/sriov-x710.service
  root@proxmoxve:~# vi /etc/systemd/system/sriov-x710.service
Ligne 52 : Ligne 62 :
  ExecStart=/bin/bash -c 'set -e; \
  ExecStart=/bin/bash -c 'set -e; \
  DEV=<font color=green>enp8s0f1np1</font>; \
  DEV=<font color=green>enp8s0f1np1</font>; \
# wait for the PF to exist
  for i in {1..20}; do [ -e /sys/class/net/$DEV ] && break; sleep 0.2; done; \
  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; \
  echo 0 > /sys/class/net/$DEV/device/sriov_numvfs; \
Ligne 71 : Ligne 80 :
  systemctl enable sriov-x710
  systemctl enable sriov-x710
  systemctl start sriov-x710
  systemctl start sriov-x710
= Hookscript pour permettre aux cartes réseaux virtuelles de communiquer avec les VF sur le même "bridge" =
[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 <nowiki>https://</nowiki>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>
|}
== Inscription du script ==
{{Méta bandeau
  | niveau = information
  | icône = loupe
  | texte  = Le script ne n'est pas nécessaire sur les machines avec la VF, il doit être inscrit sur les machines avec une carte réseau virtuelle qui souhaite communiquer avec une VF sur le même bridge!
}}
Pour les VM sans VF :
# qm set <font color = blue>100</font> --hookscript local:snippets/bridgefix.sh
Pour les conteneurs LXC :
# pct set <font color = blue>100</font> --hookscript local:snippets/bridgefix.sh

Dernière version du 11 avril 2026 à 14: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 aux cartes réseaux virtuelles de communiquer avec les VF sur le même "bridge"

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