blob: 9650cd40caf8c5f0cda08bb43c34dfe7f9bd8d4d [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
Kent Hagerman45a13e42020-04-13 12:23:50 -0400105func (tdm *testDeviceManager) GetDevice(ctx context.Context, deviceID *voltha.ID) (*voltha.Device, error) {
106 if d, ok := tdm.devices[deviceID.Id]; 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) {
Kent Hagerman45a13e42020-04-13 12:23:50 -0400413 return tfd.dMgr.GetDevice(ctx, &voltha.ID{Id: 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
khenaidoo442e7c72020-03-10 16:13:48 -0400420func (tfd *testFlowDecomposer) GetLogicalDevice(ctx context.Context) (*voltha.LogicalDevice, error) {
421 return nil, 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{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400516 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
517 },
518 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800519 expectedOltFlow, err := fu.MkFlowStat(faParent)
520 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400521 derivedFlow := oltFlowAndGroup.GetFlow(0)
522 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
523
npujar1d86a522019-11-14 17:11:16 +0530524 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400525 KV: fu.OfpFlowModArgs{"priority": 1000},
526 MatchFields: []*ofp.OfpOxmOfbField{
527 fu.InPort(2),
528 fu.TunnelId(uint64(1)),
529 fu.EthType(0x888e),
530 },
531 Actions: []*ofp.OfpAction{
532 fu.PushVlan(0x8100),
533 fu.SetField(fu.VlanVid(50)),
534 fu.Output(1),
535 },
536 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800537 expectedOnuFlow, err := fu.MkFlowStat(faChild)
538 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400539 derivedFlow = onu1FlowAndGroup.GetFlow(0)
540 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
541}
542
543func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
544
npujar1d86a522019-11-14 17:11:16 +0530545 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400546 KV: fu.OfpFlowModArgs{"priority": 1000},
547 MatchFields: []*ofp.OfpOxmOfbField{
548 fu.InPort(1),
549 fu.VlanVid(0),
550 fu.EthType(0x888e),
551 },
552 Actions: []*ofp.OfpAction{
553 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
554 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
555 },
556 }
557
Scott Bakerfdea1e32020-02-21 15:35:41 -0800558 fs, err := fu.MkFlowStat(fa)
559 assert.Nil(t, err)
560 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400561 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800562 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400563
khenaidoo820197c2020-02-13 16:35:33 -0500564 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
565 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400566 onu1FlowAndGroup := deviceRules.Rules["onu1"]
567 oltFlowAndGroup := deviceRules.Rules["olt"]
568 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
569 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
570 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
571
npujar1d86a522019-11-14 17:11:16 +0530572 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400573 KV: fu.OfpFlowModArgs{"priority": 1000},
574 MatchFields: []*ofp.OfpOxmOfbField{
575 fu.InPort(1),
576 fu.TunnelId(uint64(1)),
577 fu.VlanVid(0),
578 fu.EthType(0x888e),
579 },
580 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400581 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
582 },
583 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800584 expectedOltFlow, err := fu.MkFlowStat(faParent)
585 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400586 derivedFlow := oltFlowAndGroup.GetFlow(0)
587 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
588
npujar1d86a522019-11-14 17:11:16 +0530589 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400590 KV: fu.OfpFlowModArgs{"priority": 1000},
591 MatchFields: []*ofp.OfpOxmOfbField{
592 fu.InPort(2),
593 fu.TunnelId(uint64(1)),
594 fu.EthType(0x888e),
595 },
596 Actions: []*ofp.OfpAction{
597 fu.PushVlan(0x8100),
598 fu.SetField(fu.VlanVid(0)),
599 fu.Output(1),
600 },
601 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800602 expectedOnuFlow, err := fu.MkFlowStat(faChild)
603 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400604 derivedFlow = onu1FlowAndGroup.GetFlow(0)
605 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
606}
607
608func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400609
npujar1d86a522019-11-14 17:11:16 +0530610 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400611 KV: fu.OfpFlowModArgs{"priority": 1000},
612 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400613 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400614 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400615 },
616 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400617 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
618 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400619 },
620 }
621
Scott Bakerfdea1e32020-02-21 15:35:41 -0800622 fs, err := fu.MkFlowStat(fa)
623 assert.Nil(t, err)
624 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo89b0e942018-10-21 21:11:33 -0400625 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800626 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400627
khenaidoo820197c2020-02-13 16:35:33 -0500628 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
629 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400630 onu1FlowAndGroup := deviceRules.Rules["onu1"]
631 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400632 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400633 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400634 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
635
npujar1d86a522019-11-14 17:11:16 +0530636 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400637 KV: fu.OfpFlowModArgs{"priority": 1000},
638 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400639 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400640 fu.TunnelId(uint64(1)),
641 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400642 },
643 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400644 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400645 },
646 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800647 expectedOltFlow, err := fu.MkFlowStat(faParent)
648 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400649 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400650 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400651
npujar1d86a522019-11-14 17:11:16 +0530652 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400653 KV: fu.OfpFlowModArgs{"priority": 1000},
654 MatchFields: []*ofp.OfpOxmOfbField{
655 fu.InPort(2),
656 fu.TunnelId(uint64(1)),
657 fu.EthType(0x888e),
658 },
659 Actions: []*ofp.OfpAction{
660 fu.Output(1),
661 },
662 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800663 expectedOnuFlow, err := fu.MkFlowStat(faChild)
664 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400665 derivedFlow = onu1FlowAndGroup.GetFlow(0)
666 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400667}
668
669func TestDhcpReRouteRuleDecomposition(t *testing.T) {
670
npujar1d86a522019-11-14 17:11:16 +0530671 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400672 KV: fu.OfpFlowModArgs{"priority": 1000},
673 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400674 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400675 fu.EthType(0x0800),
676 fu.Ipv4Dst(0xffffffff),
677 fu.IpProto(17),
678 fu.UdpSrc(68),
679 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400680 },
681 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400682 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400683 },
684 }
685
Scott Bakerfdea1e32020-02-21 15:35:41 -0800686 fs, err := fu.MkFlowStat(fa)
687 assert.Nil(t, err)
688 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo89b0e942018-10-21 21:11:33 -0400689 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800690 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400691
khenaidoo820197c2020-02-13 16:35:33 -0500692 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
693 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400694 onu1FlowAndGroup := deviceRules.Rules["onu1"]
695 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400696 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
697 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400698 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400699 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
700
npujar1d86a522019-11-14 17:11:16 +0530701 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400702 KV: fu.OfpFlowModArgs{"priority": 1000},
703 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400704 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400705 fu.TunnelId(uint64(1)),
706 fu.EthType(0x0800),
707 fu.Ipv4Dst(0xffffffff),
708 fu.IpProto(17),
709 fu.UdpSrc(68),
710 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400711 },
712 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400713 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400714 },
715 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800716 expectedOltFlow, err := fu.MkFlowStat(faParent)
717 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400718 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400719 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400720
npujar1d86a522019-11-14 17:11:16 +0530721 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400722 KV: fu.OfpFlowModArgs{"priority": 1000},
723 MatchFields: []*ofp.OfpOxmOfbField{
724 fu.InPort(2),
725 fu.TunnelId(uint64(1)),
726 fu.EthType(0x0800),
727 fu.Ipv4Dst(0xffffffff),
728 fu.IpProto(17),
729 fu.UdpSrc(68),
730 fu.UdpDst(67),
731 },
732 Actions: []*ofp.OfpAction{
733 fu.Output(1),
734 },
735 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800736 expectedOnuFlow, err := fu.MkFlowStat(faChild)
737 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400738 derivedFlow = onu1FlowAndGroup.GetFlow(0)
739 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400740}
741
Humera Kouser4ff89012019-08-25 19:01:51 -0400742func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530743 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400744 KV: fu.OfpFlowModArgs{"priority": 1000},
745 MatchFields: []*ofp.OfpOxmOfbField{
746 fu.InPort(10),
747 fu.EthType(0x88CC),
748 },
749 Actions: []*ofp.OfpAction{
750 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
751 },
752 }
753
Scott Bakerfdea1e32020-02-21 15:35:41 -0800754 fs, err := fu.MkFlowStat(fa)
755 assert.Nil(t, err)
756 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
Humera Kouser4ff89012019-08-25 19:01:51 -0400757 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800758 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo820197c2020-02-13 16:35:33 -0500759 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
760 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400761 onu1FlowAndGroup := deviceRules.Rules["onu1"]
762 oltFlowAndGroup := deviceRules.Rules["olt"]
763 assert.Nil(t, onu1FlowAndGroup)
764 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
765 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
766
767 fa = &fu.FlowArgs{
768 KV: fu.OfpFlowModArgs{"priority": 1000},
769 MatchFields: []*ofp.OfpOxmOfbField{
770 fu.InPort(2),
771 fu.EthType(0x88CC),
772 },
773 Actions: []*ofp.OfpAction{
774 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
775 },
776 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800777 expectedOltFlow, err := fu.MkFlowStat(fa)
778 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400779 derivedFlow := oltFlowAndGroup.GetFlow(0)
780 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
781}
782
khenaidood20a5852018-10-22 22:09:55 -0400783func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530784 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400785 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400786 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400787 fu.InPort(1),
788 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
789 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400790 },
791 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400792 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400793 },
794 }
795
npujar1d86a522019-11-14 17:11:16 +0530796 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400797 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400798 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400799 fu.InPort(1),
800 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
801 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400802 },
803 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400804 fu.PushVlan(0x8100),
805 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
806 fu.SetField(fu.VlanPcp(0)),
807 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400808 },
809 }
810
Scott Bakerfdea1e32020-02-21 15:35:41 -0800811 fs, err := fu.MkFlowStat(fa)
812 assert.Nil(t, err)
813 fs2, err := fu.MkFlowStat(fa2)
814 assert.Nil(t, err)
815 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs, fs2}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400816 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
817 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
818 Data: &ofp.OfpInstruction_GotoTable{
819 GotoTable: &ofp.OfpInstructionGotoTable{
820 TableId: 1,
821 },
822 }}}
823
khenaidood20a5852018-10-22 22:09:55 -0400824 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800825 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400826
khenaidoo820197c2020-02-13 16:35:33 -0500827 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
828 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400829 onu1FlowAndGroup := deviceRules.Rules["onu1"]
830 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400831 assert.NotNil(t, onu1FlowAndGroup)
832 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400833 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400834 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
835 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
836 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
837
838 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400839 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400840 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400841 fu.InPort(2),
842 fu.TunnelId(uint64(1)),
843 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
844 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400845 },
846 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400847 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
848 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400849 },
850 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400851
khenaidoo3306c992019-05-24 16:57:35 -0400852 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400853 // Form the expected flow
Scott Bakerfdea1e32020-02-21 15:35:41 -0800854 expectedOnu1Flow, err := fu.MkFlowStat(fa)
855 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400856 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
857 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
858 Data: &ofp.OfpInstruction_Actions{
859 Actions: &ofp.OfpInstructionActions{
860 Actions: []*ofp.OfpAction{{
861 Type: 0,
862 Action: &ofp.OfpAction_Output{
863 Output: &ofp.OfpActionOutput{
864 Port: 1,
865 MaxLen: 65509,
866 },
867 }}}}}}}
868
869 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400870 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
871
872 fa = &fu.FlowArgs{
873 KV: fu.OfpFlowModArgs{"priority": 500},
874 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400875 fu.InPort(1),
876 fu.TunnelId(uint64(1)),
877 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
878 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400879 },
880 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400881 fu.PushVlan(0x8100),
882 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
883 fu.SetField(fu.VlanPcp(0)),
884 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400885 },
886 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800887 expectedOltFlow, err := fu.MkFlowStat(fa)
888 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400889 derivedFlow = oltFlowAndGroup.GetFlow(0)
890 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
891}
892
893func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Girish Kumarf56a4682020-03-20 20:07:46 +0000894 logger.Debugf("Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530895 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400896 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400897 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400898 fu.InPort(10),
899 fu.Metadata_ofp((1000 << 32) | 1),
900 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400901 },
902 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400903 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400904 },
905 }
906
npujar1d86a522019-11-14 17:11:16 +0530907 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400908 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400909 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400910 fu.InPort(10),
911 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
912 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400913 },
914 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400915 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
916 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400917 },
918 }
919
Scott Bakerfdea1e32020-02-21 15:35:41 -0800920 fs1, err := fu.MkFlowStat(fa1)
921 assert.Nil(t, err)
922 fs2, err := fu.MkFlowStat(fa2)
923 assert.Nil(t, err)
924 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs1, fs2}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400925 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
926 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
927 Data: &ofp.OfpInstruction_GotoTable{
928 GotoTable: &ofp.OfpInstructionGotoTable{
929 TableId: 1,
930 },
931 }}}
932
khenaidood20a5852018-10-22 22:09:55 -0400933 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800934 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400935
khenaidoo820197c2020-02-13 16:35:33 -0500936 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
937 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400938 onu1FlowAndGroup := deviceRules.Rules["onu1"]
939 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400940 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400941 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
942 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
943 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
944
945 fa1 = &fu.FlowArgs{
946 KV: fu.OfpFlowModArgs{"priority": 500},
947 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400948 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400949 fu.TunnelId(uint64(10)),
950 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400951 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400952 },
953 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400954 fu.PopVlan(),
955 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400956 },
957 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400958
khenaidood20a5852018-10-22 22:09:55 -0400959 derivedFlow := oltFlowAndGroup.GetFlow(0)
Scott Bakerfdea1e32020-02-21 15:35:41 -0800960 expectedOltFlow, err := fu.MkFlowStat(fa1)
961 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400962 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
963 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
964 Data: &ofp.OfpInstruction_Actions{
965 Actions: &ofp.OfpInstructionActions{
966 Actions: []*ofp.OfpAction{{
967 Type: 0,
968 Action: &ofp.OfpAction_Output{
969 Output: &ofp.OfpActionOutput{
970 Port: 1,
971 MaxLen: 65509,
972 },
973 }}}}}}}
974 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400975 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
976
977 fa1 = &fu.FlowArgs{
978 KV: fu.OfpFlowModArgs{"priority": 500},
979 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400980 fu.InPort(1),
981 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
982 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400983 },
984 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400985 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
986 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400987 },
988 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800989 expectedOnu1Flow, err := fu.MkFlowStat(fa1)
990 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400991 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400992 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
993}
994
995func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530996 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -0400997 KV: fu.OfpFlowModArgs{"priority": 500},
998 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400999 fu.InPort(10),
1000 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1001 fu.VlanPcp(0),
1002 fu.EthType(0x800),
1003 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001004 },
1005 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001006 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001007 },
1008 }
1009
npujar1d86a522019-11-14 17:11:16 +05301010 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -04001011 GroupId: 10,
1012 Buckets: []*ofp.OfpBucket{
1013 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001014 fu.PopVlan(),
1015 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001016 },
1017 },
1018 },
1019 }
1020
Scott Bakerfdea1e32020-02-21 15:35:41 -08001021 fs, err := fu.MkFlowStat(fa)
1022 assert.Nil(t, err)
1023 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo68c930b2019-05-13 11:46:51 -04001024 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
Scott Bakerfdea1e32020-02-21 15:35:41 -08001025 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -04001026
khenaidoo820197c2020-02-13 16:35:33 -05001027 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
1028 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001029 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -04001030 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1031 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1032
1033 fa = &fu.FlowArgs{
1034 KV: fu.OfpFlowModArgs{"priority": 500},
1035 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +00001036 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -04001037 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1038 fu.VlanPcp(0),
1039 fu.EthType(0x800),
1040 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001041 },
1042 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001043 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001044 },
1045 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001046 expectedOltFlow, err := fu.MkFlowStat(fa)
1047 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001048 derivedFlow := oltFlowAndGroup.GetFlow(0)
1049 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001050}