HEX
Server: Apache/2.4.63 (Unix)
System: Linux TOMS-220NAS 4.4.302+ #86009 SMP Wed Nov 26 18:19:17 CST 2025 x86_64
User: flavio87 (1026)
PHP: 8.3.27
Disabled: NONE
Upload Files
File: //proc/25618/root/etc/rc.network
#!/bin/sh -
# Copyright (c) 2000-2012 Synology Inc. All rights reserved.

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin

. /etc.defaults/rc.subr
. /etc/iproute2/script/gateway-mgt-function

KERNEL_VCODE=`KernelVersionCode $(KernelVersion)`

SYNOINFO_DEF="/etc.defaults/synoinfo.conf"
PLATFORM=`get_key_value $SYNOINFO_DEF unique | cut -d"_" -f2`
SYNONET="/usr/syno/sbin/synonet"
SYNONETDTOOL="/usr/syno/sbin/synonetdtool"
SUPPORTOOBCTL=$(/bin/get_key_value "${SYNOINFO_DEF}" support_oob_ctl)

if [ $KERNEL_VCODE -ge $(KernelVersionCode "2.6.32") ]; then
	NET_COMMON_MODULES="llc"
	BRIDGE_MODULES="stp bridge"
	VLAN_MODULES="8021q"
else
	BRIDGE_MODULES=
	TC_MODULES=
	VLAN_MODULES=
fi

# @ret
#     3: router mode (maybe bridge mode included)
#     2: bridge mode
#     1: normal mode
check_topology_mode ()
{
	local bridge_exist=1
	for ifn in `ls /sys/class/net`; do
		if [ ! -d "/sys/class/net/${ifn}/bridge" ]; then
			continue
		fi
		bridge_exist=2
		local IFCFG_FILE="/etc/sysconfig/network-scripts/ifcfg-${ifn}"
		local LOCAL_LAN=`/bin/get_key_value ${IFCFG_FILE} LOCAL_LAN`
		if [ "$LOCAL_LAN" = "yes" ]; then
			return 3
		fi
	done
	return $bridge_exist
}

set_kernel_topology_mode()
{
	local SupportTopology=`get_key_value /etc/synoinfo.conf support_net_topology`
	local NetTopology=`get_key_value /etc/synoinfo.conf net_topology`
	local topology="0"

	if [ "yes" != "${SupportTopology}" ]; then
		return 0;
	fi

	case "$NetTopology" in
		client)
			topology="1"
			;;
		bridge)
			topology="2"
			;;
		router)
			topology="3"
			;;
		*)
			;;
	esac
	if [ -f "/proc/sys/kernel/syno_topology_mode" ]; then
		echo "${topology}" > /proc/sys/kernel/syno_topology_mode
	fi
}

