blob: cc89331c7456a5beb6178b5deacee01d8979411f [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"
npujar1d86a522019-11-14 17:11:16 +053020
khenaidoo89b0e942018-10-21 21:11:33 -040021 "github.com/opencord/voltha-go/rw_core/graph"
khenaidooab1f7bd2019-11-14 14:00:27 -050022 "github.com/opencord/voltha-go/rw_core/mocks"
Scott Baker807addd2019-10-24 15:16:21 -070023 fu "github.com/opencord/voltha-lib-go/v2/pkg/flows"
24 "github.com/opencord/voltha-lib-go/v2/pkg/log"
Scott Baker555307d2019-11-04 08:58:01 -080025 ofp "github.com/opencord/voltha-protos/v2/go/openflow_13"
26 "github.com/opencord/voltha-protos/v2/go/voltha"
khenaidoo89b0e942018-10-21 21:11:33 -040027 "github.com/stretchr/testify/assert"
28
29 "testing"
30)
31
khenaidoo89b0e942018-10-21 21:11:33 -040032func init() {
Manikkaraj kb1a10922019-07-29 12:10:34 -040033 // Setup default logger - applies for packages that do not have specific logger set
34 if _, err := log.SetDefaultLogger(log.JSON, 0, log.Fields{"instanceId": 1}); err != nil {
35 log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
36 }
37
38 // Update all loggers (provisioned via init) with a common field
39 if err := log.UpdateAllLoggers(log.Fields{"instanceId": 1}); err != nil {
40 log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
41 }
42
43 // Update all loggers to log level specified as input parameter
44 log.SetAllLogLevel(0)
khenaidoo89b0e942018-10-21 21:11:33 -040045}
46
47type testDeviceManager struct {
khenaidooab1f7bd2019-11-14 14:00:27 -050048 mocks.DeviceManager
khenaidoo89b0e942018-10-21 21:11:33 -040049 devices map[string]*voltha.Device
50}
51
52func newTestDeviceManager() *testDeviceManager {
53 var tdm testDeviceManager
54 tdm.devices = make(map[string]*voltha.Device)
55 tdm.devices["olt"] = &voltha.Device{
56 Id: "olt",
57 Root: true,
58 ParentId: "logical_device",
59 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040060 {PortNo: 1, Label: "pon"},
61 {PortNo: 2, Label: "nni"},
khenaidoo89b0e942018-10-21 21:11:33 -040062 },
63 }
64 tdm.devices["onu1"] = &voltha.Device{
65 Id: "onu1",
66 Root: false,
67 ParentId: "olt",
68 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040069 {PortNo: 1, Label: "pon"},
70 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040071 },
72 }
73 tdm.devices["onu2"] = &voltha.Device{
74 Id: "onu2",
75 Root: false,
76 ParentId: "olt",
77 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040078 {PortNo: 1, Label: "pon"},
79 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040080 },
81 }
82 tdm.devices["onu3"] = &voltha.Device{
83 Id: "onu3",
84 Root: false,
85 ParentId: "olt",
86 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040087 {PortNo: 1, Label: "pon"},
88 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040089 },
90 }
91 tdm.devices["onu4"] = &voltha.Device{
92 Id: "onu4",
93 Root: false,
94 ParentId: "olt",
95 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040096 {PortNo: 1, Label: "pon"},
97 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040098 },
99 }
100 return &tdm
101}
102
npujar1d86a522019-11-14 17:11:16 +0530103func (tdm *testDeviceManager) GetDevice(deviceID string) (*voltha.Device, error) {
104 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo89b0e942018-10-21 21:11:33 -0400105 return d, nil
106 }
npujar1d86a522019-11-14 17:11:16 +0530107 return nil, errors.New("ABSENT")
khenaidoo89b0e942018-10-21 21:11:33 -0400108}
npujar1d86a522019-11-14 17:11:16 +0530109func (tdm *testDeviceManager) IsRootDevice(deviceID string) (bool, error) {
110 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo19d7b632018-10-30 10:49:50 -0400111 return d.Root, nil
112 }
npujar1d86a522019-11-14 17:11:16 +0530113 return false, errors.New("ABSENT")
khenaidoo19d7b632018-10-30 10:49:50 -0400114}
khenaidoo89b0e942018-10-21 21:11:33 -0400115
116type testFlowDecomposer struct {
117 dMgr *testDeviceManager
118 logicalPorts map[uint32]*voltha.LogicalPort
119 routes map[graph.OFPortLink][]graph.RouteHop
120 defaultRules *fu.DeviceRules
121 deviceGraph *graph.DeviceGraph
122 fd *FlowDecomposer
123}
124
125func newTestFlowDecomposer(deviceMgr *testDeviceManager) *testFlowDecomposer {
126 var tfd testFlowDecomposer
127 tfd.dMgr = deviceMgr
128
129 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
130 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
131 // port
132 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
133 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
134 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
135 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
136 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
137
138 tfd.routes = make(map[graph.OFPortLink][]graph.RouteHop)
139
140 //DOWNSTREAM ROUTES
141
142 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 1}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400143 {
khenaidoo89b0e942018-10-21 21:11:33 -0400144 DeviceID: "olt",
145 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
146 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
147 },
khenaidood20a5852018-10-22 22:09:55 -0400148 {
khenaidoo89b0e942018-10-21 21:11:33 -0400149 DeviceID: "onu1",
150 Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
151 Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
152 },
153 }
154
155 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 2}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400156 {
khenaidoo89b0e942018-10-21 21:11:33 -0400157 DeviceID: "olt",
158 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
159 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
160 },
khenaidood20a5852018-10-22 22:09:55 -0400161 {
khenaidoo89b0e942018-10-21 21:11:33 -0400162 DeviceID: "onu2",
163 Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
164 Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
165 },
166 }
167 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 3}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400168 {
khenaidoo89b0e942018-10-21 21:11:33 -0400169 DeviceID: "olt",
170 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
171 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
172 },
khenaidood20a5852018-10-22 22:09:55 -0400173 {
khenaidoo89b0e942018-10-21 21:11:33 -0400174 DeviceID: "onu3",
175 Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
176 Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
177 },
178 }
179 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 4}] = []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: "onu4",
187 Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
188 Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
189 },
190 }
Humera Kouser4ff89012019-08-25 19:01:51 -0400191 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 10}] = []graph.RouteHop{
192 {
193 DeviceID: "olt",
194 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
195 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
196 },
197 {
198 DeviceID: "olt",
199 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
200 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
201 },
202 }
khenaidoo89b0e942018-10-21 21:11:33 -0400203
204 //UPSTREAM DATA PLANE
205
206 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400207 {
khenaidoo89b0e942018-10-21 21:11:33 -0400208 DeviceID: "onu1",
209 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
210 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
211 },
khenaidood20a5852018-10-22 22:09:55 -0400212 {
khenaidoo89b0e942018-10-21 21:11:33 -0400213 DeviceID: "olt",
214 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
215 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
216 },
217 }
218 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400219 {
khenaidoo89b0e942018-10-21 21:11:33 -0400220 DeviceID: "onu2",
221 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
222 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
223 },
khenaidood20a5852018-10-22 22:09:55 -0400224 {
khenaidoo89b0e942018-10-21 21:11:33 -0400225 DeviceID: "olt",
226 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
227 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
228 },
229 }
230 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400231 {
khenaidoo89b0e942018-10-21 21:11:33 -0400232 DeviceID: "onu3",
233 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
234 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
235 },
khenaidood20a5852018-10-22 22:09:55 -0400236 {
khenaidoo89b0e942018-10-21 21:11:33 -0400237 DeviceID: "olt",
238 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
239 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
240 },
241 }
242 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400243 {
khenaidoo89b0e942018-10-21 21:11:33 -0400244 DeviceID: "onu4",
245 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
246 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
247 },
khenaidood20a5852018-10-22 22:09:55 -0400248 {
khenaidoo89b0e942018-10-21 21:11:33 -0400249 DeviceID: "olt",
250 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
251 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
252 },
253 }
254
255 //UPSTREAM NEXT TABLE BASED
256
257 // openflow port 0 means absence of a port - go/protobuf interpretation
258 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400259 {
khenaidoo89b0e942018-10-21 21:11:33 -0400260 DeviceID: "onu1",
261 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
262 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
263 },
khenaidood20a5852018-10-22 22:09:55 -0400264 {
khenaidoo89b0e942018-10-21 21:11:33 -0400265 DeviceID: "olt",
266 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
267 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
268 },
269 }
270 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400271 {
khenaidoo89b0e942018-10-21 21:11:33 -0400272 DeviceID: "onu2",
273 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
274 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
275 },
khenaidood20a5852018-10-22 22:09:55 -0400276 {
khenaidoo89b0e942018-10-21 21:11:33 -0400277 DeviceID: "olt",
278 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
279 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
280 },
281 }
282 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400283 {
khenaidoo89b0e942018-10-21 21:11:33 -0400284 DeviceID: "onu3",
285 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
286 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
287 },
khenaidood20a5852018-10-22 22:09:55 -0400288 {
khenaidoo89b0e942018-10-21 21:11:33 -0400289 DeviceID: "olt",
290 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
291 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
292 },
293 }
294 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400295 {
khenaidoo89b0e942018-10-21 21:11:33 -0400296 DeviceID: "onu4",
297 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
298 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
299 },
khenaidood20a5852018-10-22 22:09:55 -0400300 {
khenaidoo89b0e942018-10-21 21:11:33 -0400301 DeviceID: "olt",
302 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
303 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
304 },
305 }
306
307 // DOWNSTREAM NEXT TABLE BASED
308
309 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400310 {
khenaidoo89b0e942018-10-21 21:11:33 -0400311 DeviceID: "olt",
312 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
313 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
314 },
khenaidood20a5852018-10-22 22:09:55 -0400315 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400316 }
317
318 tfd.routes[graph.OFPortLink{Ingress: 0, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400319 {}, // 1st hop is wildcard
320 {
khenaidoo89b0e942018-10-21 21:11:33 -0400321 DeviceID: "olt",
322 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
323 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
324 },
325 }
326
327 // DEFAULT RULES
328
329 tfd.defaultRules = fu.NewDeviceRules()
330 fg := fu.NewFlowsAndGroups()
npujar1d86a522019-11-14 17:11:16 +0530331 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400332 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400333 fu.InPort(2),
334 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400335 },
336 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400337 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
338 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400339 },
340 }
khenaidoo68c930b2019-05-13 11:46:51 -0400341 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400342 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
343
344 fg = fu.NewFlowsAndGroups()
345 fa = &fu.FlowArgs{
346 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400347 fu.InPort(2),
348 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400349 },
350 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400351 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
352 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400353 },
354 }
khenaidoo68c930b2019-05-13 11:46:51 -0400355 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400356 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
357
358 fg = fu.NewFlowsAndGroups()
359 fa = &fu.FlowArgs{
360 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400361 fu.InPort(2),
362 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400363 },
364 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400365 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 103)),
366 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400367 },
368 }
khenaidoo68c930b2019-05-13 11:46:51 -0400369 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400370 tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
371
372 fg = fu.NewFlowsAndGroups()
373 fa = &fu.FlowArgs{
374 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400375 fu.InPort(2),
376 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400377 },
378 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400379 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
380 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400381 },
382 }
khenaidoo68c930b2019-05-13 11:46:51 -0400383 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400384 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
385
386 //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 -0400387 tfd.deviceGraph = graph.NewDeviceGraph("ldid", tfd.getDeviceHelper)
khenaidoo89b0e942018-10-21 21:11:33 -0400388 tfd.deviceGraph.RootPorts = make(map[uint32]uint32)
389 tfd.deviceGraph.RootPorts[10] = 10
390
391 tfd.fd = NewFlowDecomposer(tfd.dMgr)
392
393 return &tfd
394}
395
npujar1d86a522019-11-14 17:11:16 +0530396func (tfd *testFlowDecomposer) getDeviceHelper(deviceID string) (*voltha.Device, error) {
397 return tfd.dMgr.GetDevice(deviceID)
khenaidoo89b0e942018-10-21 21:11:33 -0400398}
399
npujar1d86a522019-11-14 17:11:16 +0530400func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400401 return ""
402}
403
khenaidoo19d7b632018-10-30 10:49:50 -0400404func (tfd *testFlowDecomposer) GetLogicalDevice() (*voltha.LogicalDevice, error) {
405 return nil, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400406}
407
408func (tfd *testFlowDecomposer) GetDeviceGraph() *graph.DeviceGraph {
409 return tfd.deviceGraph
410}
411
412func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
413 return tfd.defaultRules
414}
415
416func (tfd *testFlowDecomposer) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
417 lPorts := make([]uint32, 0)
418 var exclPort uint32
419 if len(excludePort) == 1 {
420 exclPort = excludePort[0]
421 }
khenaidood20a5852018-10-22 22:09:55 -0400422 for portno := range tfd.logicalPorts {
khenaidoo89b0e942018-10-21 21:11:33 -0400423 if portno != exclPort {
424 lPorts = append(lPorts, portno)
425 }
426 }
427 return lPorts
428}
429
khenaidoo19d7b632018-10-30 10:49:50 -0400430func (tfd *testFlowDecomposer) GetRoute(ingressPortNo uint32, egressPortNo uint32) []graph.RouteHop {
khenaidoo89b0e942018-10-21 21:11:33 -0400431 var portLink graph.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400432 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400433 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400434 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400435 portLink.Egress = 10
436 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400437 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400438 }
khenaidoo19d7b632018-10-30 10:49:50 -0400439 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400440 portLink.Ingress = 0
441 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400442 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400443 }
444 for key, val := range tfd.routes {
445 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
446 return val
447 }
448 }
449 return nil
450}
451
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400452func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
453
npujar1d86a522019-11-14 17:11:16 +0530454 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400455 KV: fu.OfpFlowModArgs{"priority": 1000},
456 MatchFields: []*ofp.OfpOxmOfbField{
457 fu.InPort(1),
458 fu.VlanVid(50),
459 fu.EthType(0x888e),
460 },
461 Actions: []*ofp.OfpAction{
462 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
463 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
464 },
465 }
466
467 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
468 groups := ofp.FlowGroups{}
469 tfd := newTestFlowDecomposer(newTestDeviceManager())
470
471 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
472 onu1FlowAndGroup := deviceRules.Rules["onu1"]
473 oltFlowAndGroup := deviceRules.Rules["olt"]
474 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
475 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
476 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
477
npujar1d86a522019-11-14 17:11:16 +0530478 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400479 KV: fu.OfpFlowModArgs{"priority": 1000},
480 MatchFields: []*ofp.OfpOxmOfbField{
481 fu.InPort(1),
482 fu.TunnelId(uint64(1)),
483 fu.VlanVid(50),
484 fu.EthType(0x888e),
485 },
486 Actions: []*ofp.OfpAction{
487 fu.PushVlan(0x8100),
488 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
489 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
490 },
491 }
492 expectedOltFlow := fu.MkFlowStat(faParent)
493 derivedFlow := oltFlowAndGroup.GetFlow(0)
494 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
495
npujar1d86a522019-11-14 17:11:16 +0530496 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400497 KV: fu.OfpFlowModArgs{"priority": 1000},
498 MatchFields: []*ofp.OfpOxmOfbField{
499 fu.InPort(2),
500 fu.TunnelId(uint64(1)),
501 fu.EthType(0x888e),
502 },
503 Actions: []*ofp.OfpAction{
504 fu.PushVlan(0x8100),
505 fu.SetField(fu.VlanVid(50)),
506 fu.Output(1),
507 },
508 }
509 expectedOnuFlow := fu.MkFlowStat(faChild)
510 derivedFlow = onu1FlowAndGroup.GetFlow(0)
511 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
512}
513
514func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
515
npujar1d86a522019-11-14 17:11:16 +0530516 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400517 KV: fu.OfpFlowModArgs{"priority": 1000},
518 MatchFields: []*ofp.OfpOxmOfbField{
519 fu.InPort(1),
520 fu.VlanVid(0),
521 fu.EthType(0x888e),
522 },
523 Actions: []*ofp.OfpAction{
524 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
525 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
526 },
527 }
528
529 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
530 groups := ofp.FlowGroups{}
531 tfd := newTestFlowDecomposer(newTestDeviceManager())
532
533 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
534 onu1FlowAndGroup := deviceRules.Rules["onu1"]
535 oltFlowAndGroup := deviceRules.Rules["olt"]
536 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
537 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
538 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
539
npujar1d86a522019-11-14 17:11:16 +0530540 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400541 KV: fu.OfpFlowModArgs{"priority": 1000},
542 MatchFields: []*ofp.OfpOxmOfbField{
543 fu.InPort(1),
544 fu.TunnelId(uint64(1)),
545 fu.VlanVid(0),
546 fu.EthType(0x888e),
547 },
548 Actions: []*ofp.OfpAction{
549 fu.PushVlan(0x8100),
550 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
551 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
552 },
553 }
554 expectedOltFlow := fu.MkFlowStat(faParent)
555 derivedFlow := oltFlowAndGroup.GetFlow(0)
556 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
557
npujar1d86a522019-11-14 17:11:16 +0530558 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400559 KV: fu.OfpFlowModArgs{"priority": 1000},
560 MatchFields: []*ofp.OfpOxmOfbField{
561 fu.InPort(2),
562 fu.TunnelId(uint64(1)),
563 fu.EthType(0x888e),
564 },
565 Actions: []*ofp.OfpAction{
566 fu.PushVlan(0x8100),
567 fu.SetField(fu.VlanVid(0)),
568 fu.Output(1),
569 },
570 }
571 expectedOnuFlow := fu.MkFlowStat(faChild)
572 derivedFlow = onu1FlowAndGroup.GetFlow(0)
573 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
574}
575
576func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400577
npujar1d86a522019-11-14 17:11:16 +0530578 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400579 KV: fu.OfpFlowModArgs{"priority": 1000},
580 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400581 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400582 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400583 },
584 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400585 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
586 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400587 },
588 }
589
khenaidoo68c930b2019-05-13 11:46:51 -0400590 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400591 groups := ofp.FlowGroups{}
592 tfd := newTestFlowDecomposer(newTestDeviceManager())
593
khenaidoo3306c992019-05-24 16:57:35 -0400594 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400595 onu1FlowAndGroup := deviceRules.Rules["onu1"]
596 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400597 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400598 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400599 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
600
npujar1d86a522019-11-14 17:11:16 +0530601 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400602 KV: fu.OfpFlowModArgs{"priority": 1000},
603 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400604 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400605 fu.TunnelId(uint64(1)),
606 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400607 },
608 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400609 fu.PushVlan(0x8100),
610 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
611 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400612 },
613 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400614 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400615 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400616 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400617
npujar1d86a522019-11-14 17:11:16 +0530618 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400619 KV: fu.OfpFlowModArgs{"priority": 1000},
620 MatchFields: []*ofp.OfpOxmOfbField{
621 fu.InPort(2),
622 fu.TunnelId(uint64(1)),
623 fu.EthType(0x888e),
624 },
625 Actions: []*ofp.OfpAction{
626 fu.Output(1),
627 },
628 }
629 expectedOnuFlow := fu.MkFlowStat(faChild)
630 derivedFlow = onu1FlowAndGroup.GetFlow(0)
631 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400632}
633
634func TestDhcpReRouteRuleDecomposition(t *testing.T) {
635
npujar1d86a522019-11-14 17:11:16 +0530636 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400637 KV: fu.OfpFlowModArgs{"priority": 1000},
638 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400639 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400640 fu.EthType(0x0800),
641 fu.Ipv4Dst(0xffffffff),
642 fu.IpProto(17),
643 fu.UdpSrc(68),
644 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400645 },
646 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400647 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400648 },
649 }
650
khenaidoo68c930b2019-05-13 11:46:51 -0400651 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400652 groups := ofp.FlowGroups{}
653 tfd := newTestFlowDecomposer(newTestDeviceManager())
654
khenaidoo3306c992019-05-24 16:57:35 -0400655 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400656 onu1FlowAndGroup := deviceRules.Rules["onu1"]
657 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400658 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
659 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400660 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400661 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
662
npujar1d86a522019-11-14 17:11:16 +0530663 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400664 KV: fu.OfpFlowModArgs{"priority": 1000},
665 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400666 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400667 fu.TunnelId(uint64(1)),
668 fu.EthType(0x0800),
669 fu.Ipv4Dst(0xffffffff),
670 fu.IpProto(17),
671 fu.UdpSrc(68),
672 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400673 },
674 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400675 fu.PushVlan(0x8100),
676 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
677 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400678 },
679 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400680 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400681 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400682 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400683
npujar1d86a522019-11-14 17:11:16 +0530684 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400685 KV: fu.OfpFlowModArgs{"priority": 1000},
686 MatchFields: []*ofp.OfpOxmOfbField{
687 fu.InPort(2),
688 fu.TunnelId(uint64(1)),
689 fu.EthType(0x0800),
690 fu.Ipv4Dst(0xffffffff),
691 fu.IpProto(17),
692 fu.UdpSrc(68),
693 fu.UdpDst(67),
694 },
695 Actions: []*ofp.OfpAction{
696 fu.Output(1),
697 },
698 }
699 expectedOnuFlow := fu.MkFlowStat(faChild)
700 derivedFlow = onu1FlowAndGroup.GetFlow(0)
701 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400702}
703
Humera Kouser4ff89012019-08-25 19:01:51 -0400704func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530705 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400706 KV: fu.OfpFlowModArgs{"priority": 1000},
707 MatchFields: []*ofp.OfpOxmOfbField{
708 fu.InPort(10),
709 fu.EthType(0x88CC),
710 },
711 Actions: []*ofp.OfpAction{
712 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
713 },
714 }
715
716 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
717 groups := ofp.FlowGroups{}
718 tfd := newTestFlowDecomposer(newTestDeviceManager())
719 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
720 onu1FlowAndGroup := deviceRules.Rules["onu1"]
721 oltFlowAndGroup := deviceRules.Rules["olt"]
722 assert.Nil(t, onu1FlowAndGroup)
723 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
724 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
725
726 fa = &fu.FlowArgs{
727 KV: fu.OfpFlowModArgs{"priority": 1000},
728 MatchFields: []*ofp.OfpOxmOfbField{
729 fu.InPort(2),
730 fu.EthType(0x88CC),
731 },
732 Actions: []*ofp.OfpAction{
733 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
734 },
735 }
736 expectedOltFlow := fu.MkFlowStat(fa)
737 derivedFlow := oltFlowAndGroup.GetFlow(0)
738 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
739}
740
khenaidood20a5852018-10-22 22:09:55 -0400741func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530742 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400743 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400744 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400745 fu.InPort(1),
746 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
747 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400748 },
749 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400750 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400751 },
752 }
753
npujar1d86a522019-11-14 17:11:16 +0530754 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400755 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400756 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400757 fu.InPort(1),
758 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
759 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400760 },
761 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400762 fu.PushVlan(0x8100),
763 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
764 fu.SetField(fu.VlanPcp(0)),
765 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400766 },
767 }
768
khenaidoo68c930b2019-05-13 11:46:51 -0400769 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400770 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
771 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
772 Data: &ofp.OfpInstruction_GotoTable{
773 GotoTable: &ofp.OfpInstructionGotoTable{
774 TableId: 1,
775 },
776 }}}
777
khenaidood20a5852018-10-22 22:09:55 -0400778 groups := ofp.FlowGroups{}
779 tfd := newTestFlowDecomposer(newTestDeviceManager())
780
khenaidoo3306c992019-05-24 16:57:35 -0400781 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400782 onu1FlowAndGroup := deviceRules.Rules["onu1"]
783 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400784 assert.NotNil(t, onu1FlowAndGroup)
785 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400786 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400787 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
788 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
789 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
790
791 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400792 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400793 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400794 fu.InPort(2),
795 fu.TunnelId(uint64(1)),
796 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
797 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400798 },
799 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400800 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
801 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400802 },
803 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400804
khenaidoo3306c992019-05-24 16:57:35 -0400805 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400806 // Form the expected flow
807 expectedOnu1Flow := fu.MkFlowStat(fa)
808 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
809 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
810 Data: &ofp.OfpInstruction_Actions{
811 Actions: &ofp.OfpInstructionActions{
812 Actions: []*ofp.OfpAction{{
813 Type: 0,
814 Action: &ofp.OfpAction_Output{
815 Output: &ofp.OfpActionOutput{
816 Port: 1,
817 MaxLen: 65509,
818 },
819 }}}}}}}
820
821 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400822 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
823
824 fa = &fu.FlowArgs{
825 KV: fu.OfpFlowModArgs{"priority": 500},
826 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400827 fu.InPort(1),
828 fu.TunnelId(uint64(1)),
829 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
830 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400831 },
832 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400833 fu.PushVlan(0x8100),
834 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
835 fu.SetField(fu.VlanPcp(0)),
836 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400837 },
838 }
khenaidoo68c930b2019-05-13 11:46:51 -0400839 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -0400840 derivedFlow = oltFlowAndGroup.GetFlow(0)
841 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
842}
843
844func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Manikkaraj kb1a10922019-07-29 12:10:34 -0400845 log.Debugf("Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530846 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400847 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400848 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400849 fu.InPort(10),
850 fu.Metadata_ofp((1000 << 32) | 1),
851 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400852 },
853 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400854 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400855 },
856 }
857
npujar1d86a522019-11-14 17:11:16 +0530858 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400859 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400860 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400861 fu.InPort(10),
862 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
863 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400864 },
865 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400866 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
867 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400868 },
869 }
870
khenaidoo68c930b2019-05-13 11:46:51 -0400871 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa1), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400872 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
873 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
874 Data: &ofp.OfpInstruction_GotoTable{
875 GotoTable: &ofp.OfpInstructionGotoTable{
876 TableId: 1,
877 },
878 }}}
879
khenaidood20a5852018-10-22 22:09:55 -0400880 groups := ofp.FlowGroups{}
881 tfd := newTestFlowDecomposer(newTestDeviceManager())
882
khenaidoo3306c992019-05-24 16:57:35 -0400883 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400884
khenaidood20a5852018-10-22 22:09:55 -0400885 onu1FlowAndGroup := deviceRules.Rules["onu1"]
886 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400887 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400888 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
889 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
890 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
891
892 fa1 = &fu.FlowArgs{
893 KV: fu.OfpFlowModArgs{"priority": 500},
894 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400895 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400896 fu.TunnelId(uint64(10)),
897 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400898 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400899 },
900 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400901 fu.PopVlan(),
902 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400903 },
904 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400905
khenaidood20a5852018-10-22 22:09:55 -0400906 derivedFlow := oltFlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400907 expectedOltFlow := fu.MkFlowStat(fa1)
908 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
909 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
910 Data: &ofp.OfpInstruction_Actions{
911 Actions: &ofp.OfpInstructionActions{
912 Actions: []*ofp.OfpAction{{
913 Type: 0,
914 Action: &ofp.OfpAction_Output{
915 Output: &ofp.OfpActionOutput{
916 Port: 1,
917 MaxLen: 65509,
918 },
919 }}}}}}}
920 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400921 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
922
923 fa1 = &fu.FlowArgs{
924 KV: fu.OfpFlowModArgs{"priority": 500},
925 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400926 fu.InPort(1),
927 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
928 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400929 },
930 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400931 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
932 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400933 },
934 }
khenaidoo68c930b2019-05-13 11:46:51 -0400935 expectedOnu1Flow := fu.MkFlowStat(fa1)
khenaidoo3306c992019-05-24 16:57:35 -0400936 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400937 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
938}
939
940func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530941 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -0400942 KV: fu.OfpFlowModArgs{"priority": 500},
943 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400944 fu.InPort(10),
945 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
946 fu.VlanPcp(0),
947 fu.EthType(0x800),
948 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400949 },
950 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400951 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -0400952 },
953 }
954
npujar1d86a522019-11-14 17:11:16 +0530955 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -0400956 GroupId: 10,
957 Buckets: []*ofp.OfpBucket{
958 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400959 fu.PopVlan(),
960 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400961 },
962 },
963 },
964 }
965
khenaidoo68c930b2019-05-13 11:46:51 -0400966 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
967 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
khenaidood20a5852018-10-22 22:09:55 -0400968 tfd := newTestFlowDecomposer(newTestDeviceManager())
969
khenaidoo3306c992019-05-24 16:57:35 -0400970 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400971 onu1FlowAndGroup := deviceRules.Rules["onu1"]
972 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400973 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400974 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
975 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
976 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
977
978 fa = &fu.FlowArgs{
979 KV: fu.OfpFlowModArgs{"priority": 500},
980 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400981 fu.InPort(2),
982 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
983 fu.VlanPcp(0),
984 fu.EthType(0x800),
985 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400986 },
987 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400988 fu.PopVlan(),
989 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400990 },
991 }
khenaidoo68c930b2019-05-13 11:46:51 -0400992 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -0400993 derivedFlow := oltFlowAndGroup.GetFlow(0)
994 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
995
996 fa = &fu.FlowArgs{
997 KV: fu.OfpFlowModArgs{"priority": 500},
998 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400999 fu.InPort(1),
1000 fu.EthType(0x800),
1001 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001002 },
1003 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001004 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -04001005 },
1006 }
khenaidoo68c930b2019-05-13 11:46:51 -04001007 expectedOnu1Flow := fu.MkFlowStat(fa)
khenaidoo3306c992019-05-24 16:57:35 -04001008 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -04001009 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
1010}