diff --git a/ovs/vswitch.go b/ovs/vswitch.go index 181ced2..2c3ba22 100644 --- a/ovs/vswitch.go +++ b/ovs/vswitch.go @@ -17,6 +17,8 @@ package ovs import ( "encoding/json" "fmt" + "net" + "strconv" "strings" ) @@ -202,6 +204,17 @@ func (v *VSwitchSetService) Bridge(bridge string, options BridgeOptions) error { type BridgeOptions struct { // Protocols specifies the OpenFlow protocols the bridge should use. Protocols []string + + // HWAddr specifies the MAC address to be assigned to the bridge. + HWAddr string + + // STP defines if the spanning tree protocol is to be enabled on the bridge. A + // nil value here will not change the STP config of the bridge. + STP *bool + + // Other defines bridge config options not otherwise present in this package + // but available in ovs such as rstp options (e.g. `rstp_enable=false`). + Other []string } // slice creates a string slice containing any non-zero option values from the @@ -213,7 +226,15 @@ func (o BridgeOptions) slice() []string { s = append(s, fmt.Sprintf("protocols=%s", strings.Join(o.Protocols, ","))) } - return s + if hw, err := net.ParseMAC(o.HWAddr); err == nil { + s = append(s, fmt.Sprintf("other-config:hwaddr=%s", hw.String())) + } + + if o.STP != nil { + s = append(s, fmt.Sprintf("stp_enable=%s", strconv.FormatBool(*o.STP))) + } + + return append(s, o.Other...) } // Interface sets configuration for an interface using the values from an diff --git a/ovs/vswitch_test.go b/ovs/vswitch_test.go index 8298537..0c81d4a 100644 --- a/ovs/vswitch_test.go +++ b/ovs/vswitch_test.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "reflect" + "strconv" "strings" "testing" ) @@ -461,7 +462,7 @@ func TestClientVSwitchGetBridgeProtocolsOK(t *testing.T) { } } -func TestClientVSwitchSetBridgeProtocolsOK(t *testing.T) { +func TestClientVSwitchSetBridgeOptionsOK(t *testing.T) { const bridge = "br0" protocols := []string{ ProtocolOpenFlow10, @@ -471,6 +472,9 @@ func TestClientVSwitchSetBridgeProtocolsOK(t *testing.T) { ProtocolOpenFlow14, ProtocolOpenFlow15, } + hwaddr := "55:84:a3:2f:d3:20" + stp := true + other := []string{"rstp_enable=false"} c := testClient([]OptionFunc{Timeout(1)}, func(cmd string, args ...string) ([]byte, error) { if want, got := "ovs-vsctl", cmd; want != got { @@ -484,7 +488,10 @@ func TestClientVSwitchSetBridgeProtocolsOK(t *testing.T) { "bridge", bridge, fmt.Sprintf("protocols=%s", strings.Join(protocols, ",")), + fmt.Sprintf("other-config:hwaddr=%s", hwaddr), + fmt.Sprintf("stp_enable=%s", strconv.FormatBool(stp)), } + wantArgs = append(wantArgs, other...) if want, got := wantArgs, args; !reflect.DeepEqual(want, got) { t.Fatalf("incorrect arguments\n- want: %v\n- got: %v", want, got) @@ -495,6 +502,9 @@ func TestClientVSwitchSetBridgeProtocolsOK(t *testing.T) { err := c.VSwitch.Set.Bridge(bridge, BridgeOptions{ Protocols: protocols, + HWAddr: hwaddr, + STP: &stp, + Other: other, }) if err != nil { t.Fatalf("unexpected error for Client.VSwitch.Set.Bridge: %v", err)