#!/bin/sh
: ${distdir="/usr/local/cbsd"}
[ ! -r "${distdir}/subr/cbsdbootstrap.subr" ] && exit 1
. ${distdir}/subr/cbsdbootstrap.subr || exit 1
. ${distdir}/subr/nc.subr
. ${distdir}/subr/tools.subr
test_sql_stuff

[ ! -h "${dbdir}/local.sqlite" ] && exit

OVS_BASED=0
OVS_VSCTL_CMD=$( which ovs-vsctl )

SYSTEMCTL_CMD=$( which systemctl )

if [ -z "${SYSTEMCTL_CMD}" ]; then
	echo "no sysctemctl"
	exit 1
fi

if [ -z "${OVS_VSCTL_CMD}" ]; then
	OVS_BASED=0
else
	OVS_BASED=1
fi

ACN_LOGFILE="${BASE_LOGS_DIR}/auto_configure_nic.log"

# auto_configure_nic.sh -a init -f -m static -i %s -h %s -t 3
usage()
{
	echo "Usage: $0 -a ACTION [-f] -h hwaddr -i ip -m mode -t timeout -v vagrant_mgmt_iface"
	echo "If there is a network interface with address 00:00:00:00:*, skip configure: sign of the vagrant"
	echo " -a ACTION, can be: init, required. e.g: -a init"
	echo " -d, DNS for nameserver ( comma-separated as delimeter for multiple ): e.g: -d 8.8.8.8 , -d 8.8.8.8,8.8.4.4"
	echo " -f, FORCE re-initialization (for Vagrant mostly), opt, e.g: -f"
	echo " -h, HWADDR, set mac address for cbsd-default, e.g: -h 00:00:00:00:00:01"
	echo " -g, GW, for static mode"
	echo " -i, IP address for static mode, e.g: -i 192.168.0.2"
	echo " -m, mgmt-cbsd mode: DHCP or STATIC, can be: [static|dhcp], e.g: -m static"
	echo " -t, timeout before reboot when config was changed, in seconds, e.g: -t 3"
	echo " -u, uplink interface, by default unset (= auto), e.g: -u ens14"
	echo " -w, VLANID for cbsd-mgmt"
	echo " -s, IPMASK for static mode, by default: 255.255.255.0"
	echo " -v, vagrant management interface, by default unset. e.g: -v ens14. Will be sets in in dhcp"
	echo
	echo " e.g.:  ./auto_configure_nic.sh -a init -m static [-i 192.168.0.2 -g 192.168.0.1]"
	exit 1
}

get_default_uplink()
{
	local _uplink i
	_uplink=$( ${IP_CMD} route | ${AWK_CMD} '/default/ { print $5 }' | ${HEAD_CMD} -n1 )

	if [ -z "${_uplink}" ]; then
		# try to determine by NIC list
		for i in $( ${LS_CMD} -1 /sys/class/net ); do
			case ${i} in
				lo)
					continue
					;;
				ovs*)
					continue
					;;
				cbsd*)
					continue
					;;
				*)
					# first NIC win!
					_uplink="${i}"
					break
					;;
			esac
		done
	fi

	printf "${_uplink}"
}


