blob: 88e6c039ade4159ae210d9c6d5611e17ac67497f [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"
Kent Hagerman433a31a2020-05-20 19:04:48 -040021 "testing"
22
Kent Hagerman6031aad2020-07-29 16:36:33 -040023 "github.com/opencord/voltha-go/rw_core/core/device/state"
khenaidoo820197c2020-02-13 16:35:33 -050024 "github.com/opencord/voltha-go/rw_core/route"
Maninderdfadc982020-10-28 14:04:33 +053025 fu "github.com/opencord/voltha-lib-go/v4/pkg/flows"
26 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
27 "github.com/opencord/voltha-protos/v4/go/voltha"
khenaidoo89b0e942018-10-21 21:11:33 -040028 "github.com/stretchr/testify/assert"
khenaidoo820197c2020-02-13 16:35:33 -050029 "google.golang.org/grpc/codes"
30 "google.golang.org/grpc/status"
khenaidoo89b0e942018-10-21 21:11:33 -040031)
32
khenaidoo89b0e942018-10-21 21:11:33 -040033type testDeviceManager struct {
Kent Hagerman6031aad2020-07-29 16:36:33 -040034 state.DeviceManager
Kent Hagerman2a07b862020-06-19 15:23:07 -040035 devices map[string]*voltha.Device
36 devicePorts map[string]map[uint32]*voltha.Port
khenaidoo89b0e942018-10-21 21:11:33 -040037}
38
39func newTestDeviceManager() *testDeviceManager {
40 var tdm testDeviceManager
41 tdm.devices = make(map[string]*voltha.Device)
Kent Hagerman2a07b862020-06-19 15:23:07 -040042 tdm.devicePorts = make(map[string]map[uint32]*voltha.Port)
khenaidoo89b0e942018-10-21 21:11:33 -040043 tdm.devices["olt"] = &voltha.Device{
44 Id: "olt",
45 Root: true,
46 ParentId: "logical_device",
Kent Hagerman2a07b862020-06-19 15:23:07 -040047 }
48 tdm.devicePorts["olt"] = map[uint32]*voltha.Port{
49 1: {PortNo: 1, Label: "pon"},
50 2: {PortNo: 2, Label: "nni"},
khenaidoo89b0e942018-10-21 21:11:33 -040051 }
52 tdm.devices["onu1"] = &voltha.Device{
53 Id: "onu1",
54 Root: false,
55 ParentId: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -040056 }
57 tdm.devicePorts["onu1"] = map[uint32]*voltha.Port{
58 1: {PortNo: 1, Label: "pon"},
59 2: {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040060 }
61 tdm.devices["onu2"] = &voltha.Device{
62 Id: "onu2",
63 Root: false,
64 ParentId: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -040065 }
66 tdm.devicePorts["onu2"] = map[uint32]*voltha.Port{
67 1: {PortNo: 1, Label: "pon"},
68 2: {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040069 }
70 tdm.devices["onu3"] = &voltha.Device{
71 Id: "onu3",
72 Root: false,
73 ParentId: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -040074 }
75 tdm.devicePorts["onu3"] = map[uint32]*voltha.Port{
76 1: {PortNo: 1, Label: "pon"},
77 2: {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040078 }
79 tdm.devices["onu4"] = &voltha.Device{
80 Id: "onu4",
81 Root: false,
82 ParentId: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -040083 }
84 tdm.devicePorts["onu4"] = map[uint32]*voltha.Port{
85 1: {PortNo: 1, Label: "pon"},
86 2: {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040087 }
88 return &tdm
89}
90
Kent Hagerman45a13e42020-04-13 12:23:50 -040091func (tdm *testDeviceManager) GetDevice(ctx context.Context, deviceID *voltha.ID) (*voltha.Device, error) {
92 if d, ok := tdm.devices[deviceID.Id]; ok {
khenaidoo89b0e942018-10-21 21:11:33 -040093 return d, nil
94 }
npujar1d86a522019-11-14 17:11:16 +053095 return nil, errors.New("ABSENT")
khenaidoo89b0e942018-10-21 21:11:33 -040096}
Kent Hagerman2a07b862020-06-19 15:23:07 -040097func (tdm *testDeviceManager) listDevicePorts(ctx context.Context, deviceID string) (map[uint32]*voltha.Port, error) {
98 ports, have := tdm.devicePorts[deviceID]
99 if !have {
100 return nil, errors.New("ABSENT")
101 }
102 return ports, nil
103}
npujar1d86a522019-11-14 17:11:16 +0530104func (tdm *testDeviceManager) IsRootDevice(deviceID string) (bool, error) {
105 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo19d7b632018-10-30 10:49:50 -0400106 return d.Root, nil
107 }
npujar1d86a522019-11-14 17:11:16 +0530108 return false, errors.New("ABSENT")
khenaidoo19d7b632018-10-30 10:49:50 -0400109}
khenaidoo89b0e942018-10-21 21:11:33 -0400110
111type testFlowDecomposer struct {
Esin Karaman09959ae2019-11-29 13:59:58 +0000112 dMgr *testDeviceManager
113 logicalPorts map[uint32]*voltha.LogicalPort
khenaidoo820197c2020-02-13 16:35:33 -0500114 routes map[route.OFPortLink][]route.Hop
Esin Karaman09959ae2019-11-29 13:59:58 +0000115 defaultRules *fu.DeviceRules
khenaidoo820197c2020-02-13 16:35:33 -0500116 deviceRoutes *route.DeviceRoutes
Esin Karaman09959ae2019-11-29 13:59:58 +0000117 fd *FlowDecomposer
118 logicalPortsNo map[uint32]bool
khenaidoo89b0e942018-10-21 21:11:33 -0400119}
120
Scott Bakerfdea1e32020-02-21 15:35:41 -0800121func newTestFlowDecomposer(t *testing.T, deviceMgr *testDeviceManager) *testFlowDecomposer {
khenaidoo89b0e942018-10-21 21:11:33 -0400122 var tfd testFlowDecomposer
123 tfd.dMgr = deviceMgr
124
125 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
Esin Karaman09959ae2019-11-29 13:59:58 +0000126 tfd.logicalPortsNo = make(map[uint32]bool)
khenaidoo89b0e942018-10-21 21:11:33 -0400127 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
128 // port
129 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
Esin Karaman09959ae2019-11-29 13:59:58 +0000130 tfd.logicalPorts[65536] = &voltha.LogicalPort{Id: "65536", DeviceId: "olt", DevicePortNo: 65536}
khenaidoo89b0e942018-10-21 21:11:33 -0400131 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
132 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
133 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
134 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
135
Esin Karaman09959ae2019-11-29 13:59:58 +0000136 tfd.logicalPortsNo[10] = false
137 tfd.logicalPortsNo[65536] = true // nni
138
khenaidoo820197c2020-02-13 16:35:33 -0500139 tfd.routes = make(map[route.OFPortLink][]route.Hop)
khenaidoo89b0e942018-10-21 21:11:33 -0400140
141 //DOWNSTREAM ROUTES
142
khenaidoo820197c2020-02-13 16:35:33 -0500143 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 1}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400144 {
khenaidoo89b0e942018-10-21 21:11:33 -0400145 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400146 Ingress: 2,
147 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400148 },
khenaidood20a5852018-10-22 22:09:55 -0400149 {
khenaidoo89b0e942018-10-21 21:11:33 -0400150 DeviceID: "onu1",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400151 Ingress: 1,
152 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400153 },
154 }
155
khenaidoo820197c2020-02-13 16:35:33 -0500156 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 2}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400157 {
khenaidoo89b0e942018-10-21 21:11:33 -0400158 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400159 Ingress: 2,
160 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400161 },
khenaidood20a5852018-10-22 22:09:55 -0400162 {
khenaidoo89b0e942018-10-21 21:11:33 -0400163 DeviceID: "onu2",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400164 Ingress: 1,
165 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400166 },
167 }
khenaidoo820197c2020-02-13 16:35:33 -0500168 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 3}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400169 {
khenaidoo89b0e942018-10-21 21:11:33 -0400170 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400171 Ingress: 2,
172 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400173 },
khenaidood20a5852018-10-22 22:09:55 -0400174 {
khenaidoo89b0e942018-10-21 21:11:33 -0400175 DeviceID: "onu3",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400176 Ingress: 1,
177 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400178 },
179 }
khenaidoo820197c2020-02-13 16:35:33 -0500180 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 4}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400181 {
khenaidoo89b0e942018-10-21 21:11:33 -0400182 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400183 Ingress: 2,
184 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400185 },
khenaidood20a5852018-10-22 22:09:55 -0400186 {
khenaidoo89b0e942018-10-21 21:11:33 -0400187 DeviceID: "onu4",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400188 Ingress: 1,
189 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400190 },
191 }
khenaidoo820197c2020-02-13 16:35:33 -0500192 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 10}] = []route.Hop{
Humera Kouser4ff89012019-08-25 19:01:51 -0400193 {
194 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400195 Ingress: 2,
196 Egress: 2,
Humera Kouser4ff89012019-08-25 19:01:51 -0400197 },
198 {
199 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400200 Ingress: 2,
201 Egress: 2,
Humera Kouser4ff89012019-08-25 19:01:51 -0400202 },
203 }
khenaidoo89b0e942018-10-21 21:11:33 -0400204
205 //UPSTREAM DATA PLANE
206
khenaidoo820197c2020-02-13 16:35:33 -0500207 tfd.routes[route.OFPortLink{Ingress: 1, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400208 {
khenaidoo89b0e942018-10-21 21:11:33 -0400209 DeviceID: "onu1",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400210 Ingress: 2,
211 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400212 },
khenaidood20a5852018-10-22 22:09:55 -0400213 {
khenaidoo89b0e942018-10-21 21:11:33 -0400214 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400215 Ingress: 1,
216 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400217 },
218 }
khenaidoo820197c2020-02-13 16:35:33 -0500219 tfd.routes[route.OFPortLink{Ingress: 2, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400220 {
khenaidoo89b0e942018-10-21 21:11:33 -0400221 DeviceID: "onu2",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400222 Ingress: 2,
223 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400224 },
khenaidood20a5852018-10-22 22:09:55 -0400225 {
khenaidoo89b0e942018-10-21 21:11:33 -0400226 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400227 Ingress: 1,
228 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400229 },
230 }
khenaidoo820197c2020-02-13 16:35:33 -0500231 tfd.routes[route.OFPortLink{Ingress: 3, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400232 {
khenaidoo89b0e942018-10-21 21:11:33 -0400233 DeviceID: "onu3",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400234 Ingress: 2,
235 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400236 },
khenaidood20a5852018-10-22 22:09:55 -0400237 {
khenaidoo89b0e942018-10-21 21:11:33 -0400238 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400239 Ingress: 1,
240 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400241 },
242 }
khenaidoo820197c2020-02-13 16:35:33 -0500243 tfd.routes[route.OFPortLink{Ingress: 4, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400244 {
khenaidoo89b0e942018-10-21 21:11:33 -0400245 DeviceID: "onu4",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400246 Ingress: 2,
247 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400248 },
khenaidood20a5852018-10-22 22:09:55 -0400249 {
khenaidoo89b0e942018-10-21 21:11:33 -0400250 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400251 Ingress: 1,
252 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400253 },
254 }
255
256 //UPSTREAM NEXT TABLE BASED
257
258 // openflow port 0 means absence of a port - go/protobuf interpretation
khenaidoo820197c2020-02-13 16:35:33 -0500259 tfd.routes[route.OFPortLink{Ingress: 1, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400260 {
khenaidoo89b0e942018-10-21 21:11:33 -0400261 DeviceID: "onu1",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400262 Ingress: 2,
263 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400264 },
khenaidood20a5852018-10-22 22:09:55 -0400265 {
khenaidoo89b0e942018-10-21 21:11:33 -0400266 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400267 Ingress: 1,
268 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400269 },
270 }
khenaidoo820197c2020-02-13 16:35:33 -0500271 tfd.routes[route.OFPortLink{Ingress: 2, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400272 {
khenaidoo89b0e942018-10-21 21:11:33 -0400273 DeviceID: "onu2",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400274 Ingress: 2,
275 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400276 },
khenaidood20a5852018-10-22 22:09:55 -0400277 {
khenaidoo89b0e942018-10-21 21:11:33 -0400278 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400279 Ingress: 1,
280 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400281 },
282 }
khenaidoo820197c2020-02-13 16:35:33 -0500283 tfd.routes[route.OFPortLink{Ingress: 3, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400284 {
khenaidoo89b0e942018-10-21 21:11:33 -0400285 DeviceID: "onu3",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400286 Ingress: 2,
287 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400288 },
khenaidood20a5852018-10-22 22:09:55 -0400289 {
khenaidoo89b0e942018-10-21 21:11:33 -0400290 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400291 Ingress: 1,
292 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400293 },
294 }
khenaidoo820197c2020-02-13 16:35:33 -0500295 tfd.routes[route.OFPortLink{Ingress: 4, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400296 {
khenaidoo89b0e942018-10-21 21:11:33 -0400297 DeviceID: "onu4",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400298 Ingress: 2,
299 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400300 },
khenaidood20a5852018-10-22 22:09:55 -0400301 {
khenaidoo89b0e942018-10-21 21:11:33 -0400302 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400303 Ingress: 1,
304 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400305 },
306 }
307
308 // DOWNSTREAM NEXT TABLE BASED
309
khenaidoo820197c2020-02-13 16:35:33 -0500310 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400311 {
khenaidoo89b0e942018-10-21 21:11:33 -0400312 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400313 Ingress: 2,
314 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400315 },
khenaidood20a5852018-10-22 22:09:55 -0400316 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400317 }
318
khenaidoo820197c2020-02-13 16:35:33 -0500319 tfd.routes[route.OFPortLink{Ingress: 0, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400320 {}, // 1st hop is wildcard
321 {
khenaidoo89b0e942018-10-21 21:11:33 -0400322 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400323 Ingress: 1,
324 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400325 },
326 }
327
328 // DEFAULT RULES
329
330 tfd.defaultRules = fu.NewDeviceRules()
331 fg := fu.NewFlowsAndGroups()
npujar1d86a522019-11-14 17:11:16 +0530332 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400333 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400334 fu.InPort(2),
335 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400336 },
337 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400338 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
339 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400340 },
341 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800342 fs, err := fu.MkFlowStat(fa)
343 assert.Nil(t, err)
344 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400345 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
346
347 fg = fu.NewFlowsAndGroups()
348 fa = &fu.FlowArgs{
349 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400350 fu.InPort(2),
351 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400352 },
353 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400354 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
355 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400356 },
357 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800358 fs, err = fu.MkFlowStat(fa)
359 assert.Nil(t, err)
360 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400361 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
362
363 fg = fu.NewFlowsAndGroups()
364 fa = &fu.FlowArgs{
365 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400366 fu.InPort(2),
367 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400368 },
369 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400370 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 103)),
371 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400372 },
373 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800374 fs, err = fu.MkFlowStat(fa)
375 assert.Nil(t, err)
376 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400377 tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
378
379 fg = fu.NewFlowsAndGroups()
380 fa = &fu.FlowArgs{
381 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400382 fu.InPort(2),
383 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
khenaidoo89b0e942018-10-21 21:11:33 -0400384 },
385 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400386 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
387 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400388 },
389 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800390 fs, err = fu.MkFlowStat(fa)
391 assert.Nil(t, err)
392 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400393 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
394
395 //Set up the device graph - flow decomposer uses it only to verify whether a port is a root port.
Kent Hagerman2a07b862020-06-19 15:23:07 -0400396 tfd.deviceRoutes = route.NewDeviceRoutes("ldid", "olt", tfd.dMgr.listDevicePorts)
khenaidoo820197c2020-02-13 16:35:33 -0500397 tfd.deviceRoutes.RootPorts = make(map[uint32]uint32)
398 tfd.deviceRoutes.RootPorts[10] = 10
khenaidoo89b0e942018-10-21 21:11:33 -0400399
Kent Hagerman6031aad2020-07-29 16:36:33 -0400400 tfd.fd = NewFlowDecomposer(func(ctx context.Context, deviceID string) (*voltha.Device, error) {
401 return tfd.dMgr.GetDevice(ctx, &voltha.ID{Id: deviceID})
402 })
khenaidoo89b0e942018-10-21 21:11:33 -0400403
404 return &tfd
405}
406
npujar1d86a522019-11-14 17:11:16 +0530407func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400408 return ""
409}
410
khenaidoo442e7c72020-03-10 16:13:48 -0400411func (tfd *testFlowDecomposer) GetLogicalDevice(ctx context.Context) (*voltha.LogicalDevice, error) {
412 return nil, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400413}
414
khenaidoo820197c2020-02-13 16:35:33 -0500415func (tfd *testFlowDecomposer) GetDeviceRoutes() *route.DeviceRoutes {
416 return tfd.deviceRoutes
khenaidoo89b0e942018-10-21 21:11:33 -0400417}
418
419func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
420 return tfd.defaultRules
421}
422
Rohan Agrawal31f21802020-06-12 05:38:46 +0000423func (tfd *testFlowDecomposer) GetWildcardInputPorts(ctx context.Context, excludePort uint32) map[uint32]struct{} {
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400424 lPorts := make(map[uint32]struct{})
425 for portNo := range tfd.logicalPorts {
426 if portNo != excludePort {
427 lPorts[portNo] = struct{}{}
khenaidoo89b0e942018-10-21 21:11:33 -0400428 }
429 }
430 return lPorts
431}
432
khenaidoo820197c2020-02-13 16:35:33 -0500433func (tfd *testFlowDecomposer) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
434 var portLink route.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400435 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400436 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400437 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400438 portLink.Egress = 10
439 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400440 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400441 }
khenaidoo19d7b632018-10-30 10:49:50 -0400442 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400443 portLink.Ingress = 0
444 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400445 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400446 }
447 for key, val := range tfd.routes {
448 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
khenaidoo820197c2020-02-13 16:35:33 -0500449 return val, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400450 }
451 }
khenaidoo820197c2020-02-13 16:35:33 -0500452 return nil, status.Errorf(codes.FailedPrecondition, "no route from:%d to:%d", ingressPortNo, egressPortNo)
khenaidoo89b0e942018-10-21 21:11:33 -0400453}
454
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400455func (tfd *testFlowDecomposer) GetNNIPorts() map[uint32]struct{} {
456 nniPorts := make(map[uint32]struct{})
Esin Karaman09959ae2019-11-29 13:59:58 +0000457 for portNo, nni := range tfd.logicalPortsNo {
458 if nni {
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400459 nniPorts[portNo] = struct{}{}
Esin Karaman09959ae2019-11-29 13:59:58 +0000460 }
461 }
462 return nniPorts
463}
464
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400465func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
466
npujar1d86a522019-11-14 17:11:16 +0530467 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400468 KV: fu.OfpFlowModArgs{"priority": 1000},
469 MatchFields: []*ofp.OfpOxmOfbField{
470 fu.InPort(1),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700471 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400472 fu.EthType(0x888e),
473 },
474 Actions: []*ofp.OfpAction{
475 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
476 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
477 },
478 }
479
Scott Bakerfdea1e32020-02-21 15:35:41 -0800480 fs, err := fu.MkFlowStat(fa)
481 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400482 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800483 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400484
Kent Hagerman433a31a2020-05-20 19:04:48 -0400485 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500486 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400487 onu1FlowAndGroup := deviceRules.Rules["onu1"]
488 oltFlowAndGroup := deviceRules.Rules["olt"]
489 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
490 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
491 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
492
npujar1d86a522019-11-14 17:11:16 +0530493 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400494 KV: fu.OfpFlowModArgs{"priority": 1000},
495 MatchFields: []*ofp.OfpOxmOfbField{
496 fu.InPort(1),
497 fu.TunnelId(uint64(1)),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700498 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400499 fu.EthType(0x888e),
500 },
501 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400502 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
503 },
504 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800505 expectedOltFlow, err := fu.MkFlowStat(faParent)
506 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400507 derivedFlow := oltFlowAndGroup.GetFlow(0)
508 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
509
npujar1d86a522019-11-14 17:11:16 +0530510 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400511 KV: fu.OfpFlowModArgs{"priority": 1000},
512 MatchFields: []*ofp.OfpOxmOfbField{
513 fu.InPort(2),
514 fu.TunnelId(uint64(1)),
515 fu.EthType(0x888e),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700516 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400517 },
518 Actions: []*ofp.OfpAction{
519 fu.PushVlan(0x8100),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700520 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400521 fu.Output(1),
522 },
523 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800524 expectedOnuFlow, err := fu.MkFlowStat(faChild)
525 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400526 derivedFlow = onu1FlowAndGroup.GetFlow(0)
527 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
528}
529
530func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
531
npujar1d86a522019-11-14 17:11:16 +0530532 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400533 KV: fu.OfpFlowModArgs{"priority": 1000},
534 MatchFields: []*ofp.OfpOxmOfbField{
535 fu.InPort(1),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700536 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400537 fu.EthType(0x888e),
538 },
539 Actions: []*ofp.OfpAction{
540 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
541 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
542 },
543 }
544
Scott Bakerfdea1e32020-02-21 15:35:41 -0800545 fs, err := fu.MkFlowStat(fa)
546 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400547 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800548 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400549
Kent Hagerman433a31a2020-05-20 19:04:48 -0400550 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500551 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400552 onu1FlowAndGroup := deviceRules.Rules["onu1"]
553 oltFlowAndGroup := deviceRules.Rules["olt"]
554 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
555 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
556 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
557
npujar1d86a522019-11-14 17:11:16 +0530558 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400559 KV: fu.OfpFlowModArgs{"priority": 1000},
560 MatchFields: []*ofp.OfpOxmOfbField{
561 fu.InPort(1),
562 fu.TunnelId(uint64(1)),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700563 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400564 fu.EthType(0x888e),
565 },
566 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400567 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
568 },
569 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800570 expectedOltFlow, err := fu.MkFlowStat(faParent)
571 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400572 derivedFlow := oltFlowAndGroup.GetFlow(0)
573 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
574
npujar1d86a522019-11-14 17:11:16 +0530575 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400576 KV: fu.OfpFlowModArgs{"priority": 1000},
577 MatchFields: []*ofp.OfpOxmOfbField{
578 fu.InPort(2),
579 fu.TunnelId(uint64(1)),
580 fu.EthType(0x888e),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700581 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400582 },
583 Actions: []*ofp.OfpAction{
584 fu.PushVlan(0x8100),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700585 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400586 fu.Output(1),
587 },
588 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800589 expectedOnuFlow, err := fu.MkFlowStat(faChild)
590 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400591 derivedFlow = onu1FlowAndGroup.GetFlow(0)
592 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
593}
594
595func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400596
npujar1d86a522019-11-14 17:11:16 +0530597 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400598 KV: fu.OfpFlowModArgs{"priority": 1000},
599 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400600 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400601 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400602 },
603 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400604 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
605 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400606 },
607 }
608
Scott Bakerfdea1e32020-02-21 15:35:41 -0800609 fs, err := fu.MkFlowStat(fa)
610 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400611 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800612 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400613
Kent Hagerman433a31a2020-05-20 19:04:48 -0400614 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500615 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400616 onu1FlowAndGroup := deviceRules.Rules["onu1"]
617 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400618 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400619 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400620 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
621
npujar1d86a522019-11-14 17:11:16 +0530622 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400623 KV: fu.OfpFlowModArgs{"priority": 1000},
624 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400625 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400626 fu.TunnelId(uint64(1)),
627 fu.EthType(0x888e),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700628 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
khenaidoo89b0e942018-10-21 21:11:33 -0400629 },
630 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400631 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400632 },
633 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800634 expectedOltFlow, err := fu.MkFlowStat(faParent)
635 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400636 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400637 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400638
npujar1d86a522019-11-14 17:11:16 +0530639 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400640 KV: fu.OfpFlowModArgs{"priority": 1000},
641 MatchFields: []*ofp.OfpOxmOfbField{
642 fu.InPort(2),
643 fu.TunnelId(uint64(1)),
644 fu.EthType(0x888e),
645 },
646 Actions: []*ofp.OfpAction{
Girish Gowdra9a50f032020-09-16 13:21:10 -0700647 fu.PushVlan(0x8100),
648 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400649 fu.Output(1),
650 },
651 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800652 expectedOnuFlow, err := fu.MkFlowStat(faChild)
653 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400654 derivedFlow = onu1FlowAndGroup.GetFlow(0)
655 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400656}
657
Marcos Aurelio Carrero (Furukawa)a61a72c2021-01-28 13:48:20 -0300658func TestPppoedReRouteRuleVlanDecomposition(t *testing.T) {
659
660 fa := &fu.FlowArgs{
661 KV: fu.OfpFlowModArgs{"priority": 1000},
662 MatchFields: []*ofp.OfpOxmOfbField{
663 fu.InPort(1),
664 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
665 fu.EthType(0x8863),
666 },
667 Actions: []*ofp.OfpAction{
668 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
669 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
670 },
671 }
672
673 fs, err := fu.MkFlowStat(fa)
674 assert.Nil(t, err)
675 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
676 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
677
678 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
679 assert.Nil(t, err)
680 onu1FlowAndGroup := deviceRules.Rules["onu1"]
681 oltFlowAndGroup := deviceRules.Rules["olt"]
682 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
683 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
684 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
685
686 faParent := &fu.FlowArgs{
687 KV: fu.OfpFlowModArgs{"priority": 1000},
688 MatchFields: []*ofp.OfpOxmOfbField{
689 fu.InPort(1),
690 fu.TunnelId(uint64(1)),
691 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
692 fu.EthType(0x8863),
693 },
694 Actions: []*ofp.OfpAction{
695 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
696 },
697 }
698 expectedOltFlow, err := fu.MkFlowStat(faParent)
699 assert.Nil(t, err)
700 derivedFlow := oltFlowAndGroup.GetFlow(0)
701 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
702
703 faChild := &fu.FlowArgs{
704 KV: fu.OfpFlowModArgs{"priority": 1000},
705 MatchFields: []*ofp.OfpOxmOfbField{
706 fu.InPort(2),
707 fu.TunnelId(uint64(1)),
708 fu.EthType(0x8863),
709 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
710 },
711 Actions: []*ofp.OfpAction{
712 fu.PushVlan(0x8100),
713 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
714 fu.Output(1),
715 },
716 }
717 expectedOnuFlow, err := fu.MkFlowStat(faChild)
718 assert.Nil(t, err)
719 derivedFlow = onu1FlowAndGroup.GetFlow(0)
720 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
721}
722
khenaidoo89b0e942018-10-21 21:11:33 -0400723func TestDhcpReRouteRuleDecomposition(t *testing.T) {
724
npujar1d86a522019-11-14 17:11:16 +0530725 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400726 KV: fu.OfpFlowModArgs{"priority": 1000},
727 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400728 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400729 fu.EthType(0x0800),
730 fu.Ipv4Dst(0xffffffff),
731 fu.IpProto(17),
732 fu.UdpSrc(68),
733 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400734 },
735 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400736 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400737 },
738 }
739
Scott Bakerfdea1e32020-02-21 15:35:41 -0800740 fs, err := fu.MkFlowStat(fa)
741 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400742 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800743 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400744
Kent Hagerman433a31a2020-05-20 19:04:48 -0400745 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500746 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400747 onu1FlowAndGroup := deviceRules.Rules["onu1"]
748 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400749 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
750 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400751 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400752 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
753
npujar1d86a522019-11-14 17:11:16 +0530754 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400755 KV: fu.OfpFlowModArgs{"priority": 1000},
756 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400757 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400758 fu.TunnelId(uint64(1)),
759 fu.EthType(0x0800),
760 fu.Ipv4Dst(0xffffffff),
761 fu.IpProto(17),
762 fu.UdpSrc(68),
763 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400764 },
765 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400766 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400767 },
768 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800769 expectedOltFlow, err := fu.MkFlowStat(faParent)
770 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400771 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400772 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400773
npujar1d86a522019-11-14 17:11:16 +0530774 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400775 KV: fu.OfpFlowModArgs{"priority": 1000},
776 MatchFields: []*ofp.OfpOxmOfbField{
777 fu.InPort(2),
778 fu.TunnelId(uint64(1)),
779 fu.EthType(0x0800),
780 fu.Ipv4Dst(0xffffffff),
781 fu.IpProto(17),
782 fu.UdpSrc(68),
783 fu.UdpDst(67),
784 },
785 Actions: []*ofp.OfpAction{
786 fu.Output(1),
787 },
788 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800789 expectedOnuFlow, err := fu.MkFlowStat(faChild)
790 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400791 derivedFlow = onu1FlowAndGroup.GetFlow(0)
792 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400793}
794
Humera Kouser4ff89012019-08-25 19:01:51 -0400795func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530796 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400797 KV: fu.OfpFlowModArgs{"priority": 1000},
798 MatchFields: []*ofp.OfpOxmOfbField{
799 fu.InPort(10),
800 fu.EthType(0x88CC),
801 },
802 Actions: []*ofp.OfpAction{
803 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
804 },
805 }
806
Scott Bakerfdea1e32020-02-21 15:35:41 -0800807 fs, err := fu.MkFlowStat(fa)
808 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400809 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800810 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Kent Hagerman433a31a2020-05-20 19:04:48 -0400811 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500812 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400813 onu1FlowAndGroup := deviceRules.Rules["onu1"]
814 oltFlowAndGroup := deviceRules.Rules["olt"]
815 assert.Nil(t, onu1FlowAndGroup)
816 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
817 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
818
819 fa = &fu.FlowArgs{
820 KV: fu.OfpFlowModArgs{"priority": 1000},
821 MatchFields: []*ofp.OfpOxmOfbField{
822 fu.InPort(2),
823 fu.EthType(0x88CC),
824 },
825 Actions: []*ofp.OfpAction{
826 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
827 },
828 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800829 expectedOltFlow, err := fu.MkFlowStat(fa)
830 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400831 derivedFlow := oltFlowAndGroup.GetFlow(0)
832 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
833}
834
khenaidood20a5852018-10-22 22:09:55 -0400835func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530836 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400837 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400838 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400839 fu.InPort(1),
840 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
841 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400842 },
843 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400844 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400845 },
846 }
847
npujar1d86a522019-11-14 17:11:16 +0530848 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400849 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400850 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400851 fu.InPort(1),
852 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
853 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400854 },
855 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400856 fu.PushVlan(0x8100),
857 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
858 fu.SetField(fu.VlanPcp(0)),
859 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400860 },
861 }
862
Scott Bakerfdea1e32020-02-21 15:35:41 -0800863 fs, err := fu.MkFlowStat(fa)
864 assert.Nil(t, err)
865 fs2, err := fu.MkFlowStat(fa2)
866 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400867
868 fs.Instructions = []*ofp.OfpInstruction{{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400869 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
870 Data: &ofp.OfpInstruction_GotoTable{
871 GotoTable: &ofp.OfpInstructionGotoTable{
872 TableId: 1,
873 },
874 }}}
Kent Hagerman433a31a2020-05-20 19:04:48 -0400875 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs, fs2.Id: fs2}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400876
Scott Bakerfdea1e32020-02-21 15:35:41 -0800877 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400878
Kent Hagerman433a31a2020-05-20 19:04:48 -0400879 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500880 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400881 onu1FlowAndGroup := deviceRules.Rules["onu1"]
882 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400883 assert.NotNil(t, onu1FlowAndGroup)
884 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400885 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400886 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
887 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
888 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
889
890 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400891 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400892 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400893 fu.InPort(2),
894 fu.TunnelId(uint64(1)),
895 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
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) | 101)),
900 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400901 },
902 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400903
khenaidoo3306c992019-05-24 16:57:35 -0400904 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400905 // Form the expected flow
Scott Bakerfdea1e32020-02-21 15:35:41 -0800906 expectedOnu1Flow, err := fu.MkFlowStat(fa)
907 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400908 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
909 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
910 Data: &ofp.OfpInstruction_Actions{
911 Actions: &ofp.OfpInstructionActions{
912 Actions: []*ofp.OfpAction{{
913 Type: 0,
914 Action: &ofp.OfpAction_Output{
915 Output: &ofp.OfpActionOutput{
916 Port: 1,
917 MaxLen: 65509,
918 },
919 }}}}}}}
920
921 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400922 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
923
924 fa = &fu.FlowArgs{
925 KV: fu.OfpFlowModArgs{"priority": 500},
926 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400927 fu.InPort(1),
928 fu.TunnelId(uint64(1)),
929 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
930 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400931 },
932 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400933 fu.PushVlan(0x8100),
934 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
935 fu.SetField(fu.VlanPcp(0)),
936 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400937 },
938 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800939 expectedOltFlow, err := fu.MkFlowStat(fa)
940 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400941 derivedFlow = oltFlowAndGroup.GetFlow(0)
942 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
943}
944
945func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000946 ctx := context.Background()
947 logger.Debugf(ctx, "Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530948 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400949 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400950 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400951 fu.InPort(10),
952 fu.Metadata_ofp((1000 << 32) | 1),
953 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400954 },
955 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400956 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400957 },
958 }
959
npujar1d86a522019-11-14 17:11:16 +0530960 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400961 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400962 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400963 fu.InPort(10),
964 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
965 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400966 },
967 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400968 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
969 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400970 },
971 }
972
Scott Bakerfdea1e32020-02-21 15:35:41 -0800973 fs1, err := fu.MkFlowStat(fa1)
974 assert.Nil(t, err)
975 fs2, err := fu.MkFlowStat(fa2)
976 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400977 fs1.Instructions = []*ofp.OfpInstruction{{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400978 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
979 Data: &ofp.OfpInstruction_GotoTable{
980 GotoTable: &ofp.OfpInstructionGotoTable{
981 TableId: 1,
982 },
983 }}}
Kent Hagerman433a31a2020-05-20 19:04:48 -0400984 flows := map[uint64]*ofp.OfpFlowStats{fs1.Id: fs1, fs2.Id: fs2}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400985
Scott Bakerfdea1e32020-02-21 15:35:41 -0800986 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400987
Kent Hagerman433a31a2020-05-20 19:04:48 -0400988 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500989 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400990 onu1FlowAndGroup := deviceRules.Rules["onu1"]
991 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400992 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400993 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
994 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
995 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
996
997 fa1 = &fu.FlowArgs{
998 KV: fu.OfpFlowModArgs{"priority": 500},
999 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001000 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -04001001 fu.TunnelId(uint64(10)),
1002 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -04001003 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -04001004 },
1005 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001006 fu.PopVlan(),
1007 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001008 },
1009 }
Manikkaraj kb1a10922019-07-29 12:10:34 -04001010
khenaidood20a5852018-10-22 22:09:55 -04001011 derivedFlow := oltFlowAndGroup.GetFlow(0)
Scott Bakerfdea1e32020-02-21 15:35:41 -08001012 expectedOltFlow, err := fu.MkFlowStat(fa1)
1013 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -04001014 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
1015 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
1016 Data: &ofp.OfpInstruction_Actions{
1017 Actions: &ofp.OfpInstructionActions{
1018 Actions: []*ofp.OfpAction{{
1019 Type: 0,
1020 Action: &ofp.OfpAction_Output{
1021 Output: &ofp.OfpActionOutput{
1022 Port: 1,
1023 MaxLen: 65509,
1024 },
1025 }}}}}}}
1026 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -04001027 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
1028
1029 fa1 = &fu.FlowArgs{
1030 KV: fu.OfpFlowModArgs{"priority": 500},
1031 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001032 fu.InPort(1),
1033 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
1034 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -04001035 },
1036 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001037 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
1038 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -04001039 },
1040 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001041 expectedOnu1Flow, err := fu.MkFlowStat(fa1)
1042 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -04001043 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -04001044 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
1045}
1046
1047func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +05301048 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -04001049 KV: fu.OfpFlowModArgs{"priority": 500},
1050 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001051 fu.InPort(10),
1052 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1053 fu.VlanPcp(0),
1054 fu.EthType(0x800),
1055 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001056 },
1057 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001058 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001059 },
1060 }
1061
npujar1d86a522019-11-14 17:11:16 +05301062 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -04001063 GroupId: 10,
1064 Buckets: []*ofp.OfpBucket{
1065 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001066 fu.PopVlan(),
1067 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001068 },
1069 },
1070 },
1071 }
1072
Scott Bakerfdea1e32020-02-21 15:35:41 -08001073 fs, err := fu.MkFlowStat(fa)
1074 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -04001075 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
1076 groups := map[uint32]*ofp.OfpGroupEntry{ga.GroupId: fu.MkGroupStat(ga)}
Scott Bakerfdea1e32020-02-21 15:35:41 -08001077 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -04001078
khenaidoo820197c2020-02-13 16:35:33 -05001079 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
1080 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001081 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -04001082 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1083 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1084
1085 fa = &fu.FlowArgs{
1086 KV: fu.OfpFlowModArgs{"priority": 500},
1087 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +00001088 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -04001089 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1090 fu.VlanPcp(0),
1091 fu.EthType(0x800),
1092 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001093 },
1094 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001095 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001096 },
1097 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001098 expectedOltFlow, err := fu.MkFlowStat(fa)
1099 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001100 derivedFlow := oltFlowAndGroup.GetFlow(0)
1101 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001102}