blob: eb7ad754e589d4d8d05b1fe738eb882519cd5fd9 [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"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080024 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
25 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoo89b0e942018-10-21 21:11:33 -040026 "github.com/stretchr/testify/assert"
khenaidoo820197c2020-02-13 16:35:33 -050027 "google.golang.org/grpc/codes"
28 "google.golang.org/grpc/status"
khenaidoo89b0e942018-10-21 21:11:33 -040029
30 "testing"
31)
32
khenaidoo89b0e942018-10-21 21:11:33 -040033type testDeviceManager struct {
khenaidooab1f7bd2019-11-14 14:00:27 -050034 mocks.DeviceManager
khenaidoo89b0e942018-10-21 21:11:33 -040035 devices map[string]*voltha.Device
36}
37
38func newTestDeviceManager() *testDeviceManager {
39 var tdm testDeviceManager
40 tdm.devices = make(map[string]*voltha.Device)
41 tdm.devices["olt"] = &voltha.Device{
42 Id: "olt",
43 Root: true,
44 ParentId: "logical_device",
45 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040046 {PortNo: 1, Label: "pon"},
47 {PortNo: 2, Label: "nni"},
khenaidoo89b0e942018-10-21 21:11:33 -040048 },
49 }
50 tdm.devices["onu1"] = &voltha.Device{
51 Id: "onu1",
52 Root: false,
53 ParentId: "olt",
54 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040055 {PortNo: 1, Label: "pon"},
56 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040057 },
58 }
59 tdm.devices["onu2"] = &voltha.Device{
60 Id: "onu2",
61 Root: false,
62 ParentId: "olt",
63 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040064 {PortNo: 1, Label: "pon"},
65 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040066 },
67 }
68 tdm.devices["onu3"] = &voltha.Device{
69 Id: "onu3",
70 Root: false,
71 ParentId: "olt",
72 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040073 {PortNo: 1, Label: "pon"},
74 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040075 },
76 }
77 tdm.devices["onu4"] = &voltha.Device{
78 Id: "onu4",
79 Root: false,
80 ParentId: "olt",
81 Ports: []*voltha.Port{
khenaidood20a5852018-10-22 22:09:55 -040082 {PortNo: 1, Label: "pon"},
83 {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040084 },
85 }
86 return &tdm
87}
88
Kent Hagerman45a13e42020-04-13 12:23:50 -040089func (tdm *testDeviceManager) GetDevice(ctx context.Context, deviceID *voltha.ID) (*voltha.Device, error) {
90 if d, ok := tdm.devices[deviceID.Id]; ok {
khenaidoo89b0e942018-10-21 21:11:33 -040091 return d, nil
92 }
npujar1d86a522019-11-14 17:11:16 +053093 return nil, errors.New("ABSENT")
khenaidoo89b0e942018-10-21 21:11:33 -040094}
npujar1d86a522019-11-14 17:11:16 +053095func (tdm *testDeviceManager) IsRootDevice(deviceID string) (bool, error) {
96 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo19d7b632018-10-30 10:49:50 -040097 return d.Root, nil
98 }
npujar1d86a522019-11-14 17:11:16 +053099 return false, errors.New("ABSENT")
khenaidoo19d7b632018-10-30 10:49:50 -0400100}
khenaidoo89b0e942018-10-21 21:11:33 -0400101
102type testFlowDecomposer struct {
Esin Karaman09959ae2019-11-29 13:59:58 +0000103 dMgr *testDeviceManager
104 logicalPorts map[uint32]*voltha.LogicalPort
khenaidoo820197c2020-02-13 16:35:33 -0500105 routes map[route.OFPortLink][]route.Hop
Esin Karaman09959ae2019-11-29 13:59:58 +0000106 defaultRules *fu.DeviceRules
khenaidoo820197c2020-02-13 16:35:33 -0500107 deviceRoutes *route.DeviceRoutes
Esin Karaman09959ae2019-11-29 13:59:58 +0000108 fd *FlowDecomposer
109 logicalPortsNo map[uint32]bool
khenaidoo89b0e942018-10-21 21:11:33 -0400110}
111
Scott Bakerfdea1e32020-02-21 15:35:41 -0800112func newTestFlowDecomposer(t *testing.T, deviceMgr *testDeviceManager) *testFlowDecomposer {
khenaidoo89b0e942018-10-21 21:11:33 -0400113 var tfd testFlowDecomposer
114 tfd.dMgr = deviceMgr
115
116 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
Esin Karaman09959ae2019-11-29 13:59:58 +0000117 tfd.logicalPortsNo = make(map[uint32]bool)
khenaidoo89b0e942018-10-21 21:11:33 -0400118 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
119 // port
120 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
Esin Karaman09959ae2019-11-29 13:59:58 +0000121 tfd.logicalPorts[65536] = &voltha.LogicalPort{Id: "65536", DeviceId: "olt", DevicePortNo: 65536}
khenaidoo89b0e942018-10-21 21:11:33 -0400122 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
123 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
124 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
125 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
126
Esin Karaman09959ae2019-11-29 13:59:58 +0000127 tfd.logicalPortsNo[10] = false
128 tfd.logicalPortsNo[65536] = true // nni
129
khenaidoo820197c2020-02-13 16:35:33 -0500130 tfd.routes = make(map[route.OFPortLink][]route.Hop)
khenaidoo89b0e942018-10-21 21:11:33 -0400131
132 //DOWNSTREAM ROUTES
133
khenaidoo820197c2020-02-13 16:35:33 -0500134 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 1}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400135 {
khenaidoo89b0e942018-10-21 21:11:33 -0400136 DeviceID: "olt",
137 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
138 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
139 },
khenaidood20a5852018-10-22 22:09:55 -0400140 {
khenaidoo89b0e942018-10-21 21:11:33 -0400141 DeviceID: "onu1",
142 Ingress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
143 Egress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
144 },
145 }
146
khenaidoo820197c2020-02-13 16:35:33 -0500147 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 2}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400148 {
khenaidoo89b0e942018-10-21 21:11:33 -0400149 DeviceID: "olt",
150 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
151 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
152 },
khenaidood20a5852018-10-22 22:09:55 -0400153 {
khenaidoo89b0e942018-10-21 21:11:33 -0400154 DeviceID: "onu2",
155 Ingress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
156 Egress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
157 },
158 }
khenaidoo820197c2020-02-13 16:35:33 -0500159 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 3}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400160 {
khenaidoo89b0e942018-10-21 21:11:33 -0400161 DeviceID: "olt",
162 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
163 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
164 },
khenaidood20a5852018-10-22 22:09:55 -0400165 {
khenaidoo89b0e942018-10-21 21:11:33 -0400166 DeviceID: "onu3",
167 Ingress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
168 Egress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
169 },
170 }
khenaidoo820197c2020-02-13 16:35:33 -0500171 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 4}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400172 {
khenaidoo89b0e942018-10-21 21:11:33 -0400173 DeviceID: "olt",
174 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
175 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
176 },
khenaidood20a5852018-10-22 22:09:55 -0400177 {
khenaidoo89b0e942018-10-21 21:11:33 -0400178 DeviceID: "onu4",
179 Ingress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
180 Egress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
181 },
182 }
khenaidoo820197c2020-02-13 16:35:33 -0500183 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 10}] = []route.Hop{
Humera Kouser4ff89012019-08-25 19:01:51 -0400184 {
185 DeviceID: "olt",
186 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
187 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
188 },
189 {
190 DeviceID: "olt",
191 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
192 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
193 },
194 }
khenaidoo89b0e942018-10-21 21:11:33 -0400195
196 //UPSTREAM DATA PLANE
197
khenaidoo820197c2020-02-13 16:35:33 -0500198 tfd.routes[route.OFPortLink{Ingress: 1, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400199 {
khenaidoo89b0e942018-10-21 21:11:33 -0400200 DeviceID: "onu1",
201 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
202 Egress: tfd.dMgr.devices["onu1"].Ports[0].PortNo,
203 },
khenaidood20a5852018-10-22 22:09:55 -0400204 {
khenaidoo89b0e942018-10-21 21:11:33 -0400205 DeviceID: "olt",
206 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
207 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
208 },
209 }
khenaidoo820197c2020-02-13 16:35:33 -0500210 tfd.routes[route.OFPortLink{Ingress: 2, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400211 {
khenaidoo89b0e942018-10-21 21:11:33 -0400212 DeviceID: "onu2",
213 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
214 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
215 },
khenaidood20a5852018-10-22 22:09:55 -0400216 {
khenaidoo89b0e942018-10-21 21:11:33 -0400217 DeviceID: "olt",
218 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
219 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
220 },
221 }
khenaidoo820197c2020-02-13 16:35:33 -0500222 tfd.routes[route.OFPortLink{Ingress: 3, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400223 {
khenaidoo89b0e942018-10-21 21:11:33 -0400224 DeviceID: "onu3",
225 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
226 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
227 },
khenaidood20a5852018-10-22 22:09:55 -0400228 {
khenaidoo89b0e942018-10-21 21:11:33 -0400229 DeviceID: "olt",
230 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
231 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
232 },
233 }
khenaidoo820197c2020-02-13 16:35:33 -0500234 tfd.routes[route.OFPortLink{Ingress: 4, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400235 {
khenaidoo89b0e942018-10-21 21:11:33 -0400236 DeviceID: "onu4",
237 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
238 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
239 },
khenaidood20a5852018-10-22 22:09:55 -0400240 {
khenaidoo89b0e942018-10-21 21:11:33 -0400241 DeviceID: "olt",
242 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
243 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
244 },
245 }
246
247 //UPSTREAM NEXT TABLE BASED
248
249 // openflow port 0 means absence of a port - go/protobuf interpretation
khenaidoo820197c2020-02-13 16:35:33 -0500250 tfd.routes[route.OFPortLink{Ingress: 1, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400251 {
khenaidoo89b0e942018-10-21 21:11:33 -0400252 DeviceID: "onu1",
253 Ingress: tfd.dMgr.devices["onu1"].Ports[1].PortNo,
254 Egress: tfd.dMgr.devices["onu1"].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 }
khenaidoo820197c2020-02-13 16:35:33 -0500262 tfd.routes[route.OFPortLink{Ingress: 2, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400263 {
khenaidoo89b0e942018-10-21 21:11:33 -0400264 DeviceID: "onu2",
265 Ingress: tfd.dMgr.devices["onu2"].Ports[1].PortNo,
266 Egress: tfd.dMgr.devices["onu2"].Ports[0].PortNo,
267 },
khenaidood20a5852018-10-22 22:09:55 -0400268 {
khenaidoo89b0e942018-10-21 21:11:33 -0400269 DeviceID: "olt",
270 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
271 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
272 },
273 }
khenaidoo820197c2020-02-13 16:35:33 -0500274 tfd.routes[route.OFPortLink{Ingress: 3, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400275 {
khenaidoo89b0e942018-10-21 21:11:33 -0400276 DeviceID: "onu3",
277 Ingress: tfd.dMgr.devices["onu3"].Ports[1].PortNo,
278 Egress: tfd.dMgr.devices["onu3"].Ports[0].PortNo,
279 },
khenaidood20a5852018-10-22 22:09:55 -0400280 {
khenaidoo89b0e942018-10-21 21:11:33 -0400281 DeviceID: "olt",
282 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
283 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
284 },
285 }
khenaidoo820197c2020-02-13 16:35:33 -0500286 tfd.routes[route.OFPortLink{Ingress: 4, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400287 {
khenaidoo89b0e942018-10-21 21:11:33 -0400288 DeviceID: "onu4",
289 Ingress: tfd.dMgr.devices["onu4"].Ports[1].PortNo,
290 Egress: tfd.dMgr.devices["onu4"].Ports[0].PortNo,
291 },
khenaidood20a5852018-10-22 22:09:55 -0400292 {
khenaidoo89b0e942018-10-21 21:11:33 -0400293 DeviceID: "olt",
294 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
295 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
296 },
297 }
298
299 // DOWNSTREAM NEXT TABLE BASED
300
khenaidoo820197c2020-02-13 16:35:33 -0500301 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400302 {
khenaidoo89b0e942018-10-21 21:11:33 -0400303 DeviceID: "olt",
304 Ingress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
305 Egress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
306 },
khenaidood20a5852018-10-22 22:09:55 -0400307 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400308 }
309
khenaidoo820197c2020-02-13 16:35:33 -0500310 tfd.routes[route.OFPortLink{Ingress: 0, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400311 {}, // 1st hop is wildcard
312 {
khenaidoo89b0e942018-10-21 21:11:33 -0400313 DeviceID: "olt",
314 Ingress: tfd.dMgr.devices["olt"].Ports[0].PortNo,
315 Egress: tfd.dMgr.devices["olt"].Ports[1].PortNo,
316 },
317 }
318
319 // DEFAULT RULES
320
321 tfd.defaultRules = fu.NewDeviceRules()
322 fg := fu.NewFlowsAndGroups()
npujar1d86a522019-11-14 17:11:16 +0530323 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400324 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400325 fu.InPort(2),
326 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400327 },
328 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400329 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
330 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400331 },
332 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800333 fs, err := fu.MkFlowStat(fa)
334 assert.Nil(t, err)
335 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400336 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
337
338 fg = fu.NewFlowsAndGroups()
339 fa = &fu.FlowArgs{
340 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) | 102)),
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("onu2", 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) | 103)),
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("onu3", 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) | 104)),
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("onu4", fg)
385
386 //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 -0500387 tfd.deviceRoutes = route.NewDeviceRoutes("ldid", tfd.getDeviceHelper)
388 tfd.deviceRoutes.RootPorts = make(map[uint32]uint32)
389 tfd.deviceRoutes.RootPorts[10] = 10
khenaidoo89b0e942018-10-21 21:11:33 -0400390
391 tfd.fd = NewFlowDecomposer(tfd.dMgr)
392
393 return &tfd
394}
395
npujar467fe752020-01-16 20:17:45 +0530396func (tfd *testFlowDecomposer) getDeviceHelper(ctx context.Context, deviceID string) (*voltha.Device, error) {
Kent Hagerman45a13e42020-04-13 12:23:50 -0400397 return tfd.dMgr.GetDevice(ctx, &voltha.ID{Id: deviceID})
khenaidoo89b0e942018-10-21 21:11:33 -0400398}
399
npujar1d86a522019-11-14 17:11:16 +0530400func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400401 return ""
402}
403
khenaidoo442e7c72020-03-10 16:13:48 -0400404func (tfd *testFlowDecomposer) GetLogicalDevice(ctx context.Context) (*voltha.LogicalDevice, error) {
405 return nil, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400406}
407
khenaidoo820197c2020-02-13 16:35:33 -0500408func (tfd *testFlowDecomposer) GetDeviceRoutes() *route.DeviceRoutes {
409 return tfd.deviceRoutes
khenaidoo89b0e942018-10-21 21:11:33 -0400410}
411
412func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
413 return tfd.defaultRules
414}
415
416func (tfd *testFlowDecomposer) GetWildcardInputPorts(excludePort ...uint32) []uint32 {
417 lPorts := make([]uint32, 0)
418 var exclPort uint32
419 if len(excludePort) == 1 {
420 exclPort = excludePort[0]
421 }
khenaidood20a5852018-10-22 22:09:55 -0400422 for portno := range tfd.logicalPorts {
khenaidoo89b0e942018-10-21 21:11:33 -0400423 if portno != exclPort {
424 lPorts = append(lPorts, portno)
425 }
426 }
427 return lPorts
428}
429
khenaidoo820197c2020-02-13 16:35:33 -0500430func (tfd *testFlowDecomposer) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
431 var portLink route.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400432 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400433 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400434 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400435 portLink.Egress = 10
436 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400437 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400438 }
khenaidoo19d7b632018-10-30 10:49:50 -0400439 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400440 portLink.Ingress = 0
441 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400442 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400443 }
444 for key, val := range tfd.routes {
445 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
khenaidoo820197c2020-02-13 16:35:33 -0500446 return val, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400447 }
448 }
khenaidoo820197c2020-02-13 16:35:33 -0500449 return nil, status.Errorf(codes.FailedPrecondition, "no route from:%d to:%d", ingressPortNo, egressPortNo)
khenaidoo89b0e942018-10-21 21:11:33 -0400450}
451
Esin Karaman09959ae2019-11-29 13:59:58 +0000452func (tfd *testFlowDecomposer) GetNNIPorts() []uint32 {
453 nniPorts := make([]uint32, 0)
454 for portNo, nni := range tfd.logicalPortsNo {
455 if nni {
456 nniPorts = append(nniPorts, portNo)
457 }
458 }
459 return nniPorts
460}
461
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400462func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
463
npujar1d86a522019-11-14 17:11:16 +0530464 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400465 KV: fu.OfpFlowModArgs{"priority": 1000},
466 MatchFields: []*ofp.OfpOxmOfbField{
467 fu.InPort(1),
468 fu.VlanVid(50),
469 fu.EthType(0x888e),
470 },
471 Actions: []*ofp.OfpAction{
472 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
473 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
474 },
475 }
476
Scott Bakerfdea1e32020-02-21 15:35:41 -0800477 fs, err := fu.MkFlowStat(fa)
478 assert.Nil(t, err)
479 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400480 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800481 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400482
khenaidoo820197c2020-02-13 16:35:33 -0500483 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
484 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400485 onu1FlowAndGroup := deviceRules.Rules["onu1"]
486 oltFlowAndGroup := deviceRules.Rules["olt"]
487 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
488 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
489 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
490
npujar1d86a522019-11-14 17:11:16 +0530491 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400492 KV: fu.OfpFlowModArgs{"priority": 1000},
493 MatchFields: []*ofp.OfpOxmOfbField{
494 fu.InPort(1),
495 fu.TunnelId(uint64(1)),
496 fu.VlanVid(50),
497 fu.EthType(0x888e),
498 },
499 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400500 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
501 },
502 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800503 expectedOltFlow, err := fu.MkFlowStat(faParent)
504 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400505 derivedFlow := oltFlowAndGroup.GetFlow(0)
506 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
507
npujar1d86a522019-11-14 17:11:16 +0530508 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400509 KV: fu.OfpFlowModArgs{"priority": 1000},
510 MatchFields: []*ofp.OfpOxmOfbField{
511 fu.InPort(2),
512 fu.TunnelId(uint64(1)),
513 fu.EthType(0x888e),
514 },
515 Actions: []*ofp.OfpAction{
516 fu.PushVlan(0x8100),
517 fu.SetField(fu.VlanVid(50)),
518 fu.Output(1),
519 },
520 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800521 expectedOnuFlow, err := fu.MkFlowStat(faChild)
522 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400523 derivedFlow = onu1FlowAndGroup.GetFlow(0)
524 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
525}
526
527func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
528
npujar1d86a522019-11-14 17:11:16 +0530529 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400530 KV: fu.OfpFlowModArgs{"priority": 1000},
531 MatchFields: []*ofp.OfpOxmOfbField{
532 fu.InPort(1),
533 fu.VlanVid(0),
534 fu.EthType(0x888e),
535 },
536 Actions: []*ofp.OfpAction{
537 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
538 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
539 },
540 }
541
Scott Bakerfdea1e32020-02-21 15:35:41 -0800542 fs, err := fu.MkFlowStat(fa)
543 assert.Nil(t, err)
544 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400545 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800546 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400547
khenaidoo820197c2020-02-13 16:35:33 -0500548 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
549 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400550 onu1FlowAndGroup := deviceRules.Rules["onu1"]
551 oltFlowAndGroup := deviceRules.Rules["olt"]
552 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
553 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
554 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
555
npujar1d86a522019-11-14 17:11:16 +0530556 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400557 KV: fu.OfpFlowModArgs{"priority": 1000},
558 MatchFields: []*ofp.OfpOxmOfbField{
559 fu.InPort(1),
560 fu.TunnelId(uint64(1)),
561 fu.VlanVid(0),
562 fu.EthType(0x888e),
563 },
564 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400565 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
566 },
567 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800568 expectedOltFlow, err := fu.MkFlowStat(faParent)
569 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400570 derivedFlow := oltFlowAndGroup.GetFlow(0)
571 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
572
npujar1d86a522019-11-14 17:11:16 +0530573 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400574 KV: fu.OfpFlowModArgs{"priority": 1000},
575 MatchFields: []*ofp.OfpOxmOfbField{
576 fu.InPort(2),
577 fu.TunnelId(uint64(1)),
578 fu.EthType(0x888e),
579 },
580 Actions: []*ofp.OfpAction{
581 fu.PushVlan(0x8100),
582 fu.SetField(fu.VlanVid(0)),
583 fu.Output(1),
584 },
585 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800586 expectedOnuFlow, err := fu.MkFlowStat(faChild)
587 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400588 derivedFlow = onu1FlowAndGroup.GetFlow(0)
589 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
590}
591
592func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400593
npujar1d86a522019-11-14 17:11:16 +0530594 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400595 KV: fu.OfpFlowModArgs{"priority": 1000},
596 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400597 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400598 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400599 },
600 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400601 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
602 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400603 },
604 }
605
Scott Bakerfdea1e32020-02-21 15:35:41 -0800606 fs, err := fu.MkFlowStat(fa)
607 assert.Nil(t, err)
608 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo89b0e942018-10-21 21:11:33 -0400609 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800610 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400611
khenaidoo820197c2020-02-13 16:35:33 -0500612 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
613 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400614 onu1FlowAndGroup := deviceRules.Rules["onu1"]
615 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400616 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400617 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400618 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
619
npujar1d86a522019-11-14 17:11:16 +0530620 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400621 KV: fu.OfpFlowModArgs{"priority": 1000},
622 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400623 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400624 fu.TunnelId(uint64(1)),
625 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400626 },
627 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400628 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400629 },
630 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800631 expectedOltFlow, err := fu.MkFlowStat(faParent)
632 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400633 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400634 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400635
npujar1d86a522019-11-14 17:11:16 +0530636 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400637 KV: fu.OfpFlowModArgs{"priority": 1000},
638 MatchFields: []*ofp.OfpOxmOfbField{
639 fu.InPort(2),
640 fu.TunnelId(uint64(1)),
641 fu.EthType(0x888e),
642 },
643 Actions: []*ofp.OfpAction{
644 fu.Output(1),
645 },
646 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800647 expectedOnuFlow, err := fu.MkFlowStat(faChild)
648 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400649 derivedFlow = onu1FlowAndGroup.GetFlow(0)
650 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400651}
652
653func TestDhcpReRouteRuleDecomposition(t *testing.T) {
654
npujar1d86a522019-11-14 17:11:16 +0530655 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400656 KV: fu.OfpFlowModArgs{"priority": 1000},
657 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400658 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400659 fu.EthType(0x0800),
660 fu.Ipv4Dst(0xffffffff),
661 fu.IpProto(17),
662 fu.UdpSrc(68),
663 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400664 },
665 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400666 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400667 },
668 }
669
Scott Bakerfdea1e32020-02-21 15:35:41 -0800670 fs, err := fu.MkFlowStat(fa)
671 assert.Nil(t, err)
672 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo89b0e942018-10-21 21:11:33 -0400673 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800674 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400675
khenaidoo820197c2020-02-13 16:35:33 -0500676 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
677 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400678 onu1FlowAndGroup := deviceRules.Rules["onu1"]
679 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400680 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
681 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400682 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400683 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
684
npujar1d86a522019-11-14 17:11:16 +0530685 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400686 KV: fu.OfpFlowModArgs{"priority": 1000},
687 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400688 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400689 fu.TunnelId(uint64(1)),
690 fu.EthType(0x0800),
691 fu.Ipv4Dst(0xffffffff),
692 fu.IpProto(17),
693 fu.UdpSrc(68),
694 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400695 },
696 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400697 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400698 },
699 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800700 expectedOltFlow, err := fu.MkFlowStat(faParent)
701 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400702 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400703 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400704
npujar1d86a522019-11-14 17:11:16 +0530705 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400706 KV: fu.OfpFlowModArgs{"priority": 1000},
707 MatchFields: []*ofp.OfpOxmOfbField{
708 fu.InPort(2),
709 fu.TunnelId(uint64(1)),
710 fu.EthType(0x0800),
711 fu.Ipv4Dst(0xffffffff),
712 fu.IpProto(17),
713 fu.UdpSrc(68),
714 fu.UdpDst(67),
715 },
716 Actions: []*ofp.OfpAction{
717 fu.Output(1),
718 },
719 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800720 expectedOnuFlow, err := fu.MkFlowStat(faChild)
721 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400722 derivedFlow = onu1FlowAndGroup.GetFlow(0)
723 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400724}
725
Humera Kouser4ff89012019-08-25 19:01:51 -0400726func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530727 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400728 KV: fu.OfpFlowModArgs{"priority": 1000},
729 MatchFields: []*ofp.OfpOxmOfbField{
730 fu.InPort(10),
731 fu.EthType(0x88CC),
732 },
733 Actions: []*ofp.OfpAction{
734 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
735 },
736 }
737
Scott Bakerfdea1e32020-02-21 15:35:41 -0800738 fs, err := fu.MkFlowStat(fa)
739 assert.Nil(t, err)
740 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
Humera Kouser4ff89012019-08-25 19:01:51 -0400741 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800742 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo820197c2020-02-13 16:35:33 -0500743 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
744 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400745 onu1FlowAndGroup := deviceRules.Rules["onu1"]
746 oltFlowAndGroup := deviceRules.Rules["olt"]
747 assert.Nil(t, onu1FlowAndGroup)
748 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
749 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
750
751 fa = &fu.FlowArgs{
752 KV: fu.OfpFlowModArgs{"priority": 1000},
753 MatchFields: []*ofp.OfpOxmOfbField{
754 fu.InPort(2),
755 fu.EthType(0x88CC),
756 },
757 Actions: []*ofp.OfpAction{
758 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
759 },
760 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800761 expectedOltFlow, err := fu.MkFlowStat(fa)
762 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400763 derivedFlow := oltFlowAndGroup.GetFlow(0)
764 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
765}
766
khenaidood20a5852018-10-22 22:09:55 -0400767func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530768 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400769 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400770 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400771 fu.InPort(1),
772 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
773 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400774 },
775 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400776 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400777 },
778 }
779
npujar1d86a522019-11-14 17:11:16 +0530780 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400781 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400782 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400783 fu.InPort(1),
784 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
785 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400786 },
787 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400788 fu.PushVlan(0x8100),
789 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
790 fu.SetField(fu.VlanPcp(0)),
791 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400792 },
793 }
794
Scott Bakerfdea1e32020-02-21 15:35:41 -0800795 fs, err := fu.MkFlowStat(fa)
796 assert.Nil(t, err)
797 fs2, err := fu.MkFlowStat(fa2)
798 assert.Nil(t, err)
799 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs, fs2}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400800 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
801 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
802 Data: &ofp.OfpInstruction_GotoTable{
803 GotoTable: &ofp.OfpInstructionGotoTable{
804 TableId: 1,
805 },
806 }}}
807
khenaidood20a5852018-10-22 22:09:55 -0400808 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800809 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400810
khenaidoo820197c2020-02-13 16:35:33 -0500811 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
812 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400813 onu1FlowAndGroup := deviceRules.Rules["onu1"]
814 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400815 assert.NotNil(t, onu1FlowAndGroup)
816 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400817 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400818 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
819 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
820 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
821
822 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400823 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400824 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400825 fu.InPort(2),
826 fu.TunnelId(uint64(1)),
827 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
828 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400829 },
830 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400831 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
832 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400833 },
834 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400835
khenaidoo3306c992019-05-24 16:57:35 -0400836 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400837 // Form the expected flow
Scott Bakerfdea1e32020-02-21 15:35:41 -0800838 expectedOnu1Flow, err := fu.MkFlowStat(fa)
839 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400840 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
841 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
842 Data: &ofp.OfpInstruction_Actions{
843 Actions: &ofp.OfpInstructionActions{
844 Actions: []*ofp.OfpAction{{
845 Type: 0,
846 Action: &ofp.OfpAction_Output{
847 Output: &ofp.OfpActionOutput{
848 Port: 1,
849 MaxLen: 65509,
850 },
851 }}}}}}}
852
853 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400854 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
855
856 fa = &fu.FlowArgs{
857 KV: fu.OfpFlowModArgs{"priority": 500},
858 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400859 fu.InPort(1),
860 fu.TunnelId(uint64(1)),
861 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
862 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400863 },
864 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400865 fu.PushVlan(0x8100),
866 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
867 fu.SetField(fu.VlanPcp(0)),
868 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400869 },
870 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800871 expectedOltFlow, err := fu.MkFlowStat(fa)
872 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400873 derivedFlow = oltFlowAndGroup.GetFlow(0)
874 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
875}
876
877func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Girish Kumarf56a4682020-03-20 20:07:46 +0000878 logger.Debugf("Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530879 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400880 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400881 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400882 fu.InPort(10),
883 fu.Metadata_ofp((1000 << 32) | 1),
884 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400885 },
886 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400887 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400888 },
889 }
890
npujar1d86a522019-11-14 17:11:16 +0530891 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400892 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400893 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400894 fu.InPort(10),
895 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
896 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400897 },
898 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400899 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
900 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400901 },
902 }
903
Scott Bakerfdea1e32020-02-21 15:35:41 -0800904 fs1, err := fu.MkFlowStat(fa1)
905 assert.Nil(t, err)
906 fs2, err := fu.MkFlowStat(fa2)
907 assert.Nil(t, err)
908 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs1, fs2}}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400909 flows.Items[0].Instructions = []*ofp.OfpInstruction{{
910 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
911 Data: &ofp.OfpInstruction_GotoTable{
912 GotoTable: &ofp.OfpInstructionGotoTable{
913 TableId: 1,
914 },
915 }}}
916
khenaidood20a5852018-10-22 22:09:55 -0400917 groups := ofp.FlowGroups{}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800918 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400919
khenaidoo820197c2020-02-13 16:35:33 -0500920 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
921 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400922 onu1FlowAndGroup := deviceRules.Rules["onu1"]
923 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400924 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400925 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
926 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
927 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
928
929 fa1 = &fu.FlowArgs{
930 KV: fu.OfpFlowModArgs{"priority": 500},
931 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400932 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400933 fu.TunnelId(uint64(10)),
934 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400935 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400936 },
937 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400938 fu.PopVlan(),
939 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400940 },
941 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400942
khenaidood20a5852018-10-22 22:09:55 -0400943 derivedFlow := oltFlowAndGroup.GetFlow(0)
Scott Bakerfdea1e32020-02-21 15:35:41 -0800944 expectedOltFlow, err := fu.MkFlowStat(fa1)
945 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400946 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
947 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
948 Data: &ofp.OfpInstruction_Actions{
949 Actions: &ofp.OfpInstructionActions{
950 Actions: []*ofp.OfpAction{{
951 Type: 0,
952 Action: &ofp.OfpAction_Output{
953 Output: &ofp.OfpActionOutput{
954 Port: 1,
955 MaxLen: 65509,
956 },
957 }}}}}}}
958 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400959 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
960
961 fa1 = &fu.FlowArgs{
962 KV: fu.OfpFlowModArgs{"priority": 500},
963 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400964 fu.InPort(1),
965 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
966 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400967 },
968 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400969 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
970 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400971 },
972 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800973 expectedOnu1Flow, err := fu.MkFlowStat(fa1)
974 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400975 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400976 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
977}
978
979func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530980 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -0400981 KV: fu.OfpFlowModArgs{"priority": 500},
982 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400983 fu.InPort(10),
984 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
985 fu.VlanPcp(0),
986 fu.EthType(0x800),
987 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400988 },
989 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400990 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -0400991 },
992 }
993
npujar1d86a522019-11-14 17:11:16 +0530994 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -0400995 GroupId: 10,
996 Buckets: []*ofp.OfpBucket{
997 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400998 fu.PopVlan(),
999 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001000 },
1001 },
1002 },
1003 }
1004
Scott Bakerfdea1e32020-02-21 15:35:41 -08001005 fs, err := fu.MkFlowStat(fa)
1006 assert.Nil(t, err)
1007 flows := ofp.Flows{Items: []*ofp.OfpFlowStats{fs}}
khenaidoo68c930b2019-05-13 11:46:51 -04001008 groups := ofp.FlowGroups{Items: []*ofp.OfpGroupEntry{fu.MkGroupStat(ga)}}
Scott Bakerfdea1e32020-02-21 15:35:41 -08001009 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -04001010
khenaidoo820197c2020-02-13 16:35:33 -05001011 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
1012 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001013 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -04001014 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1015 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1016
1017 fa = &fu.FlowArgs{
1018 KV: fu.OfpFlowModArgs{"priority": 500},
1019 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +00001020 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -04001021 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1022 fu.VlanPcp(0),
1023 fu.EthType(0x800),
1024 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001025 },
1026 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001027 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001028 },
1029 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001030 expectedOltFlow, err := fu.MkFlowStat(fa)
1031 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001032 derivedFlow := oltFlowAndGroup.GetFlow(0)
1033 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001034}