flush_cfg()
{
	local _ret=0

	[ ${OVS_BASED} -eq 0 ] && return 0

	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - flush_cfg - started${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
	. /usr/share/openvswitch/scripts/ovs-lib

	# protection from unit changes
	${SYSTEMCTL_CMD} daemon-reload || true
	${SYSTEMCTL_CMD} stop openvswitch-switch.service || true
	ovs_ctl stop || true
	[ -d /etc/openvswitch ] && ${RM_CMD} -rf /etc/openvswitch
	${MKDIR_CMD} /etc/openvswitch
	# ovs-ctl.in set_system_ids() / set_defaults():
	#SYSTEM_TYPE=`lsb_release --id -s`
	#system_release=`lsb_release --release -s`
	#system_codename=`lsb_release --codename -s`
	#SYSTEM_VERSION="${system_release}-${system_codename}"
	ovs_ctl --system-id=random --system-version=11.7-bullseye start
	_ret=$?
	if [ ${_ret} -ne 0 ]; then
		err 1 "${W2_COLOR}${MY_APPLICATION} flush_cfg failed: ${N2_COLOR}ovs_ctl --system-id=random --system-version=11.7-bullseye start"
	fi
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - flush_cfg - finished${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
}

generate_interfaces_config()
{
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - generate_interfaces_config - started${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

	${TRUNCATE_CMD} -s0 /etc/network/interfaces

	local UPLINK_MTU=$1
	${CAT_CMD} >> /etc/network/interfaces << EOF
# Generated by CBSD auto_configure_nic.sh

# The loopback network interface
auto lo
iface lo inet loopback

EOF

	if [ ${OVS_BASED} -eq 1 ]; then
		${CAT_CMD} >> /etc/network/interfaces << EOF
# Created by CBSD auto_configure_nic
# The primary network interface
auto ${UPLINK}
iface ${UPLINK} inet manual
    post-up ip link set dev ${UPLINK} mtu ${UPLINK_MTU}

EOF
	else
		MGMT_INTERFACE="${UPLINK}"
	fi
if [ -n "$VAGRANT_MGMT" ]; then
	${CAT_CMD} >> /etc/network/interfaces <<EOF
auto ${VAGRANT_MGMT}
iface ${VAGRANT_MGMT} inet dhcp
EOF
fi

	# скрипт нужен в любом случае (с шебангом), не зависимо, dhcp это или
	# статика (ниже она заполняет файл с route).
	[ ! -d ${NODE_DIR} ] && ${MKDIR_CMD} -p ${NODE_DIR}
	[ ! -d ${NODE_DIR}/bin ] && ${MKDIR_CMD} -p ${NODE_DIR}/bin
	if [ ! -r ${NODE_DIR}/bin/route.sh ]; then
		${CAT_CMD} > ${NODE_DIR}/bin/route.sh <<EOF
#!/bin/bash
# managed by auto_configure_nic script
EOF
	fi

	${CHMOD_CMD} +x ${NODE_DIR}/bin/route.sh

	case "${MODE}" in
		static)
		if $( echo ${IPADDR} | ${GREP_CMD} -q '/' ); then
			ip_prefix=1
			IPMASK=
		else
			ip_prefix=0
			[ -z "${IPMASK}" ] && IPMASK="255.255.255.0"
		fi

			${CAT_CMD} >> /etc/network/interfaces <<EOF
auto ${MGMT_INTERFACE}
iface ${MGMT_INTERFACE} inet static
    address ${IPADDR}
EOF
			if [ -n "$IPMASK" ]; then
				${CAT_CMD} >> /etc/network/interfaces <<EOF
    netmask ${IPMASK}
EOF
			fi
			if [ -n "$DNS" ]; then
				true
#				${ECHO} "Config DNS ${LOCAL_MODULES_DIR}/systemd.yaml" | ${TEE_CMD} -a ${ACN_LOGFILE}
#				echo > ${LOCAL_MODULES_DIR}/systemd.yaml
#				echo "systemd::dns:" >> ${LOCAL_MODULES_DIR}/systemd.yaml
#				OIFS="$IFS"
#				IFS=","
#				for i in $DNS; do
#					IFS="$OIFS"
#					echo "  - ${i}" >> ${LOCAL_MODULES_DIR}/systemd.yaml
#					IFS=","
#				done
#				IFS="$OIFS"
#				${CHMOD_CMD} 0664 ${LOCAL_MODULES_DIR}/systemd.yaml
			fi

			if [ -n "$GW" ]; then
				${CAT_CMD} >> /etc/network/interfaces <<EOF
    gateway ${GW}
EOF
			fi
			;;
		*)
			# dhcp by default
			configure_dhclient
			${CAT_CMD} >> /etc/network/interfaces <<EOF
auto $MGMT_INTERFACE
iface $MGMT_INTERFACE inet dhcp
EOF
			;;
	esac
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - generate_interfaces_config - finished${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
}

flush_dhclient_lease_pid()
{
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - flush_dhclient_lease_pid - started${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

	local infname=$1
	local dhclient_lease_inf_file="/var/lib/dhcp/dhclient.$infname.leases"
	local dhclient_lease_file="/var/lib/dhcp/dhclient.leases"

	ifdown $infname
	if [ -f "/var/run/dhclient.$infname.pid" ]; then
		kill "$( ${CAT_CMD} "/var/run/dhclient.$infname.pid" )"
		${RM_CMD} "/var/run/dhclient.$infname.pid"
	fi

	if [ -f "/var/run/dhclient.pid" ]; then
		kill "$( ${CAT_CMD} "/var/run/dhclient.pid" )"
		${RM_CMD} "/var/run/dhclient.pid"
	fi

	if [ -f $dhclient_lease_inf_file ]; then
		${RM_CMD} $dhclient_lease_inf_file
	fi

	if [ -f $dhclient_lease_file ]; then
		${RM_CMD} $dhclient_lease_file
	fi

	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - flush_dhclient_lease_pid - finished${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
}

configure_dhclient()
{
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - configure_dhclient - started${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

	local _dhclient='/etc/dhcp/dhclient.conf'
	local _timeout="timeout 20"
	local _req_routers="interface \"$MGMT_INTERFACE\" { also request routers; }"
	local _command="$( ${GREP_CMD} "$_req_routers" $_dhclient )"

	[ ! -r "$_dhclient" ] && return 0
	[ -z "$_command"  ] && ${SED_CMD} -i "1s/^/$_timeout;\n/" $_dhclient && echo $_req_routers >> $_dhclient

	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - configure_dhclient - finished${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
}

add_blackhole_ovs_br()
{
	[ ${OVS_BASED} -eq 0 ] && return 0

	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - add_blackhole_ovs_br - started${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

	. /usr/share/openvswitch/scripts/ovs-lib
	${OVS_VSCTL_CMD} add-br ${BLACKHOLE_OVS}
	ovs-ofctl add-flow ${BLACKHOLE_OVS} 'table=0,action=drop'

	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - add_blackhole_ovs_br - finished${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
}

add_default_ovs_br()
{
	[ ${OVS_BASED} -eq 0 ] && return 0

	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - add_default_ovs_br - started${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

	. /usr/share/openvswitch/scripts/ovs-lib
	${OVS_VSCTL_CMD} add-br ${DEFAULT_OVS}
	# Генерация мака, чтоб lshw при установке на vmware видела этот bridge, иначе он берет мак с физики
	DEFAULT_BR_MAC=$( mac_gen 00:a0:98} )
	${OVS_VSCTL_CMD} set bridge ${DEFAULT_OVS} other-config:hwaddr=\"${DEFAULT_BR_MAC}\"
	${OVS_VSCTL_CMD} add-port ${DEFAULT_OVS} ${UPLINK}
	${OVS_VSCTL_CMD} set port ${UPLINK} vlan_mode=trunk

  # Добавить блокирующий паттерн в lldp, чтобы не работал на всех доступных интерфейсах, пока
  # узел не будет добавлен в кластер
  if [ -d "/etc/lldpd.d" ]; then
    ${ECHO} 'configure system interface pattern "!*"' > /etc/lldpd.d/lldpd_config.conf
  fi

	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - add_default_ovs_br - finished${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} default uplink interface ${UPLINK} connected to ${DEFAULT_OVS}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
}

add_mgmt_interface()
{
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - add_mgmt_interface - started${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

	[ ${OVS_BASED} -eq 1 ] && . /usr/share/openvswitch/scripts/ovs-lib

	local _MAC

	if [ -n "${HWADDR}" ]; then
		_MAC="${HWADDR}"
	else
		_MAC=$( mac_gen 00:a0:98 )
	fi

	if [ ${OVS_BASED} -eq 1 ]; then
		set -o xtrace
		${OVS_VSCTL_CMD} add-port ${DEFAULT_OVS} ${MGMT_INTERFACE} -- set interface ${MGMT_INTERFACE} type=internal mac=\""${_MAC}"\" | ${TEE_CMD} -a ${ACN_LOGFILE}
		${OVS_VSCTL_CMD} set port ${MGMT_INTERFACE} vlan_mode=access | ${TEE_CMD} -a ${ACN_LOGFILE}
		${OVS_VSCTL_CMD} set int ${MGMT_INTERFACE} mtu_request=${UPLINK_MTU} | ${TEE_CMD} -a ${ACN_LOGFILE}

		# MAC ON THE FLY: test
		${OVS_VSCTL_CMD} set interface ${MGMT_INTERFACE} mac=\"${_MAC}\"
		if [ -n "${VLANID}" ]; then
			${OVS_VSCTL_CMD} set port ${MGMT_INTERFACE} tag=${VLANID} | ${TEE_CMD} -a | ${TEE_CMD} -a ${ACN_LOGFILE}
			${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} ${MGMT_INTERFACE} VLANID is set to ${VLANID}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
		fi
		set +o xtrace
	fi

	generate_interfaces_config $UPLINK_MTU

	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} function - add_mgmt_interface - finished${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} management interface MAC-address is set to ${_MAC}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
	${IP_CMD} a

	# re-check
	if [ ${OVS_BASED} -eq 1 ]; then
		if $( ${OVS_VSCTL_CMD} show | ${GREP_CMD} -q "${MGMT_INTERFACE}" ); then
			${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR}${MGMT_INTERFACE} added${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
		else
			err 1 "${W1_COLOR}${MY_APPLICATION} failed: ${N1_COLOR}configuring ${MGMT_INTERFACE}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
		fi
	fi
	return 0
}

## MAIN
# force modify
FORCE=0

# vagrant attribute
IS_VAGRANT=0

#
MODIFIED=0

# timeout before reboot when cfg is changed
REBOOT_TIMEOUT=10

# cbsd-mgmt IP address mode by default: dhcp
MODE="dhcp"

# hwaddr random, if unset
HWADDR=

# ip addr by default: unset
IPADDR=

# uplink by default: unset
UPLINK=

# ipmask by default: unset
IPMASK=

# gw by default: unset
GW=

# DNS by default: unset
DNS=

# vagrant management interface by default: unset
VAGRANT_MGMT=

# VLANID for cbsd-mgmt: unset
VLANID=

# Also detach auto_configure_nic script: useful on remote (e.g. via SSH/Vagrant) connecction
DETACHED_MODE=

# -a ACTION, can be: init, required. e.g: -a init
# -d, DNS for nameserver ( comma-separated as delimer for multiple ): e.g: -d 8.8.8.8 , -d 8.8.8.8,8.8.4.4
# -f, FORCE re-initialization (for Vagrant mostly), opt, e.g: -f
# -h, HWADDR, set MAC address for mgmt-vail, e.g: -h 00:00:00:00:00:01
# -g, GW, set gateway for static mode
# -i, IP address for static mode, e.g: -i 192.168.0.2
# -m, mgmt-cbsd mode: DHCP or STATIC, can be: [static|dhcp], e.g: -m static
# -t, timeout before reboot when config was changes, in seconds, e.g: -t 3
# -u, set UPLINK to specified interface
# -s, set mask for static mode, by default: 255.255.255.0
# -v, vagrant management interface, by default unset. e.g: -v ens14. Will be sets in in dhcp"

MY_ARGS="${*}"
${ECHO} "${N1_COLOR}${MY_APPLICATION} args: ${N2_COLOR}${MY_ARGS}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

while getopts "a:d:fh:g:i:m:t:u:s:v:w:z:" opt; do
	case "$opt" in
		a) ACTION="${OPTARG}" ;;
		d) DNS="${OPTARG}" ;;
		f) FORCE=1 ;;
		g) GW="${OPTARG}" ;;
		h) HWADDR="${OPTARG}" ;;
		i) IPADDR="${OPTARG}" ;;
		m) MODE="${OPTARG}" ;;
		t) REBOOT_TIMEOUT="${OPTARG}" ;;
		u) UPLINK="${OPTARG}" ;;
		s) IPMASK="${OPTARG}" ;;
		v) VAGRANT_MGMT="${OPTARG}" ;;
		w) VLANID="${OPTARG}" ;;
		z) DETACHED_MODE="${OPTARG}" ;;
	esac
