EVOLUTION-MANAGER
Edit File: pf_ringctl
#!/bin/bash # # Load the PF_RING kernel module and drivers # DISTRO="unknown" if [ -f /lib/lsb/init-functions ]; then DISTRO="debian" . /lib/lsb/init-functions fi if [ -f /etc/init.d/functions ]; then DISTRO="centos" . /etc/init.d/functions fi PF_RING="pf_ring" PF_RING_CONFIG_DIR="/etc/pf_ring" DRIVERS_FLAVOR=("zc") DKMS_DRIVERS=('e1000e' 'igb' 'ixgbe' 'ixgbevf' 'i40e' 'fm10k') ERROR=0 DRIVER_INSTALLED=0 OLD_HUGEPAGES_CONFIG="${PF_RING_CONFIG_DIR}/hugepages" HUGEPAGES_CONFIG="${PF_RING_CONFIG_DIR}/hugepages.conf" HUGEPAGES_SIZE=`grep Hugepagesize /proc/meminfo | cut -d ':' -f 2|sed 's/kB//g'|sed 's/ //g'` # KB HUGEPAGES_MOUNTPOINT="/dev/hugepages" MTU_CONFIG="${PF_RING_CONFIG_DIR}/mtu.conf" FORCESTART=0 FORCESTART_FILE="${PF_RING_CONFIG_DIR}/pf_ring.start" DRIVER_FORCESTART_FILE="${PF_RING_CONFIG_DIR}/forcestart" # touch to load zc even if it matches the management DO_NOT_LOAD_HUGEPAGES=0 # set to 1 to disable hugepages preallocation LOAD_HUGEPAGES=0 INTERFACES_CONFIG="${PF_RING_CONFIG_DIR}/interfaces.conf" MEM_AVAIL=1048576 # 1GB Hugepages (this avoids consuming all memory at boot time, causing kernel panic) # Including interfaces conf containing MANAGEMENT_INTERFACES, CAPTURE_INTERFACES [ -f ${INTERFACES_CONFIG} ] && . ${INTERFACES_CONFIG} if [ "${MANAGEMENT_INTERFACES}" != "" ]; then MGMT_INTERFACES=($MANAGEMENT_INTERFACES) else MGMT_INTERFACES=("$(/sbin/route | grep default | head -n 1 | tr -s ' ' | cut -d ' ' -f 8)") fi function is_management_interface { local e for e in "${MGMT_INTERFACES[@]}" ; do [[ "$e" == "$1" ]] && return 0 done return 1 } function is_management_interface_driver { local e for e in "${MGMT_INTERFACES[@]}" ; do DRIVER="$(/sbin/ethtool -i $e | grep driver | cut -d ' ' -f 2)" [[ "$DRIVER" == "$1" ]] && return 0 done return 1 } function dkms_installed { if [ ${DISTRO} == "debian" ]; then if [ `dpkg -l | grep $1-zc-dkms | wc -l` -gt 0 ]; then return 0 fi elif [ ${DISTRO} == "centos" ]; then if [ `rpm -qa | grep $1-zc | wc -l` -gt 0 ]; then return 0 fi fi return 1 } check_pf_ring() { # check the module status ERROR=0 WARNING=0 RETVAL=0 if [ $1 == "start" ] && [ `lsmod | grep ^${PF_RING} | wc -l ` -gt 0 ]; then MSG="PF_RING already loaded." WARNING=1 RETVAL=1 elif [ $1 == "stop" ] && [ `lsmod | grep ^${PF_RING} | wc -l ` -le 0 ]; then MSG="PF_RING already unloaded." WARNING=1 RETVAL=1 fi if [ ${ERROR} -gt 0 ]; then if [ ${DISTRO} == "debian" ]; then log_failure_msg "${MSG}" log_end_msg $ERROR exit 99 elif [ ${DISTRO} == "centos" ]; then echo -n ${MSG} echo_failure; echo exit 99 fi elif [ ${WARNING} -gt 0 ]; then [ ${DISTRO} == "debian" ] && log_daemon_msg "${MSG}" [ ${DISTRO} == "centos" ] && echo -n "${MSG}" [ ${DISTRO} == "debian" ] && log_end_msg $ERROR [ ${DISTRO} == "centos" ] && echo_success && echo fi return $RETVAL } rebuild_dkms() { # Get module version MOD_VERSION=`ls -1d /usr/src/${1}* | tail -1 | cut -d '/' -f 4 | sed -e "s/${1}-//"` echo "Uninstalling old ${1} version" /usr/sbin/dkms uninstall -m ${1} -v ${MOD_VERSION} > /dev/null #/usr/sbin/dkms remove -m ${1} -v ${MOD_VERSION} -k `uname -r` > /dev/null /usr/sbin/dkms remove -m ${1} -v ${MOD_VERSION} --all > /dev/null echo "Compiling new ${1} driver" /usr/sbin/dkms build -m ${1} -v ${MOD_VERSION} > /dev/null echo "Installing new ${1} driver" /usr/sbin/dkms install -m ${1} -v ${MOD_VERSION} > /dev/null } check_hugepages() { HUGEPAGES_TOTAL=0 if [ -f ${HUGEPAGES_CONFIG} ]; then while IFS=" " read HUGEPAGES_NODE HUGEPAGES_NUMBER HUGEPAGES_GID; do HUGEPAGES_TOTAL=$(( HUGEPAGES_TOTAL + ${HUGEPAGES_NUMBER/hugepagenumber=/} )) done < ${HUGEPAGES_CONFIG} else HUGEPAGES_TOTAL=$(( MEM_AVAIL / HUGEPAGES_SIZE )) fi #check if huge pages are already loaded and the number of pages are greater than defined or minimum value if [ `cat /sys/kernel/mm/hugepages/hugepages-${HUGEPAGES_SIZE}kB/nr_hugepages` -gt ${HUGEPAGES_TOTAL} ] && [ `grep ${HUGEPAGES_MOUNTPOINT} /proc/mounts | wc -l` -gt 0 ]; then LOAD_HUGEPAGES=0 return fi } unload_hugepages() { umount ${HUGEPAGES_MOUNTPOINT} echo 0 > /sys/kernel/mm/hugepages/hugepages-${HUGEPAGES_SIZE}kB/nr_hugepages } load_hugepages() { check_hugepages HUGEPAGES_NUMBER=0 if [ ${LOAD_HUGEPAGES} -eq 0 ]; then #hugepages already loaded return fi MOUNT_OPTION="" if [ -f ${HUGEPAGES_CONFIG} ]; then while read node ; do # entry should contain 'node=X hugepagenumber=Y gid=Z' HUGEPAGES_NODE=`echo ${node} | cut -d ' ' -f 1 | cut -d '=' -f 2` HUGEPAGES_NUMBER=`echo ${node} | cut -d ' ' -f 2 | cut -d '=' -f 2` HUGEPAGES_GID=`echo ${node} | cut -d ' ' -f 3 | cut -d '=' -f 2` if [[ ${HUGEPAGES_NUMBER} -gt 0 ]] && [ -f /sys/devices/system/node/node${HUGEPAGES_NODE}/hugepages/hugepages-${HUGEPAGES_SIZE}kB/nr_hugepages ]; then echo ${HUGEPAGES_NUMBER} > /sys/devices/system/node/node${HUGEPAGES_NODE}/hugepages/hugepages-${HUGEPAGES_SIZE}kB/nr_hugepages fi if [ -n "$HUGEPAGES_GID" ]; then MOUNT_OPTION="-o gid=${HUGEPAGES_GID}" fi HUGEPAGES_NODE="" HUGEPAGES_NUMBER="" done <<< "$(cat ${HUGEPAGES_CONFIG})" else # set it to default # Computing max available #MEM_AVAIL=`grep MemFree /proc/meminfo | cut -d ':' -f 2|sed 's/kB//g'|sed 's/ //g'`; #MEM_AVAIL=$(( MEM_AVAIL - 524288 )) HUGEPAGES_NUMBER=$(( MEM_AVAIL / HUGEPAGES_SIZE )) if [[ ${HUGEPAGES_NUMBER} -gt 0 ]]; then echo ${HUGEPAGES_NUMBER} > /sys/kernel/mm/hugepages/hugepages-${HUGEPAGES_SIZE}kB/nr_hugepages fi fi if [ `grep ${HUGEPAGES_MOUNTPOINT} /proc/mounts | wc -l` -eq 0 ]; then if [ ! -d ${HUGEPAGES_MOUNTPOINT} ]; then mkdir ${HUGEPAGES_MOUNTPOINT} fi mount -t hugetlbfs ${MOUNT_OPTION} none ${HUGEPAGES_MOUNTPOINT} fi } set_interface_mtu() { MTU="" if [ -f ${MTU_CONFIG} ]; then HWADDR=`ip link show ${1} | grep -w link/ether | awk '{print $2}'` MTU=`grep -w "${HWADDR}" ${MTU_CONFIG} | cut -d ' ' -f 2` if [ $((MTU)) -ne 0 ]; then /sbin/ifconfig ${1} mtu ${MTU} > /dev/null 2>&1 fi fi } start_interfaces() { SETUP_FOR_PACKET_CAPTURE=$1 if [ "${CAPTURE_INTERFACES}" != "" ]; then INTERFACES=($CAPTURE_INTERFACES) else INTERFACES=($(cat /proc/net/dev | grep ':' | cut -d ':' -f 1|grep -v 'lo' | tr '\n' ' '| sed 's/ / /g')) fi for D in ${INTERFACES[@]} ; do D_PHYSIF=$D # Check if this is a VLAN interface if [ -f /proc/net/vlan/config ]; then D_PHYSIF=$(eval "cat /proc/net/vlan/config | awk '/^${D} / {print \$5}'") if [ -z $D_PHYSIF ]; then D_PHYSIF=$D fi fi if [ $SETUP_FOR_PACKET_CAPTURE -eq 1 ] && ! is_management_interface $D_PHYSIF ; then # Disabling offloads /sbin/ethtool -K $D sg off tso off gso off gro off > /dev/null 2>&1 # Disabling VLAN stripping /sbin/ethtool -K $D rxvlan off > /dev/null 2>&1 # Disabling Flow Control /sbin/ethtool -A $D rx off > /dev/null 2>&1 /sbin/ethtool -A $D tx off > /dev/null 2>&1 # Setting max number of RX/TX slots MAX_RX_SLOTS=$(/sbin/ethtool -g $D 2>/dev/null | grep "RX" | head -n 1 | cut -d ':' -f 2 | tr -d '\t') MAX_TX_SLOTS=$(/sbin/ethtool -g $D 2>/dev/null | grep "TX" | head -n 1 | cut -d ':' -f 2 | tr -d '\t') if [ ! -z $MAX_RX_SLOTS ]; then /sbin/ethtool -G $D rx $MAX_RX_SLOTS 2>/dev/null /sbin/ethtool -G $D tx $MAX_TX_SLOTS 2>/dev/null fi set_interface_mtu ${D} fi /sbin/ifconfig $D up done } load_driver() { DRV_PARAM="" if [ `/sbin/modinfo ${1}-${2} | wc -l` -gt 1 ]; then # driver is available DRV_PARAM=`cat ${PF_RING_CONFIG_DIR}/${2}/${1}/${1}.conf` if [ ! -f ${DRIVER_FORCESTART_FILE} ] && is_management_interface_driver ${1} ; then echo "Skipping driver ${1}: driver matches the management interface" return fi # unload old module if needed if [ `lsmod |grep -w ^${1} | wc -l` -eq 1 ]; then /sbin/modprobe -r ${1} if [ `echo $?` -gt 0 ]; then echo "Error unloading driver ${1}" return fi fi # check if already loaded if [ `lsmod |grep -w ^${1}_${2} | wc -l` -eq 1 ]; then echo "Driver ${1}-${2} already installed" DRIVER_INSTALLED=1 return fi /sbin/modprobe ${1}_${2} ${DRV_PARAM} if [ `echo $?` -gt 0 ]; then echo "Error loading driver ${1}-${2}" # last resort: try rebuilding dkms driver rebuild_dkms ${1}-${2} # attempt to load the driver now that it has been rebuilt /sbin/modprobe ${1}_${2} ${DRV_PARAM} if [ `echo $?` -eq 0 ]; then DRIVER_INSTALLED=1 fi else DRIVER_INSTALLED=1 fi else echo "Driver ${1}-${2} not available" fi } load_zc() { # load dependencies /sbin/modprobe uio > /dev/null 2>&1 /sbin/modprobe ptp > /dev/null 2>&1 /sbin/modprobe vxlan > /dev/null 2>&1 /sbin/modprobe dca > /dev/null 2>&1 /sbin/modprobe configfs > /dev/null 2>&1 # load dkms drivers # search for file under /etc/pf_ring/zc/{e1000e,igb,ixgbe,ixgbevf,i40e,fm10k}/{e1000e,igb,ixgbe,ixgbevf,i40e,fm10k}.conf for F in ${DRIVERS_FLAVOR[@]} ; do for D in ${DKMS_DRIVERS[@]} ; do if [ -f ${PF_RING_CONFIG_DIR}/${F}/${D}/${D}.conf ] && [ -f ${PF_RING_CONFIG_DIR}/${F}/${D}/${D}.start ]; then load_driver ${D} ${F} if [ ${F} == "zc" ] && [ ${DO_NOT_LOAD_HUGEPAGES} -eq 0 ]; then LOAD_HUGEPAGES=1 fi fi done done if hash systemctl 2>/dev/null; then if [ `find /etc/systemd/system/multi-user.target.wants/ -name "cluster@*.service" | wc -l ` -ge 1 ]; then LOAD_HUGEPAGES=1 fi else if [ `grep '\-u\=' /etc/cluster/cluster-*conf 2>/dev/null | wc -l` -ge 1 ] && [ `ls /etc/cluster/cluster-*.start 2>/dev/null | wc -l` -ge 1 ]; then LOAD_HUGEPAGES=1 fi fi if [ -f ${HUGEPAGES_CONFIG} ] ; then LOAD_HUGEPAGES=1 fi if [ ${LOAD_HUGEPAGES} -eq 1 ] ; then load_hugepages fi } load_nt() { if [ $(lspci | grep Napatech | wc -l) -gt 0 ] && [ -d "/opt/napatech3" ]; then if [ $(ps aux | grep ntservice | grep napatech | wc -l) -eq 0 ]; then /opt/napatech3/bin/ntstart.sh fi fi } unload_driver() { /sbin/modprobe -r ${1}_${2} if [ `echo $?` -gt 0 ]; then echo "Error unloading driver ${1}" return fi # Restore vanilla driver /sbin/modprobe ${1} } unload_zc() { UNLOAD_HUGEPAGES=0 for F in ${DRIVERS_FLAVOR[@]} ; do for D in ${DKMS_DRIVERS[@]} ; do if [ `/sbin/lsmod | grep -w ^${D}_${F} |wc -l ` -eq 1 ]; then unload_driver ${D} ${F} if [ ${F} == "zc" ] && [ ${DO_NOT_LOAD_HUGEPAGES} -eq 0 ]; then UNLOAD_HUGEPAGES=1 fi fi done done if [ ${UNLOAD_HUGEPAGES} -eq 1 ]; then unload_hugepages fi start_interfaces 0 } start_pf_ring() { init_config if [ ! -d /var/lib/dkms/pfring ]; then [ ${DISTRO} == "debian" ] && log_daemon_msg "PF_RING kernel module not installed, please install pfring-dkms" [ ${DISTRO} == "centos" ] && echo "PF_RING kernel module not installed, please install pfring-dkms" return fi if [ ! -f "${FORCESTART_FILE}" ] && [ ${FORCESTART} -eq 0 ]; then # remove pf_ring in any case /sbin/modprobe -r pf_ring echo "PF_RING not enabled: please touch /etc/pf_ring/pf_ring.start" [ ${DISTRO} == "debian" ] && log_end_msg $ERROR [ ${DISTRO} == "centos" ] && echo_success && echo return fi [ ${DISTRO} == "debian" ] && log_daemon_msg "Starting PF_RING module" [ ${DISTRO} == "centos" ] && echo -n "Starting PF_RING module: " # Set CPU freq to performance useful in particular # on CPUs with aggressive scaling such as Intel E5 find /sys/devices/system/cpu/ -name scaling_governor -exec sh -c 'echo performance > {}' \; KERNEL_VERSION=$(uname -r) PARAM="$(cat "$PF_RING_CONFIG_DIR/pf_ring.conf")" PF_RING_MOD="/lib/modules/$KERNEL_VERSION/kernel/net/pf_ring/pf_ring.ko" PF_RING_MOD_LOCAL="/usr/local/pfring/kernel/pf_ring.ko" check_pf_ring start if [ $? -ne 0 ]; then : # pf_ring.ko already loaded else # Try loading pfring /sbin/modprobe pf_ring $PARAM if [ `echo $?` -gt 0 ]; then # try building dkms rebuild_dkms pfring /sbin/modprobe pf_ring $PARAM # try with local copies in case of failure if [ `echo $?` -gt 0 ]; then if [ -f $PF_RING_MOD ]; then /sbin/insmod $PF_RING_MOD $PARAM elif [ -f $PF_RING_MOD_LOCAL ]; then /sbin/insmod $PF_RING_MOD_LOCAL $PARAM fi fi fi if [ `lsmod | grep ^${PF_RING} | wc -l ` -le 0 ] ; then # PF_RING not loaded. Exiting MSG="Unable to load PF_RING. Exiting" ERROR=1 if [ ${DISTRO} == "debian" ]; then log_failure_msg "${MSG}" log_end_msg $ERROR exit 99 elif [ ${DISTRO} == "centos" ]; then echo -n ${MSG} echo_failure; echo exit 99 fi fi fi ## Load NTOP drivers ## load_zc ## Load Napatech drivers ## load_nt ## Sleep a bit for changes to be applied sleep 1 ## Load NTOP drivers ## sleep 1 ## Load dummy interfaces associated to timelines or nic cards ## local N2IF_SCRIPT="/usr/bin/n2if" if [ -f "${N2IF_SCRIPT}" ]; then ${N2IF_SCRIPT} up-all sleep 1 fi start_interfaces 1 [ ${DISTRO} == "debian" ] && log_end_msg $ERROR [ ${DISTRO} == "centos" ] && echo_success && echo } stop_pf_ring() { [ ${DISTRO} == "debian" ] && log_daemon_msg "Stopping PF_RING module" [ ${DISTRO} == "centos" ] && echo -n "Stopping PF_RING module: " check_pf_ring stop if [ $? -ne 0 ]; then return fi if hash systemctl 2>/dev/null && [ -f /etc/systemd/system/nprobe@.service ]; then # Systemd will take care of stopping nprobe : elif [ -f /etc/init.d/nprobe ]; then /etc/init.d/nprobe stop fi if hash systemctl 2>/dev/null && [ -f /etc/systemd/system/n2disk@.service ]; then # Systemd will take care of stopping n2disk : elif [ -f /etc/init.d/n2disk ]; then /etc/init.d/n2disk stop fi if hash systemctl 2>/dev/null && [ -f /etc/systemd/system/ntopng.service ]; then # Systemd will take care of stopping ntopng : elif [ -f /etc/init.d/ntopng ]; then /etc/init.d/ntopng stop fi if hash systemctl 2>/dev/null && [ -f /etc/systemd/system/cento.service ]; then # Systemd will take care of stopping cento : elif [ -f /etc/init.d/cento ]; then /etc/init.d/cento stop fi if hash systemctl 2>/dev/null && [ -f /etc/systemd/system/cluster@.service ]; then # Systemd will take care of stopping clusters : elif [ -f /etc/init.d/cluster ]; then /etc/init.d/cluster stop fi if hash systemctl 2>/dev/null && [ -f /etc/systemd/system/nscrub.service ]; then # Systemd will take care of stopping clusters : elif [ -f /etc/init.d/nscrub ]; then /etc/init.d/nscrub stop fi sleep 1 ## Unload drivers ## unload_zc NUM="$(grep pf_ring /proc/modules|wc -l)" if [ $NUM -gt 0 ]; then /sbin/modprobe -r pf_ring NUM="$(grep pf_ring /proc/modules|wc -l)" if [ ${NUM} -gt 0 ]; then MSG="unable to unload PF_RING module" [ ${DISTRO} == "debian" ] && log_failure_msg "$MSG" [ ${DISTRO} == "centos" ] && echo_failure ERROR=1 fi fi [ ${DISTRO} == "debian" ] && log_end_msg $ERROR [ ${DISTRO} == "centos" ] && echo_success && echo } check_driver_status() { local NUM_CONFIGED_DRIVERS=0 local NUM_LOADED_DRIVERS=0 local UNLOADED_DRIVERS=() for F in ${DRIVERS_FLAVOR[@]} ; do for D in ${DKMS_DRIVERS[@]} ; do if [ -f ${PF_RING_CONFIG_DIR}/${F}/${D}/${D}.conf ] && [ -f ${PF_RING_CONFIG_DIR}/${F}/${D}/${D}.start ]; then NUM_CONFIGED_DRIVERS=$((NUM_CONFIGED_DRIVERS+1)) if [ `lsmod |grep -w ^${D}_${F} | wc -l` -eq 1 ]; then NUM_LOADED_DRIVERS=$((NUM_LOADED_DRIVERS+1)) else UNLOADED_DRIVERS+=(${D}_${F}) fi fi done done if [ $NUM_CONFIGED_DRIVERS -eq $NUM_LOADED_DRIVERS ]; then echo "UP" else local MSG="The following drivers has not been loaded: " for driver in ${UNLOADED_DRIVERS[@]}; do MSG+="$driver " done echo "$MSG" fi } check_pf_ring_status() { # check the module status if [ -f ${PF_RING_CONFIG_DIR}/${PF_RING}.conf ] && [ -f ${PF_RING_CONFIG_DIR}/${PF_RING}.start ]; then if [ `lsmod | grep ^${PF_RING} | wc -l` -gt 0 ]; then echo "UP" elif [ `lsmod | grep ^${PF_RING} | wc -l` -le 0 ]; then local MSG="pf_ring module not running" echo "$MSG" fi fi } get_status() { EXIT_CODE=0 driver_result=$(check_driver_status); pf_ring_result=$(check_pf_ring_status); if [[ $driver_result == UP* ]]; then echo "Drivers Loaded" else echo "$driver_result" EXIT_CODE=3 fi if [[ $pf_ring_result == UP* ]]; then echo "pf_ring Loaded" else echo "$pf_ring_result" EXIT_CODE=3 fi exit "$EXIT_CODE" } init_config() { if [ -f "${PF_RING_CONFIG_DIR}/pf_ring.conf" ]; then return # PF_RING already configured, do not change the current conf fi # Create an initial configuration structure if [ ! -d "${PF_RING_CONFIG_DIR}" ]; then mkdir ${PF_RING_CONFIG_DIR} fi if [ ! -f "${PF_RING_CONFIG_DIR}/pf_ring.conf" ]; then touch "${PF_RING_CONFIG_DIR}/pf_ring.conf" fi if [ ! -f "${PF_RING_CONFIG_DIR}/pf_ring.start" ]; then touch "${PF_RING_CONFIG_DIR}/pf_ring.start" fi if [ ! -f ${INTERFACES_CONFIG} ]; then touch "${INTERFACES_CONFIG}" echo "#MANAGEMENT_INTERFACES=\"eth0\"" >> ${INTERFACES_CONFIG} echo "#CAPTURE_INTERFACES=\"eth1 eth2\"" >> ${INTERFACES_CONFIG} fi for F in ${DRIVERS_FLAVOR[@]} ; do for D in ${DKMS_DRIVERS[@]} ; do if [ ! -d ${PF_RING_CONFIG_DIR}/${F}/${D} ]; then mkdir -p ${PF_RING_CONFIG_DIR}/${F}/${D} fi done done } ######## echo "$(/bin/date) pf_ringctl $1" >> /var/log/ntop-systemd.log case "$1" in start) FORCESTART=1 start_pf_ring; ;; start-if-enabled) start_pf_ring; ;; stop) stop_pf_ring; ;; restart) FORCESTART=1 stop_pf_ring; start_pf_ring; ;; restart-if-enabled) stop_pf_ring; start_pf_ring; ;; status) get_status; ;; *) echo "Usage: ${0} {start|stop|restart|status}" exit 1 esac echo "$(/bin/date) pf_ringctl done" >> /var/log/ntop-systemd.log exit 0