blob: 29c1a6aeecad6a8ac510c867caad8f7602831b31 [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"
khenaidooab1f7bd2019-11-14 14:00:27 -050021 "github.com/opencord/voltha-go/rw_core/mocks"
khenaidoo820197c2020-02-13 16:35:33 -050022 "github.com/opencord/voltha-go/rw_core/route"
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"
khenaidoo820197c2020-02-13 16:35:33 -050028 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/status"
khenaidoo89b0e942018-10-21 21:11:33 -040030
31 "testing"
32)
33
khenaidoo89b0e942018-10-21 21:11:33 -040034func init() {
Manikkaraj kb1a10922019-07-29 12:10:34 -040035 // Setup default logger - applies for packages that do not have specific logger set
36 if _, err := log.SetDefaultLogger(log.JSON, 0, log.Fields{"instanceId": 1}); err != nil {
37 log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
38 }
39
40 // Update all loggers (provisioned via init) with a common field
41 if err := log.UpdateAllLoggers(log.Fields{"instanceId": 1}); err != nil {
42 log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
43 }
44
45 // Update all loggers to log level specified as input parameter
46 log.SetAllLogLevel(0)
khenaidoo89b0e942018-10-21 21:11:33 -040047}
48
49type testDeviceManager struct {
khenaidooab1f7bd2019-11-14 14:00:27 -050050 mocks.DeviceManager
khenaidoo89b0e942018-10-21 21:11:33 -040051 devices map[string]*voltha.Device
52}
53
54func newTestDeviceManager() *testDeviceManager {
55 var tdm testDeviceManager
56 tdm.devices = make(map[string]*voltha.Device)
57 tdm.devices["olt"] = &voltha.Device{
58 Id: "olt",
59 Root: true,
60 ParentId: "logical_device",
61 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040062 {PortNo: 1, Label: "pon"},
63 {PortNo: 2, Label: "nni"},
khenaidoo89b0e942018-10-21 21:11:33 -040064 },
65 }
66 tdm.devices["onu1"] = &voltha.Device{
67 Id: "onu1",
68 Root: false,
69 ParentId: "olt",
70 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040071 {PortNo: 1, Label: "pon"},
72 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040073 },
74 }
75 tdm.devices["onu2"] = &voltha.Device{
76 Id: "onu2",
77 Root: false,
78 ParentId: "olt",
79 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040080 {PortNo: 1, Label: "pon"},
81 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040082 },
83 }
84 tdm.devices["onu3"] = &voltha.Device{
85 Id: "onu3",
86 Root: false,
87 ParentId: "olt",
88 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040089 {PortNo: 1, Label: "pon"},
90 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040091 },
92 }
93 tdm.devices["onu4"] = &voltha.Device{
94 Id: "onu4",
95 Root: false,
96 ParentId: "olt",
97 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040098 {PortNo: 1, Label: "pon"},
99 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -0400100 },
101 }
102 return &tdm
103}
104
npujar467fe752020-01-16 20:17:45 +0530105func (tdm *testDeviceManager) GetDevice(ctx context.Context, deviceID string) (*voltha.Device, error) {
npujar1d86a522019-11-14 17:11:16 +0530106 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo89b0e942018-10-21 21:11:33 -0400107 return d, nil
108 }
npujar1d86a522019-11-14 17:11:16 +0530109 return nil, errors.New("ABSENT")
khenaidoo89b0e942018-10-21 21:11:33 -0400110}
npujar1d86a522019-11-14 17:11:16 +0530111func (tdm *testDeviceManager) IsRootDevice(deviceID string) (bool, error) {
112 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo19d7b632018-10-30 10:49:50 -0400113 return d.Root, nil
114 }
npujar1d86a522019-11-14 17:11:16 +0530115 return false, errors.New("ABSENT")
khenaidoo19d7b632018-10-30 10:49:50 -0400116}
khenaidoo89b0e942018-10-21 21:11:33 -0400117
118type testFlowDecomposer struct {
Esin Karaman09959ae2019-11-29 13:59:58 +0000119 dMgr *testDeviceManager
120 logicalPorts map[uint32]*voltha.LogicalPort
khenaidoo820197c2020-02-13 16:35:33 -0500121 routes map[route.OFPortLink][]route.Hop
Esin Karaman09959ae2019-11-29 13:59:58 +0000122 defaultRules *fu.DeviceRules
khenaidoo820197c2020-02-13 16:35:33 -0500123 deviceRoutes *route.DeviceRoutes
Esin Karaman09959ae2019-11-29 13:59:58 +0000124 fd *FlowDecomposer
125 logicalPortsNo map[uint32]bool
khenaidoo89b0e942018-10-21 21:11:33 -0400126}
127
128func newTestFlowDecomposer(deviceMgr *testDeviceManager) *testFlowDecomposer {
129 var tfd testFlowDecomposer
130 tfd.dMgr = deviceMgr
131
132 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
Esin Karaman09959ae2019-11-29 13:59:58 +0000133 tfd.logicalPortsNo = make(map[uint32]bool)
khenaidoo89b0e942018-10-21 21:11:33 -0400134 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
135 // port
136 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
Esin Karaman09959ae2019-11-29 13:59:58 +0000137 tfd.logicalPorts[65536] = &voltha.LogicalPort{Id: "65536", DeviceId: "olt", DevicePortNo: 65536}
khenaidoo89b0e942018-10-21 21:11:33 -0400138 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
139 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
140 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
141 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
142
Esin Karaman09959ae2019-11-29 13:59:58 +0000143 tfd.logicalPortsNo[10] = false
144 tfd.logicalPortsNo[65536] = true // nni
145
khenaidoo820197c2020-02-13 16:35:33 -0500146 tfd.routes = make(map[route.OFPortLink][]route.Hop)
khenaidoo89b0e942018-10-21 21:11:33 -0400147
148 //DOWNSTREAM ROUTES
149
khenaidoo820197c2020-02-13 16:35:33 -0500150 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 1}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400151 {
khenaidoo89b0e942018-10-21 21:11:33 -0400152 DeviceID: "olt",
153 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
154 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
155 },
khenaidood20a5852018-10-22 22:09:55 -0400156 {
khenaidoo89b0e942018-10-21 21:11:33 -0400157 DeviceID: "onu1",
158 Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
159 Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
160 },
161 }
162
khenaidoo820197c2020-02-13 16:35:33 -0500163 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 2}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400164 {
khenaidoo89b0e942018-10-21 21:11:33 -0400165 DeviceID: "olt",
166 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
167 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
168 },
khenaidood20a5852018-10-22 22:09:55 -0400169 {
khenaidoo89b0e942018-10-21 21:11:33 -0400170 DeviceID: "onu2",
171 Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
172 Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
173 },
174 }
khenaidoo820197c2020-02-13 16:35:33 -0500175 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 3}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400176 {
khenaidoo89b0e942018-10-21 21:11:33 -0400177 DeviceID: "olt",
178 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
179 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
180 },
khenaidood20a5852018-10-22 22:09:55 -0400181 {
khenaidoo89b0e942018-10-21 21:11:33 -0400182 DeviceID: "onu3",
183 Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
184 Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
185 },
186 }
khenaidoo820197c2020-02-13 16:35:33 -0500187 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 4}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400188 {
khenaidoo89b0e942018-10-21 21:11:33 -0400189 DeviceID: "olt",
190 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
191 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
192 },
khenaidood20a5852018-10-22 22:09:55 -0400193 {
khenaidoo89b0e942018-10-21 21:11:33 -0400194 DeviceID: "onu4",
195 Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
196 Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
197 },
198 }
khenaidoo820197c2020-02-13 16:35:33 -0500199 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 10}] = []route.Hop{
Humera Kouser4ff89012019-08-25 19:01:51 -0400200 {
201 DeviceID: "olt",
202 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
203 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
204 },
205 {
206 DeviceID: "olt",
207 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
208 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
209 },
210 }
khenaidoo89b0e942018-10-21 21:11:33 -0400211
212 //UPSTREAM DATA PLANE
213
khenaidoo820197c2020-02-13 16:35:33 -0500214 tfd.routes[route.OFPortLink{Ingress: 1, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400215 {
khenaidoo89b0e942018-10-21 21:11:33 -0400216 DeviceID: "onu1",
217 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
218 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
219 },
khenaidood20a5852018-10-22 22:09:55 -0400220 {
khenaidoo89b0e942018-10-21 21:11:33 -0400221 DeviceID: "olt",
222 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
223 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
224 },
225 }
khenaidoo820197c2020-02-13 16:35:33 -0500226 tfd.routes[route.OFPortLink{Ingress: 2, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400227 {
khenaidoo89b0e942018-10-21 21:11:33 -0400228 DeviceID: "onu2",
229 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
230 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
231 },
khenaidood20a5852018-10-22 22:09:55 -0400232 {
khenaidoo89b0e942018-10-21 21:11:33 -0400233 DeviceID: "olt",
234 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
235 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
236 },
237 }
khenaidoo820197c2020-02-13 16:35:33 -0500238 tfd.routes[route.OFPortLink{Ingress: 3, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400239 {
khenaidoo89b0e942018-10-21 21:11:33 -0400240 DeviceID: "onu3",
241 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
242 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
243 },
khenaidood20a5852018-10-22 22:09:55 -0400244 {
khenaidoo89b0e942018-10-21 21:11:33 -0400245 DeviceID: "olt",
246 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
247 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
248 },
249 }
khenaidoo820197c2020-02-13 16:35:33 -0500250 tfd.routes[route.OFPortLink{Ingress: 4, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400251 {
khenaidoo89b0e942018-10-21 21:11:33 -0400252 DeviceID: "onu4",
253 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
254 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
255 },
khenaidood20a5852018-10-22 22:09:55 -0400256 {
khenaidoo89b0e942018-10-21 21:11:33 -0400257 DeviceID: "olt",
258 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
259 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
260 },
261 }
262
263 //UPSTREAM NEXT TABLE BASED
264
265 // openflow port 0 means absence of a port - go/protobuf interpretation
khenaidoo820197c2020-02-13 16:35:33 -0500266 tfd.routes[route.OFPortLink{Ingress: 1, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400267 {
khenaidoo89b0e942018-10-21 21:11:33 -0400268 DeviceID: "onu1",
269 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
270 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
271 },
khenaidood20a5852018-10-22 22:09:55 -0400272 {
khenaidoo89b0e942018-10-21 21:11:33 -0400273 DeviceID: "olt",
274 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
275 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
276 },
277 }
khenaidoo820197c2020-02-13 16:35:33 -0500278 tfd.routes[route.OFPortLink{Ingress: 2, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400279 {
khenaidoo89b0e942018-10-21 21:11:33 -0400280 DeviceID: "onu2",
281 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
282 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
283 },
khenaidood20a5852018-10-22 22:09:55 -0400284 {
khenaidoo89b0e942018-10-21 21:11:33 -0400285 DeviceID: "olt",
286 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
287 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
288 },
289 }
khenaidoo820197c2020-02-13 16:35:33 -0500290 tfd.routes[route.OFPortLink{Ingress: 3, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400291 {
khenaidoo89b0e942018-10-21 21:11:33 -0400292 DeviceID: "onu3",
293 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
294 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
295 },
khenaidood20a5852018-10-22 22:09:55 -0400296 {
khenaidoo89b0e942018-10-21 21:11:33 -0400297 DeviceID: "olt",
298 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
299 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
300 },
301 }
khenaidoo820197c2020-02-13 16:35:33 -0500302 tfd.routes[route.OFPortLink{Ingress: 4, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400303 {
khenaidoo89b0e942018-10-21 21:11:33 -0400304 DeviceID: "onu4",
305 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
306 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
307 },
khenaidood20a5852018-10-22 22:09:55 -0400308 {
khenaidoo89b0e942018-10-21 21:11:33 -0400309 DeviceID: "olt",
310 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
311 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
312 },
313 }
314
315 // DOWNSTREAM NEXT TABLE BASED
316
khenaidoo820197c2020-02-13 16:35:33 -0500317 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400318 {
khenaidoo89b0e942018-10-21 21:11:33 -0400319 DeviceID: "olt",
320 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
321 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
322 },
khenaidood20a5852018-10-22 22:09:55 -0400323 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400324 }
325
khenaidoo820197c2020-02-13 16:35:33 -0500326 tfd.routes[route.OFPortLink{Ingress: 0, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400327 {}, // 1st hop is wildcard
328 {
khenaidoo89b0e942018-10-21 21:11:33 -0400329 DeviceID: "olt",
330 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
331 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
332 },
333 }
334
335 // DEFAULT RULES
336
337 tfd.defaultRules = fu.NewDeviceRules()
338 fg := fu.NewFlowsAndGroups()
npujar1d86a522019-11-14 17:11:16 +0530339 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400340 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400341 fu.InPort(2),
342 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400343 },
344 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400345 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
346 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400347 },
348 }
khenaidoo68c930b2019-05-13 11:46:51 -0400349 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400350 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
351
352 fg = fu.NewFlowsAndGroups()
353 fa = &fu.FlowArgs{
354 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400355 fu.InPort(2),
356 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400357 },
358 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400359 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
360 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400361 },
362 }
khenaidoo68c930b2019-05-13 11:46:51 -0400363 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400364 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
365
366 fg = fu.NewFlowsAndGroups()
367 fa = &fu.FlowArgs{
368 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400369 fu.InPort(2),
370 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400371 },
372 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400373 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 103)),
374 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400375 },
376 }
khenaidoo68c930b2019-05-13 11:46:51 -0400377 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400378 tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
379
380 fg = fu.NewFlowsAndGroups()
381 fa = &fu.FlowArgs{
382 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400383 fu.InPort(2),
384 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400385 },
386 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400387 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
388 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400389 },
390 }
khenaidoo68c930b2019-05-13 11:46:51 -0400391 fg.AddFlow(fu.MkFlowStat(fa))
khenaidoo89b0e942018-10-21 21:11:33 -0400392 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
393
394 //Set up the device graph - flow decomposer uses it only to verify whether a port is a root port.
khenaidoo820197c2020-02-13 16:35:33 -0500395 tfd.deviceRoutes = route.NewDeviceRoutes("ldid", tfd.getDeviceHelper)
396 tfd.deviceRoutes.RootPorts = make(map[uint32]uint32)
397 tfd.deviceRoutes.RootPorts[10] = 10
khenaidoo89b0e942018-10-21 21:11:33 -0400398
399 tfd.fd = NewFlowDecomposer(tfd.dMgr)
400
401 return &tfd
402}
403
npujar467fe752020-01-16 20:17:45 +0530404func (tfd *testFlowDecomposer) getDeviceHelper(ctx context.Context, deviceID string) (*voltha.Device, error) {
405 return tfd.dMgr.GetDevice(ctx, deviceID)
khenaidoo89b0e942018-10-21 21:11:33 -0400406}
407
npujar1d86a522019-11-14 17:11:16 +0530408func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400409 return ""
410}
411
khenaidoo6e55d9e2019-12-12 18:26:26 -0500412func (tfd *testFlowDecomposer) GetLogicalDevice() *voltha.LogicalDevice {
413 return nil
khenaidoo89b0e942018-10-21 21:11:33 -0400414}
415
khenaidoo820197c2020-02-13 16:35:33 -0500416func (tfd *testFlowDecomposer) GetDeviceRoutes() *route.DeviceRoutes {
417 return tfd.deviceRoutes
khenaidoo89b0e942018-10-21 21:11:33 -0400418}
419
420func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
421 return tfd.defaultRules
422}
423
424func (tfd *testFlowDecomposer) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
425 lPorts := make([]uint32, 0)
426 var exclPort uint32
427 if len(excludePort) == 1 {
428 exclPort = excludePort[0]
429 }
khenaidood20a5852018-10-22 22:09:55 -0400430 for portno := range tfd.logicalPorts {
khenaidoo89b0e942018-10-21 21:11:33 -0400431 if portno != exclPort {
432 lPorts = append(lPorts, portno)
433 }
434 }
435 return lPorts
436}
437
khenaidoo820197c2020-02-13 16:35:33 -0500438func (tfd *testFlowDecomposer) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
439 var portLink route.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400440 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400441 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400442 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400443 portLink.Egress = 10
444 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400445 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400446 }
khenaidoo19d7b632018-10-30 10:49:50 -0400447 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400448 portLink.Ingress = 0
449 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400450 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400451 }
452 for key, val := range tfd.routes {
453 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
khenaidoo820197c2020-02-13 16:35:33 -0500454 return val, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400455 }
456 }
khenaidoo820197c2020-02-13 16:35:33 -0500457 return nil, status.Errorf(codes.FailedPrecondition, "no route from:%d to:%d", ingressPortNo, egressPortNo)
khenaidoo89b0e942018-10-21 21:11:33 -0400458}
459
Esin Karaman09959ae2019-11-29 13:59:58 +0000460func (tfd *testFlowDecomposer) GetNNIPorts() []uint32 {
461 nniPorts := make([]uint32, 0)
462 for portNo, nni := range tfd.logicalPortsNo {
463 if nni {
464 nniPorts = append(nniPorts, portNo)
465 }
466 }
467 return nniPorts
468}
469
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400470func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
471
npujar1d86a522019-11-14 17:11:16 +0530472 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400473 KV: fu.OfpFlowModArgs{"priority": 1000},
474 MatchFields: []*ofp.OfpOxmOfbField{
475 fu.InPort(1),
476 fu.VlanVid(50),
477 fu.EthType(0x888e),
478 },
479 Actions: []*ofp.OfpAction{
480 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
481 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
482 },
483 }
484
485 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
486 groups := ofp.FlowGroups{}
487 tfd := newTestFlowDecomposer(newTestDeviceManager())
488
khenaidoo820197c2020-02-13 16:35:33 -0500489 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
490 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400491 onu1FlowAndGroup := deviceRules.Rules["onu1"]
492 oltFlowAndGroup := deviceRules.Rules["olt"]
493 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
494 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
495 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
496
npujar1d86a522019-11-14 17:11:16 +0530497 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400498 KV: fu.OfpFlowModArgs{"priority": 1000},
499 MatchFields: []*ofp.OfpOxmOfbField{
500 fu.InPort(1),
501 fu.TunnelId(uint64(1)),
502 fu.VlanVid(50),
503 fu.EthType(0x888e),
504 },
505 Actions: []*ofp.OfpAction{
506 fu.PushVlan(0x8100),
507 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
508 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
509 },
510 }
511 expectedOltFlow := fu.MkFlowStat(faParent)
512 derivedFlow := oltFlowAndGroup.GetFlow(0)
513 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
514
npujar1d86a522019-11-14 17:11:16 +0530515 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400516 KV: fu.OfpFlowModArgs{"priority": 1000},
517 MatchFields: []*ofp.OfpOxmOfbField{
518 fu.InPort(2),
519 fu.TunnelId(uint64(1)),
520 fu.EthType(0x888e),
521 },
522 Actions: []*ofp.OfpAction{
523 fu.PushVlan(0x8100),
524 fu.SetField(fu.VlanVid(50)),
525 fu.Output(1),
526 },
527 }
528 expectedOnuFlow := fu.MkFlowStat(faChild)
529 derivedFlow = onu1FlowAndGroup.GetFlow(0)
530 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
531}
532
533func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
534
npujar1d86a522019-11-14 17:11:16 +0530535 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400536 KV: fu.OfpFlowModArgs{"priority": 1000},
537 MatchFields: []*ofp.OfpOxmOfbField{
538 fu.InPort(1),
539 fu.VlanVid(0),
540 fu.EthType(0x888e),
541 },
542 Actions: []*ofp.OfpAction{
543 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
544 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
545 },
546 }
547
548 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
549 groups := ofp.FlowGroups{}
550 tfd := newTestFlowDecomposer(newTestDeviceManager())
551
khenaidoo820197c2020-02-13 16:35:33 -0500552 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
553 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400554 onu1FlowAndGroup := deviceRules.Rules["onu1"]
555 oltFlowAndGroup := deviceRules.Rules["olt"]
556 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
557 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
558 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
559
npujar1d86a522019-11-14 17:11:16 +0530560 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400561 KV: fu.OfpFlowModArgs{"priority": 1000},
562 MatchFields: []*ofp.OfpOxmOfbField{
563 fu.InPort(1),
564 fu.TunnelId(uint64(1)),
565 fu.VlanVid(0),
566 fu.EthType(0x888e),
567 },
568 Actions: []*ofp.OfpAction{
569 fu.PushVlan(0x8100),
570 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
571 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
572 },
573 }
574 expectedOltFlow := fu.MkFlowStat(faParent)
575 derivedFlow := oltFlowAndGroup.GetFlow(0)
576 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
577
npujar1d86a522019-11-14 17:11:16 +0530578 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400579 KV: fu.OfpFlowModArgs{"priority": 1000},
580 MatchFields: []*ofp.OfpOxmOfbField{
581 fu.InPort(2),
582 fu.TunnelId(uint64(1)),
583 fu.EthType(0x888e),
584 },
585 Actions: []*ofp.OfpAction{
586 fu.PushVlan(0x8100),
587 fu.SetField(fu.VlanVid(0)),
588 fu.Output(1),
589 },
590 }
591 expectedOnuFlow := fu.MkFlowStat(faChild)
592 derivedFlow = onu1FlowAndGroup.GetFlow(0)
593 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
594}
595
596func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400597
npujar1d86a522019-11-14 17:11:16 +0530598 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400599 KV: fu.OfpFlowModArgs{"priority": 1000},
600 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400601 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400602 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400603 },
604 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400605 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
606 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400607 },
608 }
609
khenaidoo68c930b2019-05-13 11:46:51 -0400610 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400611 groups := ofp.FlowGroups{}
612 tfd := newTestFlowDecomposer(newTestDeviceManager())
613
khenaidoo820197c2020-02-13 16:35:33 -0500614 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
615 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400616 onu1FlowAndGroup := deviceRules.Rules["onu1"]
617 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400618 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400619 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400620 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
621
npujar1d86a522019-11-14 17:11:16 +0530622 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400623 KV: fu.OfpFlowModArgs{"priority": 1000},
624 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400625 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400626 fu.TunnelId(uint64(1)),
627 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400628 },
629 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400630 fu.PushVlan(0x8100),
631 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
632 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400633 },
634 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400635 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400636 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400637 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400638
npujar1d86a522019-11-14 17:11:16 +0530639 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400640 KV: fu.OfpFlowModArgs{"priority": 1000},
641 MatchFields: []*ofp.OfpOxmOfbField{
642 fu.InPort(2),
643 fu.TunnelId(uint64(1)),
644 fu.EthType(0x888e),
645 },
646 Actions: []*ofp.OfpAction{
647 fu.Output(1),
648 },
649 }
650 expectedOnuFlow := fu.MkFlowStat(faChild)
651 derivedFlow = onu1FlowAndGroup.GetFlow(0)
652 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400653}
654
655func TestDhcpReRouteRuleDecomposition(t *testing.T) {
656
npujar1d86a522019-11-14 17:11:16 +0530657 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400658 KV: fu.OfpFlowModArgs{"priority": 1000},
659 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400660 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400661 fu.EthType(0x0800),
662 fu.Ipv4Dst(0xffffffff),
663 fu.IpProto(17),
664 fu.UdpSrc(68),
665 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400666 },
667 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400668 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400669 },
670 }
671
khenaidoo68c930b2019-05-13 11:46:51 -0400672 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
khenaidoo89b0e942018-10-21 21:11:33 -0400673 groups := ofp.FlowGroups{}
674 tfd := newTestFlowDecomposer(newTestDeviceManager())
675
khenaidoo820197c2020-02-13 16:35:33 -0500676 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
677 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400678 onu1FlowAndGroup := deviceRules.Rules["onu1"]
679 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400680 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
681 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400682 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400683 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
684
npujar1d86a522019-11-14 17:11:16 +0530685 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400686 KV: fu.OfpFlowModArgs{"priority": 1000},
687 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400688 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400689 fu.TunnelId(uint64(1)),
690 fu.EthType(0x0800),
691 fu.Ipv4Dst(0xffffffff),
692 fu.IpProto(17),
693 fu.UdpSrc(68),
694 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400695 },
696 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400697 fu.PushVlan(0x8100),
698 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
699 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400700 },
701 }
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400702 expectedOltFlow := fu.MkFlowStat(faParent)
khenaidoo3306c992019-05-24 16:57:35 -0400703 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400704 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400705
npujar1d86a522019-11-14 17:11:16 +0530706 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400707 KV: fu.OfpFlowModArgs{"priority": 1000},
708 MatchFields: []*ofp.OfpOxmOfbField{
709 fu.InPort(2),
710 fu.TunnelId(uint64(1)),
711 fu.EthType(0x0800),
712 fu.Ipv4Dst(0xffffffff),
713 fu.IpProto(17),
714 fu.UdpSrc(68),
715 fu.UdpDst(67),
716 },
717 Actions: []*ofp.OfpAction{
718 fu.Output(1),
719 },
720 }
721 expectedOnuFlow := fu.MkFlowStat(faChild)
722 derivedFlow = onu1FlowAndGroup.GetFlow(0)
723 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400724}
725
Humera Kouser4ff89012019-08-25 19:01:51 -0400726func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530727 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400728 KV: fu.OfpFlowModArgs{"priority": 1000},
729 MatchFields: []*ofp.OfpOxmOfbField{
730 fu.InPort(10),
731 fu.EthType(0x88CC),
732 },
733 Actions: []*ofp.OfpAction{
734 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
735 },
736 }
737
738 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
739 groups := ofp.FlowGroups{}
740 tfd := newTestFlowDecomposer(newTestDeviceManager())
khenaidoo820197c2020-02-13 16:35:33 -0500741 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
742 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400743 onu1FlowAndGroup := deviceRules.Rules["onu1"]
744 oltFlowAndGroup := deviceRules.Rules["olt"]
745 assert.Nil(t, onu1FlowAndGroup)
746 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
747 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
748
749 fa = &fu.FlowArgs{
750 KV: fu.OfpFlowModArgs{"priority": 1000},
751 MatchFields: []*ofp.OfpOxmOfbField{
752 fu.InPort(2),
753 fu.EthType(0x88CC),
754 },
755 Actions: []*ofp.OfpAction{
756 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
757 },
758 }
759 expectedOltFlow := fu.MkFlowStat(fa)
760 derivedFlow := oltFlowAndGroup.GetFlow(0)
761 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
762}
763
khenaidood20a5852018-10-22 22:09:55 -0400764func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530765 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400766 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400767 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400768 fu.InPort(1),
769 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
770 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400771 },
772 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400773 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400774 },
775 }
776
npujar1d86a522019-11-14 17:11:16 +0530777 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400778 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400779 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400780 fu.InPort(1),
781 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
782 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400783 },
784 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400785 fu.PushVlan(0x8100),
786 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
787 fu.SetField(fu.VlanPcp(0)),
788 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400789 },
790 }
791
khenaidoo68c930b2019-05-13 11:46:51 -0400792 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400793 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
794 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
795 Data: &ofp.OfpInstruction_GotoTable{
796 GotoTable: &ofp.OfpInstructionGotoTable{
797 TableId: 1,
798 },
799 }}}
800
khenaidood20a5852018-10-22 22:09:55 -0400801 groups := ofp.FlowGroups{}
802 tfd := newTestFlowDecomposer(newTestDeviceManager())
803
khenaidoo820197c2020-02-13 16:35:33 -0500804 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
805 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400806 onu1FlowAndGroup := deviceRules.Rules["onu1"]
807 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400808 assert.NotNil(t, onu1FlowAndGroup)
809 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400810 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400811 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
812 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
813 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
814
815 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400816 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400817 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400818 fu.InPort(2),
819 fu.TunnelId(uint64(1)),
820 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
821 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400822 },
823 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400824 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
825 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400826 },
827 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400828
khenaidoo3306c992019-05-24 16:57:35 -0400829 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400830 // Form the expected flow
831 expectedOnu1Flow := fu.MkFlowStat(fa)
832 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
833 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
834 Data: &ofp.OfpInstruction_Actions{
835 Actions: &ofp.OfpInstructionActions{
836 Actions: []*ofp.OfpAction{{
837 Type: 0,
838 Action: &ofp.OfpAction_Output{
839 Output: &ofp.OfpActionOutput{
840 Port: 1,
841 MaxLen: 65509,
842 },
843 }}}}}}}
844
845 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400846 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
847
848 fa = &fu.FlowArgs{
849 KV: fu.OfpFlowModArgs{"priority": 500},
850 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400851 fu.InPort(1),
852 fu.TunnelId(uint64(1)),
853 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
854 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400855 },
856 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400857 fu.PushVlan(0x8100),
858 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
859 fu.SetField(fu.VlanPcp(0)),
860 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400861 },
862 }
khenaidoo68c930b2019-05-13 11:46:51 -0400863 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -0400864 derivedFlow = oltFlowAndGroup.GetFlow(0)
865 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
866}
867
868func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Manikkaraj kb1a10922019-07-29 12:10:34 -0400869 log.Debugf("Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530870 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400871 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400872 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400873 fu.InPort(10),
874 fu.Metadata_ofp((1000 << 32) | 1),
875 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400876 },
877 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400878 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400879 },
880 }
881
npujar1d86a522019-11-14 17:11:16 +0530882 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400883 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400884 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400885 fu.InPort(10),
886 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
887 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400888 },
889 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400890 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
891 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400892 },
893 }
894
khenaidoo68c930b2019-05-13 11:46:51 -0400895 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa1), fu.MkFlowStat(fa2)}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400896 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
897 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
898 Data: &ofp.OfpInstruction_GotoTable{
899 GotoTable: &ofp.OfpInstructionGotoTable{
900 TableId: 1,
901 },
902 }}}
903
khenaidood20a5852018-10-22 22:09:55 -0400904 groups := ofp.FlowGroups{}
905 tfd := newTestFlowDecomposer(newTestDeviceManager())
906
khenaidoo820197c2020-02-13 16:35:33 -0500907 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
908 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400909 onu1FlowAndGroup := deviceRules.Rules["onu1"]
910 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400911 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400912 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
913 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
914 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
915
916 fa1 = &fu.FlowArgs{
917 KV: fu.OfpFlowModArgs{"priority": 500},
918 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400919 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400920 fu.TunnelId(uint64(10)),
921 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400922 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400923 },
924 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400925 fu.PopVlan(),
926 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400927 },
928 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400929
khenaidood20a5852018-10-22 22:09:55 -0400930 derivedFlow := oltFlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400931 expectedOltFlow := fu.MkFlowStat(fa1)
932 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
933 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
934 Data: &ofp.OfpInstruction_Actions{
935 Actions: &ofp.OfpInstructionActions{
936 Actions: []*ofp.OfpAction{{
937 Type: 0,
938 Action: &ofp.OfpAction_Output{
939 Output: &ofp.OfpActionOutput{
940 Port: 1,
941 MaxLen: 65509,
942 },
943 }}}}}}}
944 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400945 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
946
947 fa1 = &fu.FlowArgs{
948 KV: fu.OfpFlowModArgs{"priority": 500},
949 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400950 fu.InPort(1),
951 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
952 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400953 },
954 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400955 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
956 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400957 },
958 }
khenaidoo68c930b2019-05-13 11:46:51 -0400959 expectedOnu1Flow := fu.MkFlowStat(fa1)
khenaidoo3306c992019-05-24 16:57:35 -0400960 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400961 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
962}
963
964func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530965 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -0400966 KV: fu.OfpFlowModArgs{"priority": 500},
967 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400968 fu.InPort(10),
969 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
970 fu.VlanPcp(0),
971 fu.EthType(0x800),
972 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400973 },
974 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400975 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -0400976 },
977 }
978
npujar1d86a522019-11-14 17:11:16 +0530979 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -0400980 GroupId: 10,
981 Buckets: []*ofp.OfpBucket{
982 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400983 fu.PopVlan(),
984 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400985 },
986 },
987 },
988 }
989
khenaidoo68c930b2019-05-13 11:46:51 -0400990 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fu.MkFlowStat(fa)}}
991 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
khenaidood20a5852018-10-22 22:09:55 -0400992 tfd := newTestFlowDecomposer(newTestDeviceManager())
993
khenaidoo820197c2020-02-13 16:35:33 -0500994 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
995 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400996 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -0400997 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
998 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
999
1000 fa = &fu.FlowArgs{
1001 KV: fu.OfpFlowModArgs{"priority": 500},
1002 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +00001003 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -04001004 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1005 fu.VlanPcp(0),
1006 fu.EthType(0x800),
1007 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001008 },
1009 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001010 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001011 },
1012 }
khenaidoo68c930b2019-05-13 11:46:51 -04001013 expectedOltFlow := fu.MkFlowStat(fa)
khenaidood20a5852018-10-22 22:09:55 -04001014 derivedFlow := oltFlowAndGroup.GetFlow(0)
1015 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001016}