forked from contiv/ofnet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ofnet_port_test.go
279 lines (230 loc) · 7.57 KB
/
ofnet_port_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
package ofnet
import (
"fmt"
"strings"
"testing"
"time"
"github.com/vishvananda/netlink"
)
var gblOfPort = 1
func TestUplinkPortCreateDelete(t *testing.T) {
uplinkSinglePort := createPort("upPort")
uplinkBondedPort := createBondedPort("upBond", []string{"vvport311", "vvport312"})
// Check uplink port creation in vlan bridge mode
err := addUplink(vlanAgents[0], uplinkSinglePort)
if err != nil {
t.Fatalf("Uplink port creation failed for vlanagent: %+v", err)
}
err = delUplink(vlanAgents[0], uplinkSinglePort)
if err != nil {
t.Fatalf("Uplink port deletion failed for vlanagent: %+v", err)
}
// Check uplink bonded port creation in vlan bridge mode
err = addUplink(vlanAgents[0], uplinkBondedPort)
if err != nil {
t.Fatalf("Uplink bonded port creation failed for vlanagent: %+v", err)
}
err = delUplink(vlanAgents[0], uplinkBondedPort)
if err != nil {
t.Fatalf("Uplink bonded port deletion failed for vlanagent: %+v", err)
}
// Check uplink port creation in vlrouter mode
// In vlrouter mode, we currently support only one interface
err = addUplink(vlrtrAgents[0], uplinkSinglePort)
if err != nil {
t.Fatalf("Uplink port creation failed for vlrouter agent: %+v", err)
}
err = delUplink(vlrtrAgents[0], uplinkSinglePort)
if err != nil {
t.Fatalf("Uplink port deletion failed for vlrouter agent: %+v", err)
}
}
func TestPortActiveLinksStateChange(t *testing.T) {
bondName := "upBond1"
linkNames := []string{"vvport321", "vvport322", "vvport323", "vvport324", "vvport325"}
uplinkBondedPort := createBondedPort(bondName, linkNames)
err := addUplink(vlanAgents[0], uplinkBondedPort)
if err != nil {
t.Fatalf("Uplink bonded port creation failed for vlanagent: %+v", err)
}
defer delUplink(vlanAgents[0], uplinkBondedPort)
vlanBr := vlanAgents[0].datapath.(*VlanBridge)
vlanUplink := vlanBr.GetUplink(bondName)
if len(linkNames) != len(vlanUplink.ActiveLinks) {
t.Fatalf("Num active links not equal to num interfaces added.")
}
err = setLinkUpDown(linkNames[0], linkDown)
if err != nil {
t.Errorf("Error setting link down for %s", linkNames[0])
}
// Wait for a few seconds for Link messages to be triggered and processed
time.Sleep(3 * time.Second)
if len(vlanUplink.ActiveLinks) != 4 {
t.Fatalf("Number of active links not updated after link down. %+v", vlanUplink)
}
// Check Active links on link bringup
err = setLinkUpDown(linkNames[0], linkUp)
if err != nil {
t.Errorf("Error setting link up for %s", linkNames[0])
}
// Wait for a few seconds for Link messages to be triggered and processed
time.Sleep(3 * time.Second)
if len(linkNames) != len(vlanUplink.ActiveLinks) {
t.Fatalf("Active links not updated after link bringup of %s", linkNames[0])
}
}
func TestPortLACPStatusChange(t *testing.T) {
bondName := "upBond1"
linkNames := []string{"vvport321", "vvport322", "vvport323", "vvport324", "vvport325"}
uplinkBondedPort := createBondedPort(bondName, linkNames)
err := addUplink(vlanAgents[0], uplinkBondedPort)
if err != nil {
t.Fatalf("Uplink bonded port creation failed for vlanagent: %+v", err)
}
defer delUplink(vlanAgents[0], uplinkBondedPort)
vlanBr := vlanAgents[0].datapath.(*VlanBridge)
vlanUplink := vlanBr.GetUplink(bondName)
if len(linkNames) != len(vlanUplink.ActiveLinks) {
t.Fatalf("Num active links not equal to num interfaces added.")
}
// Check LACP Down event processing
lacpDownUpd := LinkUpdateInfo{LinkName: linkNames[0], LacpStatus: false}
portUpd := PortUpdate{UpdateType: LacpUpdate, UpdateInfo: lacpDownUpd}
portUpds := PortUpdates{PortName: bondName, Updates: []PortUpdate{portUpd}}
err = vlanAgents[0].UpdateUplink(uplinkBondedPort.Name, portUpds)
if err != nil {
t.Fatalf("Error processing update uplink. Err: %+v", err)
}
if len(linkNames)-1 != len(vlanUplink.ActiveLinks) {
t.Fatalf("LACP down port update did not update active links")
}
// Check LACP Up event processing
lacpUpUpd := LinkUpdateInfo{LinkName: linkNames[0], LacpStatus: true}
portUpd = PortUpdate{UpdateType: LacpUpdate, UpdateInfo: lacpUpUpd}
portUpds = PortUpdates{PortName: bondName, Updates: []PortUpdate{portUpd}}
err = vlanAgents[0].UpdateUplink(uplinkBondedPort.Name, portUpds)
if err != nil {
t.Fatalf("Error processing update uplink. Err: %+v", err)
}
if len(linkNames) != len(vlanUplink.ActiveLinks) {
t.Fatalf("LACP up port update did not update active links")
}
// Test multiple events
link1Upd := PortUpdate{UpdateType: LacpUpdate, UpdateInfo: LinkUpdateInfo{LinkName: linkNames[0], LacpStatus: false}}
link2Upd := PortUpdate{UpdateType: LacpUpdate, UpdateInfo: LinkUpdateInfo{LinkName: linkNames[1], LacpStatus: false}}
link3Upd := PortUpdate{UpdateType: LacpUpdate, UpdateInfo: LinkUpdateInfo{LinkName: linkNames[2], LacpStatus: false}}
portUpds = PortUpdates{PortName: bondName, Updates: []PortUpdate{link1Upd, link2Upd, link3Upd}}
err = vlanAgents[0].UpdateUplink(uplinkBondedPort.Name, portUpds)
if err != nil {
t.Fatalf("Error processing update uplink. Err: %+v", err)
}
if len(linkNames)-3 != len(vlanUplink.ActiveLinks) {
t.Fatalf("Mulitple LACP down port update did not update active links")
}
}
func createPort(portName string) *PortInfo {
var port PortInfo
link := LinkInfo{
Name: portName,
OfPort: uint32(gblOfPort),
LinkStatus: linkDown,
Port: &port,
}
port = PortInfo{
Name: portName,
Type: PortType,
LinkStatus: linkDown,
MbrLinks: []*LinkInfo{&link},
}
gblOfPort++
return &port
}
func createBondedPort(bondName string, linkNames []string) *PortInfo {
var links []*LinkInfo
var port PortInfo
for i := 0; i < len(linkNames); i++ {
link := &LinkInfo{
Name: linkNames[i],
OfPort: uint32(gblOfPort),
LinkStatus: linkDown,
Port: &port,
}
links = append(links, link)
gblOfPort++
}
port = PortInfo{
Name: bondName,
Type: BondType,
LinkStatus: linkDown,
MbrLinks: links,
}
return &port
}
// setLinkUpDown sets the individual physical interface status up/down
func setLinkUpDown(linkName string, status linkStatus) error {
var err error
link := findLink(linkName)
if link == nil {
return fmt.Errorf("Could not find link: %s", linkName)
}
if status == linkUp {
err = netlink.LinkSetUp(link)
} else {
err = netlink.LinkSetDown(link)
}
return err
}
// findLink finds the physical interface entity
func findLink(linkName string) netlink.Link {
list, _ := netlink.LinkList()
for _, l := range list {
if strings.EqualFold(l.Attrs().Name, linkName) {
return l
}
}
return nil
}
// addUplink adds a dummy uplink to ofnet agent
func addUplink(ofa *OfnetAgent, uplinkPort *PortInfo) error {
for _, link := range uplinkPort.MbrLinks {
link := &netlink.Veth{
LinkAttrs: netlink.LinkAttrs{
Name: link.Name,
TxQLen: 100,
MTU: 1500,
},
PeerName: link.Name + "peer",
}
netlink.LinkDel(link)
time.Sleep(100 * time.Millisecond)
if err := netlink.LinkAdd(link); err != nil {
return err
}
}
time.Sleep(time.Second)
// add it to ofnet
err := ofa.AddUplink(uplinkPort)
if err != nil {
return err
}
for _, link := range uplinkPort.MbrLinks {
setLinkUpDown(link.Name, linkUp)
}
time.Sleep(5 * time.Second)
return nil
}
// delUplink deletes an uplink from ofnet agent
func delUplink(ofa *OfnetAgent, uplinkPort *PortInfo) error {
err := ofa.RemoveUplink(uplinkPort.Name)
if err != nil {
return fmt.Errorf("Error deleting uplink. Err: %v", err)
}
for _, mbrLink := range uplinkPort.MbrLinks {
link := findLink(mbrLink.Name)
// cleanup the uplink
if err := netlink.LinkDel(link); err != nil {
return fmt.Errorf("Error deleting link: %v", err)
}
}
return nil
}