blob: f21f5899995de0f7b1c7906f3d54273e8a5dbf7f [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"
Scott Baker807addd2019-10-24 15:16:21 -070021 fu "github.com/opencord/voltha-lib-go/v2/pkg/flows"
22 "github.com/opencord/voltha-lib-go/v2/pkg/log"
Scott Baker555307d2019-11-04 08:58:01 -080023 ofp "github.com/opencord/voltha-protos/v2/go/openflow_13"
24 "github.com/opencord/voltha-protos/v2/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
khenaidoo89b0e942018-10-21 21:11:33 -0400149type testFlowDecomposer struct {
150 dMgr *testDeviceManager
151 logicalPorts map[uint32]*voltha.LogicalPort
152 routes map[graph.OFPortLink][]graph.RouteHop
153 defaultRules *fu.DeviceRules
154 deviceGraph *graph.DeviceGraph
155 fd *FlowDecomposer
156}
157
158func newTestFlowDecomposer(deviceMgr *testDeviceManager) *testFlowDecomposer {
159 var tfd testFlowDecomposer
160 tfd.dMgr = deviceMgr
161
162 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
163 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
164 // port
165 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
166 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
167 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
168 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
169 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
170
171 tfd.routes = make(map[graph.OFPortLink][]graph.RouteHop)
172
173 //DOWNSTREAM ROUTES
174
175 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 1}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400176 {
khenaidoo89b0e942018-10-21 21:11:33 -0400177 DeviceID: "olt",
178 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
179 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
180 },
khenaidood20a5852018-10-22 22:09:55 -0400181 {
khenaidoo89b0e942018-10-21 21:11:33 -0400182 DeviceID: "onu1",
183 Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
184 Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
185 },
186 }
187
188 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 2}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400189 {
khenaidoo89b0e942018-10-21 21:11:33 -0400190 DeviceID: "olt",
191 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
192 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
193 },
khenaidood20a5852018-10-22 22:09:55 -0400194 {
khenaidoo89b0e942018-10-21 21:11:33 -0400195 DeviceID: "onu2",
196 Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
197 Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
198 },
199 }
200 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 3}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400201 {
khenaidoo89b0e942018-10-21 21:11:33 -0400202 DeviceID: "olt",
203 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
204 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
205 },
khenaidood20a5852018-10-22 22:09:55 -0400206 {
khenaidoo89b0e942018-10-21 21:11:33 -0400207 DeviceID: "onu3",
208 Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
209 Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
210 },
211 }
212 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 4}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400213 {
khenaidoo89b0e942018-10-21 21:11:33 -0400214 DeviceID: "olt",
215 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
216 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
217 },
khenaidood20a5852018-10-22 22:09:55 -0400218 {
khenaidoo89b0e942018-10-21 21:11:33 -0400219 DeviceID: "onu4",
220 Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
221 Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
222 },
223 }
Humera Kouser4ff89012019-08-25 19:01:51 -0400224 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 10}] = []graph.RouteHop{
225 {
226 DeviceID: "olt",
227 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
228 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
229 },
230 {
231 DeviceID: "olt",
232 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
233 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
234 },
235 }
khenaidoo89b0e942018-10-21 21:11:33 -0400236
237 //UPSTREAM DATA PLANE
238
239 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400240 {
khenaidoo89b0e942018-10-21 21:11:33 -0400241 DeviceID: "onu1",
242 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
243 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
244 },
khenaidood20a5852018-10-22 22:09:55 -0400245 {
khenaidoo89b0e942018-10-21 21:11:33 -0400246 DeviceID: "olt",
247 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
248 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
249 },
250 }
251 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400252 {
khenaidoo89b0e942018-10-21 21:11:33 -0400253 DeviceID: "onu2",
254 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
255 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
256 },
khenaidood20a5852018-10-22 22:09:55 -0400257 {
khenaidoo89b0e942018-10-21 21:11:33 -0400258 DeviceID: "olt",
259 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
260 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
261 },
262 }
263 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400264 {
khenaidoo89b0e942018-10-21 21:11:33 -0400265 DeviceID: "onu3",
266 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
267 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
268 },
khenaidood20a5852018-10-22 22:09:55 -0400269 {
khenaidoo89b0e942018-10-21 21:11:33 -0400270 DeviceID: "olt",
271 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
272 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
273 },
274 }
275 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400276 {
khenaidoo89b0e942018-10-21 21:11:33 -0400277 DeviceID: "onu4",
278 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
279 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
280 },
khenaidood20a5852018-10-22 22:09:55 -0400281 {
khenaidoo89b0e942018-10-21 21:11:33 -0400282 DeviceID: "olt",
283 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
284 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
285 },
286 }
287
288 //UPSTREAM NEXT TABLE BASED
289
290 // openflow port 0 means absence of a port - go/protobuf interpretation
291 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400292 {
khenaidoo89b0e942018-10-21 21:11:33 -0400293 DeviceID: "onu1",
294 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
295 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
296 },
khenaidood20a5852018-10-22 22:09:55 -0400297 {
khenaidoo89b0e942018-10-21 21:11:33 -0400298 DeviceID: "olt",
299 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
300 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
301 },
302 }
303 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400304 {
khenaidoo89b0e942018-10-21 21:11:33 -0400305 DeviceID: "onu2",
306 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
307 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
308 },
khenaidood20a5852018-10-22 22:09:55 -0400309 {
khenaidoo89b0e942018-10-21 21:11:33 -0400310 DeviceID: "olt",
311 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
312 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
313 },
314 }
315 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400316 {
khenaidoo89b0e942018-10-21 21:11:33 -0400317 DeviceID: "onu3",
318 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
319 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
320 },
khenaidood20a5852018-10-22 22:09:55 -0400321 {
khenaidoo89b0e942018-10-21 21:11:33 -0400322 DeviceID: "olt",
323 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
324 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
325 },
326 }
327 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400328 {
khenaidoo89b0e942018-10-21 21:11:33 -0400329 DeviceID: "onu4",
330 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
331 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
332 },
khenaidood20a5852018-10-22 22:09:55 -0400333 {
khenaidoo89b0e942018-10-21 21:11:33 -0400334 DeviceID: "olt",
335 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
336 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
337 },
338 }
339
340 // DOWNSTREAM NEXT TABLE BASED
341
342 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400343 {
khenaidoo89b0e942018-10-21 21:11:33 -0400344 DeviceID: "olt",
345 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
346 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
347 },
khenaidood20a5852018-10-22 22:09:55 -0400348 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400349 }
350
351 tfd.routes[graph.OFPortLink{Ingress: 0, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400352 {}, // 1st hop is wildcard
353 {
khenaidoo89b0e942018-10-21 21:11:33 -0400354 DeviceID: "olt",
355 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
356 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
357 },
358 }
359
360 // DEFAULT RULES
361
362 tfd.defaultRules = fu.NewDeviceRules()
363 fg := fu.NewFlowsAndGroups()
364 var fa *fu.FlowArgs
365 fa = &fu.FlowArgs{
366 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400367 fu.InPort(2),
368 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400369 },
370 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400371 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
372 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400373 },
374 }
khenaidoo68c930b2019-05-13 11:46:51 -0400375 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400376 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
377
378 fg = fu.NewFlowsAndGroups()
379 fa = &fu.FlowArgs{
380 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400381 fu.InPort(2),
382 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400383 },
384 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400385 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
386 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400387 },
388 }
khenaidoo68c930b2019-05-13 11:46:51 -0400389 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400390 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
391
392 fg = fu.NewFlowsAndGroups()
393 fa = &fu.FlowArgs{
394 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400395 fu.InPort(2),
396 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400397 },
398 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400399 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 103)),
400 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400401 },
402 }
khenaidoo68c930b2019-05-13 11:46:51 -0400403 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400404 tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
405
406 fg = fu.NewFlowsAndGroups()
407 fa = &fu.FlowArgs{
408 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400409 fu.InPort(2),
410 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400411 },
412 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400413 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
414 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400415 },
416 }
khenaidoo68c930b2019-05-13 11:46:51 -0400417 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400418 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
419
420 //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 -0400421 tfd.deviceGraph = graph.NewDeviceGraph("ldid", tfd.getDeviceHelper)
khenaidoo89b0e942018-10-21 21:11:33 -0400422 tfd.deviceGraph.RootPorts = make(map[uint32]uint32)
423 tfd.deviceGraph.RootPorts[10] = 10
424
425 tfd.fd = NewFlowDecomposer(tfd.dMgr)
426
427 return &tfd
428}
429
430func (tfd *testFlowDecomposer) getDeviceHelper(deviceId string) (*voltha.Device, error) {
431 return tfd.dMgr.GetDevice(deviceId)
432}
433
434func (tfd *testFlowDecomposer) GetDeviceLogicalId() string {
435 return ""
436}
437
khenaidoo19d7b632018-10-30 10:49:50 -0400438func (tfd *testFlowDecomposer) GetLogicalDevice() (*voltha.LogicalDevice, error) {
439 return nil, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400440}
441
442func (tfd *testFlowDecomposer) GetDeviceGraph() *graph.DeviceGraph {
443 return tfd.deviceGraph
444}
445
446func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
447 return tfd.defaultRules
448}
449
450func (tfd *testFlowDecomposer) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
451 lPorts := make([]uint32, 0)
452 var exclPort uint32
453 if len(excludePort) == 1 {
454 exclPort = excludePort[0]
455 }
khenaidood20a5852018-10-22 22:09:55 -0400456 for portno := range tfd.logicalPorts {
khenaidoo89b0e942018-10-21 21:11:33 -0400457 if portno != exclPort {
458 lPorts = append(lPorts, portno)
459 }
460 }
461 return lPorts
462}
463
khenaidoo19d7b632018-10-30 10:49:50 -0400464func (tfd *testFlowDecomposer) GetRoute(ingressPortNo uint32, egressPortNo uint32) []graph.RouteHop {
khenaidoo89b0e942018-10-21 21:11:33 -0400465 var portLink graph.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400466 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400467 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400468 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400469 portLink.Egress = 10
470 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400471 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400472 }
khenaidoo19d7b632018-10-30 10:49:50 -0400473 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400474 portLink.Ingress = 0
475 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400476 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400477 }
478 for key, val := range tfd.routes {
479 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
480 return val
481 }
482 }
483 return nil
484}
485
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400486func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
487
488 var fa *fu.FlowArgs
489 fa = &fu.FlowArgs{
490 KV: fu.OfpFlowModArgs{"priority": 1000},
491 MatchFields: []*ofp.OfpOxmOfbField{
492 fu.InPort(1),
493 fu.VlanVid(50),
494 fu.EthType(0x888e),
495 },
496 Actions: []*ofp.OfpAction{
497 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
498 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
499 },
500 }
501
502 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
503 groups := ofp.FlowGroups{}
504 tfd := newTestFlowDecomposer(newTestDeviceManager())
505
506 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
507 onu1FlowAndGroup := deviceRules.Rules["onu1"]
508 oltFlowAndGroup := deviceRules.Rules["olt"]
509 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
510 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
511 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
512
513 var faParent *fu.FlowArgs
514 faParent = &fu.FlowArgs{
515 KV: fu.OfpFlowModArgs{"priority": 1000},
516 MatchFields: []*ofp.OfpOxmOfbField{
517 fu.InPort(1),
518 fu.TunnelId(uint64(1)),
519 fu.VlanVid(50),
520 fu.EthType(0x888e),
521 },
522 Actions: []*ofp.OfpAction{
523 fu.PushVlan(0x8100),
524 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
525 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
526 },
527 }
528 expectedOltFlow := fu.MkFlowStat(faParent)
529 derivedFlow := oltFlowAndGroup.GetFlow(0)
530 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
531
532 var faChild *fu.FlowArgs
533 faChild = &fu.FlowArgs{
534 KV: fu.OfpFlowModArgs{"priority": 1000},
535 MatchFields: []*ofp.OfpOxmOfbField{
536 fu.InPort(2),
537 fu.TunnelId(uint64(1)),
538 fu.EthType(0x888e),
539 },
540 Actions: []*ofp.OfpAction{
541 fu.PushVlan(0x8100),
542 fu.SetField(fu.VlanVid(50)),
543 fu.Output(1),
544 },
545 }
546 expectedOnuFlow := fu.MkFlowStat(faChild)
547 derivedFlow = onu1FlowAndGroup.GetFlow(0)
548 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
549}
550
551func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
552
553 var fa *fu.FlowArgs
554 fa = &fu.FlowArgs{
555 KV: fu.OfpFlowModArgs{"priority": 1000},
556 MatchFields: []*ofp.OfpOxmOfbField{
557 fu.InPort(1),
558 fu.VlanVid(0),
559 fu.EthType(0x888e),
560 },
561 Actions: []*ofp.OfpAction{
562 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
563 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
564 },
565 }
566
567 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
568 groups := ofp.FlowGroups{}
569 tfd := newTestFlowDecomposer(newTestDeviceManager())
570
571 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
572 onu1FlowAndGroup := deviceRules.Rules["onu1"]
573 oltFlowAndGroup := deviceRules.Rules["olt"]
574 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
575 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
576 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
577
578 var faParent *fu.FlowArgs
579 faParent = &fu.FlowArgs{
580 KV: fu.OfpFlowModArgs{"priority": 1000},
581 MatchFields: []*ofp.OfpOxmOfbField{
582 fu.InPort(1),
583 fu.TunnelId(uint64(1)),
584 fu.VlanVid(0),
585 fu.EthType(0x888e),
586 },
587 Actions: []*ofp.OfpAction{
588 fu.PushVlan(0x8100),
589 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
590 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
591 },
592 }
593 expectedOltFlow := fu.MkFlowStat(faParent)
594 derivedFlow := oltFlowAndGroup.GetFlow(0)
595 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
596
597 var faChild *fu.FlowArgs
598 faChild = &fu.FlowArgs{
599 KV: fu.OfpFlowModArgs{"priority": 1000},
600 MatchFields: []*ofp.OfpOxmOfbField{
601 fu.InPort(2),
602 fu.TunnelId(uint64(1)),
603 fu.EthType(0x888e),
604 },
605 Actions: []*ofp.OfpAction{
606 fu.PushVlan(0x8100),
607 fu.SetField(fu.VlanVid(0)),
608 fu.Output(1),
609 },
610 }
611 expectedOnuFlow := fu.MkFlowStat(faChild)
612 derivedFlow = onu1FlowAndGroup.GetFlow(0)
613 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
614}
615
616func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400617
618 var fa *fu.FlowArgs
619 fa = &fu.FlowArgs{
620 KV: fu.OfpFlowModArgs{"priority": 1000},
621 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400622 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400623 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400624 },
625 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400626 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
627 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400628 },
629 }
630
khenaidoo68c930b2019-05-13 11:46:51 -0400631 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400632 groups := ofp.FlowGroups{}
633 tfd := newTestFlowDecomposer(newTestDeviceManager())
634
khenaidoo3306c992019-05-24 16:57:35 -0400635 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400636 onu1FlowAndGroup := deviceRules.Rules["onu1"]
637 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400638 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400639 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400640 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
641
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400642 var faParent *fu.FlowArgs
643 faParent = &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400644 KV: fu.OfpFlowModArgs{"priority": 1000},
645 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400646 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400647 fu.TunnelId(uint64(1)),
648 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400649 },
650 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400651 fu.PushVlan(0x8100),
652 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
653 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400654 },
655 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400656 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400657 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400658 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400659
660 var faChild *fu.FlowArgs
661 faChild = &fu.FlowArgs{
662 KV: fu.OfpFlowModArgs{"priority": 1000},
663 MatchFields: []*ofp.OfpOxmOfbField{
664 fu.InPort(2),
665 fu.TunnelId(uint64(1)),
666 fu.EthType(0x888e),
667 },
668 Actions: []*ofp.OfpAction{
669 fu.Output(1),
670 },
671 }
672 expectedOnuFlow := fu.MkFlowStat(faChild)
673 derivedFlow = onu1FlowAndGroup.GetFlow(0)
674 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400675}
676
677func TestDhcpReRouteRuleDecomposition(t *testing.T) {
678
679 var fa *fu.FlowArgs
680 fa = &fu.FlowArgs{
681 KV: fu.OfpFlowModArgs{"priority": 1000},
682 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400683 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400684 fu.EthType(0x0800),
685 fu.Ipv4Dst(0xffffffff),
686 fu.IpProto(17),
687 fu.UdpSrc(68),
688 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400689 },
690 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400691 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400692 },
693 }
694
khenaidoo68c930b2019-05-13 11:46:51 -0400695 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400696 groups := ofp.FlowGroups{}
697 tfd := newTestFlowDecomposer(newTestDeviceManager())
698
khenaidoo3306c992019-05-24 16:57:35 -0400699 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400700 onu1FlowAndGroup := deviceRules.Rules["onu1"]
701 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400702 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
703 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400704 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400705 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
706
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400707 var faParent *fu.FlowArgs
708 faParent = &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400709 KV: fu.OfpFlowModArgs{"priority": 1000},
710 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400711 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400712 fu.TunnelId(uint64(1)),
713 fu.EthType(0x0800),
714 fu.Ipv4Dst(0xffffffff),
715 fu.IpProto(17),
716 fu.UdpSrc(68),
717 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400718 },
719 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400720 fu.PushVlan(0x8100),
721 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
722 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400723 },
724 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400725 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400726 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400727 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400728
729 var faChild *fu.FlowArgs
730 faChild = &fu.FlowArgs{
731 KV: fu.OfpFlowModArgs{"priority": 1000},
732 MatchFields: []*ofp.OfpOxmOfbField{
733 fu.InPort(2),
734 fu.TunnelId(uint64(1)),
735 fu.EthType(0x0800),
736 fu.Ipv4Dst(0xffffffff),
737 fu.IpProto(17),
738 fu.UdpSrc(68),
739 fu.UdpDst(67),
740 },
741 Actions: []*ofp.OfpAction{
742 fu.Output(1),
743 },
744 }
745 expectedOnuFlow := fu.MkFlowStat(faChild)
746 derivedFlow = onu1FlowAndGroup.GetFlow(0)
747 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400748}
749
Humera Kouser4ff89012019-08-25 19:01:51 -0400750func TestLldpReRouteRuleDecomposition(t *testing.T) {
751 var fa *fu.FlowArgs
752 fa = &fu.FlowArgs{
753 KV: fu.OfpFlowModArgs{"priority": 1000},
754 MatchFields: []*ofp.OfpOxmOfbField{
755 fu.InPort(10),
756 fu.EthType(0x88CC),
757 },
758 Actions: []*ofp.OfpAction{
759 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
760 },
761 }
762
763 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
764 groups := ofp.FlowGroups{}
765 tfd := newTestFlowDecomposer(newTestDeviceManager())
766 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
767 onu1FlowAndGroup := deviceRules.Rules["onu1"]
768 oltFlowAndGroup := deviceRules.Rules["olt"]
769 assert.Nil(t, onu1FlowAndGroup)
770 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
771 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
772
773 fa = &fu.FlowArgs{
774 KV: fu.OfpFlowModArgs{"priority": 1000},
775 MatchFields: []*ofp.OfpOxmOfbField{
776 fu.InPort(2),
777 fu.EthType(0x88CC),
778 },
779 Actions: []*ofp.OfpAction{
780 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
781 },
782 }
783 expectedOltFlow := fu.MkFlowStat(fa)
784 derivedFlow := oltFlowAndGroup.GetFlow(0)
785 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
786}
787
khenaidood20a5852018-10-22 22:09:55 -0400788func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
khenaidood20a5852018-10-22 22:09:55 -0400789 var fa *fu.FlowArgs
790 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400791 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400792 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400793 fu.InPort(1),
794 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
795 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400796 },
797 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400798 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400799 },
800 }
801
802 var fa2 *fu.FlowArgs
803 fa2 = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400804 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400805 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400806 fu.InPort(1),
807 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
808 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400809 },
810 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400811 fu.PushVlan(0x8100),
812 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
813 fu.SetField(fu.VlanPcp(0)),
814 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400815 },
816 }
817
khenaidoo68c930b2019-05-13 11:46:51 -0400818 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400819 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
820 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
821 Data: &ofp.OfpInstruction_GotoTable{
822 GotoTable: &ofp.OfpInstructionGotoTable{
823 TableId: 1,
824 },
825 }}}
826
khenaidood20a5852018-10-22 22:09:55 -0400827 groups := ofp.FlowGroups{}
828 tfd := newTestFlowDecomposer(newTestDeviceManager())
829
khenaidoo3306c992019-05-24 16:57:35 -0400830 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400831 onu1FlowAndGroup := deviceRules.Rules["onu1"]
832 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400833 assert.NotNil(t, onu1FlowAndGroup)
834 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400835 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400836 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
837 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
838 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
839
840 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400841 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400842 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400843 fu.InPort(2),
844 fu.TunnelId(uint64(1)),
845 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
846 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400847 },
848 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400849 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
850 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400851 },
852 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400853
khenaidoo3306c992019-05-24 16:57:35 -0400854 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400855 // Form the expected flow
856 expectedOnu1Flow := fu.MkFlowStat(fa)
857 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
858 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
859 Data: &ofp.OfpInstruction_Actions{
860 Actions: &ofp.OfpInstructionActions{
861 Actions: []*ofp.OfpAction{{
862 Type: 0,
863 Action: &ofp.OfpAction_Output{
864 Output: &ofp.OfpActionOutput{
865 Port: 1,
866 MaxLen: 65509,
867 },
868 }}}}}}}
869
870 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400871 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
872
873 fa = &fu.FlowArgs{
874 KV: fu.OfpFlowModArgs{"priority": 500},
875 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400876 fu.InPort(1),
877 fu.TunnelId(uint64(1)),
878 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
879 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400880 },
881 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400882 fu.PushVlan(0x8100),
883 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
884 fu.SetField(fu.VlanPcp(0)),
885 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400886 },
887 }
khenaidoo68c930b2019-05-13 11:46:51 -0400888 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -0400889 derivedFlow = oltFlowAndGroup.GetFlow(0)
890 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
891}
892
893func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Manikkaraj kb1a10922019-07-29 12:10:34 -0400894 log.Debugf("Starting Test Unicast Downstream")
khenaidood20a5852018-10-22 22:09:55 -0400895 var fa1 *fu.FlowArgs
896 fa1 = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400897 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400898 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400899 fu.InPort(10),
900 fu.Metadata_ofp((1000 << 32) | 1),
901 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400902 },
903 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400904 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400905 },
906 }
907
908 var fa2 *fu.FlowArgs
909 fa2 = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400910 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400911 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400912 fu.InPort(10),
913 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
914 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400915 },
916 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400917 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
918 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400919 },
920 }
921
khenaidoo68c930b2019-05-13 11:46:51 -0400922 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa1), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400923 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
924 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
925 Data: &ofp.OfpInstruction_GotoTable{
926 GotoTable: &ofp.OfpInstructionGotoTable{
927 TableId: 1,
928 },
929 }}}
930
khenaidood20a5852018-10-22 22:09:55 -0400931 groups := ofp.FlowGroups{}
932 tfd := newTestFlowDecomposer(newTestDeviceManager())
933
khenaidoo3306c992019-05-24 16:57:35 -0400934 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400935
khenaidood20a5852018-10-22 22:09:55 -0400936 onu1FlowAndGroup := deviceRules.Rules["onu1"]
937 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400938 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400939 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
940 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
941 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
942
943 fa1 = &fu.FlowArgs{
944 KV: fu.OfpFlowModArgs{"priority": 500},
945 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400946 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400947 fu.TunnelId(uint64(10)),
948 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400949 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400950 },
951 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400952 fu.PopVlan(),
953 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400954 },
955 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400956
khenaidood20a5852018-10-22 22:09:55 -0400957 derivedFlow := oltFlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400958 expectedOltFlow := fu.MkFlowStat(fa1)
959 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
960 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
961 Data: &ofp.OfpInstruction_Actions{
962 Actions: &ofp.OfpInstructionActions{
963 Actions: []*ofp.OfpAction{{
964 Type: 0,
965 Action: &ofp.OfpAction_Output{
966 Output: &ofp.OfpActionOutput{
967 Port: 1,
968 MaxLen: 65509,
969 },
970 }}}}}}}
971 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400972 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
973
974 fa1 = &fu.FlowArgs{
975 KV: fu.OfpFlowModArgs{"priority": 500},
976 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400977 fu.InPort(1),
978 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
979 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400980 },
981 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400982 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
983 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400984 },
985 }
khenaidoo68c930b2019-05-13 11:46:51 -0400986 expectedOnu1Flow := fu.MkFlowStat(fa1)
khenaidoo3306c992019-05-24 16:57:35 -0400987 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400988 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
989}
990
991func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
992 var fa *fu.FlowArgs
993 fa = &fu.FlowArgs{
994 KV: fu.OfpFlowModArgs{"priority": 500},
995 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400996 fu.InPort(10),
997 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
998 fu.VlanPcp(0),
999 fu.EthType(0x800),
1000 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001001 },
1002 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001003 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001004 },
1005 }
1006
1007 var ga *fu.GroupArgs
1008 ga = &fu.GroupArgs{
1009 GroupId: 10,
1010 Buckets: []*ofp.OfpBucket{
1011 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001012 fu.PopVlan(),
1013 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001014 },
1015 },
1016 },
1017 }
1018
khenaidoo68c930b2019-05-13 11:46:51 -04001019 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
1020 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
khenaidood20a5852018-10-22 22:09:55 -04001021 tfd := newTestFlowDecomposer(newTestDeviceManager())
1022
khenaidoo3306c992019-05-24 16:57:35 -04001023 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -04001024 onu1FlowAndGroup := deviceRules.Rules["onu1"]
1025 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -04001026 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -04001027 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
1028 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1029 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1030
1031 fa = &fu.FlowArgs{
1032 KV: fu.OfpFlowModArgs{"priority": 500},
1033 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001034 fu.InPort(2),
1035 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1036 fu.VlanPcp(0),
1037 fu.EthType(0x800),
1038 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001039 },
1040 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001041 fu.PopVlan(),
1042 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001043 },
1044 }
khenaidoo68c930b2019-05-13 11:46:51 -04001045 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -04001046 derivedFlow := oltFlowAndGroup.GetFlow(0)
1047 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
1048
1049 fa = &fu.FlowArgs{
1050 KV: fu.OfpFlowModArgs{"priority": 500},
1051 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001052 fu.InPort(1),
1053 fu.EthType(0x800),
1054 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001055 },
1056 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001057 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -04001058 },
1059 }
khenaidoo68c930b2019-05-13 11:46:51 -04001060 expectedOnu1Flow := fu.MkFlowStat(fa)
khenaidoo3306c992019-05-24 16:57:35 -04001061 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -04001062 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
1063}