openvswitch: support setting OpenFlow datapath ID
authorStijn Tintel <stijn@linux-ipv6.be>
Mon, 26 Jul 2021 16:04:19 +0000 (19:04 +0300)
committerStijn Tintel <stijn@linux-ipv6.be>
Thu, 29 Jul 2021 08:02:34 +0000 (11:02 +0300)
By default, Open vSwitch will generate the OpenFlow datapath ID of a
bridge based on the MAC address of one of its ports. Due to this, it's
possible that the datapath ID changes when new ports are added. When the
datapath ID changes, Open vSwitch disconnects from the controller, as
there is no way to notify the controller that the datapath ID has
changed.

Add an option to set the datapath ID so that the above situation can be
avoided. The option takes either exactly 16 hex characters, or when
prefixed with 0x, between 1 and 16 hex characters.

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 10be08240cf69ee4cfc7dc6b272c881240eaf51f..9c23a2467e4bcc406cbcab645b1373c3dcc088c2 100644 (file)
@@ -17,7 +17,7 @@ include ./openvswitch.mk
 #
 PKG_NAME:=openvswitch
 PKG_VERSION:=$(ovs_version)
-PKG_RELEASE:=4
+PKG_RELEASE:=5
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://www.openvswitch.org/releases/
 PKG_HASH:=7d5797f2bf2449c6a266149e88f72123540f7fe7f31ad52902057ae8d8f88c38
index 2bbb026295fa917b8871ff542b24b01ff03576d7..5ed04d77126db1d4ad5d2570dc0542a1be953bb3 100644 (file)
@@ -72,11 +72,12 @@ set to 0 to launch the respective daemons.
 The ovs_bridge section also supports the options below,
 for initialising a virtual bridge with an OpenFlow controller.
 
-| Name       | Type    | Required | Default                        | Description                                                |
-|------------|---------|----------|--------------------------------|------------------------------------------------------------|
-| 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     |
+| Name        | Type    | Required | Default                        | Description                                                |
+|-------------|---------|----------|--------------------------------|------------------------------------------------------------|
+| 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     |
+| datapath_id | string  | no       | (none)                         | The OpenFlow datapath ID for this bridge                   |
 
 The ovs_port section can be used to add ports to a bridge. It supports the options below.
 
index 6139cb47ed689cf8d8baf6a3b1d413c22533068b..56900b88835e7096b31193d28a6f6e219eddc2f4 100644 (file)
@@ -11,6 +11,7 @@ config ovs_bridge
        option disabled 1
        option name 'my-bridge'
        option controller 'tcp:192.168.0.1'
+       option datapath_id ''
 
 config ovs_port
        option disabled 1
index 6db6ecea7b85fd5788a9ec3893e1fd884a4a5967..32adbac494e166247f0846cfc133cd5f7f3af545 100755 (executable)
@@ -171,12 +171,26 @@ ovs_bridge_port_cleanup() {
        done
 }
 
+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_init() {
        local cfg="$1"
 
        local disabled
        local name
        local controller
+       local datapath_id
 
        config_get_bool disabled "$cfg" disabled 0
        [ "$disabled" == "0" ] || return
@@ -184,6 +198,13 @@ ovs_bridge_init() {
        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_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