blob: 8e2d9f356cefb7b13bdc60d59c604d070c39544e [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 (
npujar467fe752020-01-16 20:17:45 +053019 "context"
khenaidoo89b0e942018-10-21 21:11:33 -040020 "errors"
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"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080023 fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
24 "github.com/opencord/voltha-lib-go/v3/pkg/log"
25 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
26 "github.com/opencord/voltha-protos/v3/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
npujar467fe752020-01-16 20:17:45 +0530103func (tdm *testDeviceManager) GetDevice(ctx context.Context, deviceID string) (*voltha.Device, error) {
npujar1d86a522019-11-14 17:11:16 +0530104 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 {
Esin Karaman09959ae2019-11-29 13:59:58 +0000117 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 logicalPortsNo map[uint32]bool
khenaidoo89b0e942018-10-21 21:11:33 -0400124}
125
126func newTestFlowDecomposer(deviceMgr *testDeviceManager) *testFlowDecomposer {
127 var tfd testFlowDecomposer
128 tfd.dMgr = deviceMgr
129
130 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
Esin Karaman09959ae2019-11-29 13:59:58 +0000131 tfd.logicalPortsNo = make(map[uint32]bool)
khenaidoo89b0e942018-10-21 21:11:33 -0400132 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
133 // port
134 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
Esin Karaman09959ae2019-11-29 13:59:58 +0000135 tfd.logicalPorts[65536] = &voltha.LogicalPort{Id: "65536", DeviceId: "olt", DevicePortNo: 65536}
khenaidoo89b0e942018-10-21 21:11:33 -0400136 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
137 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
138 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
139 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
140
Esin Karaman09959ae2019-11-29 13:59:58 +0000141 tfd.logicalPortsNo[10] = false
142 tfd.logicalPortsNo[65536] = true // nni
143
khenaidoo89b0e942018-10-21 21:11:33 -0400144 tfd.routes = make(map[graph.OFPortLink][]graph.RouteHop)
145
146 //DOWNSTREAM ROUTES
147
148 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 1}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400149 {
khenaidoo89b0e942018-10-21 21:11:33 -0400150 DeviceID: "olt",
151 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
152 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
153 },
khenaidood20a5852018-10-22 22:09:55 -0400154 {
khenaidoo89b0e942018-10-21 21:11:33 -0400155 DeviceID: "onu1",
156 Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
157 Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
158 },
159 }
160
161 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 2}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400162 {
khenaidoo89b0e942018-10-21 21:11:33 -0400163 DeviceID: "olt",
164 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
165 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
166 },
khenaidood20a5852018-10-22 22:09:55 -0400167 {
khenaidoo89b0e942018-10-21 21:11:33 -0400168 DeviceID: "onu2",
169 Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
170 Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
171 },
172 }
173 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 3}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400174 {
khenaidoo89b0e942018-10-21 21:11:33 -0400175 DeviceID: "olt",
176 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
177 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
178 },
khenaidood20a5852018-10-22 22:09:55 -0400179 {
khenaidoo89b0e942018-10-21 21:11:33 -0400180 DeviceID: "onu3",
181 Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
182 Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
183 },
184 }
185 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 4}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400186 {
khenaidoo89b0e942018-10-21 21:11:33 -0400187 DeviceID: "olt",
188 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
189 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
190 },
khenaidood20a5852018-10-22 22:09:55 -0400191 {
khenaidoo89b0e942018-10-21 21:11:33 -0400192 DeviceID: "onu4",
193 Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
194 Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
195 },
196 }
Humera Kouser4ff89012019-08-25 19:01:51 -0400197 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 10}] = []graph.RouteHop{
198 {
199 DeviceID: "olt",
200 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
201 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
202 },
203 {
204 DeviceID: "olt",
205 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
206 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
207 },
208 }
khenaidoo89b0e942018-10-21 21:11:33 -0400209
210 //UPSTREAM DATA PLANE
211
212 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400213 {
khenaidoo89b0e942018-10-21 21:11:33 -0400214 DeviceID: "onu1",
215 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
216 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
217 },
khenaidood20a5852018-10-22 22:09:55 -0400218 {
khenaidoo89b0e942018-10-21 21:11:33 -0400219 DeviceID: "olt",
220 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
221 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
222 },
223 }
224 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400225 {
khenaidoo89b0e942018-10-21 21:11:33 -0400226 DeviceID: "onu2",
227 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
228 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
229 },
khenaidood20a5852018-10-22 22:09:55 -0400230 {
khenaidoo89b0e942018-10-21 21:11:33 -0400231 DeviceID: "olt",
232 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
233 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
234 },
235 }
236 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400237 {
khenaidoo89b0e942018-10-21 21:11:33 -0400238 DeviceID: "onu3",
239 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
240 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
241 },
khenaidood20a5852018-10-22 22:09:55 -0400242 {
khenaidoo89b0e942018-10-21 21:11:33 -0400243 DeviceID: "olt",
244 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
245 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
246 },
247 }
248 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400249 {
khenaidoo89b0e942018-10-21 21:11:33 -0400250 DeviceID: "onu4",
251 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
252 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
253 },
khenaidood20a5852018-10-22 22:09:55 -0400254 {
khenaidoo89b0e942018-10-21 21:11:33 -0400255 DeviceID: "olt",
256 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
257 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
258 },
259 }
260
261 //UPSTREAM NEXT TABLE BASED
262
263 // openflow port 0 means absence of a port - go/protobuf interpretation
264 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400265 {
khenaidoo89b0e942018-10-21 21:11:33 -0400266 DeviceID: "onu1",
267 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
268 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
269 },
khenaidood20a5852018-10-22 22:09:55 -0400270 {
khenaidoo89b0e942018-10-21 21:11:33 -0400271 DeviceID: "olt",
272 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
273 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
274 },
275 }
276 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400277 {
khenaidoo89b0e942018-10-21 21:11:33 -0400278 DeviceID: "onu2",
279 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
280 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
281 },
khenaidood20a5852018-10-22 22:09:55 -0400282 {
khenaidoo89b0e942018-10-21 21:11:33 -0400283 DeviceID: "olt",
284 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
285 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
286 },
287 }
288 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400289 {
khenaidoo89b0e942018-10-21 21:11:33 -0400290 DeviceID: "onu3",
291 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
292 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
293 },
khenaidood20a5852018-10-22 22:09:55 -0400294 {
khenaidoo89b0e942018-10-21 21:11:33 -0400295 DeviceID: "olt",
296 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
297 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
298 },
299 }
300 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400301 {
khenaidoo89b0e942018-10-21 21:11:33 -0400302 DeviceID: "onu4",
303 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
304 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
305 },
khenaidood20a5852018-10-22 22:09:55 -0400306 {
khenaidoo89b0e942018-10-21 21:11:33 -0400307 DeviceID: "olt",
308 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
309 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
310 },
311 }
312
313 // DOWNSTREAM NEXT TABLE BASED
314
315 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400316 {
khenaidoo89b0e942018-10-21 21:11:33 -0400317 DeviceID: "olt",
318 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
319 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
320 },
khenaidood20a5852018-10-22 22:09:55 -0400321 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400322 }
323
324 tfd.routes[graph.OFPortLink{Ingress: 0, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400325 {}, // 1st hop is wildcard
326 {
khenaidoo89b0e942018-10-21 21:11:33 -0400327 DeviceID: "olt",
328 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
329 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
330 },
331 }
332
333 // DEFAULT RULES
334
335 tfd.defaultRules = fu.NewDeviceRules()
336 fg := fu.NewFlowsAndGroups()
npujar1d86a522019-11-14 17:11:16 +0530337 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400338 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400339 fu.InPort(2),
340 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400341 },
342 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400343 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
344 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400345 },
346 }
khenaidoo68c930b2019-05-13 11:46:51 -0400347 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400348 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
349
350 fg = fu.NewFlowsAndGroups()
351 fa = &fu.FlowArgs{
352 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400353 fu.InPort(2),
354 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400355 },
356 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400357 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
358 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400359 },
360 }
khenaidoo68c930b2019-05-13 11:46:51 -0400361 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400362 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
363
364 fg = fu.NewFlowsAndGroups()
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) | 103)),
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("onu3", 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) | 104)),
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("onu4", fg)
391
392 //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 -0400393 tfd.deviceGraph = graph.NewDeviceGraph("ldid", tfd.getDeviceHelper)
khenaidoo89b0e942018-10-21 21:11:33 -0400394 tfd.deviceGraph.RootPorts = make(map[uint32]uint32)
395 tfd.deviceGraph.RootPorts[10] = 10
396
397 tfd.fd = NewFlowDecomposer(tfd.dMgr)
398
399 return &tfd
400}
401
npujar467fe752020-01-16 20:17:45 +0530402func (tfd *testFlowDecomposer) getDeviceHelper(ctx context.Context, deviceID string) (*voltha.Device, error) {
403 return tfd.dMgr.GetDevice(ctx, deviceID)
khenaidoo89b0e942018-10-21 21:11:33 -0400404}
405
npujar1d86a522019-11-14 17:11:16 +0530406func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400407 return ""
408}
409
khenaidoo6e55d9e2019-12-12 18:26:26 -0500410func (tfd *testFlowDecomposer) GetLogicalDevice() *voltha.LogicalDevice {
411 return nil
khenaidoo89b0e942018-10-21 21:11:33 -0400412}
413
414func (tfd *testFlowDecomposer) GetDeviceGraph() *graph.DeviceGraph {
415 return tfd.deviceGraph
416}
417
418func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
419 return tfd.defaultRules
420}
421
422func (tfd *testFlowDecomposer) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
423 lPorts := make([]uint32, 0)
424 var exclPort uint32
425 if len(excludePort) == 1 {
426 exclPort = excludePort[0]
427 }
khenaidood20a5852018-10-22 22:09:55 -0400428 for portno := range tfd.logicalPorts {
khenaidoo89b0e942018-10-21 21:11:33 -0400429 if portno != exclPort {
430 lPorts = append(lPorts, portno)
431 }
432 }
433 return lPorts
434}
435
khenaidoo19d7b632018-10-30 10:49:50 -0400436func (tfd *testFlowDecomposer) GetRoute(ingressPortNo uint32, egressPortNo uint32) []graph.RouteHop {
khenaidoo89b0e942018-10-21 21:11:33 -0400437 var portLink graph.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400438 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400439 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400440 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400441 portLink.Egress = 10
442 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400443 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400444 }
khenaidoo19d7b632018-10-30 10:49:50 -0400445 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400446 portLink.Ingress = 0
447 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400448 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400449 }
450 for key, val := range tfd.routes {
451 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
452 return val
453 }
454 }
455 return nil
456}
457
Esin Karaman09959ae2019-11-29 13:59:58 +0000458func (tfd *testFlowDecomposer) GetNNIPorts() []uint32 {
459 nniPorts := make([]uint32, 0)
460 for portNo, nni := range tfd.logicalPortsNo {
461 if nni {
462 nniPorts = append(nniPorts, portNo)
463 }
464 }
465 return nniPorts
466}
467
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400468func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
469
npujar1d86a522019-11-14 17:11:16 +0530470 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400471 KV: fu.OfpFlowModArgs{"priority": 1000},
472 MatchFields: []*ofp.OfpOxmOfbField{
473 fu.InPort(1),
474 fu.VlanVid(50),
475 fu.EthType(0x888e),
476 },
477 Actions: []*ofp.OfpAction{
478 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
479 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
480 },
481 }
482
483 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
484 groups := ofp.FlowGroups{}
485 tfd := newTestFlowDecomposer(newTestDeviceManager())
486
npujar467fe752020-01-16 20:17:45 +0530487 deviceRules := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400488 onu1FlowAndGroup := deviceRules.Rules["onu1"]
489 oltFlowAndGroup := deviceRules.Rules["olt"]
490 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
491 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
492 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
493
npujar1d86a522019-11-14 17:11:16 +0530494 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400495 KV: fu.OfpFlowModArgs{"priority": 1000},
496 MatchFields: []*ofp.OfpOxmOfbField{
497 fu.InPort(1),
498 fu.TunnelId(uint64(1)),
499 fu.VlanVid(50),
500 fu.EthType(0x888e),
501 },
502 Actions: []*ofp.OfpAction{
503 fu.PushVlan(0x8100),
504 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
505 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
506 },
507 }
508 expectedOltFlow := fu.MkFlowStat(faParent)
509 derivedFlow := oltFlowAndGroup.GetFlow(0)
510 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
511
npujar1d86a522019-11-14 17:11:16 +0530512 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400513 KV: fu.OfpFlowModArgs{"priority": 1000},
514 MatchFields: []*ofp.OfpOxmOfbField{
515 fu.InPort(2),
516 fu.TunnelId(uint64(1)),
517 fu.EthType(0x888e),
518 },
519 Actions: []*ofp.OfpAction{
520 fu.PushVlan(0x8100),
521 fu.SetField(fu.VlanVid(50)),
522 fu.Output(1),
523 },
524 }
525 expectedOnuFlow := fu.MkFlowStat(faChild)
526 derivedFlow = onu1FlowAndGroup.GetFlow(0)
527 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
528}
529
530func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
531
npujar1d86a522019-11-14 17:11:16 +0530532 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400533 KV: fu.OfpFlowModArgs{"priority": 1000},
534 MatchFields: []*ofp.OfpOxmOfbField{
535 fu.InPort(1),
536 fu.VlanVid(0),
537 fu.EthType(0x888e),
538 },
539 Actions: []*ofp.OfpAction{
540 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
541 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
542 },
543 }
544
545 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
546 groups := ofp.FlowGroups{}
547 tfd := newTestFlowDecomposer(newTestDeviceManager())
548
npujar467fe752020-01-16 20:17:45 +0530549 deviceRules := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400550 onu1FlowAndGroup := deviceRules.Rules["onu1"]
551 oltFlowAndGroup := deviceRules.Rules["olt"]
552 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
553 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
554 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
555
npujar1d86a522019-11-14 17:11:16 +0530556 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400557 KV: fu.OfpFlowModArgs{"priority": 1000},
558 MatchFields: []*ofp.OfpOxmOfbField{
559 fu.InPort(1),
560 fu.TunnelId(uint64(1)),
561 fu.VlanVid(0),
562 fu.EthType(0x888e),
563 },
564 Actions: []*ofp.OfpAction{
565 fu.PushVlan(0x8100),
566 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
567 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
568 },
569 }
570 expectedOltFlow := fu.MkFlowStat(faParent)
571 derivedFlow := oltFlowAndGroup.GetFlow(0)
572 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
573
npujar1d86a522019-11-14 17:11:16 +0530574 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400575 KV: fu.OfpFlowModArgs{"priority": 1000},
576 MatchFields: []*ofp.OfpOxmOfbField{
577 fu.InPort(2),
578 fu.TunnelId(uint64(1)),
579 fu.EthType(0x888e),
580 },
581 Actions: []*ofp.OfpAction{
582 fu.PushVlan(0x8100),
583 fu.SetField(fu.VlanVid(0)),
584 fu.Output(1),
585 },
586 }
587 expectedOnuFlow := fu.MkFlowStat(faChild)
588 derivedFlow = onu1FlowAndGroup.GetFlow(0)
589 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
590}
591
592func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400593
npujar1d86a522019-11-14 17:11:16 +0530594 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400595 KV: fu.OfpFlowModArgs{"priority": 1000},
596 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400597 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400598 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400599 },
600 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400601 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
602 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400603 },
604 }
605
khenaidoo68c930b2019-05-13 11:46:51 -0400606 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400607 groups := ofp.FlowGroups{}
608 tfd := newTestFlowDecomposer(newTestDeviceManager())
609
npujar467fe752020-01-16 20:17:45 +0530610 deviceRules := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400611 onu1FlowAndGroup := deviceRules.Rules["onu1"]
612 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400613 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400614 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400615 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
616
npujar1d86a522019-11-14 17:11:16 +0530617 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400618 KV: fu.OfpFlowModArgs{"priority": 1000},
619 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400620 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400621 fu.TunnelId(uint64(1)),
622 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400623 },
624 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400625 fu.PushVlan(0x8100),
626 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
627 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400628 },
629 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400630 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400631 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400632 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400633
npujar1d86a522019-11-14 17:11:16 +0530634 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400635 KV: fu.OfpFlowModArgs{"priority": 1000},
636 MatchFields: []*ofp.OfpOxmOfbField{
637 fu.InPort(2),
638 fu.TunnelId(uint64(1)),
639 fu.EthType(0x888e),
640 },
641 Actions: []*ofp.OfpAction{
642 fu.Output(1),
643 },
644 }
645 expectedOnuFlow := fu.MkFlowStat(faChild)
646 derivedFlow = onu1FlowAndGroup.GetFlow(0)
647 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400648}
649
650func TestDhcpReRouteRuleDecomposition(t *testing.T) {
651
npujar1d86a522019-11-14 17:11:16 +0530652 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400653 KV: fu.OfpFlowModArgs{"priority": 1000},
654 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400655 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400656 fu.EthType(0x0800),
657 fu.Ipv4Dst(0xffffffff),
658 fu.IpProto(17),
659 fu.UdpSrc(68),
660 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400661 },
662 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400663 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400664 },
665 }
666
khenaidoo68c930b2019-05-13 11:46:51 -0400667 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400668 groups := ofp.FlowGroups{}
669 tfd := newTestFlowDecomposer(newTestDeviceManager())
670
npujar467fe752020-01-16 20:17:45 +0530671 deviceRules := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400672 onu1FlowAndGroup := deviceRules.Rules["onu1"]
673 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400674 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
675 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400676 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400677 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
678
npujar1d86a522019-11-14 17:11:16 +0530679 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400680 KV: fu.OfpFlowModArgs{"priority": 1000},
681 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400682 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400683 fu.TunnelId(uint64(1)),
684 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.PushVlan(0x8100),
692 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
693 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400694 },
695 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400696 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400697 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400698 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400699
npujar1d86a522019-11-14 17:11:16 +0530700 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400701 KV: fu.OfpFlowModArgs{"priority": 1000},
702 MatchFields: []*ofp.OfpOxmOfbField{
703 fu.InPort(2),
704 fu.TunnelId(uint64(1)),
705 fu.EthType(0x0800),
706 fu.Ipv4Dst(0xffffffff),
707 fu.IpProto(17),
708 fu.UdpSrc(68),
709 fu.UdpDst(67),
710 },
711 Actions: []*ofp.OfpAction{
712 fu.Output(1),
713 },
714 }
715 expectedOnuFlow := fu.MkFlowStat(faChild)
716 derivedFlow = onu1FlowAndGroup.GetFlow(0)
717 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400718}
719
Humera Kouser4ff89012019-08-25 19:01:51 -0400720func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530721 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400722 KV: fu.OfpFlowModArgs{"priority": 1000},
723 MatchFields: []*ofp.OfpOxmOfbField{
724 fu.InPort(10),
725 fu.EthType(0x88CC),
726 },
727 Actions: []*ofp.OfpAction{
728 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
729 },
730 }
731
732 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
733 groups := ofp.FlowGroups{}
734 tfd := newTestFlowDecomposer(newTestDeviceManager())
npujar467fe752020-01-16 20:17:45 +0530735 deviceRules := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
Humera Kouser4ff89012019-08-25 19:01:51 -0400736 onu1FlowAndGroup := deviceRules.Rules["onu1"]
737 oltFlowAndGroup := deviceRules.Rules["olt"]
738 assert.Nil(t, onu1FlowAndGroup)
739 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
740 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
741
742 fa = &fu.FlowArgs{
743 KV: fu.OfpFlowModArgs{"priority": 1000},
744 MatchFields: []*ofp.OfpOxmOfbField{
745 fu.InPort(2),
746 fu.EthType(0x88CC),
747 },
748 Actions: []*ofp.OfpAction{
749 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
750 },
751 }
752 expectedOltFlow := fu.MkFlowStat(fa)
753 derivedFlow := oltFlowAndGroup.GetFlow(0)
754 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
755}
756
khenaidood20a5852018-10-22 22:09:55 -0400757func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530758 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400759 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400760 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400761 fu.InPort(1),
762 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
763 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400764 },
765 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400766 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400767 },
768 }
769
npujar1d86a522019-11-14 17:11:16 +0530770 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400771 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400772 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400773 fu.InPort(1),
774 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
775 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400776 },
777 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400778 fu.PushVlan(0x8100),
779 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
780 fu.SetField(fu.VlanPcp(0)),
781 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400782 },
783 }
784
khenaidoo68c930b2019-05-13 11:46:51 -0400785 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400786 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
787 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
788 Data: &ofp.OfpInstruction_GotoTable{
789 GotoTable: &ofp.OfpInstructionGotoTable{
790 TableId: 1,
791 },
792 }}}
793
khenaidood20a5852018-10-22 22:09:55 -0400794 groups := ofp.FlowGroups{}
795 tfd := newTestFlowDecomposer(newTestDeviceManager())
796
npujar467fe752020-01-16 20:17:45 +0530797 deviceRules := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400798 onu1FlowAndGroup := deviceRules.Rules["onu1"]
799 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400800 assert.NotNil(t, onu1FlowAndGroup)
801 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400802 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400803 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
804 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
805 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
806
807 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400808 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400809 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400810 fu.InPort(2),
811 fu.TunnelId(uint64(1)),
812 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
813 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400814 },
815 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400816 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
817 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400818 },
819 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400820
khenaidoo3306c992019-05-24 16:57:35 -0400821 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400822 // Form the expected flow
823 expectedOnu1Flow := fu.MkFlowStat(fa)
824 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
825 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
826 Data: &ofp.OfpInstruction_Actions{
827 Actions: &ofp.OfpInstructionActions{
828 Actions: []*ofp.OfpAction{{
829 Type: 0,
830 Action: &ofp.OfpAction_Output{
831 Output: &ofp.OfpActionOutput{
832 Port: 1,
833 MaxLen: 65509,
834 },
835 }}}}}}}
836
837 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400838 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
839
840 fa = &fu.FlowArgs{
841 KV: fu.OfpFlowModArgs{"priority": 500},
842 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400843 fu.InPort(1),
844 fu.TunnelId(uint64(1)),
845 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
846 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400847 },
848 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400849 fu.PushVlan(0x8100),
850 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
851 fu.SetField(fu.VlanPcp(0)),
852 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400853 },
854 }
khenaidoo68c930b2019-05-13 11:46:51 -0400855 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -0400856 derivedFlow = oltFlowAndGroup.GetFlow(0)
857 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
858}
859
860func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Manikkaraj kb1a10922019-07-29 12:10:34 -0400861 log.Debugf("Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530862 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400863 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400864 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400865 fu.InPort(10),
866 fu.Metadata_ofp((1000 << 32) | 1),
867 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400868 },
869 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400870 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400871 },
872 }
873
npujar1d86a522019-11-14 17:11:16 +0530874 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400875 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400876 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400877 fu.InPort(10),
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.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
883 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400884 },
885 }
886
khenaidoo68c930b2019-05-13 11:46:51 -0400887 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa1), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400888 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
889 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
890 Data: &ofp.OfpInstruction_GotoTable{
891 GotoTable: &ofp.OfpInstructionGotoTable{
892 TableId: 1,
893 },
894 }}}
895
khenaidood20a5852018-10-22 22:09:55 -0400896 groups := ofp.FlowGroups{}
897 tfd := newTestFlowDecomposer(newTestDeviceManager())
898
npujar467fe752020-01-16 20:17:45 +0530899 deviceRules := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400900
khenaidood20a5852018-10-22 22:09:55 -0400901 onu1FlowAndGroup := deviceRules.Rules["onu1"]
902 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400903 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400904 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
905 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
906 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
907
908 fa1 = &fu.FlowArgs{
909 KV: fu.OfpFlowModArgs{"priority": 500},
910 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400911 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400912 fu.TunnelId(uint64(10)),
913 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400914 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400915 },
916 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400917 fu.PopVlan(),
918 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400919 },
920 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400921
khenaidood20a5852018-10-22 22:09:55 -0400922 derivedFlow := oltFlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400923 expectedOltFlow := fu.MkFlowStat(fa1)
924 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
925 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
926 Data: &ofp.OfpInstruction_Actions{
927 Actions: &ofp.OfpInstructionActions{
928 Actions: []*ofp.OfpAction{{
929 Type: 0,
930 Action: &ofp.OfpAction_Output{
931 Output: &ofp.OfpActionOutput{
932 Port: 1,
933 MaxLen: 65509,
934 },
935 }}}}}}}
936 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400937 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
938
939 fa1 = &fu.FlowArgs{
940 KV: fu.OfpFlowModArgs{"priority": 500},
941 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400942 fu.InPort(1),
943 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
944 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400945 },
946 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400947 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
948 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400949 },
950 }
khenaidoo68c930b2019-05-13 11:46:51 -0400951 expectedOnu1Flow := fu.MkFlowStat(fa1)
khenaidoo3306c992019-05-24 16:57:35 -0400952 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400953 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
954}
955
956func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530957 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -0400958 KV: fu.OfpFlowModArgs{"priority": 500},
959 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400960 fu.InPort(10),
961 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
962 fu.VlanPcp(0),
963 fu.EthType(0x800),
964 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400965 },
966 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400967 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -0400968 },
969 }
970
npujar1d86a522019-11-14 17:11:16 +0530971 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -0400972 GroupId: 10,
973 Buckets: []*ofp.OfpBucket{
974 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400975 fu.PopVlan(),
976 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400977 },
978 },
979 },
980 }
981
khenaidoo68c930b2019-05-13 11:46:51 -0400982 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
983 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
khenaidood20a5852018-10-22 22:09:55 -0400984 tfd := newTestFlowDecomposer(newTestDeviceManager())
985
npujar467fe752020-01-16 20:17:45 +0530986 deviceRules := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400987 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -0400988 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
989 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
990
991 fa = &fu.FlowArgs{
992 KV: fu.OfpFlowModArgs{"priority": 500},
993 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +0000994 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -0400995 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
996 fu.VlanPcp(0),
997 fu.EthType(0x800),
998 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400999 },
1000 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001001 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001002 },
1003 }
khenaidoo68c930b2019-05-13 11:46:51 -04001004 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -04001005 derivedFlow := oltFlowAndGroup.GetFlow(0)
1006 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001007}