packages/net/openvswitch/files/openvswitch.init
Stijn Tintel 596051c77e openvswitch: bring up member ports
Open vSwitch does not bring up ports automatically. This is not a
problem for wireless ports, or for ports configured in
/etc/config/network, but other ports will be down, and require manual
interaction to be brought up. Configuring them with proto none will
cause netifd to do some actions on them, which might cause undefined
results, and will also bloat the UCI config file.

The cleanest solution is to bring all member ports up as part of the
init script.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2021-11-19 14:15:42 +08:00

281 lines
5.8 KiB
Bash
Executable file

#!/bin/sh /etc/rc.common
# Copyright (C) 2013 Julius Schulz-Zander <julius@net.t-labs.tu-berlin.de>
# Copyright (C) 2014-2017 OpenWrt.org
# Copyright (C) 2018 Yousong Zhou <yszhou4tech@gmail.com>
# Copyright (C) 2021 Felix Fietkau <nbd@nbd.name>
. /lib/functions/procd.sh
START=15
basescript=$(readlink "$initscript")
ovs_ctl="/usr/share/openvswitch/scripts/ovs-ctl"; [ -x "$ovs_ctl" ] || ovs_ctl=:
ovn_ctl="/usr/share/ovn/scripts/ovn-ctl"; [ -x "$ovn_ctl" ] || ovn_ctl=:
extra_command "status" "Get status information"
service_triggers() {
procd_add_reload_trigger openvswitch
}
init_triggers() {
procd_open_service "$(basename ${basescript:-$initscript})" "$initscript"
procd_close_service set
}
start() {
init_triggers
ovs_action start "$@"
}
reload() {
start
}
running() {
return 0
}
stop() {
procd_kill "$(basename ${basescript:-$initscript})"
ovs_action stop "$@"
}
restart() {
init_triggers
ovs_action restart "$@"
}
status() {
ovs_action status "$@"
}
ovs_action_cfgs=
ovs_action() {
local action="$1"; shift
local cfgtype
ovs_action_cfgs="$*"
config_load openvswitch
for cfgtype in ovs ovn_northd ovn_controller; do
config_foreach "ovs_xx" "$cfgtype" "$action" "$cfgtype"
done
case "$action" in
restart|start)
config_foreach ovs_bridge_init "ovs_bridge"
;;
esac
}
ovs_xx() {
local cfg="$1"
local action="$2"
local cfgtype="$3"
local disabled
if [ -n "$ovs_action_cfgs" ] && ! list_contains "ovs_action_cfgs" "$cfg"; then
return
fi
case "$action" in
status|stop) ;;
*)
config_get_bool disabled "$cfg" disabled 0
[ "$disabled" == "0" ] || return
;;
esac
case "$cfgtype" in
ovs)
"$ovs_ctl" "$action" \
--system-id=random 1000>&-
ovs_set_ssl
;;
ovn_*)
"$ovn_ctl" "${action}_${cfgtype#ovn_}"
;;
esac
}
ovs_bridge_parse_port() {
case "$1" in
*:*)
port="${1%%:*}"
type="${1#*:}"
;;
*)
port="$1"
type=""
;;
esac
}
ovs_bridge_port_add() {
[ -n "$1" ] || return
ovs_bridge_parse_port "$1"
cur_type="$(ovs-vsctl get interface "$port" type 2>/dev/null)"
[ "$?" = 0 ] && {
[ "$type" = "$cur_type" ] || ovs-vsctl del-port "$port"
}
ovs-vsctl --may-exist add-port "$name" "$port" ${type:+ -- set interface "$port" type="$type"}
ovs_bridge_port_up "$port"
__port_list="$__port_list ${port} "
}
ovs_bridge_port_add_complex() {
local cfg="$1"
local cur_bridge="$2"
local bridge disabled ofport port tag type
local cur_tag cur_type del_port
config_get_bool disabled "$cfg" disabled 0
[ "$disabled" = "0" ] || return
config_get bridge "$cfg" bridge
[ "$bridge" = "$cur_bridge" ] || return
ovs-vsctl br-exists "$bridge" || return
config_get port "$cfg" port
[ -n "$port" ] || return
config_get ofport "$cfg" ofport
config_get tag "$cfg" tag
if [ -n "$tag" ]; then
if cur_tag="$(ovs-vsctl get port "$port" tag 2>/dev/null)"; then
[ "$tag" = "$cur_tag" ] || del_port=1
fi
fi
config_get type "$cfg" type
if [ -n "$type" ]; then
if cur_type="$(ovs-vsctl get interface "$port" type 2>/dev/null)"; then
[ "$type" = "$cur_type" ] || del_port=1
fi
fi
[ "${del_port:-0}" -eq 1 ] && ovs-vsctl --if-exists del-port "$bridge" "$port"
ovs-vsctl --may-exist add-port "$bridge" "$port" ${tag:+tag="$tag"} \
${ofport:+ -- set interface "$port" ofport_request="$ofport"} \
${type:+ -- set interface "$port" type="$type"}
ovs_bridge_port_up "$port"
__port_list="$__port_list ${port} "
}
ovs_bridge_port_cleanup() {
for port in `ovs-vsctl list-ports "$name"`; do
case "$__port_list" in
*" $port "*);;
*) ovs-vsctl del-port "$port";;
esac
done
}
ovs_bridge_port_up() {
local port="$1"
ip link set dev "$port" up
}
ovs_bridge_validate_datapath_id() {
local dpid="$1"
if expr "$dpid" : '[[:xdigit:]]\{16\}$' > /dev/null; then
return 0
elif expr "$dpid" : '0x[[:xdigit:]]\{1,16\}$' > /dev/null; then
return 0
else
logger -t openvswitch "invalid datapath_id: $dpid"
return 1
fi
}
ovs_bridge_validate_datapath_desc() {
local dpdesc="$1"
if [ "$(echo $dpdesc | wc -c)" -le 255 ]; then
return 0
else
logger -t openvswitch "invalid datapath_desc: $dpdesc"
return 1
fi
}
ovs_bridge_validate_fail_mode() {
local fail_mode="$1"
case "$fail_mode" in
secure|standalone)
return 0
;;
*)
logger -t openvswitch "invalid fail_mode: $fail_mode"
return 1
;;
esac
}
ovs_bridge_init() {
local cfg="$1"
local disabled
local name
local controller
local datapath_id
config_get_bool disabled "$cfg" disabled 0
[ "$disabled" == "0" ] || return
config_get name "$cfg" name $cfg
ovs-vsctl --may-exist add-br "$name"
config_get datapath_id "$cfg" datapath_id
[ -n "$datapath_id" ] && {
ovs_bridge_validate_datapath_id "$datapath_id" && {
ovs-vsctl --if-exists set bridge "$name" other-config:datapath-id="$datapath_id"
}
}
config_get datapath_desc "$cfg" datapath_desc
[ -n "$datapath_desc" ] && {
ovs_bridge_validate_datapath_desc "$datapath_desc" && {
ovs-vsctl --if-exists set bridge "$name" other-config:dp-desc="$datapath_desc"
}
}
config_get fail_mode "$cfg" fail_mode
[ -n "$fail_mode" ] && {
ovs_bridge_validate_fail_mode "$fail_mode" && {
ovs-vsctl set-fail-mode "$name" "$fail_mode" 2> /dev/null
} || {
ovs-vsctl del-fail-mode "$name" 2> /dev/null
}
} || {
ovs-vsctl del-fail-mode "$name" 2> /dev/null
}
config_list_foreach "$cfg" "ports" ovs_bridge_port_add
config_foreach ovs_bridge_port_add_complex ovs_port "$name"
config_get_bool drop "$cfg" "drop_unknown_ports" 0
[ "$drop" == 1 ] && ovs_bridge_port_cleanup
config_get controller "$cfg" controller
[ -n "$controller" ] && \
ovs-vsctl set-controller "$name" "$controller"
}
ovs_set_ssl() {
local ca="$(uci -q get openvswitch.ovs.ca)"
[ -f "$ca" ] || return
local cert="$(uci get openvswitch.ovs.cert)"
[ -f "$cert" ] || return
local key="$(uci get openvswitch.ovs.key)"
[ -f "$key" ] || return
ovs-vsctl set-ssl "$key" "$cert" "$ca"
}