blob: dac2e6b98340c1247cdcb14c90c6fa71ceb3a789 [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 */
npujar1d86a522019-11-14 17:11:16 +053016package flowdecomposition
khenaidoo89b0e942018-10-21 21:11:33 -040017
18import (
19 "errors"
khenaidoo89b0e942018-10-21 21:11:33 -040020 "github.com/opencord/voltha-go/rw_core/graph"
khenaidooab1f7bd2019-11-14 14:00:27 -050021 "github.com/opencord/voltha-go/rw_core/mocks"
Scott Baker807addd2019-10-24 15:16:21 -070022 fu "github.com/opencord/voltha-lib-go/v2/pkg/flows"
23 "github.com/opencord/voltha-lib-go/v2/pkg/log"
Scott Baker555307d2019-11-04 08:58:01 -080024 ofp "github.com/opencord/voltha-protos/v2/go/openflow_13"
25 "github.com/opencord/voltha-protos/v2/go/voltha"
khenaidoo89b0e942018-10-21 21:11:33 -040026 "github.com/stretchr/testify/assert"
27
28 "testing"
29)
30
khenaidoo89b0e942018-10-21 21:11:33 -040031func init() {
Manikkaraj kb1a10922019-07-29 12:10:34 -040032 // Setup default logger - applies for packages that do not have specific logger set
33 if _, err := log.SetDefaultLogger(log.JSON, 0, log.Fields{"instanceId": 1}); err != nil {
34 log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
35 }
36
37 // Update all loggers (provisioned via init) with a common field
38 if err := log.UpdateAllLoggers(log.Fields{"instanceId": 1}); err != nil {
39 log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
40 }
41
42 // Update all loggers to log level specified as input parameter
43 log.SetAllLogLevel(0)
khenaidoo89b0e942018-10-21 21:11:33 -040044}
45
46type testDeviceManager struct {
khenaidooab1f7bd2019-11-14 14:00:27 -050047 mocks.DeviceManager
khenaidoo89b0e942018-10-21 21:11:33 -040048 devices map[string]*voltha.Device
49}
50
51func newTestDeviceManager() *testDeviceManager {
52 var tdm testDeviceManager
53 tdm.devices = make(map[string]*voltha.Device)
54 tdm.devices["olt"] = &voltha.Device{
55 Id: "olt",
56 Root: true,
57 ParentId: "logical_device",
58 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040059 {PortNo: 1, Label: "pon"},
60 {PortNo: 2, Label: "nni"},
khenaidoo89b0e942018-10-21 21:11:33 -040061 },
62 }
63 tdm.devices["onu1"] = &voltha.Device{
64 Id: "onu1",
65 Root: false,
66 ParentId: "olt",
67 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040068 {PortNo: 1, Label: "pon"},
69 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040070 },
71 }
72 tdm.devices["onu2"] = &voltha.Device{
73 Id: "onu2",
74 Root: false,
75 ParentId: "olt",
76 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040077 {PortNo: 1, Label: "pon"},
78 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040079 },
80 }
81 tdm.devices["onu3"] = &voltha.Device{
82 Id: "onu3",
83 Root: false,
84 ParentId: "olt",
85 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040086 {PortNo: 1, Label: "pon"},
87 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040088 },
89 }
90 tdm.devices["onu4"] = &voltha.Device{
91 Id: "onu4",
92 Root: false,
93 ParentId: "olt",
94 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040095 {PortNo: 1, Label: "pon"},
96 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040097 },
98 }
99 return &tdm
100}
101
npujar1d86a522019-11-14 17:11:16 +0530102func (tdm *testDeviceManager) GetDevice(deviceID string) (*voltha.Device, error) {
103 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo89b0e942018-10-21 21:11:33 -0400104 return d, nil
105 }
npujar1d86a522019-11-14 17:11:16 +0530106 return nil, errors.New("ABSENT")
khenaidoo89b0e942018-10-21 21:11:33 -0400107}
npujar1d86a522019-11-14 17:11:16 +0530108func (tdm *testDeviceManager) IsRootDevice(deviceID string) (bool, error) {
109 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo19d7b632018-10-30 10:49:50 -0400110 return d.Root, nil
111 }
npujar1d86a522019-11-14 17:11:16 +0530112 return false, errors.New("ABSENT")
khenaidoo19d7b632018-10-30 10:49:50 -0400113}
khenaidoo89b0e942018-10-21 21:11:33 -0400114
115type testFlowDecomposer struct {
Esin Karaman09959ae2019-11-29 13:59:58 +0000116 dMgr *testDeviceManager
117 logicalPorts map[uint32]*voltha.LogicalPort
118 routes map[graph.OFPortLink][]graph.RouteHop
119 defaultRules *fu.DeviceRules
120 deviceGraph *graph.DeviceGraph
121 fd *FlowDecomposer
122 logicalPortsNo map[uint32]bool
khenaidoo89b0e942018-10-21 21:11:33 -0400123}
124
125func newTestFlowDecomposer(deviceMgr *testDeviceManager) *testFlowDecomposer {
126 var tfd testFlowDecomposer
127 tfd.dMgr = deviceMgr
128
129 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
Esin Karaman09959ae2019-11-29 13:59:58 +0000130 tfd.logicalPortsNo = make(map[uint32]bool)
khenaidoo89b0e942018-10-21 21:11:33 -0400131 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
132 // port
133 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
Esin Karaman09959ae2019-11-29 13:59:58 +0000134 tfd.logicalPorts[65536] = &voltha.LogicalPort{Id: "65536", DeviceId: "olt", DevicePortNo: 65536}
khenaidoo89b0e942018-10-21 21:11:33 -0400135 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
136 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
137 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
138 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
139
Esin Karaman09959ae2019-11-29 13:59:58 +0000140 tfd.logicalPortsNo[10] = false
141 tfd.logicalPortsNo[65536] = true // nni
142
khenaidoo89b0e942018-10-21 21:11:33 -0400143 tfd.routes = make(map[graph.OFPortLink][]graph.RouteHop)
144
145 //DOWNSTREAM ROUTES
146
147 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 1}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400148 {
khenaidoo89b0e942018-10-21 21:11:33 -0400149 DeviceID: "olt",
150 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
151 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
152 },
khenaidood20a5852018-10-22 22:09:55 -0400153 {
khenaidoo89b0e942018-10-21 21:11:33 -0400154 DeviceID: "onu1",
155 Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
156 Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
157 },
158 }
159
160 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 2}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400161 {
khenaidoo89b0e942018-10-21 21:11:33 -0400162 DeviceID: "olt",
163 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
164 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
165 },
khenaidood20a5852018-10-22 22:09:55 -0400166 {
khenaidoo89b0e942018-10-21 21:11:33 -0400167 DeviceID: "onu2",
168 Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
169 Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
170 },
171 }
172 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 3}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400173 {
khenaidoo89b0e942018-10-21 21:11:33 -0400174 DeviceID: "olt",
175 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
176 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
177 },
khenaidood20a5852018-10-22 22:09:55 -0400178 {
khenaidoo89b0e942018-10-21 21:11:33 -0400179 DeviceID: "onu3",
180 Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
181 Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
182 },
183 }
184 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 4}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400185 {
khenaidoo89b0e942018-10-21 21:11:33 -0400186 DeviceID: "olt",
187 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
188 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
189 },
khenaidood20a5852018-10-22 22:09:55 -0400190 {
khenaidoo89b0e942018-10-21 21:11:33 -0400191 DeviceID: "onu4",
192 Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
193 Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
194 },
195 }
Humera Kouser4ff89012019-08-25 19:01:51 -0400196 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 10}] = []graph.RouteHop{
197 {
198 DeviceID: "olt",
199 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
200 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
201 },
202 {
203 DeviceID: "olt",
204 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
205 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
206 },
207 }
khenaidoo89b0e942018-10-21 21:11:33 -0400208
209 //UPSTREAM DATA PLANE
210
211 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400212 {
khenaidoo89b0e942018-10-21 21:11:33 -0400213 DeviceID: "onu1",
214 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
215 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
216 },
khenaidood20a5852018-10-22 22:09:55 -0400217 {
khenaidoo89b0e942018-10-21 21:11:33 -0400218 DeviceID: "olt",
219 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
220 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
221 },
222 }
223 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400224 {
khenaidoo89b0e942018-10-21 21:11:33 -0400225 DeviceID: "onu2",
226 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
227 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
228 },
khenaidood20a5852018-10-22 22:09:55 -0400229 {
khenaidoo89b0e942018-10-21 21:11:33 -0400230 DeviceID: "olt",
231 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
232 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
233 },
234 }
235 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400236 {
khenaidoo89b0e942018-10-21 21:11:33 -0400237 DeviceID: "onu3",
238 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
239 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
240 },
khenaidood20a5852018-10-22 22:09:55 -0400241 {
khenaidoo89b0e942018-10-21 21:11:33 -0400242 DeviceID: "olt",
243 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
244 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
245 },
246 }
247 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400248 {
khenaidoo89b0e942018-10-21 21:11:33 -0400249 DeviceID: "onu4",
250 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
251 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
252 },
khenaidood20a5852018-10-22 22:09:55 -0400253 {
khenaidoo89b0e942018-10-21 21:11:33 -0400254 DeviceID: "olt",
255 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
256 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
257 },
258 }
259
260 //UPSTREAM NEXT TABLE BASED
261
262 // openflow port 0 means absence of a port - go/protobuf interpretation
263 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400264 {
khenaidoo89b0e942018-10-21 21:11:33 -0400265 DeviceID: "onu1",
266 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
267 Egress: tfd.dMgr.devices["onu1"].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: 2, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400276 {
khenaidoo89b0e942018-10-21 21:11:33 -0400277 DeviceID: "onu2",
278 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
279 Egress: tfd.dMgr.devices["onu2"].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 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400288 {
khenaidoo89b0e942018-10-21 21:11:33 -0400289 DeviceID: "onu3",
290 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
291 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
292 },
khenaidood20a5852018-10-22 22:09:55 -0400293 {
khenaidoo89b0e942018-10-21 21:11:33 -0400294 DeviceID: "olt",
295 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
296 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
297 },
298 }
299 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400300 {
khenaidoo89b0e942018-10-21 21:11:33 -0400301 DeviceID: "onu4",
302 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
303 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
304 },
khenaidood20a5852018-10-22 22:09:55 -0400305 {
khenaidoo89b0e942018-10-21 21:11:33 -0400306 DeviceID: "olt",
307 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
308 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
309 },
310 }
311
312 // DOWNSTREAM NEXT TABLE BASED
313
314 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400315 {
khenaidoo89b0e942018-10-21 21:11:33 -0400316 DeviceID: "olt",
317 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
318 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
319 },
khenaidood20a5852018-10-22 22:09:55 -0400320 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400321 }
322
323 tfd.routes[graph.OFPortLink{Ingress: 0, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400324 {}, // 1st hop is wildcard
325 {
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
332 // DEFAULT RULES
333
334 tfd.defaultRules = fu.NewDeviceRules()
335 fg := fu.NewFlowsAndGroups()
npujar1d86a522019-11-14 17:11:16 +0530336 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400337 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400338 fu.InPort(2),
339 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400340 },
341 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400342 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
343 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400344 },
345 }
khenaidoo68c930b2019-05-13 11:46:51 -0400346 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400347 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
348
349 fg = fu.NewFlowsAndGroups()
350 fa = &fu.FlowArgs{
351 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400352 fu.InPort(2),
353 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400354 },
355 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400356 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
357 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400358 },
359 }
khenaidoo68c930b2019-05-13 11:46:51 -0400360 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400361 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
362
363 fg = fu.NewFlowsAndGroups()
364 fa = &fu.FlowArgs{
365 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400366 fu.InPort(2),
367 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400368 },
369 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400370 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 103)),
371 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400372 },
373 }
khenaidoo68c930b2019-05-13 11:46:51 -0400374 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400375 tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
376
377 fg = fu.NewFlowsAndGroups()
378 fa = &fu.FlowArgs{
379 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400380 fu.InPort(2),
381 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400382 },
383 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400384 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
385 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400386 },
387 }
khenaidoo68c930b2019-05-13 11:46:51 -0400388 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400389 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
390
391 //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 -0400392 tfd.deviceGraph = graph.NewDeviceGraph("ldid", tfd.getDeviceHelper)
khenaidoo89b0e942018-10-21 21:11:33 -0400393 tfd.deviceGraph.RootPorts = make(map[uint32]uint32)
394 tfd.deviceGraph.RootPorts[10] = 10
395
396 tfd.fd = NewFlowDecomposer(tfd.dMgr)
397
398 return &tfd
399}
400
npujar1d86a522019-11-14 17:11:16 +0530401func (tfd *testFlowDecomposer) getDeviceHelper(deviceID string) (*voltha.Device, error) {
402 return tfd.dMgr.GetDevice(deviceID)
khenaidoo89b0e942018-10-21 21:11:33 -0400403}
404
npujar1d86a522019-11-14 17:11:16 +0530405func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400406 return ""
407}
408
khenaidoo6e55d9e2019-12-12 18:26:26 -0500409func (tfd *testFlowDecomposer) GetLogicalDevice() *voltha.LogicalDevice {
410 return nil
khenaidoo89b0e942018-10-21 21:11:33 -0400411}
412
413func (tfd *testFlowDecomposer) GetDeviceGraph() *graph.DeviceGraph {
414 return tfd.deviceGraph
415}
416
417func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
418 return tfd.defaultRules
419}
420
421func (tfd *testFlowDecomposer) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
422 lPorts := make([]uint32, 0)
423 var exclPort uint32
424 if len(excludePort) == 1 {
425 exclPort = excludePort[0]
426 }
khenaidood20a5852018-10-22 22:09:55 -0400427 for portno := range tfd.logicalPorts {
khenaidoo89b0e942018-10-21 21:11:33 -0400428 if portno != exclPort {
429 lPorts = append(lPorts, portno)
430 }
431 }
432 return lPorts
433}
434
khenaidoo19d7b632018-10-30 10:49:50 -0400435func (tfd *testFlowDecomposer) GetRoute(ingressPortNo uint32, egressPortNo uint32) []graph.RouteHop {
khenaidoo89b0e942018-10-21 21:11:33 -0400436 var portLink graph.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400437 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400438 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400439 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400440 portLink.Egress = 10
441 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400442 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400443 }
khenaidoo19d7b632018-10-30 10:49:50 -0400444 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400445 portLink.Ingress = 0
446 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400447 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400448 }
449 for key, val := range tfd.routes {
450 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
451 return val
452 }
453 }
454 return nil
455}
456
Esin Karaman09959ae2019-11-29 13:59:58 +0000457func (tfd *testFlowDecomposer) GetNNIPorts() []uint32 {
458 nniPorts := make([]uint32, 0)
459 for portNo, nni := range tfd.logicalPortsNo {
460 if nni {
461 nniPorts = append(nniPorts, portNo)
462 }
463 }
464 return nniPorts
465}
466
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400467func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
468
npujar1d86a522019-11-14 17:11:16 +0530469 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400470 KV: fu.OfpFlowModArgs{"priority": 1000},
471 MatchFields: []*ofp.OfpOxmOfbField{
472 fu.InPort(1),
473 fu.VlanVid(50),
474 fu.EthType(0x888e),
475 },
476 Actions: []*ofp.OfpAction{
477 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
478 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
479 },
480 }
481
482 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
483 groups := ofp.FlowGroups{}
484 tfd := newTestFlowDecomposer(newTestDeviceManager())
485
486 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
487 onu1FlowAndGroup := deviceRules.Rules["onu1"]
488 oltFlowAndGroup := deviceRules.Rules["olt"]
489 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
490 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
491 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
492
npujar1d86a522019-11-14 17:11:16 +0530493 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400494 KV: fu.OfpFlowModArgs{"priority": 1000},
495 MatchFields: []*ofp.OfpOxmOfbField{
496 fu.InPort(1),
497 fu.TunnelId(uint64(1)),
498 fu.VlanVid(50),
499 fu.EthType(0x888e),
500 },
501 Actions: []*ofp.OfpAction{
502 fu.PushVlan(0x8100),
503 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
504 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
505 },
506 }
507 expectedOltFlow := fu.MkFlowStat(faParent)
508 derivedFlow := oltFlowAndGroup.GetFlow(0)
509 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
510
npujar1d86a522019-11-14 17:11:16 +0530511 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400512 KV: fu.OfpFlowModArgs{"priority": 1000},
513 MatchFields: []*ofp.OfpOxmOfbField{
514 fu.InPort(2),
515 fu.TunnelId(uint64(1)),
516 fu.EthType(0x888e),
517 },
518 Actions: []*ofp.OfpAction{
519 fu.PushVlan(0x8100),
520 fu.SetField(fu.VlanVid(50)),
521 fu.Output(1),
522 },
523 }
524 expectedOnuFlow := fu.MkFlowStat(faChild)
525 derivedFlow = onu1FlowAndGroup.GetFlow(0)
526 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
527}
528
529func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
530
npujar1d86a522019-11-14 17:11:16 +0530531 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400532 KV: fu.OfpFlowModArgs{"priority": 1000},
533 MatchFields: []*ofp.OfpOxmOfbField{
534 fu.InPort(1),
535 fu.VlanVid(0),
536 fu.EthType(0x888e),
537 },
538 Actions: []*ofp.OfpAction{
539 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
540 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
541 },
542 }
543
544 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
545 groups := ofp.FlowGroups{}
546 tfd := newTestFlowDecomposer(newTestDeviceManager())
547
548 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
549 onu1FlowAndGroup := deviceRules.Rules["onu1"]
550 oltFlowAndGroup := deviceRules.Rules["olt"]
551 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
552 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
553 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
554
npujar1d86a522019-11-14 17:11:16 +0530555 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400556 KV: fu.OfpFlowModArgs{"priority": 1000},
557 MatchFields: []*ofp.OfpOxmOfbField{
558 fu.InPort(1),
559 fu.TunnelId(uint64(1)),
560 fu.VlanVid(0),
561 fu.EthType(0x888e),
562 },
563 Actions: []*ofp.OfpAction{
564 fu.PushVlan(0x8100),
565 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
566 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
567 },
568 }
569 expectedOltFlow := fu.MkFlowStat(faParent)
570 derivedFlow := oltFlowAndGroup.GetFlow(0)
571 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
572
npujar1d86a522019-11-14 17:11:16 +0530573 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400574 KV: fu.OfpFlowModArgs{"priority": 1000},
575 MatchFields: []*ofp.OfpOxmOfbField{
576 fu.InPort(2),
577 fu.TunnelId(uint64(1)),
578 fu.EthType(0x888e),
579 },
580 Actions: []*ofp.OfpAction{
581 fu.PushVlan(0x8100),
582 fu.SetField(fu.VlanVid(0)),
583 fu.Output(1),
584 },
585 }
586 expectedOnuFlow := fu.MkFlowStat(faChild)
587 derivedFlow = onu1FlowAndGroup.GetFlow(0)
588 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
589}
590
591func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400592
npujar1d86a522019-11-14 17:11:16 +0530593 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400594 KV: fu.OfpFlowModArgs{"priority": 1000},
595 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400596 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400597 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400598 },
599 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400600 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
601 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400602 },
603 }
604
khenaidoo68c930b2019-05-13 11:46:51 -0400605 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400606 groups := ofp.FlowGroups{}
607 tfd := newTestFlowDecomposer(newTestDeviceManager())
608
khenaidoo3306c992019-05-24 16:57:35 -0400609 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400610 onu1FlowAndGroup := deviceRules.Rules["onu1"]
611 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400612 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400613 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400614 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
615
npujar1d86a522019-11-14 17:11:16 +0530616 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400617 KV: fu.OfpFlowModArgs{"priority": 1000},
618 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400619 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400620 fu.TunnelId(uint64(1)),
621 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400622 },
623 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400624 fu.PushVlan(0x8100),
625 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
626 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400627 },
628 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400629 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400630 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400631 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400632
npujar1d86a522019-11-14 17:11:16 +0530633 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400634 KV: fu.OfpFlowModArgs{"priority": 1000},
635 MatchFields: []*ofp.OfpOxmOfbField{
636 fu.InPort(2),
637 fu.TunnelId(uint64(1)),
638 fu.EthType(0x888e),
639 },
640 Actions: []*ofp.OfpAction{
641 fu.Output(1),
642 },
643 }
644 expectedOnuFlow := fu.MkFlowStat(faChild)
645 derivedFlow = onu1FlowAndGroup.GetFlow(0)
646 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400647}
648
649func TestDhcpReRouteRuleDecomposition(t *testing.T) {
650
npujar1d86a522019-11-14 17:11:16 +0530651 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400652 KV: fu.OfpFlowModArgs{"priority": 1000},
653 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400654 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400655 fu.EthType(0x0800),
656 fu.Ipv4Dst(0xffffffff),
657 fu.IpProto(17),
658 fu.UdpSrc(68),
659 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400660 },
661 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400662 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400663 },
664 }
665
khenaidoo68c930b2019-05-13 11:46:51 -0400666 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400667 groups := ofp.FlowGroups{}
668 tfd := newTestFlowDecomposer(newTestDeviceManager())
669
khenaidoo3306c992019-05-24 16:57:35 -0400670 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400671 onu1FlowAndGroup := deviceRules.Rules["onu1"]
672 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400673 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
674 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400675 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400676 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
677
npujar1d86a522019-11-14 17:11:16 +0530678 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400679 KV: fu.OfpFlowModArgs{"priority": 1000},
680 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400681 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400682 fu.TunnelId(uint64(1)),
683 fu.EthType(0x0800),
684 fu.Ipv4Dst(0xffffffff),
685 fu.IpProto(17),
686 fu.UdpSrc(68),
687 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400688 },
689 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400690 fu.PushVlan(0x8100),
691 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
692 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400693 },
694 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400695 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400696 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400697 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400698
npujar1d86a522019-11-14 17:11:16 +0530699 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400700 KV: fu.OfpFlowModArgs{"priority": 1000},
701 MatchFields: []*ofp.OfpOxmOfbField{
702 fu.InPort(2),
703 fu.TunnelId(uint64(1)),
704 fu.EthType(0x0800),
705 fu.Ipv4Dst(0xffffffff),
706 fu.IpProto(17),
707 fu.UdpSrc(68),
708 fu.UdpDst(67),
709 },
710 Actions: []*ofp.OfpAction{
711 fu.Output(1),
712 },
713 }
714 expectedOnuFlow := fu.MkFlowStat(faChild)
715 derivedFlow = onu1FlowAndGroup.GetFlow(0)
716 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400717}
718
Humera Kouser4ff89012019-08-25 19:01:51 -0400719func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530720 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400721 KV: fu.OfpFlowModArgs{"priority": 1000},
722 MatchFields: []*ofp.OfpOxmOfbField{
723 fu.InPort(10),
724 fu.EthType(0x88CC),
725 },
726 Actions: []*ofp.OfpAction{
727 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
728 },
729 }
730
731 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
732 groups := ofp.FlowGroups{}
733 tfd := newTestFlowDecomposer(newTestDeviceManager())
734 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
735 onu1FlowAndGroup := deviceRules.Rules["onu1"]
736 oltFlowAndGroup := deviceRules.Rules["olt"]
737 assert.Nil(t, onu1FlowAndGroup)
738 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
739 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
740
741 fa = &fu.FlowArgs{
742 KV: fu.OfpFlowModArgs{"priority": 1000},
743 MatchFields: []*ofp.OfpOxmOfbField{
744 fu.InPort(2),
745 fu.EthType(0x88CC),
746 },
747 Actions: []*ofp.OfpAction{
748 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
749 },
750 }
751 expectedOltFlow := fu.MkFlowStat(fa)
752 derivedFlow := oltFlowAndGroup.GetFlow(0)
753 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
754}
755
khenaidood20a5852018-10-22 22:09:55 -0400756func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530757 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400758 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400759 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400760 fu.InPort(1),
761 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
762 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400763 },
764 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400765 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400766 },
767 }
768
npujar1d86a522019-11-14 17:11:16 +0530769 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400770 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400771 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400772 fu.InPort(1),
773 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
774 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400775 },
776 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400777 fu.PushVlan(0x8100),
778 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
779 fu.SetField(fu.VlanPcp(0)),
780 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400781 },
782 }
783
khenaidoo68c930b2019-05-13 11:46:51 -0400784 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400785 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
786 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
787 Data: &ofp.OfpInstruction_GotoTable{
788 GotoTable: &ofp.OfpInstructionGotoTable{
789 TableId: 1,
790 },
791 }}}
792
khenaidood20a5852018-10-22 22:09:55 -0400793 groups := ofp.FlowGroups{}
794 tfd := newTestFlowDecomposer(newTestDeviceManager())
795
khenaidoo3306c992019-05-24 16:57:35 -0400796 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400797 onu1FlowAndGroup := deviceRules.Rules["onu1"]
798 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400799 assert.NotNil(t, onu1FlowAndGroup)
800 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400801 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400802 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
803 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
804 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
805
806 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400807 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400808 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400809 fu.InPort(2),
810 fu.TunnelId(uint64(1)),
811 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
812 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400813 },
814 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400815 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
816 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400817 },
818 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400819
khenaidoo3306c992019-05-24 16:57:35 -0400820 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400821 // Form the expected flow
822 expectedOnu1Flow := fu.MkFlowStat(fa)
823 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
824 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
825 Data: &ofp.OfpInstruction_Actions{
826 Actions: &ofp.OfpInstructionActions{
827 Actions: []*ofp.OfpAction{{
828 Type: 0,
829 Action: &ofp.OfpAction_Output{
830 Output: &ofp.OfpActionOutput{
831 Port: 1,
832 MaxLen: 65509,
833 },
834 }}}}}}}
835
836 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400837 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
838
839 fa = &fu.FlowArgs{
840 KV: fu.OfpFlowModArgs{"priority": 500},
841 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400842 fu.InPort(1),
843 fu.TunnelId(uint64(1)),
844 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
845 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400846 },
847 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400848 fu.PushVlan(0x8100),
849 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
850 fu.SetField(fu.VlanPcp(0)),
851 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400852 },
853 }
khenaidoo68c930b2019-05-13 11:46:51 -0400854 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -0400855 derivedFlow = oltFlowAndGroup.GetFlow(0)
856 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
857}
858
859func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Manikkaraj kb1a10922019-07-29 12:10:34 -0400860 log.Debugf("Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530861 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400862 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400863 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400864 fu.InPort(10),
865 fu.Metadata_ofp((1000 << 32) | 1),
866 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400867 },
868 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400869 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400870 },
871 }
872
npujar1d86a522019-11-14 17:11:16 +0530873 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400874 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400875 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400876 fu.InPort(10),
877 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
878 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400879 },
880 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400881 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
882 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400883 },
884 }
885
khenaidoo68c930b2019-05-13 11:46:51 -0400886 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa1), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400887 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
888 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
889 Data: &ofp.OfpInstruction_GotoTable{
890 GotoTable: &ofp.OfpInstructionGotoTable{
891 TableId: 1,
892 },
893 }}}
894
khenaidood20a5852018-10-22 22:09:55 -0400895 groups := ofp.FlowGroups{}
896 tfd := newTestFlowDecomposer(newTestDeviceManager())
897
khenaidoo3306c992019-05-24 16:57:35 -0400898 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400899
khenaidood20a5852018-10-22 22:09:55 -0400900 onu1FlowAndGroup := deviceRules.Rules["onu1"]
901 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400902 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400903 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
904 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
905 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
906
907 fa1 = &fu.FlowArgs{
908 KV: fu.OfpFlowModArgs{"priority": 500},
909 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400910 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400911 fu.TunnelId(uint64(10)),
912 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400913 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400914 },
915 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400916 fu.PopVlan(),
917 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400918 },
919 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400920
khenaidood20a5852018-10-22 22:09:55 -0400921 derivedFlow := oltFlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400922 expectedOltFlow := fu.MkFlowStat(fa1)
923 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
924 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
925 Data: &ofp.OfpInstruction_Actions{
926 Actions: &ofp.OfpInstructionActions{
927 Actions: []*ofp.OfpAction{{
928 Type: 0,
929 Action: &ofp.OfpAction_Output{
930 Output: &ofp.OfpActionOutput{
931 Port: 1,
932 MaxLen: 65509,
933 },
934 }}}}}}}
935 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400936 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
937
938 fa1 = &fu.FlowArgs{
939 KV: fu.OfpFlowModArgs{"priority": 500},
940 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400941 fu.InPort(1),
942 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
943 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400944 },
945 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400946 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
947 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400948 },
949 }
khenaidoo68c930b2019-05-13 11:46:51 -0400950 expectedOnu1Flow := fu.MkFlowStat(fa1)
khenaidoo3306c992019-05-24 16:57:35 -0400951 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400952 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
953}
954
955func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530956 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -0400957 KV: fu.OfpFlowModArgs{"priority": 500},
958 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400959 fu.InPort(10),
960 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
961 fu.VlanPcp(0),
962 fu.EthType(0x800),
963 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400964 },
965 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400966 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -0400967 },
968 }
969
npujar1d86a522019-11-14 17:11:16 +0530970 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -0400971 GroupId: 10,
972 Buckets: []*ofp.OfpBucket{
973 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400974 fu.PopVlan(),
975 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400976 },
977 },
978 },
979 }
980
khenaidoo68c930b2019-05-13 11:46:51 -0400981 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
982 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
khenaidood20a5852018-10-22 22:09:55 -0400983 tfd := newTestFlowDecomposer(newTestDeviceManager())
984
khenaidoo3306c992019-05-24 16:57:35 -0400985 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400986 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -0400987 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
988 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
989
990 fa = &fu.FlowArgs{
991 KV: fu.OfpFlowModArgs{"priority": 500},
992 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +0000993 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -0400994 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
995 fu.VlanPcp(0),
996 fu.EthType(0x800),
997 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400998 },
999 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001000 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001001 },
1002 }
khenaidoo68c930b2019-05-13 11:46:51 -04001003 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -04001004 derivedFlow := oltFlowAndGroup.GetFlow(0)
1005 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001006}