done
shift $(($OPTIND - 1))

[ "${ACTION}" != "init" ] && usage
[ -z "${IPMASK}" ] && IPMASK="255.255.255.0"

MY_APPLICATION="auto_configure_nic"

# make backup
if [ -n "$UPLINK" ]; then
	UPLINK="$UPLINK"
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} uplink interface ${UPLINK} from -u arg${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
else
	UPLINK=$( get_default_uplink )
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} uplink interface ${UPLINK} got by default${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
fi

[ -z "${UPLINK}" ] && err 1 "${W1_COLOR}Unable to determine UPLINK interface${N1_COLOR}, please set: ${N2_COLOR}-u IFACE${N0_COLOR}"

${IP_CMD} link show ${UPLINK} > /dev/null 2>&1
ret=$?
[ ${ret} -ne 0 ] && err 1 "${W1_COLOR}No such uplink interface: ${N1_COLOR}errcode: ${ret}: ${N2_COLOR}${IP_CMD} link show ${UPLINK}${N0_COLOR}"

# last octet is dynamic from Vagrantfile
if $( ${IP_CMD} a | ${GREP_CMD} 'link/ether' | ${GREP_CMD} -q 00:00:00:00: ); then
	# Also detach auto_configure_nic script: useful on remote (e.g. via SSH/Vagrant) connecction
	IS_VAGRANT=1
	if [ -z "${DETACHED_MODE}" -a -n "${SSH_CONNECTION}" ]; then
		# recursive exec for detach remote/SSH session
		echo "re-run in detached mode: /var/lib/ecp-cbsd/utils/other/auto_configure_nic.sh ${MY_ARGS} -z 1 >/dev/null 2>&1 &" | ${TEE_CMD} -a ${ACN_LOGFILE}
		/var/lib/ecp-cbsd/utils/other/auto_configure_nic.sh ${MY_ARGS} -z 1 >/dev/null 2>&1 &
		exit 0
	fi
fi

DT=$( ${DATE_CMD} "+%Y-%m-%d-%H-%M-%S" )
[ -r /etc/network/interfaces ] && ${CP_CMD} /etc/network/interfaces /etc/network/interfaces-${DT}

if [ "$MODE" = "static" ]; then
	[ -z "$IPADDR" ] && IPADDR=$( ${HOSTNAME_CMD} -i | ${AWK_CMD} '{print $1}' )
	[ -z "$GW" ] && GW=$( ${IP_CMD} -4 route ls | ${AWK_CMD} '/^default/{print $3}' | ${HEAD_CMD} -n1 )
	[ -z "$DNS" ] && DNS=$( ${GREP_CMD} nameserver /etc/network/interfaces | ${AWK_CMD} '{$1=""; print $0}' | ${AWK_CMD} '{for(i=1;i<NF;i++)if(i!=NF){$i=$i","}}1' | ${SED_CMD} 's/ //g' )
	[ -z "${DNS}" ] && DNS=$( ${GREP_CMD} nameserver /etc/resolv.conf | ${AWK_CMD} '{$1=""; print $0}' | ${AWK_CMD} '{for(i=1;i<NF;i++)if(i!=NF){$i=$i","}}1' | ${SED_CMD} 's/ //g' )
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} static ip address ${IPADDR} with gateway ${GW} and dns ${DNS} ${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
elif [ "$MODE" = "dhcp" ]; then
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} dynamic ip address${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
	flush_dhclient_lease_pid $UPLINK
fi

${ECHO} "${N1_COLOR}OVS_BASED: ${N2_COLOR}${OVS_BASED}${N0_COLOR}"
[ "$MODE" = "static" -a -z "$IPADDR" ] && err 1 "${W1_COLOR}${MY_APPLICATION} error: ${H5_COLOR}when mode static, ip must be set, please use -i IP${N0_COLOR}"

#if [ "$FORCE" -eq 1 ]; then
#	if [ ${OVS_BASED} -eq 1 ]; then
#		${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} flushing old openvswitch config by force flag${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
#	fi
#	flush_cfg
#	MODIFIED=1
#fi

# Manage OVS services
if [ ${OVS_BASED} -eq 1 ]; then
	for i in openvswitch-switch.service ovsdb-server.service ovs-vswitchd.service; do
		${SYSTEMCTL_CMD} stop ${i} || true
		${SYSTEMCTL_CMD} enable ${i} | ${TEE_CMD} -a ${ACN_LOGFILE}
	done

	flush_cfg

	${OVS_VSCTL_CMD} -V | ${TEE_CMD} -a ${ACN_LOGFILE}
	ret=$?
	if [ ${ret} -eq 0 ]; then
		${ECHO} "${N1_COLOR}${MY_APPLICATION}: openvswitch-switch.service service ready"
	else
		err 1 "${W1_COLOR}${MY_APPLICATION} error: ${N2_COLOR}${OVS_VSCTL_CMD} -V${N0_COLOR}"
	fi
fi

UPLINK_MTU="$( ${CAT_CMD} /sys/class/net/${UPLINK}/mtu )"
${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} uplink interface ${UPLINK} has mtu ${UPLINK_MTU}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

BLACKHOLE_OVS="cbsd-blackhole"
DEFAULT_OVS="cbsd-mgmt"
MGMT_INTERFACE="cbsd-mgmt"

echo "BLACKHOLE: $BLACKHOLE_OVS"
echo "DEFAULT_OVS: $DEFAULT_OVS"
echo

if [ ${OVS_BASED} -eq 1 ]; then
	if $( ${OVS_VSCTL_CMD} show | ${GREP_CMD} -q "${BLACKHOLE_OVS}" ); then
		${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR}${BLACKHOLE_OVS} already configured${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
	else
		${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} configuring ${BLACKHOLE_OVS}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
		add_blackhole_ovs_br
		MODIFIED=1
	fi

	if $( ${OVS_VSCTL_CMD} show | ${GREP_CMD} -q "${DEFAULT_OVS}" ); then
		${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR}${DEFAULT_OVS} interface already configured, skip${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
	else
		${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} configuring ${DEFAULT_OVS}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
		add_default_ovs_br
		MODIFIED=1
	fi

	if $( ${OVS_VSCTL_CMD} show | ${GREP_CMD} -q "${MGMT_INTERFACE}" ); then
		${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR}${MGMT_INTERFACE} interface already configured, skip${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
		add_mgmt_interface
		exit 0
	else
		${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} configuring ${MGMT_INTERFACE}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
		add_mgmt_interface
		MODIFIED=1
	fi
else
	add_mgmt_interface
fi

${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} modified status: ${MODIFIED}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

if [ ${OVS_BASED} -eq 1 ]; then
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} Start last check and transform${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
	${SYSTEMCTL_CMD} restart openvswitch-switch.service
	${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} restart openvswitch-switch.service errcode: $?${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
fi

echo "restart networking"

if [ ${OVS_BASED} -eq 1 ]; then
	. /usr/share/openvswitch/scripts/ovs-lib
	for i in openvswitch-switch.service ovsdb-server.service ovs-vswitchd.service; do
		${SYSTEMCTL_CMD} stop ${i} || true
	done
	ovs_ctl stop || true
fi

# restart network
${SYSTEMCTL_CMD} restart networking.service > /dev/null 2>&1

if [ ${OVS_BASED} -eq 1 ]; then
	for i in ovsdb-server.service ovs-vswitchd.service openvswitch-switch.service; do
		${ECHO} "${N1_COLOR}${MY_APPLICATION}: start services: ${N2_COLOR}${i}${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}
		${SYSTEMCTL_CMD} start ${i} | ${TEE_CMD} -a ${ACN_LOGFILE}
	done
fi

${IP_CMD} link set dev ${UPLINK} up
${IP_CMD} link set dev ${MGMT_INTERFACE} up
${IP_CMD} link set ${UPLINK} up
${IP_CMD} link set ${MGMT_INTERFACE} up

${ECHO} "* ${H5_COLOR}${MY_APPLICATION}: ${H1_COLOR} Exit without reboot${N0_COLOR}" | ${TEE_CMD} -a ${ACN_LOGFILE}

exit 0
