Skip to content

Commit 4e69fae

Browse files
vanytsvetkovaboch
authored andcommitted
openvswitch: add OpenvSwitch and OpenvSwitchSlave link models
Signed-off-by: Ivan Tsvetkov <ivanfromearth@gmail.com>
1 parent c7039a4 commit 4e69fae

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

link.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,21 @@ func (bridge *Bridge) Type() string {
289289
return "bridge"
290290
}
291291

292+
// OpenvSwitch links are Open vSwitch bridge devices.
293+
// Note: their lifecycle is typically managed by OVS (OVSDB/ovs-vsctl),
294+
// while netlink is used to query/link them.
295+
type OpenvSwitch struct {
296+
LinkAttrs
297+
}
298+
299+
func (ovs *OpenvSwitch) Attrs() *LinkAttrs {
300+
return &ovs.LinkAttrs
301+
}
302+
303+
func (ovs *OpenvSwitch) Type() string {
304+
return "openvswitch"
305+
}
306+
292307
// Vlan links have ParentIndex set in their Attrs()
293308
type Vlan struct {
294309
LinkAttrs
@@ -1066,6 +1081,12 @@ func (v *VrfSlave) SlaveType() string {
10661081
return "vrf"
10671082
}
10681083

1084+
type OpenvSwitchSlave struct{}
1085+
1086+
func (o *OpenvSwitchSlave) SlaveType() string {
1087+
return "openvswitch"
1088+
}
1089+
10691090
// Geneve devices must specify RemoteIP and ID (VNI) on create
10701091
// https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/drivers/net/geneve.c#L1209-L1223
10711092
type Geneve struct {

link_linux.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,6 +2188,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
21882188
link = &Ifb{}
21892189
case "bridge":
21902190
link = &Bridge{}
2191+
case "openvswitch":
2192+
link = &OpenvSwitch{}
21912193
case "vlan":
21922194
link = &Vlan{}
21932195
case "netkit":
@@ -2308,6 +2310,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
23082310
linkSlave = &BondSlave{}
23092311
case "vrf":
23102312
linkSlave = &VrfSlave{}
2313+
case "openvswitch":
2314+
linkSlave = &OpenvSwitchSlave{}
23112315
}
23122316

23132317
case nl.IFLA_INFO_SLAVE_DATA:

link_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,6 +2240,49 @@ func TestLinkByIndex(t *testing.T) {
22402240
}
22412241
}
22422242

2243+
func TestOpenvSwitch(t *testing.T) {
2244+
skipUnlessRoot(t)
2245+
skipUnlessKModuleLoaded(t, "openvswitch")
2246+
2247+
// This test validates host OVS state, so it must not create an isolated netns
2248+
// via setUpNetlinkTest(), otherwise host OVS links will be invisible.
2249+
link, err := LinkByName("ovs-system")
2250+
if err != nil {
2251+
if _, ok := err.(LinkNotFoundError); ok {
2252+
t.Skip("ovs-system interface not found")
2253+
}
2254+
t.Fatal("Failed getting link: ", err)
2255+
}
2256+
2257+
ovsSystem, ok := link.(*OpenvSwitch)
2258+
if !ok {
2259+
t.Fatalf("unexpected link type: %T", link)
2260+
}
2261+
2262+
links, err := LinkList()
2263+
if err != nil {
2264+
t.Fatal(err)
2265+
}
2266+
2267+
for _, l := range links {
2268+
if l.Attrs().Name == ovsSystem.Name {
2269+
if _, ok := l.(*OpenvSwitch); !ok {
2270+
t.Fatalf("unexpected link type: %T", l)
2271+
}
2272+
}
2273+
2274+
if l.Attrs().Slave != nil && l.Attrs().Slave.SlaveType() == "openvswitch" {
2275+
if _, ok := l.Attrs().Slave.(*OpenvSwitchSlave); !ok {
2276+
t.Fatalf("unexpected slave type: %T", l.Attrs().Slave)
2277+
}
2278+
2279+
if l.Attrs().MasterIndex != ovsSystem.Index {
2280+
t.Fatalf("Got unexpected master index: %d, expected: %d", l.Attrs().MasterIndex, ovsSystem.Index)
2281+
}
2282+
}
2283+
}
2284+
}
2285+
22432286
func TestLinkSet(t *testing.T) {
22442287
t.Cleanup(setUpNetlinkTest(t))
22452288

0 commit comments

Comments
 (0)