activate_bridge () # $1=br0
{
	unset FN_BONDING_MASTERS DN_BONDDEV SKIP_ENSLAVE DEVICE BRIDGE PRIMARY LOCAL_LAN

	[ $# -ne 0 ] || return

	if [ -d /sys/class/net/$1 ]; then
		# delete exist bridge
		ip link set dev $1 down
		/usr/bin/brctl delbr $1
	fi

	/usr/bin/brctl addbr $1
	for device in `grep -l "^BRIDGE=$1$" /etc/sysconfig/network-scripts/ifcfg-*` ; do
		DEVICE=`basename ${device} | cut -d '-' -f 2`
		$SYNONET --set_ip -4 ${DEVICE} flush
		/sbin/ifconfig ${DEVICE} up
		/usr/bin/brctl addif $1 ${DEVICE}
	done
	/usr/bin/brctl setfd $1 1
	/sbin/ip link set dev $1 up

	return 0
}

disable_bridge () # $1=br0
{
	unset FN_BONDING_MASTERS DN_BONDDEV REVERSE_SLAVES BRIDGE

	/sbin/ip link set dev $1 down
	/usr/bin/brctl delbr $1

}

install_bonding_driver () # $1=bond0 $2=BONDING_OPTS
{
	unset FN_BONDING_MASTERS DN_BONDDEV SKIP_ENSLAVE DEVICE
	FN_BONDING_MASTERS="/sys/class/net/bonding_masters"
	DN_BONDDEV="/sys/class/net/$1/bonding"
	if [ ! -f ${FN_BONDING_MASTERS} ]; then
		# Set 'max_bonds=0' to prevent kernel from creating default bonding.
		/sbin/modprobe bonding max_bonds=0 min_links=1 || return 1
	fi
	if ! echo "+$1" > ${FN_BONDING_MASTERS}; then
		/usr/bin/logger -p warn -t "$1" "already exists"
		return 0
	fi

	/sbin/ip link set dev $1 down

	# add the bits to setup driver parameters here
	for arg in $2 ; do
		key=${arg%%=*};
		value=${arg##*=};
		echo $value > ${DN_BONDDEV}/$key
	done

	/sbin/ip link set dev $1 up
	# disable IPv6 DAD (Duplicate Address Detection) check on the bonding interface
	echo "0" > /proc/sys/net/ipv6/conf/$1/accept_dad
	for device in `grep -l "^MASTER=$1" /etc/sysconfig/network-scripts/ifcfg-* | sort -V` ; do
		SKIP_ENSLAVE=0
		DEVICE=`basename ${device} | cut -d '-' -f 2`

		for slv_dev in `cat ${DN_BONDDEV}/slaves`
		do
			if [ "${slv_dev}" = "${DEVICE}" ]; then
				SKIP_ENSLAVE=1
				break
			fi
		done

		if [ "${SKIP_ENSLAVE}" -eq 0 ]; then
			/sbin/ip link set dev ${DEVICE} down
			echo "+${DEVICE}" > ${DN_BONDDEV}/slaves 2>/dev/null
			/sbin/ip link set dev ${DEVICE} up
		fi
	done
	/sbin/ip link set dev $1 up
	return 0
}

unset_bonding_driver () # $1=bond0
{
	unset FN_BONDING_MASTERS DN_BONDDEV REVERSE_SLAVES
	FN_BONDING_MASTERS="/sys/class/net/bonding_masters"
	DN_BONDDEV="/sys/class/net/$1/bonding"
	REVERSE_SLAVES=""
	[ ! -f ${FN_BONDING_MASTERS} ] && return 0

	for slv_dev in `cat ${DN_BONDDEV}/slaves`
	do
		/sbin/ip link set dev ${slv_dev} down
	done
	/sbin/ip link set dev $1 down
	echo "-$1" > ${FN_BONDING_MASTERS}
}

is_ovs_enable ()
{
	if [ ! -f  '/usr/syno/etc/synoovs/ovs_reg.conf' ]; then
		return 1
	fi

	use=`cat /usr/syno/etc/synoovs/ovs_reg.conf | wc -l`
	if [ 0 -eq $use ]; then
		return 1
	else
		return 0
	fi
}

check_external_interface_for_ovs ()
{
	if ! is_ovs_enable; then
		return 0
	fi

	synobootseq --is-ready;
	if [ $? -eq 0 ]; then
		return 0
	fi

	# skip oob while creating new interfaces
	oob=`/bin/get_key_value /etc.defaults/synoinfo.conf oob_interface`
	#For external NIC, we need to handle its ifcfg.
	#When adding the external NIC, we need to create the ifcfg-ovs_ethX and set to DHCP.
	local TMP="/tmp/ovs_conf"
	for eth in `grep -v ovs /proc/net/dev | grep "eth"  | cut -d ':' -f 1 | sed -e 's/^[ ]*//'`; do
		grep $eth /usr/syno/etc/synoovs/ovs_ignore.conf
		if [ "$?" -eq "0" ]; then
			continue
		fi

		if [ "$oob" == "$eth" ]; then
			echo "$eth" >> /usr/syno/etc/synoovs/ovs_ignore.conf
			continue
		fi

		grep $eth /usr/syno/etc/synoovs/ovs_interface.conf
		if [ "$?" -ne "0" ]; then
			#If this $eth is the new external interface.
			#we need to create the ifconfig for this interface.
			eth_ifcfg="/etc/sysconfig/network-scripts/ifcfg-${eth}"
			ovs_ifcfg="/etc/sysconfig/network-scripts/ifcfg-ovs_${eth}"

			#for original eth interface
			/usr/syno/bin/synosetkeyvalue ${eth_ifcfg} BRIDGE ovs_${eth}
			sed 's/\"//g' ${eth_ifcfg} > ${TMP}
			mv ${TMP} ${eth_ifcfg}
			#for ovs interface
			/usr/syno/bin/synosetkeyvalue ${ovs_ifcfg} DEVICE ovs_${eth}
			/usr/syno/bin/synosetkeyvalue ${ovs_ifcfg} BOOTPROTO dhcp
			/usr/syno/bin/synosetkeyvalue ${ovs_ifcfg} ONBOOT yes
			/usr/syno/bin/synosetkeyvalue ${ovs_ifcfg} TYPE OVS
			/usr/syno/bin/synosetkeyvalue ${ovs_ifcfg} PRIMARY ${eth}
			sed 's/\"//g' ${ovs_ifcfg} > ${TMP}
			mv ${TMP} ${ovs_ifcfg}

			echo $eth >> /usr/syno/etc/synoovs/ovs_interface.conf
		fi
	done
}

activate_ovs ()
{
	[ $# -ne 0 ] || return

	if ! is_ovs_enable; then
		return 0
	fi


	#If the external interface has been remove.
	#Remove the ifcfg of ovs and modify the ovs_interface.conf.
	local tmpdev=`/bin/grep -v ovs /proc/net/dev | /bin/grep ${1##ovs_}` > /dev/null 2>&1
	if [ -z "$tmpdev" ]; then
		ovs-vsctl del-br $1
		sed -i.bak "/${1##ovs_}/"d /usr/syno/etc/synoovs/ovs_interface.conf
		rm /etc/sysconfig/network-scripts/ifcfg-$1
		return 0
	fi

	ifconfigFile="/etc/sysconfig/network-scripts/ifcfg-$1"
	if ! source  "$ifconfigFile" ; then
                return
	fi

	check_exist_ovs $1
	/bin/ovs-vsctl add-br $1
	set_ovs_mac_address $1
	for device in `grep -l "^BRIDGE=$1$" /etc/sysconfig/network-scripts/ifcfg-*` ; do
		DEVICE=`basename ${device} | cut -d '-' -f 2`
		$SYNONET --set_ip -4 $DEVICE flush
		/sbin/ifconfig $DEVICE up
		if [ -e "/proc/sys/net/ipv6/conf/${DEVICE}/disable_ipv6" ]; then
			echo 1 > /proc/sys/net/ipv6/conf/${DEVICE}/disable_ipv6
		fi
		/bin/ovs-vsctl add-port $1 ${DEVICE}

		#Set MTU
		MTU_VALUE=`get_mtu_value ${DEVICE}`
		MTU="" ; [ -n "${MTU_VALUE}" ] && MTU="mtu ${MTU_VALUE}"
		ifconfig ${DEVICE} ${MTU}
	done

	start_ovs_vlan $1 $ifconfigFile
	setup_ovs_default_flow $1

	/sbin/ip link set dev $1 up

	return 0
}

disable_ovs ()
{
	if [ -f '/usr/syno/etc/synoovs/ovs_reg.conf' ]; then
		return 1
	fi

	active=`systemctl is-active synoovs-vswitch`
	if [ "$active" == "active" ]; then
		for ovsIfs in `/bin/ovs-vsctl list-br`;
		do
			/bin/ovs-vsctl del-br $ovsIfs
		done
	fi
}

remove_ovs ()
{
	ifconfigFile="/etc/sysconfig/network-scripts/ifcfg-$1"
	for slave in `synogetkeyvalue $ifconfigFile SLAVE_LIST`
	do
		/sbin/ip link set dev ${slave} down
	done

	unset OVS_VLAN_ID
	/bin/ovs-vsctl br-exists $1
	if [ $? -eq 0 ]; then
		# delete bridge
		if [ "$(grep OVS_VLAN_ID $ifconfigFile)" ]; then
			/bin/ovs-vsctl clear port $1 tag > /dev/null 2>&1
        fi
		/sbin/ip link set dev $1 down
		/bin/ovs-vsctl del-br $1
	fi
}

lock_ovs()
{
	local OVS_LOCK_FILE="/tmp/ovs_change.lock"
	exec 8>$OVS_LOCK_FILE
	flock -n -x 8
}

unlock_ovs()
{
	exec 8>&-
}

activate_ovs_bonding ()
{
	if ! is_ovs_enable; then
		return 0
	fi

	ifconfigFile="/etc/sysconfig/network-scripts/ifcfg-$1"
	if ! source  "$ifconfigFile" ; then
                return
	fi

	check_exist_ovs $1
	/bin/ovs-vsctl add-br $1
	# disable IPv6 DAD (Duplicate Address Detection) check on the bonding interface
	echo "0" > /proc/sys/net/ipv6/conf/$1/accept_dad

	# for OVS bonding, if it support the MTU, we should set the MTU for each interface.
	# /bin/ovs-vsctl add-bond ovs_bond0 bond0 eth0 eth1 $2
	slave=""
	for device in `grep -l "^MASTER=$1" /etc/sysconfig/network-scripts/ifcfg-*` ; do
		DEVICE=`basename ${device} | cut -d '-' -f 2`
		set_mac_address ${DEVICE}
		/sbin/ip link set dev ${DEVICE} down
		slave="${slave} ${DEVICE}"

		#Set MTU
		MTU_VALUE=`get_mtu_value ${DEVICE}`
		MTU="" ; [ -n "${MTU_VALUE}" ] && MTU="mtu ${MTU_VALUE}"
		ifconfig ${DEVICE} ${MTU}
	done
	/bin/ovs-vsctl add-bond $1 ${1##ovs_} ${slave} $2

	start_ovs_vlan $1 $ifconfigFile
	setup_ovs_default_flow $1

	/sbin/ip link set dev $1 up

	logger -p user.warn -t $(basename $0) "Wait for all netlink & hook event done"
	sleep 3
	logger -p user.warn -t $(basename $0) "Link up all bonding slaves, bond: $1 : [${slave}]"
	for device in ${slave}; do
		/sbin/ip link set dev ${device} up
	done

	return 0

}

check_exist_ovs()
{
	ifname=$1

	/bin/ovs-vsctl br-exists $ifname
	if [ $? -eq 0 ]; then
		# delete exist bridge
		ip link set dev $ifname down
		/bin/ovs-vsctl del-br $ifname
	fi
}

start_ovs_vlan()
{
	local ifname=$1
	local ifconfigFile=$2

	unset OVS_VLAN_ID
	eval $(grep "^OVS_VLAN_ID" $ifconfigFile)
	if [ -n "${OVS_VLAN_ID}" ]; then
		/bin/ovs-vsctl set port $ifname tag=${OVS_VLAN_ID} > /dev/null 2>&1
	fi
}

setup_ovs_default_flow()
{
	local ifname=$1

	#FIXME We create two static rules for EAPOL packets here, we should use the framework to set the default rules.
	/bin/ovs-ofctl add-flow $ifname "in_port=LOCAL dl_type=0x888e priority=2 actions=output:1"
	/bin/ovs-ofctl add-flow $ifname "in_port=1 dl_type=0x888e priority=2 actions=output:LOCAL"

}

SupportMTU=`/bin/get_key_value /etc.defaults/synoinfo.conf supportMTU`
get_mtu_value()
{
	local ifname="$1"
	local mtu_value=""

	if [ "$SupportMTU" != "yes" -o ! -x "/usr/syno/bin/synoethinfo" ]; then
		# synoethinfo does not exist in network install mode
		return
	fi
	mtu_value=`/bin/get_key_value /etc/synoinfo.conf ${ifname}_mtu`
	if [ $? -ne 1 ]; then
		return
	fi

	echo "$mtu_value"
}

check_interfaces()
{
	local ext_ifn_exist="no"
	CWD=`pwd`
	cd /etc/sysconfig/network-scripts
	rm -f ifcfg-*tmp* ifcfg-*.saved

	if [ $# -le 0 ]; then
		all_network_interfaces=`find . -name "ifcfg-*" | grep -vE "^\./ifcfg-.*\.[A-Za-z0-9]{6}" | cut -d'-' -f 2 | sort`
	else
		all_network_interfaces="$@"
	fi
	network_interfaces=""
	for thisif in $all_network_interfaces;
	do
		echo "${thisif}" | grep -c mon > /dev/null 2>&1
		if [ $? -eq 0  ]; then
			continue
		fi

		unset SLAVE BOOTPROTO BONDING_OPTS IPV6INIT TYPE BRIDGE PRIMARY LOCAL_LAN
		ThisIfConf="/etc/sysconfig/network-scripts/ifcfg-${thisif}"
		if [ ! -r ${ThisIfConf} ]; then
			continue;
		fi
		# filter out slave device
		eval $(grep "^SLAVE=" ${ThisIfConf})
		if [ "$SLAVE" = "yes" ]; then
			continue
		fi
		# filter out SHA related interfaces
		echo "${thisif}" | grep -q ":\(HA\|DRBD\)$"
		if [ $? -eq 0 ]; then
			continue;
		fi
		# filter out ntb related interfaces (internal interface of dual controller model)
		echo "${thisif}" | grep -q "^ntb_"
		if [ $? -eq 0 ]; then
			continue;
		fi
		network_interfaces="$network_interfaces ${thisif}"

		if [ "$(grep "VLAN_ROW_DEVICE=" ${ThisIfConf})" ]; then
			continue;
		fi

		eval $(grep "^BONDING_OPTS=" ${ThisIfConf})
		if [ -n "${BONDING_OPTS}" ]; then
			eval \Bond_${thisif}='${BONDING_OPTS}'
		fi

		eval $(grep "^TYPE=" ${ThisIfConf})
		eval \TYPE_${thisif}='${TYPE}'
		eval $(grep "^BRIDGE=" ${ThisIfConf})
		eval \BRIDGE_${thisif}='${BRIDGE}'
		eval $(grep "^PRIMARY=" ${ThisIfConf})
		eval \PRIMARY_${thisif}='${PRIMARY}'
		eval $(grep "^LOCAL_LAN=" ${ThisIfConf})
		eval \LOCAL_LAN_${thisif}='${LOCAL_LAN}'

		# set up ipv4 parameters
		eval $(grep "^BOOTPROTO=" ${ThisIfConf})
		if [ "${BOOTPROTO}" = "static" -o "${thisif}" = "lo" ]; then
			unset IPADDR NETMASK IP MASK MTU MTU_VALUE
			MTU_VALUE=`get_mtu_value ${thisif}`
			eval $(grep "^IPADDR=" ${ThisIfConf})
			eval $(grep "^NETMASK=" ${ThisIfConf})
			IP="" ; [ -n "${IPADDR}" ] && IP="inet ${IPADDR}"
			MASK="" ;  [ -n "${NETMASK}" ] && MASK="netmask ${NETMASK}"
			MTU="" ; [ -n "${MTU_VALUE}" ] && MTU="mtu ${MTU_VALUE}"
			if [ -n "${IP}" ]; then
				thisvalue="${IP} ${MASK} ${MTU}"
			else
				thisvalue="dhcp"
			fi
			eval \ifconfig_${thisif}='$thisvalue'
			if [ "${thisif}" != "lo" ]; then
				eval \setgw_${thisif}='1'
			fi
		elif [ "${BOOTPROTO}" = "none" ]; then
			unset MTU MTU_VALUE
			MTU_VALUE=`get_mtu_value ${thisif}`
			MTU="" ; [ -n "${MTU_VALUE}" ] && MTU="mtu ${MTU_VALUE}"
			thisvalue="inet 0.0.0.0 ${MTU}"
			eval \ifconfig_${thisif}='$thisvalue'
		else
			eval \ifconfig_${thisif}='dhcp'
			eval \setgw_${thisif}='1'
		fi
		#set up ipv6 parameters
		eval $(grep "^IPV6INIT=" ${ThisIfConf})
		eval \ifconfig_v6init_${thisif}='$IPV6INIT'
		if [ "${IPV6INIT}" = "static" ]; then
			unset IPV6ADDR IPV6_DEFAULTGW IPV6PREFIXLENG
			eval $(grep "^IPV6ADDR=" ${ThisIfConf})
			eval $(grep "^IPV6_DEFAULTGW=" ${ThisIfConf})
			eval $(grep "^IPV6PREFIXLENG=" ${ThisIfConf})
			eval \ifconfig_v6ip_${thisif}='$IPV6ADDR'
			eval \ifconfig_v6gw_${thisif}='$IPV6_DEFAULTGW'
			eval \ifconfig_pxleng_${thisif}='$IPV6PREFIXLENG'
			eval \setgw6_${thisif}='1'
		fi
	done

	# If all interfaces are local lan ,
	# the routing table should not be modified
	for ifn in ${network_interfaces}; do
		eval local_lan=\$LOCAL_LAN_${ifn}
		if [ "${local_lan}" != "yes" ]; then
			ext_ifn_exist="yes"
			break
		fi
	done

	if [ "${ext_ifn_exist}" != "yes" ]; then
		return
	fi

	cd $CWD

	ConfList="/etc/sysconfig/network"
	for ThisConfig in $ConfList;
	do
		if [ -r "$ThisConfig" ]; then
			. $ThisConfig
		fi
	done

	if [ -n "${GATEWAY}" -a "${NETWORKING}" = "yes" ]; then
		defaultrouter="${GATEWAY}"
	fi
}

# set the mac address of ovs interface by ovs way
set_ovs_mac_address()
{
	local ovs_if=$1

	# support ovs_ethX only
	if [ "ovs_eth" != "${ovs_if:0:7}" ]; then
		logger -p user.err -t $(basename $0) "failed to set mac for [${ovs_if}]"
		return
	fi

	# get the mac address of original ethX interface
	local eth_if=${ovs_if##ovs_}
	local macAddrPath="/sys/class/net/${eth_if}/address"
	if [ ! -r ${macAddrPath} ]; then
		logger -p user.err -t $(basename $0) "failed to get mac from [${macAddrPath}]"
		return
	fi

	# set mac address by ovs way
	local macAddr=$(cat ${macAddrPath})
	logger -p user.err -t $(basename $0) "set mac [$macAddr] on [${ovs_if}]"
	ovs-vsctl set bridge ${ovs_if} other-config:hwaddr=${macAddr}
}

set_mac_address()
{
	local iface=$1
	local specific_mac=$2
	local macIndex=${iface//eth/}
	local notnumber=${macIndex//[0-9]/}
	if [ -n "${notnumber}" ]; then
		# mac index is not a number so this is not a real DEVICE
		# theoritically, $1 should be eth0, eth1, eth2 ....
		# so when the string part eth was removed, only the numerical part will be left
		return;
	fi
	macIndex=`expr ${macIndex} + 1`
	if [ "${specific_mac}" != "" ]; then
		macIndex=${specific_mac}
	fi

	# check if this interface should skip
	local skipVenderMacIfs=`cat /proc/sys/kernel/syno_skip_vender_mac_interfaces`
	for skipIfn in ${skipVenderMacIfs//,/ }; do
		if [ "$iface" = "eth${skipIfn}" -a -z "$specific_mac" ]; then
			# skip
			return;
		fi
	done

	local internalNetIfNumFile="/proc/sys/kernel/syno_internal_netif_num"
	local maxLan=0
	if [ -e "$internalNetIfNumFile" ]; then
		maxLan=`cat $internalNetIfNumFile`
		if [ "${SUPPORTOOBCTL}" = "yes" ]; then
			maxLan=$((maxLan - 1))
		fi
	else
		# no internal netif num support means this is an old, old machine
		maxLan=1
	fi

	if [ ${macIndex} -gt ${maxLan} ]; then
		# exceed max lan support of DS
		return;
	fi

	local multiMacFile="/proc/sys/kernel/syno_mac_addresses"
	local macFile="/proc/sys/kernel/syno_mac_address${macIndex}"
	local macAddr=""
	if [ -e "${multiMacFile}" ]; then
		# no such a file means this is before apple pie branch v.4009
		macAddr=`/usr/bin/awk "NR==${macIndex}" ${multiMacFile}`
	elif [ -e "${macFile}" ]; then
		macAddr=`cat /proc/sys/kernel/syno_mac_address${macIndex}`
	else
		return;
	fi

	if [ -z "${macAddr}" ]; then
		# no mac address found
		if [ -z "${rndMac}" ]; then
		# can not find random mac
			rndMac=${RANDOM}${RANDOM}
			rndMac=${rndMac:0:12}
		else
			rndMac=`expr ${rndMac} + 1`
		fi
		macAddr=`printf '%012x' ${rndMac}`
	fi

	local macCloneAddr=`get_key_value /etc/synoinfo.conf macclone_${iface}`
	[ "" != "$macCloneAddr" ] && macAddr="$macCloneAddr"

	ifconfig $1 hw ether ${macAddr} > /dev/null 2>&1
}

setup_interface_ip()
{
	# check if interface exists
	local tmpdev=`/bin/grep -w $ifn /proc/net/dev` > /dev/null 2>&1
	if [ -z "$tmpdev" ]; then
		return;
	fi

	local AUTH_8021X_CONFIG="/usr/syno/etc/8021X/cfg-${ifn}"
	local ENABLE_8021X=$(get_key_value "${AUTH_8021X_CONFIG}" enable)
	if [ "${ENABLE_8021X}" = "yes" ]; then
		/usr/syno/bin/synosetkeyvalue /tmp/is_8021x_test_"${ifn}" TEST false
		/usr/syno/bin/synosystemctl start 8021x-client@"${ifn}".service
	fi

	case ${ifconfig_args} in
	'')
		;;
	[Dd][Hh][Cc][Pp])
		# DHCP inits are done all in one go below
		dhcp_interfaces="$dhcp_interfaces $ifn"
		;;
	*) #for 'static' and 'none'
		/sbin/ifconfig ${ifn} ${ifconfig_args}
	esac
	/usr/bin/logger -p err -t interface-catcher "${ifn} (${ifconfig_args}) is added " || true

	eval setgw="\$setgw_${ifn//./_}"
	eval setgw6="\$setgw6_${ifn//./_}"

	if [ -n "$setgw" ]; then
		local GATEWAY_DATABASE="/etc/iproute2/config/gateway_database"
		GATEWAY="$(get_section_key_value "${GATEWAY_DATABASE}" "${ifn}" gateway)"
		if test -z "$GATEWAY" ; then
			GATEWAY="NULL"
		fi
		DNS="$(get_section_key_value "${GATEWAY_DATABASE}" "${ifn}" dns)"
		if test -z "$DNS" ; then
			DNS="NULL"
		fi
		${SYNONETDTOOL} --add-gateway-info -4 -2 "${ifn}" "${GATEWAY}" "${DNS}" ethernet
	fi

	# Configure IPv6
	# module not loaded dont do ipv6 operation
	if [ -z "${ifIpv6}" ]; then
		return;
	fi
	if [ "yes" = "${ipv4only}" -o "off" = "${ifconfig_v6init}" ]; then
		echo 1 > /proc/sys/net/ipv6/conf/${ifn}/disable_ipv6
	else
		echo 0 > /proc/sys/net/ipv6/conf/${ifn}/disable_ipv6
		if [ "static" = "${ifconfig_v6init}" ]; then
			# if static, then add ipv6 address and default gw
			if [ -n "${ifconfig_v6ip}"  ]; then
				$SYNONET --set_ip -6 $ifn add ${ifconfig_v6ip}/${ifconfig_pxleng}
			fi
		fi
	fi

	if [ -n "$setgw6" ]; then
		local IFCFG_FILE="/etc/sysconfig/network-scripts/ifcfg-${ifn}"
		GATEWAY=$(get_key_value "${IFCFG_FILE}" IPV6_DEFAULTGW)
		if test -z "$GATEWAY" ; then
			GATEWAY="NULL"
		fi
		DNS=$(get_key_value "${IFCFG_FILE}" IPV6DNS)
		if test -z "$DNS" ; then
			DNS="NULL"
		fi
		${SYNONETDTOOL} --add-gateway-info -6 -2 "${ifn}" "${GATEWAY}" "${DNS}" ethernet
	fi
}

do_start_vlan_interface()
{
	local ifn=$1
	local ifconfigFile=""

	#form config files
	local BOOTPROTO
	local VLAN_ROW_DEVICE
	local VLAN_ID
	local IPADDR
	local NETMASK
	local IPV6INIT

	#local operation use
	local MTU_VALUE
	local IP
	local MASK
	local MTU

	#for set ip
	local ifconfig_args
	local ifconfig_pxleng
	local ifconfig_v6ip
	local ifconfig_v6gw
	local ifconfig_v6init

	ifconfigFile="/etc/sysconfig/network-scripts/ifcfg-${ifn}"

	if ! source  "$ifconfigFile" ; then
		return
	fi

	/sbin/ip link add link $VLAN_ROW_DEVICE name $VLAN_ROW_DEVICE.$VLAN_ID type vlan id $VLAN_ID
	/sbin/ip link set dev "$VLAN_ROW_DEVICE.$VLAN_ID" up

	if [ -e "/proc/sys/net/ipv4/conf/${ifn}/ignore_routes_with_linkdown" ]; then
		echo 1 > "/proc/sys/net/ipv4/conf/${ifn}/ignore_routes_with_linkdown"
	fi

	# set up ipv4 parameters
	if [ "${BOOTPROTO}" = "static" ]; then
		MTU_VALUE=`get_mtu_value ${ifn}`
		IP="" ; [ -n "${IPADDR}" ] && IP="inet ${IPADDR}"
		MASK="" ;  [ -n "${NETMASK}" ] && MASK="netmask ${NETMASK}"
		MTU="" ; [ -n "${MTU_VALUE}" ] && MTU="mtu ${MTU_VALUE}"
		if [ -n "${IP}" ]; then
			thisvalue="${IP} ${MASK} ${MTU}"
		else
			thisvalue="dhcp"
		fi
		ifconfig_args=$thisvalue
	else
		ifconfig_args='dhcp'
	fi
	eval \setgw_${ifn//./_}='1'
	#set up ipv6 parameters
	ifconfig_v6init=$IPV6INIT
	if [ "${IPV6INIT}" = "static" ]; then
		ifconfig_v6ip=$IPV6ADDR
		ifconfig_v6gw=$IPV6_DEFAULTGW
		ifconfig_pxleng=$IPV6PREFIXLENG
		eval \setgw6_${ifn//./_}='1'
	fi

	setup_interface_ip
}


start_vlan_interfaces()
{
	SYNOLoadModules ${VLAN_MODULES}

	local ifn
	for ifn in ${vlan_interface}; do
		do_start_vlan_interface $ifn
	done
}

start_network()
{
	dhcp_timeoutflags="-t 30"
	dhcp_interfaces=""
	ifgroup=""
	local ipv4only=`get_key_value /etc.defaults/synoinfo.conf ipv4only`
	local ifIpv6=$(find /sys/module -name 'ipv6' -type d)
	local ONBOOT=""
	local bridge_interfaces=""
	local vlan_interface=""
	local ifconfigFile=""
	local internalNetIfNumFile=`cat /proc/sys/kernel/syno_internal_netif_num`
	local needAutoIPForHB=0

	$SYNONET --ipv6-init
	for ifn in `ls /proc/sys/net/ipv6/conf`; do
		echo 0 > /proc/sys/net/ipv6/conf/"${ifn}"/accept_ra_defrtr
	done

	echo 0 | tee /proc/sys/net/ipv4/conf/*/send_redirects
	echo 0 | tee /proc/sys/net/ipv4/conf/*/accept_redirects
	echo 0 | tee /proc/sys/net/ipv4/conf/*/secure_redirects
	echo 0 | tee /proc/sys/net/ipv6/conf/*/accept_redirects

	if is_ovs_enable; then
		lock_ovs
	fi

	for ifn in ${network_interfaces}; do

		if [ "active" = $(synosystemctl get-active-status synonetd) ]; then
			${SYNONETDTOOL} --reset-ipv6-module ${ifn}
		fi

		ifconfigFile="/etc/sysconfig/network-scripts/ifcfg-${ifn}"
		if [ "$(grep VLAN_ROW_DEVICE $ifconfigFile)" ]; then
			vlan_interface="${vlan_interface} ${ifn}"
			continue
		fi

		if [ "kvmx64" != "${PLATFORM}" -a "kvmx64sofs" != "${PLATFORM}" -a \
				"nextkvmx64" != "${PLATFORM}" -a "kvmcloud" != "${PLATFORM}" -a \
				"kvmx64v2" != "${PLATFORM}" ]; then
			set_mac_address ${ifn}
		fi

		eval device_type=\$TYPE_${ifn}
		eval bond_opt=\$Bond_${ifn}
		if [ -n "${bond_opt}" ]; then
			if [ "${device_type}" = "OVS" ]; then
				activate_ovs_bonding ${ifn} "${bond_opt}"
			else
				install_bonding_driver ${ifn} "${bond_opt}"
			fi
		fi

		ONBOOT=`get_key_value /etc/sysconfig/network-scripts/ifcfg-${ifn} ONBOOT`
		if [ "${ONBOOT}" != "yes" ]; then
			continue;
		fi

		if [ "${device_type}" = "bridge" ]; then
			SYNOLoadModules ${NET_COMMON_MODULES}
			SYNOLoadModules ${BRIDGE_MODULES}
			activate_bridge ${ifn}
			bridge_interfaces="${bridge_interfaces} ${ifn}"
		fi

		if [ "${device_type}" = "OVS" -a ! -n "${bond_opt}" ]; then
			activate_ovs ${ifn}
			bridge_interfaces="${bridge_interfaces} ${ifn}"
		fi

		/sbin/ip link set dev "${ifn}" up

		if [ -e "/proc/sys/net/ipv4/conf/${ifn}/ignore_routes_with_linkdown" ]; then
			echo 1 > "/proc/sys/net/ipv4/conf/${ifn}/ignore_routes_with_linkdown"
		fi

		eval bridge_if=\$BRIDGE_${ifn}
		if [ -n "${bridge_if}" ]; then
			continue
		fi

		# Do the primary ifconfig if specified
		eval ifconfig_args=\$ifconfig_${ifn}
		eval ifconfig_pxleng=\$ifconfig_pxleng_${ifn}
		eval ifconfig_v6ip=\$ifconfig_v6ip_${ifn}
		eval ifconfig_v6gw=\$ifconfig_v6gw_${ifn}
		eval ifconfig_v6init=\$ifconfig_v6init_${ifn}

		setup_interface_ip
	done

	if [ -n "${vlan_interface}" ]; then
		start_vlan_interfaces
	fi

	# add bridge mac address change here
	for ifn in ${bridge_interfaces}; do
		eval primary_if=\$PRIMARY_${ifn}
		if [ -n "${primary_if}" ]; then
			local mac_addr=`ifconfig ${primary_if} | grep HWaddr | cut -d"W" -f2| cut -d"r" -f2`
			ifconfig ${ifn} hw ether ${mac_addr}
		fi
	done

	/usr/syno/sbin/syno_network_link_check

	if [ ! -z "${dhcp_interfaces}" ]; then
		if [ -x /sbin/udhcpc ]; then
			for dhcpif in ${dhcp_interfaces}
			do
				$SYNONET --set_ip -4 ${dhcpif} flush
				udhcp_flags="-p /etc/dhcpc/dhcpcd-${dhcpif}.pid -b -h `hostname`"
				${dhcp_program:-/sbin/udhcpc} -i ${dhcpif} ${udhcp_flags}
				sleep 1;
			done
		else
			dhcp_flags="-n ${dhcp_flags}"
			for dhcpif in ${dhcp_interfaces}
			do
				unset MTU MTU_VALUE
				MTU_VALUE=`get_mtu_value ${dhcpif}`
				MTU="" ; [ -n "${MTU_VALUE}" ] && MTU="mtu ${MTU_VALUE}"

				$SYNONET --set_ip -4 ${dhcpif} flush
				ifconfig ${dhcpif} ${MTU}

				systemctl is-active dhclient@${dhcpif}.service
				if [ $? -eq 0 ]; then
					logger -p user.warn "rc.network dhclient of [${dhcpif}] is already started. Do restart."
					/bin/systemctl reset-failed dhclient@${dhcpif}.service
					synosystemctl restart dhclient@${dhcpif}.service
				else
					synosystemctl start dhclient@${dhcpif}.service
				fi
			done
		fi
	fi

	if is_ovs_enable; then
		unlock_ovs
	fi

	echo 1 > /proc/sys/net/ipv4/conf/all/promote_secondaries
	if [ $# -gt 0 ]; then
		for iface in "$@"; do
			$SYNONET --ip_alias_apply "$iface"
		done
	else
		$SYNONET --ip_alias_apply
	fi

	set_default_gateway_interface
	${SYNONETDTOOL} --refresh-gateway all

	#showstat
	ifconfig

	ConfList="/etc/sysconfig/network"
	. $ConfList

	if [ "${NETWORKING}" = "yes" ]; then
		/etc/rc.network_routing ${GATEWAY} &
	fi

	set_kernel_topology_mode
}

stop_vlan_interfaces()
{
	local ifconfigFile
	local VLAN_ROW_DEVICE
	local VLAN_ID

	local ifn
	for ifn in ${vlan_interface}; do
		ifconfigFile="/etc/sysconfig/network-scripts/ifcfg-${ifn}"
		source $ifconfigFile
		ifconfig ${ifn} down
		/sbin/ip link delete $VLAN_ROW_DEVICE.$VLAN_ID
	done
	if [ -r /proc/net/vlan/config ] && [ `cat /proc/net/vlan/config |wc -l` -le 2 ]; then
		SYNOUnloadModules ${VLAN_MODULES}
	fi
}

kill_dhcp_processes()
{
	local ifn=$1
	local dhcp
	local pid
	local all_dhcp_processes="udhcpc dhclient"

	for dhcp in ${all_dhcp_processes}; do
		pid=`ps -e ww | grep ${dhcp} | grep ${ifn} | awk '{print $1}'`
		if [ -n "${pid}" ]; then
			kill -15 ${pid}
			kill  -9 ${pid}
		fi
	done
}

stop_dhcpv6()
{
	local ifn=$1

	synosystemctl stop dhclient6@${ifn}-client.service
	synosystemctl stop dhclient6@${ifn}-info.service
	synosystemctl stop dhclient6@${ifn}-pd.service
}

stop_network()
{
	none_vlan_interfaces=""
	vlan_interfaces=""
    dhcp_interfaces=""

	if [ $# -gt 0 ]; then
		for iface in "$@"; do
			$SYNONET --ip_alias_unapply "$iface"
		done
	else
		$SYNONET --ip_alias_unapply
	fi

	enable_multi_gateway=$(/bin/get_key_value /etc/synoinfo.conf multi_gateway)
	for ifn in ${network_interfaces}; do
		# FIXME: <DSM> #107178
		/usr/bin/logger -p err -t interface-catcher "${ifn} is removed" || true
		stop_ifn "$ifn"
		${SYNONETDTOOL} --del-gateway-info -4 "${ifn}"
		${SYNONETDTOOL} --del-gateway-info -6 "${ifn}"
	done

	for ifn in ${network_interfaces}; do
		ifconfigFile="/etc/sysconfig/network-scripts/ifcfg-${ifn}"
		if [ "$(grep VLAN_ROW_DEVICE $ifconfigFile)" ]; then
			vlan_interface="${vlan_interface} ${ifn}"
			continue
		fi
		none_vlan_interface="${none_vlan_interface} ${ifn}"
	done

	if [ -n "${vlan_interface}"  ]; then
		stop_vlan_interfaces
	fi

	for ifn in ${none_vlan_interface}; do
		if [ -d "/sys/class/net/${ifn}/bridge/" ]; then
			disable_bridge ${ifn}
		fi

		if [ "${ifn#ovs_*}" != "$ifn" ]; then
			remove_ovs ${ifn}
		fi

		#then stop networking
		eval device_type=\$TYPE_${ifn}
		eval bond_opt=\$Bond_${ifn}
		if [ -n "${bond_opt}" -a "${device_type}" != "OVS" ]; then
			unset_bonding_driver ${ifn}
		fi
		$SYNONET --set_ip -4 ${ifn} flush
		ifconfig ${ifn} inet down
	done

	disable_ovs

	check_topology_mode
	[ $? -eq 1 ] && SYNOUnloadModules ${BRIDGE_MODULES}

# Debug only
	ifconfig

	# Configure routing
	#
	case ${defaultrouter} in
		[Nn][Oo] | '')
			;;
		*)
			echo "Del default router ${defaultrouter}"
			/sbin/ip route del default via ${defaultrouter}
			;;
	esac
}

stop_ifn()
{
	/usr/syno/bin/synosystemctl stop dhclient@"${1}".service
	/usr/syno/bin/synosystemctl stop 8021x-client@"${1}".service
	stop_dhcpv6 $1
	kill_dhcp_processes $1
	${SYNONETDTOOL} --del-gateway-info -4 "${1}"
	${SYNONETDTOOL} --del-gateway-info -6 "${1}"
	${SYNONETDTOOL} --reset-ipv6-module "${1}"

	if [ "xyes" = "x${enable_multi_gateway}" ]; then
		${SYNONETDTOOL} --del-policy-route-rule -4 multi-gateway "${1}"
		${SYNONETDTOOL} --del-policy-route-rule -6 multi-gateway "${1}"
	fi
	${SYNONETDTOOL} --disable-route-table -4 "${1}"
	${SYNONETDTOOL} --disable-route-table -6 "${1}"
}

start_dhcp_client()
{
	if [ ! -z "${dhcp_interfaces}" ]; then
		if [ -x /sbin/udhcpc ]; then
			for dhcpif in ${dhcp_interfaces}
			do
				ifconfig ${dhcpif} up
				udhcp_flags="-p /etc/dhcpc/dhcpcd-${dhcpif}.pid -b -h `hostname`"
				${dhcp_program:-/sbin/udhcpc} -i ${dhcpif} ${udhcp_flags}
			done
		else
			dhcp_flags="-n ${dhcp_flags}"
			for dhcpif in ${dhcp_interfaces}
			do
				unset MTU MTU_VALUE
				MTU_VALUE=`get_mtu_value ${dhcpif}`
				MTU="" ; [ -n "${MTU_VALUE}" ] && MTU="mtu ${MTU_VALUE}"

				synosystemctl start dhclient@${dhcpif}.service
			done
		fi
	fi
}

setup_interface_ip_by_ifcfg()
{
	local ifn=$1

	# Do the primary ifconfig if specified
	eval ifconfig_args=\$ifconfig_${ifn}
	eval ifconfig_pxleng=\$ifconfig_pxleng_${ifn}
	eval ifconfig_v6ip=\$ifconfig_v6ip_${ifn}
	eval ifconfig_v6gw=\$ifconfig_v6gw_${ifn}
	eval ifconfig_v6init=\$ifconfig_v6init_${ifn}

	setup_interface_ip
}

turnoff_network_offload()
{
        ethtool -K $1 tso off gso off gro off
}

do_customize_setting()
{
        ds_model=`cat /proc/sys/kernel/syno_hw_version`
        #Bug id: DSM #142823, NM #6488
        #For v1000 model with internal 10G, smb broken pipe may occur when
        #doing p2p file copy stress. According to experiments, turn off TSO,
        #GSO and GRO will fix this bug, but there is some performance impact.
	interfaces=`get_key_value /etc.defaults/synoinfo.conf turnoff_nic_offload_interfaces`
	for interface in $(echo $interfaces | tr "," "\n")
	do
		if [ "$interface" != "" ]
		then
			turnoff_network_offload ${interface}
		fi
	done
}

action=$1
shift;
case "$action" in
stop)
	check_interfaces "$@"
	stop_network "$@"
	;;
start)
	check_external_interface_for_ovs
	check_interfaces "$@"
	start_network "$@"
	do_customize_setting
	;;
restart)
	check_interfaces "$@"
	stop_network "$@"
	start_network "$@"
	;;
*)
	echo "Usage: $0 [start|stop|restart]"
	;;
esac

exit 0