blob: a24765eaf1778cde0247c08bba17984a358e9d8c [file] [log] [blame]
khenaidoo89b0e942018-10-21 21:11:33 -04001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package flow_decomposition
17
18import (
19 "errors"
khenaidoo89b0e942018-10-21 21:11:33 -040020 "github.com/opencord/voltha-go/rw_core/graph"
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
102func (tdm *testDeviceManager) GetDevice(deviceId string) (*voltha.Device, error) {
103 if d, ok := tdm.devices[deviceId]; ok {
104 return d, nil
105 }
khenaidood20a5852018-10-22 22:09:55 -0400106 return nil, errors.New("ABSENT.")
khenaidoo89b0e942018-10-21 21:11:33 -0400107}
khenaidoo19d7b632018-10-30 10:49:50 -0400108func (tdm *testDeviceManager) IsRootDevice(deviceId string) (bool, error) {
109 if d, ok := tdm.devices[deviceId]; ok {
110 return d.Root, nil
111 }
112 return false, errors.New("ABSENT.")
113}
khenaidoo89b0e942018-10-21 21:11:33 -0400114
115type testFlowDecomposer struct {
116 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}
123
124func newTestFlowDecomposer(deviceMgr *testDeviceManager) *testFlowDecomposer {
125 var tfd testFlowDecomposer
126 tfd.dMgr = deviceMgr
127
128 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
129 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
130 // port
131 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
132 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
133 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
134 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
135 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
136
137 tfd.routes = make(map[graph.OFPortLink][]graph.RouteHop)
138
139 //DOWNSTREAM ROUTES
140
141 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 1}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400142 {
khenaidoo89b0e942018-10-21 21:11:33 -0400143 DeviceID: "olt",
144 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
145 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
146 },
khenaidood20a5852018-10-22 22:09:55 -0400147 {
khenaidoo89b0e942018-10-21 21:11:33 -0400148 DeviceID: "onu1",
149 Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
150 Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
151 },
152 }
153
154 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 2}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400155 {
khenaidoo89b0e942018-10-21 21:11:33 -0400156 DeviceID: "olt",
157 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
158 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
159 },
khenaidood20a5852018-10-22 22:09:55 -0400160 {
khenaidoo89b0e942018-10-21 21:11:33 -0400161 DeviceID: "onu2",
162 Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
163 Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
164 },
165 }
166 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 3}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400167 {
khenaidoo89b0e942018-10-21 21:11:33 -0400168 DeviceID: "olt",
169 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
170 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
171 },
khenaidood20a5852018-10-22 22:09:55 -0400172 {
khenaidoo89b0e942018-10-21 21:11:33 -0400173 DeviceID: "onu3",
174 Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
175 Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
176 },
177 }
178 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 4}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400179 {
khenaidoo89b0e942018-10-21 21:11:33 -0400180 DeviceID: "olt",
181 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
182 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
183 },
khenaidood20a5852018-10-22 22:09:55 -0400184 {
khenaidoo89b0e942018-10-21 21:11:33 -0400185 DeviceID: "onu4",
186 Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
187 Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
188 },
189 }
Humera Kouser4ff89012019-08-25 19:01:51 -0400190 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 10}] = []graph.RouteHop{
191 {
192 DeviceID: "olt",
193 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
194 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
195 },
196 {
197 DeviceID: "olt",
198 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
199 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
200 },
201 }
khenaidoo89b0e942018-10-21 21:11:33 -0400202
203 //UPSTREAM DATA PLANE
204
205 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400206 {
khenaidoo89b0e942018-10-21 21:11:33 -0400207 DeviceID: "onu1",
208 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
209 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
210 },
khenaidood20a5852018-10-22 22:09:55 -0400211 {
khenaidoo89b0e942018-10-21 21:11:33 -0400212 DeviceID: "olt",
213 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
214 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
215 },
216 }
217 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400218 {
khenaidoo89b0e942018-10-21 21:11:33 -0400219 DeviceID: "onu2",
220 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
221 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
222 },
khenaidood20a5852018-10-22 22:09:55 -0400223 {
khenaidoo89b0e942018-10-21 21:11:33 -0400224 DeviceID: "olt",
225 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
226 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
227 },
228 }
229 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400230 {
khenaidoo89b0e942018-10-21 21:11:33 -0400231 DeviceID: "onu3",
232 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
233 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
234 },
khenaidood20a5852018-10-22 22:09:55 -0400235 {
khenaidoo89b0e942018-10-21 21:11:33 -0400236 DeviceID: "olt",
237 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
238 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
239 },
240 }
241 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400242 {
khenaidoo89b0e942018-10-21 21:11:33 -0400243 DeviceID: "onu4",
244 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
245 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
246 },
khenaidood20a5852018-10-22 22:09:55 -0400247 {
khenaidoo89b0e942018-10-21 21:11:33 -0400248 DeviceID: "olt",
249 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
250 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
251 },
252 }
253
254 //UPSTREAM NEXT TABLE BASED
255
256 // openflow port 0 means absence of a port - go/protobuf interpretation
257 tfd.routes[graph.OFPortLink{Ingress: 1, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400258 {
khenaidoo89b0e942018-10-21 21:11:33 -0400259 DeviceID: "onu1",
260 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
261 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
262 },
khenaidood20a5852018-10-22 22:09:55 -0400263 {
khenaidoo89b0e942018-10-21 21:11:33 -0400264 DeviceID: "olt",
265 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
266 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
267 },
268 }
269 tfd.routes[graph.OFPortLink{Ingress: 2, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400270 {
khenaidoo89b0e942018-10-21 21:11:33 -0400271 DeviceID: "onu2",
272 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
273 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
274 },
khenaidood20a5852018-10-22 22:09:55 -0400275 {
khenaidoo89b0e942018-10-21 21:11:33 -0400276 DeviceID: "olt",
277 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
278 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
279 },
280 }
281 tfd.routes[graph.OFPortLink{Ingress: 3, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400282 {
khenaidoo89b0e942018-10-21 21:11:33 -0400283 DeviceID: "onu3",
284 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
285 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
286 },
khenaidood20a5852018-10-22 22:09:55 -0400287 {
khenaidoo89b0e942018-10-21 21:11:33 -0400288 DeviceID: "olt",
289 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
290 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
291 },
292 }
293 tfd.routes[graph.OFPortLink{Ingress: 4, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400294 {
khenaidoo89b0e942018-10-21 21:11:33 -0400295 DeviceID: "onu4",
296 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
297 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
298 },
khenaidood20a5852018-10-22 22:09:55 -0400299 {
khenaidoo89b0e942018-10-21 21:11:33 -0400300 DeviceID: "olt",
301 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
302 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
303 },
304 }
305
306 // DOWNSTREAM NEXT TABLE BASED
307
308 tfd.routes[graph.OFPortLink{Ingress: 10, Egress: 0}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400309 {
khenaidoo89b0e942018-10-21 21:11:33 -0400310 DeviceID: "olt",
311 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
312 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
313 },
khenaidood20a5852018-10-22 22:09:55 -0400314 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400315 }
316
317 tfd.routes[graph.OFPortLink{Ingress: 0, Egress: 10}] = []graph.RouteHop{
khenaidood20a5852018-10-22 22:09:55 -0400318 {}, // 1st hop is wildcard
319 {
khenaidoo89b0e942018-10-21 21:11:33 -0400320 DeviceID: "olt",
321 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
322 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
323 },
324 }
325
326 // DEFAULT RULES
327
328 tfd.defaultRules = fu.NewDeviceRules()
329 fg := fu.NewFlowsAndGroups()
330 var fa *fu.FlowArgs
331 fa = &fu.FlowArgs{
332 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
396func (tfd *testFlowDecomposer) getDeviceHelper(deviceId string) (*voltha.Device, error) {
397 return tfd.dMgr.GetDevice(deviceId)
398}
399
400func (tfd *testFlowDecomposer) GetDeviceLogicalId() string {
401 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
454 var fa *fu.FlowArgs
455 fa = &fu.FlowArgs{
456 KV: fu.OfpFlowModArgs{"priority": 1000},
457 MatchFields: []*ofp.OfpOxmOfbField{
458 fu.InPort(1),
459 fu.VlanVid(50),
460 fu.EthType(0x888e),
461 },
462 Actions: []*ofp.OfpAction{
463 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
464 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
465 },
466 }
467
468 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
469 groups := ofp.FlowGroups{}
470 tfd := newTestFlowDecomposer(newTestDeviceManager())
471
472 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
473 onu1FlowAndGroup := deviceRules.Rules["onu1"]
474 oltFlowAndGroup := deviceRules.Rules["olt"]
475 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
476 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
477 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
478
479 var faParent *fu.FlowArgs
480 faParent = &fu.FlowArgs{
481 KV: fu.OfpFlowModArgs{"priority": 1000},
482 MatchFields: []*ofp.OfpOxmOfbField{
483 fu.InPort(1),
484 fu.TunnelId(uint64(1)),
485 fu.VlanVid(50),
486 fu.EthType(0x888e),
487 },
488 Actions: []*ofp.OfpAction{
489 fu.PushVlan(0x8100),
490 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
491 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
492 },
493 }
494 expectedOltFlow := fu.MkFlowStat(faParent)
495 derivedFlow := oltFlowAndGroup.GetFlow(0)
496 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
497
498 var faChild *fu.FlowArgs
499 faChild = &fu.FlowArgs{
500 KV: fu.OfpFlowModArgs{"priority": 1000},
501 MatchFields: []*ofp.OfpOxmOfbField{
502 fu.InPort(2),
503 fu.TunnelId(uint64(1)),
504 fu.EthType(0x888e),
505 },
506 Actions: []*ofp.OfpAction{
507 fu.PushVlan(0x8100),
508 fu.SetField(fu.VlanVid(50)),
509 fu.Output(1),
510 },
511 }
512 expectedOnuFlow := fu.MkFlowStat(faChild)
513 derivedFlow = onu1FlowAndGroup.GetFlow(0)
514 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
515}
516
517func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
518
519 var fa *fu.FlowArgs
520 fa = &fu.FlowArgs{
521 KV: fu.OfpFlowModArgs{"priority": 1000},
522 MatchFields: []*ofp.OfpOxmOfbField{
523 fu.InPort(1),
524 fu.VlanVid(0),
525 fu.EthType(0x888e),
526 },
527 Actions: []*ofp.OfpAction{
528 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
529 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
530 },
531 }
532
533 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
534 groups := ofp.FlowGroups{}
535 tfd := newTestFlowDecomposer(newTestDeviceManager())
536
537 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
538 onu1FlowAndGroup := deviceRules.Rules["onu1"]
539 oltFlowAndGroup := deviceRules.Rules["olt"]
540 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
541 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
542 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
543
544 var faParent *fu.FlowArgs
545 faParent = &fu.FlowArgs{
546 KV: fu.OfpFlowModArgs{"priority": 1000},
547 MatchFields: []*ofp.OfpOxmOfbField{
548 fu.InPort(1),
549 fu.TunnelId(uint64(1)),
550 fu.VlanVid(0),
551 fu.EthType(0x888e),
552 },
553 Actions: []*ofp.OfpAction{
554 fu.PushVlan(0x8100),
555 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
556 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
557 },
558 }
559 expectedOltFlow := fu.MkFlowStat(faParent)
560 derivedFlow := oltFlowAndGroup.GetFlow(0)
561 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
562
563 var faChild *fu.FlowArgs
564 faChild = &fu.FlowArgs{
565 KV: fu.OfpFlowModArgs{"priority": 1000},
566 MatchFields: []*ofp.OfpOxmOfbField{
567 fu.InPort(2),
568 fu.TunnelId(uint64(1)),
569 fu.EthType(0x888e),
570 },
571 Actions: []*ofp.OfpAction{
572 fu.PushVlan(0x8100),
573 fu.SetField(fu.VlanVid(0)),
574 fu.Output(1),
575 },
576 }
577 expectedOnuFlow := fu.MkFlowStat(faChild)
578 derivedFlow = onu1FlowAndGroup.GetFlow(0)
579 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
580}
581
582func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400583
584 var fa *fu.FlowArgs
585 fa = &fu.FlowArgs{
586 KV: fu.OfpFlowModArgs{"priority": 1000},
587 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400588 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400589 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400590 },
591 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400592 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
593 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400594 },
595 }
596
khenaidoo68c930b2019-05-13 11:46:51 -0400597 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400598 groups := ofp.FlowGroups{}
599 tfd := newTestFlowDecomposer(newTestDeviceManager())
600
khenaidoo3306c992019-05-24 16:57:35 -0400601 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400602 onu1FlowAndGroup := deviceRules.Rules["onu1"]
603 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400604 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400605 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400606 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
607
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400608 var faParent *fu.FlowArgs
609 faParent = &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400610 KV: fu.OfpFlowModArgs{"priority": 1000},
611 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400612 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400613 fu.TunnelId(uint64(1)),
614 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400615 },
616 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400617 fu.PushVlan(0x8100),
618 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
619 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400620 },
621 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400622 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400623 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400624 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400625
626 var faChild *fu.FlowArgs
627 faChild = &fu.FlowArgs{
628 KV: fu.OfpFlowModArgs{"priority": 1000},
629 MatchFields: []*ofp.OfpOxmOfbField{
630 fu.InPort(2),
631 fu.TunnelId(uint64(1)),
632 fu.EthType(0x888e),
633 },
634 Actions: []*ofp.OfpAction{
635 fu.Output(1),
636 },
637 }
638 expectedOnuFlow := fu.MkFlowStat(faChild)
639 derivedFlow = onu1FlowAndGroup.GetFlow(0)
640 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400641}
642
643func TestDhcpReRouteRuleDecomposition(t *testing.T) {
644
645 var fa *fu.FlowArgs
646 fa = &fu.FlowArgs{
647 KV: fu.OfpFlowModArgs{"priority": 1000},
648 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400649 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400650 fu.EthType(0x0800),
651 fu.Ipv4Dst(0xffffffff),
652 fu.IpProto(17),
653 fu.UdpSrc(68),
654 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400655 },
656 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400657 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400658 },
659 }
660
khenaidoo68c930b2019-05-13 11:46:51 -0400661 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400662 groups := ofp.FlowGroups{}
663 tfd := newTestFlowDecomposer(newTestDeviceManager())
664
khenaidoo3306c992019-05-24 16:57:35 -0400665 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400666 onu1FlowAndGroup := deviceRules.Rules["onu1"]
667 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400668 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
669 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400670 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400671 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
672
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400673 var faParent *fu.FlowArgs
674 faParent = &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400675 KV: fu.OfpFlowModArgs{"priority": 1000},
676 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400677 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400678 fu.TunnelId(uint64(1)),
679 fu.EthType(0x0800),
680 fu.Ipv4Dst(0xffffffff),
681 fu.IpProto(17),
682 fu.UdpSrc(68),
683 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400684 },
685 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400686 fu.PushVlan(0x8100),
687 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
688 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400689 },
690 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400691 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400692 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400693 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400694
695 var faChild *fu.FlowArgs
696 faChild = &fu.FlowArgs{
697 KV: fu.OfpFlowModArgs{"priority": 1000},
698 MatchFields: []*ofp.OfpOxmOfbField{
699 fu.InPort(2),
700 fu.TunnelId(uint64(1)),
701 fu.EthType(0x0800),
702 fu.Ipv4Dst(0xffffffff),
703 fu.IpProto(17),
704 fu.UdpSrc(68),
705 fu.UdpDst(67),
706 },
707 Actions: []*ofp.OfpAction{
708 fu.Output(1),
709 },
710 }
711 expectedOnuFlow := fu.MkFlowStat(faChild)
712 derivedFlow = onu1FlowAndGroup.GetFlow(0)
713 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400714}
715
Humera Kouser4ff89012019-08-25 19:01:51 -0400716func TestLldpReRouteRuleDecomposition(t *testing.T) {
717 var fa *fu.FlowArgs
718 fa = &fu.FlowArgs{
719 KV: fu.OfpFlowModArgs{"priority": 1000},
720 MatchFields: []*ofp.OfpOxmOfbField{
721 fu.InPort(10),
722 fu.EthType(0x88CC),
723 },
724 Actions: []*ofp.OfpAction{
725 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
726 },
727 }
728
729 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
730 groups := ofp.FlowGroups{}
731 tfd := newTestFlowDecomposer(newTestDeviceManager())
732 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
733 onu1FlowAndGroup := deviceRules.Rules["onu1"]
734 oltFlowAndGroup := deviceRules.Rules["olt"]
735 assert.Nil(t, onu1FlowAndGroup)
736 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
737 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
738
739 fa = &fu.FlowArgs{
740 KV: fu.OfpFlowModArgs{"priority": 1000},
741 MatchFields: []*ofp.OfpOxmOfbField{
742 fu.InPort(2),
743 fu.EthType(0x88CC),
744 },
745 Actions: []*ofp.OfpAction{
746 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
747 },
748 }
749 expectedOltFlow := fu.MkFlowStat(fa)
750 derivedFlow := oltFlowAndGroup.GetFlow(0)
751 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
752}
753
khenaidood20a5852018-10-22 22:09:55 -0400754func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
khenaidood20a5852018-10-22 22:09:55 -0400755 var fa *fu.FlowArgs
756 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400757 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400758 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400759 fu.InPort(1),
760 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
761 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400762 },
763 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400764 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400765 },
766 }
767
768 var fa2 *fu.FlowArgs
769 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")
khenaidood20a5852018-10-22 22:09:55 -0400861 var fa1 *fu.FlowArgs
862 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
874 var fa2 *fu.FlowArgs
875 fa2 = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400876 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400877 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400878 fu.InPort(10),
879 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
880 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400881 },
882 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400883 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
884 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400885 },
886 }
887
khenaidoo68c930b2019-05-13 11:46:51 -0400888 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa1), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400889 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
890 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
891 Data: &ofp.OfpInstruction_GotoTable{
892 GotoTable: &ofp.OfpInstructionGotoTable{
893 TableId: 1,
894 },
895 }}}
896
khenaidood20a5852018-10-22 22:09:55 -0400897 groups := ofp.FlowGroups{}
898 tfd := newTestFlowDecomposer(newTestDeviceManager())
899
khenaidoo3306c992019-05-24 16:57:35 -0400900 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400901
khenaidood20a5852018-10-22 22:09:55 -0400902 onu1FlowAndGroup := deviceRules.Rules["onu1"]
903 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400904 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400905 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
906 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
907 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
908
909 fa1 = &fu.FlowArgs{
910 KV: fu.OfpFlowModArgs{"priority": 500},
911 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400912 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400913 fu.TunnelId(uint64(10)),
914 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400915 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400916 },
917 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400918 fu.PopVlan(),
919 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400920 },
921 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400922
khenaidood20a5852018-10-22 22:09:55 -0400923 derivedFlow := oltFlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400924 expectedOltFlow := fu.MkFlowStat(fa1)
925 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
926 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
927 Data: &ofp.OfpInstruction_Actions{
928 Actions: &ofp.OfpInstructionActions{
929 Actions: []*ofp.OfpAction{{
930 Type: 0,
931 Action: &ofp.OfpAction_Output{
932 Output: &ofp.OfpActionOutput{
933 Port: 1,
934 MaxLen: 65509,
935 },
936 }}}}}}}
937 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400938 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
939
940 fa1 = &fu.FlowArgs{
941 KV: fu.OfpFlowModArgs{"priority": 500},
942 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400943 fu.InPort(1),
944 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
945 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400946 },
947 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400948 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
949 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400950 },
951 }
khenaidoo68c930b2019-05-13 11:46:51 -0400952 expectedOnu1Flow := fu.MkFlowStat(fa1)
khenaidoo3306c992019-05-24 16:57:35 -0400953 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400954 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
955}
956
957func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
958 var fa *fu.FlowArgs
959 fa = &fu.FlowArgs{
960 KV: fu.OfpFlowModArgs{"priority": 500},
961 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400962 fu.InPort(10),
963 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
964 fu.VlanPcp(0),
965 fu.EthType(0x800),
966 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400967 },
968 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400969 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -0400970 },
971 }
972
973 var ga *fu.GroupArgs
974 ga = &fu.GroupArgs{
975 GroupId: 10,
976 Buckets: []*ofp.OfpBucket{
977 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400978 fu.PopVlan(),
979 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400980 },
981 },
982 },
983 }
984
khenaidoo68c930b2019-05-13 11:46:51 -0400985 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
986 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
khenaidood20a5852018-10-22 22:09:55 -0400987 tfd := newTestFlowDecomposer(newTestDeviceManager())
988
khenaidoo3306c992019-05-24 16:57:35 -0400989 deviceRules := tfd.fd.DecomposeRules(tfd, flows, groups)
khenaidood20a5852018-10-22 22:09:55 -0400990 onu1FlowAndGroup := deviceRules.Rules["onu1"]
991 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400992 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400993 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
994 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
995 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
996
997 fa = &fu.FlowArgs{
998 KV: fu.OfpFlowModArgs{"priority": 500},
999 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001000 fu.InPort(2),
1001 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1002 fu.VlanPcp(0),
1003 fu.EthType(0x800),
1004 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001005 },
1006 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001007 fu.PopVlan(),
1008 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001009 },
1010 }
khenaidoo68c930b2019-05-13 11:46:51 -04001011 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -04001012 derivedFlow := oltFlowAndGroup.GetFlow(0)
1013 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
1014
1015 fa = &fu.FlowArgs{
1016 KV: fu.OfpFlowModArgs{"priority": 500},
1017 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001018 fu.InPort(1),
1019 fu.EthType(0x800),
1020 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001021 },
1022 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001023 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -04001024 },
1025 }
khenaidoo68c930b2019-05-13 11:46:51 -04001026 expectedOnu1Flow := fu.MkFlowStat(fa)
khenaidoo3306c992019-05-24 16:57:35 -04001027 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -04001028 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
1029}