openvswitch: allow complex port configurations
authorStijn Tintel <stijn@linux-ipv6.be>
Tue, 20 Jul 2021 14:07:52 +0000 (17:07 +0300)
committerStijn Tintel <stijn@linux-ipv6.be>
Fri, 23 Jul 2021 09:16:29 +0000 (12:16 +0300)
The current way to add ports to an Open vSwitch bridge does not allow
complex port configurations. Use a dedicated uci config section per port
instead of the current port:type syntax. This way we can easily support
more features like setting the VLAN tag or the OpenFlow port number.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
net/openvswitch/Makefile
net/openvswitch/README.md
net/openvswitch/files/openvswitch.config
net/openvswitch/files/openvswitch.init

index 312cae4638f74c1a941b7426a3ca2009e729f9df..c2c1f8facb3a99612f77ed00d5d278fac42dcb85 100644 (file)
@@ -17,7 +17,7 @@ include ./openvswitch.mk
 #
 PKG_NAME:=openvswitch
 PKG_VERSION:=$(ovs_version)
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://www.openvswitch.org/releases/
 PKG_HASH:=7d5797f2bf2449c6a266149e88f72123540f7fe7f31ad52902057ae8d8f88c38
index 9008a886b82c5e235737be46e80946e7cf3493ce..2bbb026295fa917b8871ff542b24b01ff03576d7 100644 (file)
@@ -63,7 +63,7 @@ E.g. replace in-tree datapath module with upstream version
 
 # UCI configuration options
 
-There are 4 config section types in package openvswitch:
+There are 5 config section types in package openvswitch:
 ovs ovn_northd, ovn_controller & ovs_bridge.
 
 Each of these supports a disabled option, which should be 
@@ -77,3 +77,14 @@ for initialising a virtual bridge with an OpenFlow controller.
 | disabled   | boolean | no       | 0                              | If set to true, disable initialisation of the named bridge |
 | name       | string  | no       | Inherits UCI config block name | The name of the switch in the OVS daemon                   |
 | controller | string  | no       | (none)                         | The endpoint of an OpenFlow controller for this bridge     |
+
+The ovs_port section can be used to add ports to a bridge. It supports the options below.
+
+| Name     | Type    | Required | Default | Description
+| ---------|---------|----------|---------|------------------------------------------------|
+| disabled | boolean | no       | 0       | If set to 1, do not add the port to the bridge |
+| bridge   | string  | yes      | (none)  | Name of the bridge to add the port to          |
+| port     | string  | yes      | (none)  | Name of the port to add to the bridge          |
+| ofport   | integer | no       | (none)  | OpenFlow port number to be used by the port    |
+| tag      | integer | no       | (none)  | 802.1Q VLAN tag to set on the port             |
+| type     | string  | no       | (none)  | Port type, e.g. internal, erspan, type, ...    |
index 88c2ebc254b83c5125046d106584f69ca7ea453c..6139cb47ed689cf8d8baf6a3b1d413c22533068b 100644 (file)
@@ -10,4 +10,12 @@ config ovn_controller controller
 config ovs_bridge
        option disabled 1
        option name 'my-bridge'
-       option controller 'tcp:192.168.0.1'
\ No newline at end of file
+       option controller 'tcp:192.168.0.1'
+
+config ovs_port
+       option disabled 1
+       option bridge 'my-bridge'
+       option port 'ovs-port1'
+       option ofport '1'
+       option tag '123'
+       option type 'internal'
index 9958f9892897014da016b3ab5256ce77bd44957a..6db6ecea7b85fd5788a9ec3893e1fd884a4a5967 100755 (executable)
@@ -121,6 +121,47 @@ ovs_bridge_port_add() {
        __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"}
+       __port_list="$__port_list ${port} "
+}
+
 ovs_bridge_port_cleanup() {
        for port in `ovs-vsctl list-ports "$name"`; do
                case "$__port_list" in
@@ -144,6 +185,7 @@ ovs_bridge_init() {
        ovs-vsctl --may-exist add-br "$name"
 
        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