blob: 6164f0ddbb10bfdbbd08fb5b2095914d438d7e90 [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
Scott Bakerfdea1e32020-02-21 15:35:41 -0800128func newTestFlowDecomposer(t *testing.T, deviceMgr *testDeviceManager) *testFlowDecomposer {
khenaidoo89b0e942018-10-21 21:11:33 -0400129 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 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800349 fs, err := fu.MkFlowStat(fa)
350 assert.Nil(t, err)
351 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400352 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
353
354 fg = fu.NewFlowsAndGroups()
355 fa = &fu.FlowArgs{
356 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400357 fu.InPort(2),
358 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400359 },
360 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400361 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
362 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400363 },
364 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800365 fs, err = fu.MkFlowStat(fa)
366 assert.Nil(t, err)
367 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400368 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
369
370 fg = fu.NewFlowsAndGroups()
371 fa = &fu.FlowArgs{
372 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400373 fu.InPort(2),
374 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400375 },
376 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400377 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 103)),
378 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400379 },
380 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800381 fs, err = fu.MkFlowStat(fa)
382 assert.Nil(t, err)
383 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400384 tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
385
386 fg = fu.NewFlowsAndGroups()
387 fa = &fu.FlowArgs{
388 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400389 fu.InPort(2),
390 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400391 },
392 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400393 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
394 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400395 },
396 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800397 fs, err = fu.MkFlowStat(fa)
398 assert.Nil(t, err)
399 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400400 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
401
402 //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 -0500403 tfd.deviceRoutes = route.NewDeviceRoutes("ldid", tfd.getDeviceHelper)
404 tfd.deviceRoutes.RootPorts = make(map[uint32]uint32)
405 tfd.deviceRoutes.RootPorts[10] = 10
khenaidoo89b0e942018-10-21 21:11:33 -0400406
407 tfd.fd = NewFlowDecomposer(tfd.dMgr)
408
409 return &tfd
410}
411
npujar467fe752020-01-16 20:17:45 +0530412func (tfd *testFlowDecomposer) getDeviceHelper(ctx context.Context, deviceID string) (*voltha.Device, error) {
413 return tfd.dMgr.GetDevice(ctx, deviceID)
khenaidoo89b0e942018-10-21 21:11:33 -0400414}
415
npujar1d86a522019-11-14 17:11:16 +0530416func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400417 return ""
418}
419
khenaidoo6e55d9e2019-12-12 18:26:26 -0500420func (tfd *testFlowDecomposer) GetLogicalDevice() *voltha.LogicalDevice {
421 return nil
khenaidoo89b0e942018-10-21 21:11:33 -0400422}
423
khenaidoo820197c2020-02-13 16:35:33 -0500424func (tfd *testFlowDecomposer) GetDeviceRoutes() *route.DeviceRoutes {
425 return tfd.deviceRoutes
khenaidoo89b0e942018-10-21 21:11:33 -0400426}
427
428func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
429 return tfd.defaultRules
430}
431
432func (tfd *testFlowDecomposer) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
433 lPorts := make([]uint32, 0)
434 var exclPort uint32
435 if len(excludePort) == 1 {
436 exclPort = excludePort[0]
437 }
khenaidood20a5852018-10-22 22:09:55 -0400438 for portno := range tfd.logicalPorts {
khenaidoo89b0e942018-10-21 21:11:33 -0400439 if portno != exclPort {
440 lPorts = append(lPorts, portno)
441 }
442 }
443 return lPorts
444}
445
khenaidoo820197c2020-02-13 16:35:33 -0500446func (tfd *testFlowDecomposer) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
447 var portLink route.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400448 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400449 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400450 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400451 portLink.Egress = 10
452 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400453 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400454 }
khenaidoo19d7b632018-10-30 10:49:50 -0400455 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400456 portLink.Ingress = 0
457 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400458 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400459 }
460 for key, val := range tfd.routes {
461 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
khenaidoo820197c2020-02-13 16:35:33 -0500462 return val, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400463 }
464 }
khenaidoo820197c2020-02-13 16:35:33 -0500465 return nil, status.Errorf(codes.FailedPrecondition, "no route from:%d to:%d", ingressPortNo, egressPortNo)
khenaidoo89b0e942018-10-21 21:11:33 -0400466}
467
Esin Karaman09959ae2019-11-29 13:59:58 +0000468func (tfd *testFlowDecomposer) GetNNIPorts() []uint32 {
469 nniPorts := make([]uint32, 0)
470 for portNo, nni := range tfd.logicalPortsNo {
471 if nni {
472 nniPorts = append(nniPorts, portNo)
473 }
474 }
475 return nniPorts
476}
477
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400478func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
479
npujar1d86a522019-11-14 17:11:16 +0530480 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400481 KV: fu.OfpFlowModArgs{"priority": 1000},
482 MatchFields: []*ofp.OfpOxmOfbField{
483 fu.InPort(1),
484 fu.VlanVid(50),
485 fu.EthType(0x888e),
486 },
487 Actions: []*ofp.OfpAction{
488 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
489 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
490 },
491 }
492
Scott Bakerfdea1e32020-02-21 15:35:41 -0800493 fs, err := fu.MkFlowStat(fa)
494 assert.Nil(t, err)
495 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400496 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800497 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400498
khenaidoo820197c2020-02-13 16:35:33 -0500499 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
500 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400501 onu1FlowAndGroup := deviceRules.Rules["onu1"]
502 oltFlowAndGroup := deviceRules.Rules["olt"]
503 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
504 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
505 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
506
npujar1d86a522019-11-14 17:11:16 +0530507 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400508 KV: fu.OfpFlowModArgs{"priority": 1000},
509 MatchFields: []*ofp.OfpOxmOfbField{
510 fu.InPort(1),
511 fu.TunnelId(uint64(1)),
512 fu.VlanVid(50),
513 fu.EthType(0x888e),
514 },
515 Actions: []*ofp.OfpAction{
516 fu.PushVlan(0x8100),
517 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
518 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
519 },
520 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800521 expectedOltFlow, err := fu.MkFlowStat(faParent)
522 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400523 derivedFlow := oltFlowAndGroup.GetFlow(0)
524 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
525
npujar1d86a522019-11-14 17:11:16 +0530526 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400527 KV: fu.OfpFlowModArgs{"priority": 1000},
528 MatchFields: []*ofp.OfpOxmOfbField{
529 fu.InPort(2),
530 fu.TunnelId(uint64(1)),
531 fu.EthType(0x888e),
532 },
533 Actions: []*ofp.OfpAction{
534 fu.PushVlan(0x8100),
535 fu.SetField(fu.VlanVid(50)),
536 fu.Output(1),
537 },
538 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800539 expectedOnuFlow, err := fu.MkFlowStat(faChild)
540 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400541 derivedFlow = onu1FlowAndGroup.GetFlow(0)
542 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
543}
544
545func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
546
npujar1d86a522019-11-14 17:11:16 +0530547 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400548 KV: fu.OfpFlowModArgs{"priority": 1000},
549 MatchFields: []*ofp.OfpOxmOfbField{
550 fu.InPort(1),
551 fu.VlanVid(0),
552 fu.EthType(0x888e),
553 },
554 Actions: []*ofp.OfpAction{
555 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
556 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
557 },
558 }
559
Scott Bakerfdea1e32020-02-21 15:35:41 -0800560 fs, err := fu.MkFlowStat(fa)
561 assert.Nil(t, err)
562 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400563 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800564 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400565
khenaidoo820197c2020-02-13 16:35:33 -0500566 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
567 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400568 onu1FlowAndGroup := deviceRules.Rules["onu1"]
569 oltFlowAndGroup := deviceRules.Rules["olt"]
570 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
571 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
572 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
573
npujar1d86a522019-11-14 17:11:16 +0530574 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400575 KV: fu.OfpFlowModArgs{"priority": 1000},
576 MatchFields: []*ofp.OfpOxmOfbField{
577 fu.InPort(1),
578 fu.TunnelId(uint64(1)),
579 fu.VlanVid(0),
580 fu.EthType(0x888e),
581 },
582 Actions: []*ofp.OfpAction{
583 fu.PushVlan(0x8100),
584 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
585 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
586 },
587 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800588 expectedOltFlow, err := fu.MkFlowStat(faParent)
589 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400590 derivedFlow := oltFlowAndGroup.GetFlow(0)
591 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
592
npujar1d86a522019-11-14 17:11:16 +0530593 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400594 KV: fu.OfpFlowModArgs{"priority": 1000},
595 MatchFields: []*ofp.OfpOxmOfbField{
596 fu.InPort(2),
597 fu.TunnelId(uint64(1)),
598 fu.EthType(0x888e),
599 },
600 Actions: []*ofp.OfpAction{
601 fu.PushVlan(0x8100),
602 fu.SetField(fu.VlanVid(0)),
603 fu.Output(1),
604 },
605 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800606 expectedOnuFlow, err := fu.MkFlowStat(faChild)
607 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400608 derivedFlow = onu1FlowAndGroup.GetFlow(0)
609 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
610}
611
612func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400613
npujar1d86a522019-11-14 17:11:16 +0530614 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400615 KV: fu.OfpFlowModArgs{"priority": 1000},
616 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400617 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400618 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400619 },
620 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400621 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
622 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400623 },
624 }
625
Scott Bakerfdea1e32020-02-21 15:35:41 -0800626 fs, err := fu.MkFlowStat(fa)
627 assert.Nil(t, err)
628 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo89b0e942018-10-21 21:11:33 -0400629 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800630 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400631
khenaidoo820197c2020-02-13 16:35:33 -0500632 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
633 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400634 onu1FlowAndGroup := deviceRules.Rules["onu1"]
635 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400636 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400637 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400638 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
639
npujar1d86a522019-11-14 17:11:16 +0530640 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400641 KV: fu.OfpFlowModArgs{"priority": 1000},
642 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400643 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400644 fu.TunnelId(uint64(1)),
645 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400646 },
647 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400648 fu.PushVlan(0x8100),
649 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
650 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400651 },
652 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800653 expectedOltFlow, err := fu.MkFlowStat(faParent)
654 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400655 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400656 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400657
npujar1d86a522019-11-14 17:11:16 +0530658 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400659 KV: fu.OfpFlowModArgs{"priority": 1000},
660 MatchFields: []*ofp.OfpOxmOfbField{
661 fu.InPort(2),
662 fu.TunnelId(uint64(1)),
663 fu.EthType(0x888e),
664 },
665 Actions: []*ofp.OfpAction{
666 fu.Output(1),
667 },
668 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800669 expectedOnuFlow, err := fu.MkFlowStat(faChild)
670 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400671 derivedFlow = onu1FlowAndGroup.GetFlow(0)
672 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400673}
674
675func TestDhcpReRouteRuleDecomposition(t *testing.T) {
676
npujar1d86a522019-11-14 17:11:16 +0530677 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400678 KV: fu.OfpFlowModArgs{"priority": 1000},
679 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400680 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400681 fu.EthType(0x0800),
682 fu.Ipv4Dst(0xffffffff),
683 fu.IpProto(17),
684 fu.UdpSrc(68),
685 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400686 },
687 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400688 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400689 },
690 }
691
Scott Bakerfdea1e32020-02-21 15:35:41 -0800692 fs, err := fu.MkFlowStat(fa)
693 assert.Nil(t, err)
694 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo89b0e942018-10-21 21:11:33 -0400695 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800696 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400697
khenaidoo820197c2020-02-13 16:35:33 -0500698 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
699 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400700 onu1FlowAndGroup := deviceRules.Rules["onu1"]
701 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400702 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
703 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400704 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400705 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
706
npujar1d86a522019-11-14 17:11:16 +0530707 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400708 KV: fu.OfpFlowModArgs{"priority": 1000},
709 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400710 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400711 fu.TunnelId(uint64(1)),
712 fu.EthType(0x0800),
713 fu.Ipv4Dst(0xffffffff),
714 fu.IpProto(17),
715 fu.UdpSrc(68),
716 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400717 },
718 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400719 fu.PushVlan(0x8100),
720 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000)),
721 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400722 },
723 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800724 expectedOltFlow, err := fu.MkFlowStat(faParent)
725 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400726 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400727 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400728
npujar1d86a522019-11-14 17:11:16 +0530729 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400730 KV: fu.OfpFlowModArgs{"priority": 1000},
731 MatchFields: []*ofp.OfpOxmOfbField{
732 fu.InPort(2),
733 fu.TunnelId(uint64(1)),
734 fu.EthType(0x0800),
735 fu.Ipv4Dst(0xffffffff),
736 fu.IpProto(17),
737 fu.UdpSrc(68),
738 fu.UdpDst(67),
739 },
740 Actions: []*ofp.OfpAction{
741 fu.Output(1),
742 },
743 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800744 expectedOnuFlow, err := fu.MkFlowStat(faChild)
745 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400746 derivedFlow = onu1FlowAndGroup.GetFlow(0)
747 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400748}
749
Humera Kouser4ff89012019-08-25 19:01:51 -0400750func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530751 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400752 KV: fu.OfpFlowModArgs{"priority": 1000},
753 MatchFields: []*ofp.OfpOxmOfbField{
754 fu.InPort(10),
755 fu.EthType(0x88CC),
756 },
757 Actions: []*ofp.OfpAction{
758 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
759 },
760 }
761
Scott Bakerfdea1e32020-02-21 15:35:41 -0800762 fs, err := fu.MkFlowStat(fa)
763 assert.Nil(t, err)
764 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
Humera Kouser4ff89012019-08-25 19:01:51 -0400765 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800766 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo820197c2020-02-13 16:35:33 -0500767 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
768 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400769 onu1FlowAndGroup := deviceRules.Rules["onu1"]
770 oltFlowAndGroup := deviceRules.Rules["olt"]
771 assert.Nil(t, onu1FlowAndGroup)
772 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
773 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
774
775 fa = &fu.FlowArgs{
776 KV: fu.OfpFlowModArgs{"priority": 1000},
777 MatchFields: []*ofp.OfpOxmOfbField{
778 fu.InPort(2),
779 fu.EthType(0x88CC),
780 },
781 Actions: []*ofp.OfpAction{
782 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
783 },
784 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800785 expectedOltFlow, err := fu.MkFlowStat(fa)
786 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400787 derivedFlow := oltFlowAndGroup.GetFlow(0)
788 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
789}
790
khenaidood20a5852018-10-22 22:09:55 -0400791func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530792 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400793 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400794 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400795 fu.InPort(1),
796 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
797 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400798 },
799 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400800 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400801 },
802 }
803
npujar1d86a522019-11-14 17:11:16 +0530804 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400805 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400806 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400807 fu.InPort(1),
808 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
809 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400810 },
811 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400812 fu.PushVlan(0x8100),
813 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
814 fu.SetField(fu.VlanPcp(0)),
815 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400816 },
817 }
818
Scott Bakerfdea1e32020-02-21 15:35:41 -0800819 fs, err := fu.MkFlowStat(fa)
820 assert.Nil(t, err)
821 fs2, err := fu.MkFlowStat(fa2)
822 assert.Nil(t, err)
823 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs, fs2}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400824 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
825 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
826 Data: &ofp.OfpInstruction_GotoTable{
827 GotoTable: &ofp.OfpInstructionGotoTable{
828 TableId: 1,
829 },
830 }}}
831
khenaidood20a5852018-10-22 22:09:55 -0400832 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800833 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400834
khenaidoo820197c2020-02-13 16:35:33 -0500835 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
836 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400837 onu1FlowAndGroup := deviceRules.Rules["onu1"]
838 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400839 assert.NotNil(t, onu1FlowAndGroup)
840 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400841 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400842 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
843 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
844 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
845
846 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400847 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400848 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400849 fu.InPort(2),
850 fu.TunnelId(uint64(1)),
851 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
852 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400853 },
854 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400855 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
856 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400857 },
858 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400859
khenaidoo3306c992019-05-24 16:57:35 -0400860 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400861 // Form the expected flow
Scott Bakerfdea1e32020-02-21 15:35:41 -0800862 expectedOnu1Flow, err := fu.MkFlowStat(fa)
863 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400864 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
865 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
866 Data: &ofp.OfpInstruction_Actions{
867 Actions: &ofp.OfpInstructionActions{
868 Actions: []*ofp.OfpAction{{
869 Type: 0,
870 Action: &ofp.OfpAction_Output{
871 Output: &ofp.OfpActionOutput{
872 Port: 1,
873 MaxLen: 65509,
874 },
875 }}}}}}}
876
877 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400878 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
879
880 fa = &fu.FlowArgs{
881 KV: fu.OfpFlowModArgs{"priority": 500},
882 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400883 fu.InPort(1),
884 fu.TunnelId(uint64(1)),
885 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
886 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400887 },
888 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400889 fu.PushVlan(0x8100),
890 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
891 fu.SetField(fu.VlanPcp(0)),
892 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400893 },
894 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800895 expectedOltFlow, err := fu.MkFlowStat(fa)
896 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400897 derivedFlow = oltFlowAndGroup.GetFlow(0)
898 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
899}
900
901func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Manikkaraj kb1a10922019-07-29 12:10:34 -0400902 log.Debugf("Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530903 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400904 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400905 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400906 fu.InPort(10),
907 fu.Metadata_ofp((1000 << 32) | 1),
908 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400909 },
910 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400911 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400912 },
913 }
914
npujar1d86a522019-11-14 17:11:16 +0530915 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400916 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400917 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400918 fu.InPort(10),
919 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
920 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400921 },
922 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400923 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
924 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400925 },
926 }
927
Scott Bakerfdea1e32020-02-21 15:35:41 -0800928 fs1, err := fu.MkFlowStat(fa1)
929 assert.Nil(t, err)
930 fs2, err := fu.MkFlowStat(fa2)
931 assert.Nil(t, err)
932 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs1, fs2}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400933 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
934 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
935 Data: &ofp.OfpInstruction_GotoTable{
936 GotoTable: &ofp.OfpInstructionGotoTable{
937 TableId: 1,
938 },
939 }}}
940
khenaidood20a5852018-10-22 22:09:55 -0400941 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800942 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400943
khenaidoo820197c2020-02-13 16:35:33 -0500944 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
945 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400946 onu1FlowAndGroup := deviceRules.Rules["onu1"]
947 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400948 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400949 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
950 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
951 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
952
953 fa1 = &fu.FlowArgs{
954 KV: fu.OfpFlowModArgs{"priority": 500},
955 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400956 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400957 fu.TunnelId(uint64(10)),
958 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400959 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400960 },
961 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400962 fu.PopVlan(),
963 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400964 },
965 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400966
khenaidood20a5852018-10-22 22:09:55 -0400967 derivedFlow := oltFlowAndGroup.GetFlow(0)
Scott Bakerfdea1e32020-02-21 15:35:41 -0800968 expectedOltFlow, err := fu.MkFlowStat(fa1)
969 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400970 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
971 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
972 Data: &ofp.OfpInstruction_Actions{
973 Actions: &ofp.OfpInstructionActions{
974 Actions: []*ofp.OfpAction{{
975 Type: 0,
976 Action: &ofp.OfpAction_Output{
977 Output: &ofp.OfpActionOutput{
978 Port: 1,
979 MaxLen: 65509,
980 },
981 }}}}}}}
982 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400983 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
984
985 fa1 = &fu.FlowArgs{
986 KV: fu.OfpFlowModArgs{"priority": 500},
987 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400988 fu.InPort(1),
989 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
990 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400991 },
992 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400993 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
994 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400995 },
996 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800997 expectedOnu1Flow, err := fu.MkFlowStat(fa1)
998 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400999 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -04001000 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
1001}
1002
1003func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +05301004 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -04001005 KV: fu.OfpFlowModArgs{"priority": 500},
1006 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001007 fu.InPort(10),
1008 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1009 fu.VlanPcp(0),
1010 fu.EthType(0x800),
1011 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001012 },
1013 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001014 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001015 },
1016 }
1017
npujar1d86a522019-11-14 17:11:16 +05301018 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -04001019 GroupId: 10,
1020 Buckets: []*ofp.OfpBucket{
1021 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001022 fu.PopVlan(),
1023 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001024 },
1025 },
1026 },
1027 }
1028
Scott Bakerfdea1e32020-02-21 15:35:41 -08001029 fs, err := fu.MkFlowStat(fa)
1030 assert.Nil(t, err)
1031 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo68c930b2019-05-13 11:46:51 -04001032 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
Scott Bakerfdea1e32020-02-21 15:35:41 -08001033 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -04001034
khenaidoo820197c2020-02-13 16:35:33 -05001035 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
1036 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001037 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -04001038 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1039 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1040
1041 fa = &fu.FlowArgs{
1042 KV: fu.OfpFlowModArgs{"priority": 500},
1043 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +00001044 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -04001045 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1046 fu.VlanPcp(0),
1047 fu.EthType(0x800),
1048 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001049 },
1050 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001051 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001052 },
1053 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001054 expectedOltFlow, err := fu.MkFlowStat(fa)
1055 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001056 derivedFlow := oltFlowAndGroup.GetFlow(0)
1057 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001058}