blob: 3264c1292f333511ae4b3799c5c5c638c3e5a42d [file] [log] [blame]
khenaidoo89b0e942018-10-21 21:11:33 -04001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package flow_decomposition
17
18import (
19 "errors"
khenaidoo89b0e942018-10-21 21:11:33 -040020 "github.com/opencord/voltha-go/rw_core/graph"
21 fu "github.com/opencord/voltha-go/rw_core/utils"
Scott Bakercb7c88a2019-10-16 18:32:48 -070022 "github.com/opencord/voltha-lib-go/pkg/log"
khenaidoo2c6a0992019-04-29 13:46:56 -040023 ofp "github.com/opencord/voltha-protos/go/openflow_13"
24 "github.com/opencord/voltha-protos/go/voltha"
khenaidoo89b0e942018-10-21 21:11:33 -040025 "github.com/stretchr/testify/assert"
26
27 "testing"
28)
29
khenaidoo89b0e942018-10-21 21:11:33 -040030func init() {
Manikkaraj kb1a10922019-07-29 12:10:34 -040031 // Setup default logger - applies for packages that do not have specific logger set
32 if _, err := log.SetDefaultLogger(log.JSON, 0, log.Fields{"instanceId": 1}); err != nil {
33 log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
34 }
35
36 // Update all loggers (provisioned via init) with a common field
37 if err := log.UpdateAllLoggers(log.Fields{"instanceId": 1}); err != nil {
38 log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
39 }
40
41 // Update all loggers to log level specified as input parameter
42 log.SetAllLogLevel(0)
khenaidoo89b0e942018-10-21 21:11:33 -040043}
44
45type testDeviceManager struct {
46 devices map[string]*voltha.Device
47}
48
49func newTestDeviceManager() *testDeviceManager {
50 var tdm testDeviceManager
51 tdm.devices = make(map[string]*voltha.Device)
52 tdm.devices["olt"] = &voltha.Device{
53 Id: "olt",
54 Root: true,
55 ParentId: "logical_device",
56 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040057 {PortNo: 1, Label: "pon"},
58 {PortNo: 2, Label: "nni"},
khenaidoo89b0e942018-10-21 21:11:33 -040059 },
60 }
61 tdm.devices["onu1"] = &voltha.Device{
62 Id: "onu1",
63 Root: false,
64 ParentId: "olt",
65 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040066 {PortNo: 1, Label: "pon"},
67 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040068 },
69 }
70 tdm.devices["onu2"] = &voltha.Device{
71 Id: "onu2",
72 Root: false,
73 ParentId: "olt",
74 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040075 {PortNo: 1, Label: "pon"},
76 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040077 },
78 }
79 tdm.devices["onu3"] = &voltha.Device{
80 Id: "onu3",
81 Root: false,
82 ParentId: "olt",
83 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040084 {PortNo: 1, Label: "pon"},
85 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040086 },
87 }
88 tdm.devices["onu4"] = &voltha.Device{
89 Id: "onu4",
90 Root: false,
91 ParentId: "olt",
92 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040093 {PortNo: 1, Label: "pon"},
94 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040095 },
96 }
97 return &tdm
98}
99
100func (tdm *testDeviceManager) GetDevice(deviceId string) (*voltha.Device, error) {
101 if d, ok := tdm.devices[deviceId]; ok {
102 return d, nil
103 }
khenaidood20a5852018-10-22 22:09:55 -0400104 return nil, errors.New("ABSENT.")
khenaidoo89b0e942018-10-21 21:11:33 -0400105}
khenaidoo19d7b632018-10-30 10:49:50 -0400106func (tdm *testDeviceManager) IsRootDevice(deviceId string) (bool, error) {
107 if d, ok := tdm.devices[deviceId]; ok {
108 return d.Root, nil
109 }
110 return false, errors.New("ABSENT.")
111}
khenaidoo89b0e942018-10-21 21:11:33 -0400112
khenaidoo0a822f92019-05-08 15:15:57 -0400113func (tdm *testDeviceManager) NotifyInvalidTransition(pcDevice *voltha.Device) error {
114 return nil
115}
116
117func (tdm *testDeviceManager) SetAdminStateToEnable(cDevice *voltha.Device) error {
118 return nil
119}
120
121func (tdm *testDeviceManager) CreateLogicalDevice(cDevice *voltha.Device) error {
122 return nil
123}
124
125func (tdm *testDeviceManager) SetupUNILogicalPorts(cDevice *voltha.Device) error {
126 return nil
127}
128
129func (tdm *testDeviceManager) DisableAllChildDevices(cDevice *voltha.Device) error {
130 return nil
131}
132
133func (tdm *testDeviceManager) DeleteLogicalDevice(cDevice *voltha.Device) error {
134 return nil
135}
136
137func (tdm *testDeviceManager) DeleteLogicalPorts(cDevice *voltha.Device) error {
138 return nil
139}
140
141func (tdm *testDeviceManager) DeleteAllChildDevices(cDevice *voltha.Device) error {
142 return nil
143}
144
145func (tdm *testDeviceManager) RunPostDeviceDelete(cDevice *voltha.Device) error {
146 return nil
147}
148
khenaidoo59ef7be2019-06-21 12:40:28 -0400149func (tdm *testDeviceManager) MarkChildDevicesAsUnReachable(cDevice *voltha.Device) error {
150 return nil
151}
152
khenaidoo89b0e942018-10-21 21:11:33 -0400153type testFlowDecomposer struct {
154 dMgr *testDeviceManager
155 logicalPorts map[uint32]*voltha.LogicalPort
156 routes map[graph.OFPortLink][]graph.RouteHop
157 defaultRules *fu.DeviceRules
158 deviceGraph *graph.DeviceGraph
159 fd *FlowDecomposer
160}
161
162func newTestFlowDecomposer(deviceMgr *testDeviceManager) *testFlowDecomposer {
163 var tfd testFlowDecomposer
164 tfd.dMgr = deviceMgr
165
166 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
167 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
168 // port
169 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
170 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
171 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
172 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
173 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
174
175 tfd.routes = make(map[graph.OFPortLink][]graph.RouteHop)
176
177 //DOWNSTREAM ROUTES
178
179 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 1}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400180 {
khenaidoo89b0e942018-10-21 21:11:33 -0400181 DeviceID: "olt",
182 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
183 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
184 },
khenaidood20a5852018-10-22 22:09:55 -0400185 {
khenaidoo89b0e942018-10-21 21:11:33 -0400186 DeviceID: "onu1",
187 Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
188 Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
189 },
190 }
191
192 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 2}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400193 {
khenaidoo89b0e942018-10-21 21:11:33 -0400194 DeviceID: "olt",
195 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
196 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
197 },
khenaidood20a5852018-10-22 22:09:55 -0400198 {
khenaidoo89b0e942018-10-21 21:11:33 -0400199 DeviceID: "onu2",
200 Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
201 Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
202 },
203 }
204 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 3}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400205 {
khenaidoo89b0e942018-10-21 21:11:33 -0400206 DeviceID: "olt",
207 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
208 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
209 },
khenaidood20a5852018-10-22 22:09:55 -0400210 {
khenaidoo89b0e942018-10-21 21:11:33 -0400211 DeviceID: "onu3",
212 Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
213 Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
214 },
215 }
216 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 4}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400217 {
khenaidoo89b0e942018-10-21 21:11:33 -0400218 DeviceID: "olt",
219 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
220 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
221 },
khenaidood20a5852018-10-22 22:09:55 -0400222 {
khenaidoo89b0e942018-10-21 21:11:33 -0400223 DeviceID: "onu4",
224 Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
225 Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
226 },
227 }
Humera Kouser4ff89012019-08-25 19:01:51 -0400228 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 10}] = []graph.RouteHop{
229 {
230 DeviceID: "olt",
231 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
232 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
233 },
234 {
235 DeviceID: "olt",
236 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
237 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
238 },
239 }
khenaidoo89b0e942018-10-21 21:11:33 -0400240
241 //UPSTREAM DATA PLANE
242
243 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400244 {
khenaidoo89b0e942018-10-21 21:11:33 -0400245 DeviceID: "onu1",
246 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
247 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
248 },
khenaidood20a5852018-10-22 22:09:55 -0400249 {
khenaidoo89b0e942018-10-21 21:11:33 -0400250 DeviceID: "olt",
251 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
252 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
253 },
254 }
255 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400256 {
khenaidoo89b0e942018-10-21 21:11:33 -0400257 DeviceID: "onu2",
258 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
259 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
260 },
khenaidood20a5852018-10-22 22:09:55 -0400261 {
khenaidoo89b0e942018-10-21 21:11:33 -0400262 DeviceID: "olt",
263 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
264 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
265 },
266 }
267 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400268 {
khenaidoo89b0e942018-10-21 21:11:33 -0400269 DeviceID: "onu3",
270 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
271 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
272 },
khenaidood20a5852018-10-22 22:09:55 -0400273 {
khenaidoo89b0e942018-10-21 21:11:33 -0400274 DeviceID: "olt",
275 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
276 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
277 },
278 }
279 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400280 {
khenaidoo89b0e942018-10-21 21:11:33 -0400281 DeviceID: "onu4",
282 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
283 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
284 },
khenaidood20a5852018-10-22 22:09:55 -0400285 {
khenaidoo89b0e942018-10-21 21:11:33 -0400286 DeviceID: "olt",
287 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
288 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
289 },
290 }
291
292 //UPSTREAM NEXT TABLE BASED
293
294 // openflow port 0 means absence of a port - go/protobuf interpretation
295 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400296 {
khenaidoo89b0e942018-10-21 21:11:33 -0400297 DeviceID: "onu1",
298 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
299 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
300 },
khenaidood20a5852018-10-22 22:09:55 -0400301 {
khenaidoo89b0e942018-10-21 21:11:33 -0400302 DeviceID: "olt",
303 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
304 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
305 },
306 }
307 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400308 {
khenaidoo89b0e942018-10-21 21:11:33 -0400309 DeviceID: "onu2",
310 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
311 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
312 },
khenaidood20a5852018-10-22 22:09:55 -0400313 {
khenaidoo89b0e942018-10-21 21:11:33 -0400314 DeviceID: "olt",
315 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
316 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
317 },
318 }
319 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400320 {
khenaidoo89b0e942018-10-21 21:11:33 -0400321 DeviceID: "onu3",
322 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
323 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
324 },
khenaidood20a5852018-10-22 22:09:55 -0400325 {
khenaidoo89b0e942018-10-21 21:11:33 -0400326 DeviceID: "olt",
327 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
328 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
329 },
330 }
331 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400332 {
khenaidoo89b0e942018-10-21 21:11:33 -0400333 DeviceID: "onu4",
334 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
335 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
336 },
khenaidood20a5852018-10-22 22:09:55 -0400337 {
khenaidoo89b0e942018-10-21 21:11:33 -0400338 DeviceID: "olt",
339 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
340 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
341 },
342 }
343
344 // DOWNSTREAM NEXT TABLE BASED
345
346 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400347 {
khenaidoo89b0e942018-10-21 21:11:33 -0400348 DeviceID: "olt",
349 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
350 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
351 },
khenaidood20a5852018-10-22 22:09:55 -0400352 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400353 }
354
355 tfd.routes[graph.OFPortLink{Ingress: 0, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400356 {}, // 1st hop is wildcard
357 {
khenaidoo89b0e942018-10-21 21:11:33 -0400358 DeviceID: "olt",
359 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
360 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
361 },
362 }
363
364 // DEFAULT RULES
365
366 tfd.defaultRules = fu.NewDeviceRules()
367 fg := fu.NewFlowsAndGroups()
368 var fa *fu.FlowArgs
369 fa = &fu.FlowArgs{
370 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400371 fu.InPort(2),
372 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400373 },
374 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400375 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
376 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400377 },
378 }
khenaidoo68c930b2019-05-13 11:46:51 -0400379 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400380 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
381
382 fg = fu.NewFlowsAndGroups()
383 fa = &fu.FlowArgs{
384 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400385 fu.InPort(2),
386 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400387 },
388 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400389 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
390 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400391 },
392 }
khenaidoo68c930b2019-05-13 11:46:51 -0400393 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400394 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
395
396 fg = fu.NewFlowsAndGroups()
397 fa = &fu.FlowArgs{
398 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400399 fu.InPort(2),
400 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400401 },
402 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400403 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 103)),
404 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400405 },
406 }
khenaidoo68c930b2019-05-13 11:46:51 -0400407 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400408 tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
409
410 fg = fu.NewFlowsAndGroups()
411 fa = &fu.FlowArgs{
412 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400413 fu.InPort(2),
414 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400415 },
416 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400417 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
418 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400419 },
420 }
khenaidoo68c930b2019-05-13 11:46:51 -0400421 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400422 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
423
424 //Set up the device graph - flow decomposer uses it only to verify whether a port is a root port.
khenaidoo910204f2019-04-08 17:56:40 -0400425 tfd.deviceGraph = graph.NewDeviceGraph("ldid", tfd.getDeviceHelper)
khenaidoo89b0e942018-10-21 21:11:33 -0400426 tfd.deviceGraph.RootPorts = make(map[uint32]uint32)
427 tfd.deviceGraph.RootPorts[10] = 10
428
429 tfd.fd = NewFlowDecomposer(tfd.dMgr)
430
431 return &tfd
432}
433
434func (tfd *testFlowDecomposer) getDeviceHelper(deviceId string) (*voltha.Device, error) {
435 return tfd.dMgr.GetDevice(deviceId)
436}
437
438func (tfd *testFlowDecomposer) GetDeviceLogicalId() string {
439 return ""
440}
441
khenaidoo19d7b632018-10-30 10:49:50 -0400442func (tfd *testFlowDecomposer) GetLogicalDevice() (*voltha.LogicalDevice, error) {
443 return nil, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400444}
445
446func (tfd *testFlowDecomposer) GetDeviceGraph() *graph.DeviceGraph {
447 return tfd.deviceGraph
448}
449
450func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
451 return tfd.defaultRules
452}
453
454func (tfd *testFlowDecomposer) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
455 lPorts := make([]uint32, 0)
456 var exclPort uint32
457 if len(excludePort) == 1 {
458 exclPort = excludePort[0]
459 }
khenaidood20a5852018-10-22 22:09:55 -0400460 for portno := range tfd.logicalPorts {
khenaidoo89b0e942018-10-21 21:11:33 -0400461 if portno != exclPort {
462 lPorts = append(lPorts, portno)
463 }
464 }
465 return lPorts
466}
467
khenaidoo19d7b632018-10-30 10:49:50 -0400468func (tfd *testFlowDecomposer) GetRoute(ingressPortNo uint32, egressPortNo uint32) []graph.RouteHop {
khenaidoo89b0e942018-10-21 21:11:33 -0400469 var portLink graph.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400470 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400471 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400472 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400473 portLink.Egress = 10
474 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400475 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400476 }
khenaidoo19d7b632018-10-30 10:49:50 -0400477 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400478 portLink.Ingress = 0
479 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400480 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400481 }
482 for key, val := range tfd.routes {
483 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
484 return val
485 }
486 }
487 return nil
488}
489
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400490func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
491
492 var fa *fu.FlowArgs
493 fa = &fu.FlowArgs{
494 KV: fu.OfpFlowModArgs{"priority": 1000},
495 MatchFields: []*ofp.OfpOxmOfbField{
496 fu.InPort(1),
497 fu.VlanVid(50),
498 fu.EthType(0x888e),
499 },
500 Actions: []*ofp.OfpAction{
501 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
502 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
503 },
504 }
505
506 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
507 groups := ofp.FlowGroups{}
508 tfd := newTestFlowDecomposer(newTestDeviceManager())
509
510 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
511 onu1FlowAndGroup := deviceRules.Rules["onu1"]
512 oltFlowAndGroup := deviceRules.Rules["olt"]
513 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
514 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
515 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
516
517 var faParent *fu.FlowArgs
518 faParent = &fu.FlowArgs{
519 KV: fu.OfpFlowModArgs{"priority": 1000},
520 MatchFields: []*ofp.OfpOxmOfbField{
521 fu.InPort(1),
522 fu.TunnelId(uint64(1)),
523 fu.VlanVid(50),
524 fu.EthType(0x888e),
525 },
526 Actions: []*ofp.OfpAction{
527 fu.PushVlan(0x8100),
528 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
529 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
530 },
531 }
532 expectedOltFlow := fu.MkFlowStat(faParent)
533 derivedFlow := oltFlowAndGroup.GetFlow(0)
534 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
535
536 var faChild *fu.FlowArgs
537 faChild = &fu.FlowArgs{
538 KV: fu.OfpFlowModArgs{"priority": 1000},
539 MatchFields: []*ofp.OfpOxmOfbField{
540 fu.InPort(2),
541 fu.TunnelId(uint64(1)),
542 fu.EthType(0x888e),
543 },
544 Actions: []*ofp.OfpAction{
545 fu.PushVlan(0x8100),
546 fu.SetField(fu.VlanVid(50)),
547 fu.Output(1),
548 },
549 }
550 expectedOnuFlow := fu.MkFlowStat(faChild)
551 derivedFlow = onu1FlowAndGroup.GetFlow(0)
552 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
553}
554
555func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
556
557 var fa *fu.FlowArgs
558 fa = &fu.FlowArgs{
559 KV: fu.OfpFlowModArgs{"priority": 1000},
560 MatchFields: []*ofp.OfpOxmOfbField{
561 fu.InPort(1),
562 fu.VlanVid(0),
563 fu.EthType(0x888e),
564 },
565 Actions: []*ofp.OfpAction{
566 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
567 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
568 },
569 }
570
571 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
572 groups := ofp.FlowGroups{}
573 tfd := newTestFlowDecomposer(newTestDeviceManager())
574
575 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
576 onu1FlowAndGroup := deviceRules.Rules["onu1"]
577 oltFlowAndGroup := deviceRules.Rules["olt"]
578 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
579 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
580 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
581
582 var faParent *fu.FlowArgs
583 faParent = &fu.FlowArgs{
584 KV: fu.OfpFlowModArgs{"priority": 1000},
585 MatchFields: []*ofp.OfpOxmOfbField{
586 fu.InPort(1),
587 fu.TunnelId(uint64(1)),
588 fu.VlanVid(0),
589 fu.EthType(0x888e),
590 },
591 Actions: []*ofp.OfpAction{
592 fu.PushVlan(0x8100),
593 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
594 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
595 },
596 }
597 expectedOltFlow := fu.MkFlowStat(faParent)
598 derivedFlow := oltFlowAndGroup.GetFlow(0)
599 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
600
601 var faChild *fu.FlowArgs
602 faChild = &fu.FlowArgs{
603 KV: fu.OfpFlowModArgs{"priority": 1000},
604 MatchFields: []*ofp.OfpOxmOfbField{
605 fu.InPort(2),
606 fu.TunnelId(uint64(1)),
607 fu.EthType(0x888e),
608 },
609 Actions: []*ofp.OfpAction{
610 fu.PushVlan(0x8100),
611 fu.SetField(fu.VlanVid(0)),
612 fu.Output(1),
613 },
614 }
615 expectedOnuFlow := fu.MkFlowStat(faChild)
616 derivedFlow = onu1FlowAndGroup.GetFlow(0)
617 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
618}
619
620func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400621
622 var fa *fu.FlowArgs
623 fa = &fu.FlowArgs{
624 KV: fu.OfpFlowModArgs{"priority": 1000},
625 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400626 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400627 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400628 },
629 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400630 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
631 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400632 },
633 }
634
khenaidoo68c930b2019-05-13 11:46:51 -0400635 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400636 groups := ofp.FlowGroups{}
637 tfd := newTestFlowDecomposer(newTestDeviceManager())
638
khenaidoo3306c992019-05-24 16:57:35 -0400639 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400640 onu1FlowAndGroup := deviceRules.Rules["onu1"]
641 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400642 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400643 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400644 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
645
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400646 var faParent *fu.FlowArgs
647 faParent = &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400648 KV: fu.OfpFlowModArgs{"priority": 1000},
649 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400650 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400651 fu.TunnelId(uint64(1)),
652 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400653 },
654 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400655 fu.PushVlan(0x8100),
656 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
657 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400658 },
659 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400660 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400661 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400662 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400663
664 var faChild *fu.FlowArgs
665 faChild = &fu.FlowArgs{
666 KV: fu.OfpFlowModArgs{"priority": 1000},
667 MatchFields: []*ofp.OfpOxmOfbField{
668 fu.InPort(2),
669 fu.TunnelId(uint64(1)),
670 fu.EthType(0x888e),
671 },
672 Actions: []*ofp.OfpAction{
673 fu.Output(1),
674 },
675 }
676 expectedOnuFlow := fu.MkFlowStat(faChild)
677 derivedFlow = onu1FlowAndGroup.GetFlow(0)
678 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400679}
680
681func TestDhcpReRouteRuleDecomposition(t *testing.T) {
682
683 var fa *fu.FlowArgs
684 fa = &fu.FlowArgs{
685 KV: fu.OfpFlowModArgs{"priority": 1000},
686 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400687 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400688 fu.EthType(0x0800),
689 fu.Ipv4Dst(0xffffffff),
690 fu.IpProto(17),
691 fu.UdpSrc(68),
692 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400693 },
694 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400695 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400696 },
697 }
698
khenaidoo68c930b2019-05-13 11:46:51 -0400699 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400700 groups := ofp.FlowGroups{}
701 tfd := newTestFlowDecomposer(newTestDeviceManager())
702
khenaidoo3306c992019-05-24 16:57:35 -0400703 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400704 onu1FlowAndGroup := deviceRules.Rules["onu1"]
705 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400706 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
707 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400708 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400709 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
710
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400711 var faParent *fu.FlowArgs
712 faParent = &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400713 KV: fu.OfpFlowModArgs{"priority": 1000},
714 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400715 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400716 fu.TunnelId(uint64(1)),
717 fu.EthType(0x0800),
718 fu.Ipv4Dst(0xffffffff),
719 fu.IpProto(17),
720 fu.UdpSrc(68),
721 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400722 },
723 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400724 fu.PushVlan(0x8100),
725 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
726 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400727 },
728 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400729 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400730 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400731 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400732
733 var faChild *fu.FlowArgs
734 faChild = &fu.FlowArgs{
735 KV: fu.OfpFlowModArgs{"priority": 1000},
736 MatchFields: []*ofp.OfpOxmOfbField{
737 fu.InPort(2),
738 fu.TunnelId(uint64(1)),
739 fu.EthType(0x0800),
740 fu.Ipv4Dst(0xffffffff),
741 fu.IpProto(17),
742 fu.UdpSrc(68),
743 fu.UdpDst(67),
744 },
745 Actions: []*ofp.OfpAction{
746 fu.Output(1),
747 },
748 }
749 expectedOnuFlow := fu.MkFlowStat(faChild)
750 derivedFlow = onu1FlowAndGroup.GetFlow(0)
751 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400752}
753
Humera Kouser4ff89012019-08-25 19:01:51 -0400754func TestLldpReRouteRuleDecomposition(t *testing.T) {
755 var fa *fu.FlowArgs
756 fa = &fu.FlowArgs{
757 KV: fu.OfpFlowModArgs{"priority": 1000},
758 MatchFields: []*ofp.OfpOxmOfbField{
759 fu.InPort(10),
760 fu.EthType(0x88CC),
761 },
762 Actions: []*ofp.OfpAction{
763 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
764 },
765 }
766
767 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
768 groups := ofp.FlowGroups{}
769 tfd := newTestFlowDecomposer(newTestDeviceManager())
770 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
771 onu1FlowAndGroup := deviceRules.Rules["onu1"]
772 oltFlowAndGroup := deviceRules.Rules["olt"]
773 assert.Nil(t, onu1FlowAndGroup)
774 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
775 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
776
777 fa = &fu.FlowArgs{
778 KV: fu.OfpFlowModArgs{"priority": 1000},
779 MatchFields: []*ofp.OfpOxmOfbField{
780 fu.InPort(2),
781 fu.EthType(0x88CC),
782 },
783 Actions: []*ofp.OfpAction{
784 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
785 },
786 }
787 expectedOltFlow := fu.MkFlowStat(fa)
788 derivedFlow := oltFlowAndGroup.GetFlow(0)
789 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
790}
791
khenaidood20a5852018-10-22 22:09:55 -0400792func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
khenaidood20a5852018-10-22 22:09:55 -0400793 var fa *fu.FlowArgs
794 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400795 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400796 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400797 fu.InPort(1),
798 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
799 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400800 },
801 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400802 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400803 },
804 }
805
806 var fa2 *fu.FlowArgs
807 fa2 = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400808 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400809 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400810 fu.InPort(1),
811 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
812 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400813 },
814 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400815 fu.PushVlan(0x8100),
816 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
817 fu.SetField(fu.VlanPcp(0)),
818 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400819 },
820 }
821
khenaidoo68c930b2019-05-13 11:46:51 -0400822 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400823 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
824 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
825 Data: &ofp.OfpInstruction_GotoTable{
826 GotoTable: &ofp.OfpInstructionGotoTable{
827 TableId: 1,
828 },
829 }}}
830
khenaidood20a5852018-10-22 22:09:55 -0400831 groups := ofp.FlowGroups{}
832 tfd := newTestFlowDecomposer(newTestDeviceManager())
833
khenaidoo3306c992019-05-24 16:57:35 -0400834 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400835 onu1FlowAndGroup := deviceRules.Rules["onu1"]
836 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400837 assert.NotNil(t, onu1FlowAndGroup)
838 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400839 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400840 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
841 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
842 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
843
844 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400845 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400846 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400847 fu.InPort(2),
848 fu.TunnelId(uint64(1)),
849 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
850 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400851 },
852 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400853 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
854 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400855 },
856 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400857
khenaidoo3306c992019-05-24 16:57:35 -0400858 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400859 // Form the expected flow
860 expectedOnu1Flow := fu.MkFlowStat(fa)
861 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
862 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
863 Data: &ofp.OfpInstruction_Actions{
864 Actions: &ofp.OfpInstructionActions{
865 Actions: []*ofp.OfpAction{{
866 Type: 0,
867 Action: &ofp.OfpAction_Output{
868 Output: &ofp.OfpActionOutput{
869 Port: 1,
870 MaxLen: 65509,
871 },
872 }}}}}}}
873
874 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400875 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
876
877 fa = &fu.FlowArgs{
878 KV: fu.OfpFlowModArgs{"priority": 500},
879 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400880 fu.InPort(1),
881 fu.TunnelId(uint64(1)),
882 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
883 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400884 },
885 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400886 fu.PushVlan(0x8100),
887 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
888 fu.SetField(fu.VlanPcp(0)),
889 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400890 },
891 }
khenaidoo68c930b2019-05-13 11:46:51 -0400892 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -0400893 derivedFlow = oltFlowAndGroup.GetFlow(0)
894 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
895}
896
897func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Manikkaraj kb1a10922019-07-29 12:10:34 -0400898 log.Debugf("Starting Test Unicast Downstream")
khenaidood20a5852018-10-22 22:09:55 -0400899 var fa1 *fu.FlowArgs
900 fa1 = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400901 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400902 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400903 fu.InPort(10),
904 fu.Metadata_ofp((1000 << 32) | 1),
905 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400906 },
907 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400908 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400909 },
910 }
911
912 var fa2 *fu.FlowArgs
913 fa2 = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400914 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400915 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400916 fu.InPort(10),
917 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
918 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400919 },
920 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400921 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
922 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400923 },
924 }
925
khenaidoo68c930b2019-05-13 11:46:51 -0400926 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa1), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400927 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
928 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
929 Data: &ofp.OfpInstruction_GotoTable{
930 GotoTable: &ofp.OfpInstructionGotoTable{
931 TableId: 1,
932 },
933 }}}
934
khenaidood20a5852018-10-22 22:09:55 -0400935 groups := ofp.FlowGroups{}
936 tfd := newTestFlowDecomposer(newTestDeviceManager())
937
khenaidoo3306c992019-05-24 16:57:35 -0400938 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400939
khenaidood20a5852018-10-22 22:09:55 -0400940 onu1FlowAndGroup := deviceRules.Rules["onu1"]
941 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400942 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400943 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
944 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
945 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
946
947 fa1 = &fu.FlowArgs{
948 KV: fu.OfpFlowModArgs{"priority": 500},
949 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400950 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400951 fu.TunnelId(uint64(10)),
952 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400953 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400954 },
955 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400956 fu.PopVlan(),
957 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400958 },
959 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400960
khenaidood20a5852018-10-22 22:09:55 -0400961 derivedFlow := oltFlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400962 expectedOltFlow := fu.MkFlowStat(fa1)
963 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
964 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
965 Data: &ofp.OfpInstruction_Actions{
966 Actions: &ofp.OfpInstructionActions{
967 Actions: []*ofp.OfpAction{{
968 Type: 0,
969 Action: &ofp.OfpAction_Output{
970 Output: &ofp.OfpActionOutput{
971 Port: 1,
972 MaxLen: 65509,
973 },
974 }}}}}}}
975 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400976 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
977
978 fa1 = &fu.FlowArgs{
979 KV: fu.OfpFlowModArgs{"priority": 500},
980 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400981 fu.InPort(1),
982 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
983 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400984 },
985 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400986 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
987 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400988 },
989 }
khenaidoo68c930b2019-05-13 11:46:51 -0400990 expectedOnu1Flow := fu.MkFlowStat(fa1)
khenaidoo3306c992019-05-24 16:57:35 -0400991 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400992 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
993}
994
995func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
996 var fa *fu.FlowArgs
997 fa = &fu.FlowArgs{
998 KV: fu.OfpFlowModArgs{"priority": 500},
999 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001000 fu.InPort(10),
1001 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1002 fu.VlanPcp(0),
1003 fu.EthType(0x800),
1004 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001005 },
1006 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001007 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001008 },
1009 }
1010
1011 var ga *fu.GroupArgs
1012 ga = &fu.GroupArgs{
1013 GroupId: 10,
1014 Buckets: []*ofp.OfpBucket{
1015 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001016 fu.PopVlan(),
1017 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001018 },
1019 },
1020 },
1021 }
1022
khenaidoo68c930b2019-05-13 11:46:51 -04001023 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
1024 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
khenaidood20a5852018-10-22 22:09:55 -04001025 tfd := newTestFlowDecomposer(newTestDeviceManager())
1026
khenaidoo3306c992019-05-24 16:57:35 -04001027 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -04001028 onu1FlowAndGroup := deviceRules.Rules["onu1"]
1029 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -04001030 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -04001031 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
1032 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1033 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1034
1035 fa = &fu.FlowArgs{
1036 KV: fu.OfpFlowModArgs{"priority": 500},
1037 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001038 fu.InPort(2),
1039 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1040 fu.VlanPcp(0),
1041 fu.EthType(0x800),
1042 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001043 },
1044 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001045 fu.PopVlan(),
1046 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001047 },
1048 }
khenaidoo68c930b2019-05-13 11:46:51 -04001049 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -04001050 derivedFlow := oltFlowAndGroup.GetFlow(0)
1051 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
1052
1053 fa = &fu.FlowArgs{
1054 KV: fu.OfpFlowModArgs{"priority": 500},
1055 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001056 fu.InPort(1),
1057 fu.EthType(0x800),
1058 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001059 },
1060 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001061 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -04001062 },
1063 }
khenaidoo68c930b2019-05-13 11:46:51 -04001064 expectedOnu1Flow := fu.MkFlowStat(fa)
khenaidoo3306c992019-05-24 16:57:35 -04001065 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -04001066 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
1067}