blob: e847534d1395b72b77d3adfdb9abebe61986a428 [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"
Andrea Campanella408dec62021-11-10 14:32:10 +010021 "fmt"
Kent Hagerman433a31a2020-05-20 19:04:48 -040022 "testing"
23
Kent Hagerman6031aad2020-07-29 16:36:33 -040024 "github.com/opencord/voltha-go/rw_core/core/device/state"
khenaidoo820197c2020-02-13 16:35:33 -050025 "github.com/opencord/voltha-go/rw_core/route"
yasin sapli5458a1c2021-06-14 22:24:38 +000026 fu "github.com/opencord/voltha-lib-go/v5/pkg/flows"
Maninderdfadc982020-10-28 14:04:33 +053027 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
28 "github.com/opencord/voltha-protos/v4/go/voltha"
khenaidoo89b0e942018-10-21 21:11:33 -040029 "github.com/stretchr/testify/assert"
khenaidoo89b0e942018-10-21 21:11:33 -040030)
31
khenaidoo89b0e942018-10-21 21:11:33 -040032type testDeviceManager struct {
Kent Hagerman6031aad2020-07-29 16:36:33 -040033 state.DeviceManager
Kent Hagerman2a07b862020-06-19 15:23:07 -040034 devices map[string]*voltha.Device
35 devicePorts map[string]map[uint32]*voltha.Port
khenaidoo89b0e942018-10-21 21:11:33 -040036}
37
38func newTestDeviceManager() *testDeviceManager {
39 var tdm testDeviceManager
40 tdm.devices = make(map[string]*voltha.Device)
Kent Hagerman2a07b862020-06-19 15:23:07 -040041 tdm.devicePorts = make(map[string]map[uint32]*voltha.Port)
khenaidoo89b0e942018-10-21 21:11:33 -040042 tdm.devices["olt"] = &voltha.Device{
43 Id: "olt",
44 Root: true,
45 ParentId: "logical_device",
Kent Hagerman2a07b862020-06-19 15:23:07 -040046 }
47 tdm.devicePorts["olt"] = map[uint32]*voltha.Port{
48 1: {PortNo: 1, Label: "pon"},
49 2: {PortNo: 2, Label: "nni"},
khenaidoo89b0e942018-10-21 21:11:33 -040050 }
51 tdm.devices["onu1"] = &voltha.Device{
52 Id: "onu1",
53 Root: false,
54 ParentId: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -040055 }
56 tdm.devicePorts["onu1"] = map[uint32]*voltha.Port{
57 1: {PortNo: 1, Label: "pon"},
58 2: {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040059 }
60 tdm.devices["onu2"] = &voltha.Device{
61 Id: "onu2",
62 Root: false,
63 ParentId: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -040064 }
65 tdm.devicePorts["onu2"] = map[uint32]*voltha.Port{
66 1: {PortNo: 1, Label: "pon"},
67 2: {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040068 }
69 tdm.devices["onu3"] = &voltha.Device{
70 Id: "onu3",
71 Root: false,
72 ParentId: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -040073 }
74 tdm.devicePorts["onu3"] = map[uint32]*voltha.Port{
75 1: {PortNo: 1, Label: "pon"},
76 2: {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040077 }
78 tdm.devices["onu4"] = &voltha.Device{
79 Id: "onu4",
80 Root: false,
81 ParentId: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -040082 }
83 tdm.devicePorts["onu4"] = map[uint32]*voltha.Port{
84 1: {PortNo: 1, Label: "pon"},
85 2: {PortNo: 2, Label: "uni"},
khenaidoo89b0e942018-10-21 21:11:33 -040086 }
87 return &tdm
88}
89
Kent Hagerman45a13e42020-04-13 12:23:50 -040090func (tdm *testDeviceManager) GetDevice(ctx context.Context, deviceID *voltha.ID) (*voltha.Device, error) {
91 if d, ok := tdm.devices[deviceID.Id]; ok {
khenaidoo89b0e942018-10-21 21:11:33 -040092 return d, nil
93 }
npujar1d86a522019-11-14 17:11:16 +053094 return nil, errors.New("ABSENT")
khenaidoo89b0e942018-10-21 21:11:33 -040095}
Kent Hagerman2a07b862020-06-19 15:23:07 -040096func (tdm *testDeviceManager) listDevicePorts(ctx context.Context, deviceID string) (map[uint32]*voltha.Port, error) {
97 ports, have := tdm.devicePorts[deviceID]
98 if !have {
99 return nil, errors.New("ABSENT")
100 }
101 return ports, nil
102}
npujar1d86a522019-11-14 17:11:16 +0530103func (tdm *testDeviceManager) IsRootDevice(deviceID string) (bool, error) {
104 if d, ok := tdm.devices[deviceID]; ok {
khenaidoo19d7b632018-10-30 10:49:50 -0400105 return d.Root, nil
106 }
npujar1d86a522019-11-14 17:11:16 +0530107 return false, errors.New("ABSENT")
khenaidoo19d7b632018-10-30 10:49:50 -0400108}
khenaidoo89b0e942018-10-21 21:11:33 -0400109
110type testFlowDecomposer struct {
Esin Karaman09959ae2019-11-29 13:59:58 +0000111 dMgr *testDeviceManager
112 logicalPorts map[uint32]*voltha.LogicalPort
khenaidoo820197c2020-02-13 16:35:33 -0500113 routes map[route.OFPortLink][]route.Hop
Esin Karaman09959ae2019-11-29 13:59:58 +0000114 defaultRules *fu.DeviceRules
khenaidoo820197c2020-02-13 16:35:33 -0500115 deviceRoutes *route.DeviceRoutes
Esin Karaman09959ae2019-11-29 13:59:58 +0000116 fd *FlowDecomposer
117 logicalPortsNo map[uint32]bool
khenaidoo89b0e942018-10-21 21:11:33 -0400118}
119
Scott Bakerfdea1e32020-02-21 15:35:41 -0800120func newTestFlowDecomposer(t *testing.T, deviceMgr *testDeviceManager) *testFlowDecomposer {
khenaidoo89b0e942018-10-21 21:11:33 -0400121 var tfd testFlowDecomposer
122 tfd.dMgr = deviceMgr
123
124 tfd.logicalPorts = make(map[uint32]*voltha.LogicalPort)
Esin Karaman09959ae2019-11-29 13:59:58 +0000125 tfd.logicalPortsNo = make(map[uint32]bool)
khenaidoo89b0e942018-10-21 21:11:33 -0400126 // Go protobuf interpreted absence of a port as 0, so we can't use port #0 as an openflow
127 // port
128 tfd.logicalPorts[10] = &voltha.LogicalPort{Id: "10", DeviceId: "olt", DevicePortNo: 2}
Esin Karaman09959ae2019-11-29 13:59:58 +0000129 tfd.logicalPorts[65536] = &voltha.LogicalPort{Id: "65536", DeviceId: "olt", DevicePortNo: 65536}
khenaidoo89b0e942018-10-21 21:11:33 -0400130 tfd.logicalPorts[1] = &voltha.LogicalPort{Id: "1", DeviceId: "onu1", DevicePortNo: 2}
131 tfd.logicalPorts[2] = &voltha.LogicalPort{Id: "2", DeviceId: "onu2", DevicePortNo: 2}
132 tfd.logicalPorts[3] = &voltha.LogicalPort{Id: "3", DeviceId: "onu3", DevicePortNo: 2}
133 tfd.logicalPorts[4] = &voltha.LogicalPort{Id: "4", DeviceId: "onu4", DevicePortNo: 2}
134
Esin Karaman09959ae2019-11-29 13:59:58 +0000135 tfd.logicalPortsNo[10] = false
136 tfd.logicalPortsNo[65536] = true // nni
137
khenaidoo820197c2020-02-13 16:35:33 -0500138 tfd.routes = make(map[route.OFPortLink][]route.Hop)
khenaidoo89b0e942018-10-21 21:11:33 -0400139
140 //DOWNSTREAM ROUTES
141
khenaidoo820197c2020-02-13 16:35:33 -0500142 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 1}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400143 {
khenaidoo89b0e942018-10-21 21:11:33 -0400144 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400145 Ingress: 2,
146 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400147 },
khenaidood20a5852018-10-22 22:09:55 -0400148 {
khenaidoo89b0e942018-10-21 21:11:33 -0400149 DeviceID: "onu1",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400150 Ingress: 1,
151 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400152 },
153 }
154
khenaidoo820197c2020-02-13 16:35:33 -0500155 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 2}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400156 {
khenaidoo89b0e942018-10-21 21:11:33 -0400157 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400158 Ingress: 2,
159 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400160 },
khenaidood20a5852018-10-22 22:09:55 -0400161 {
khenaidoo89b0e942018-10-21 21:11:33 -0400162 DeviceID: "onu2",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400163 Ingress: 1,
164 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400165 },
166 }
khenaidoo820197c2020-02-13 16:35:33 -0500167 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 3}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400168 {
khenaidoo89b0e942018-10-21 21:11:33 -0400169 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400170 Ingress: 2,
171 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400172 },
khenaidood20a5852018-10-22 22:09:55 -0400173 {
khenaidoo89b0e942018-10-21 21:11:33 -0400174 DeviceID: "onu3",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400175 Ingress: 1,
176 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400177 },
178 }
khenaidoo820197c2020-02-13 16:35:33 -0500179 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 4}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400180 {
khenaidoo89b0e942018-10-21 21:11:33 -0400181 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400182 Ingress: 2,
183 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400184 },
khenaidood20a5852018-10-22 22:09:55 -0400185 {
khenaidoo89b0e942018-10-21 21:11:33 -0400186 DeviceID: "onu4",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400187 Ingress: 1,
188 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400189 },
190 }
khenaidoo820197c2020-02-13 16:35:33 -0500191 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 10}] = []route.Hop{
Humera Kouser4ff89012019-08-25 19:01:51 -0400192 {
193 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400194 Ingress: 2,
195 Egress: 2,
Humera Kouser4ff89012019-08-25 19:01:51 -0400196 },
197 {
198 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400199 Ingress: 2,
200 Egress: 2,
Humera Kouser4ff89012019-08-25 19:01:51 -0400201 },
202 }
khenaidoo89b0e942018-10-21 21:11:33 -0400203
204 //UPSTREAM DATA PLANE
205
khenaidoo820197c2020-02-13 16:35:33 -0500206 tfd.routes[route.OFPortLink{Ingress: 1, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400207 {
khenaidoo89b0e942018-10-21 21:11:33 -0400208 DeviceID: "onu1",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400209 Ingress: 2,
210 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400211 },
khenaidood20a5852018-10-22 22:09:55 -0400212 {
khenaidoo89b0e942018-10-21 21:11:33 -0400213 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400214 Ingress: 1,
215 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400216 },
217 }
khenaidoo820197c2020-02-13 16:35:33 -0500218 tfd.routes[route.OFPortLink{Ingress: 2, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400219 {
khenaidoo89b0e942018-10-21 21:11:33 -0400220 DeviceID: "onu2",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400221 Ingress: 2,
222 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400223 },
khenaidood20a5852018-10-22 22:09:55 -0400224 {
khenaidoo89b0e942018-10-21 21:11:33 -0400225 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400226 Ingress: 1,
227 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400228 },
229 }
khenaidoo820197c2020-02-13 16:35:33 -0500230 tfd.routes[route.OFPortLink{Ingress: 3, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400231 {
khenaidoo89b0e942018-10-21 21:11:33 -0400232 DeviceID: "onu3",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400233 Ingress: 2,
234 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400235 },
khenaidood20a5852018-10-22 22:09:55 -0400236 {
khenaidoo89b0e942018-10-21 21:11:33 -0400237 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400238 Ingress: 1,
239 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400240 },
241 }
khenaidoo820197c2020-02-13 16:35:33 -0500242 tfd.routes[route.OFPortLink{Ingress: 4, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400243 {
khenaidoo89b0e942018-10-21 21:11:33 -0400244 DeviceID: "onu4",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400245 Ingress: 2,
246 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400247 },
khenaidood20a5852018-10-22 22:09:55 -0400248 {
khenaidoo89b0e942018-10-21 21:11:33 -0400249 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400250 Ingress: 1,
251 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400252 },
253 }
254
255 //UPSTREAM NEXT TABLE BASED
256
257 // openflow port 0 means absence of a port - go/protobuf interpretation
khenaidoo820197c2020-02-13 16:35:33 -0500258 tfd.routes[route.OFPortLink{Ingress: 1, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400259 {
khenaidoo89b0e942018-10-21 21:11:33 -0400260 DeviceID: "onu1",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400261 Ingress: 2,
262 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400263 },
khenaidood20a5852018-10-22 22:09:55 -0400264 {
khenaidoo89b0e942018-10-21 21:11:33 -0400265 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400266 Ingress: 1,
267 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400268 },
269 }
khenaidoo820197c2020-02-13 16:35:33 -0500270 tfd.routes[route.OFPortLink{Ingress: 2, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400271 {
khenaidoo89b0e942018-10-21 21:11:33 -0400272 DeviceID: "onu2",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400273 Ingress: 2,
274 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400275 },
khenaidood20a5852018-10-22 22:09:55 -0400276 {
khenaidoo89b0e942018-10-21 21:11:33 -0400277 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400278 Ingress: 1,
279 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400280 },
281 }
khenaidoo820197c2020-02-13 16:35:33 -0500282 tfd.routes[route.OFPortLink{Ingress: 3, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400283 {
khenaidoo89b0e942018-10-21 21:11:33 -0400284 DeviceID: "onu3",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400285 Ingress: 2,
286 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400287 },
khenaidood20a5852018-10-22 22:09:55 -0400288 {
khenaidoo89b0e942018-10-21 21:11:33 -0400289 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400290 Ingress: 1,
291 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400292 },
293 }
khenaidoo820197c2020-02-13 16:35:33 -0500294 tfd.routes[route.OFPortLink{Ingress: 4, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400295 {
khenaidoo89b0e942018-10-21 21:11:33 -0400296 DeviceID: "onu4",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400297 Ingress: 2,
298 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400299 },
khenaidood20a5852018-10-22 22:09:55 -0400300 {
khenaidoo89b0e942018-10-21 21:11:33 -0400301 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400302 Ingress: 1,
303 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400304 },
305 }
306
307 // DOWNSTREAM NEXT TABLE BASED
308
khenaidoo820197c2020-02-13 16:35:33 -0500309 tfd.routes[route.OFPortLink{Ingress: 10, Egress: 0}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400310 {
khenaidoo89b0e942018-10-21 21:11:33 -0400311 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400312 Ingress: 2,
313 Egress: 1,
khenaidoo89b0e942018-10-21 21:11:33 -0400314 },
khenaidood20a5852018-10-22 22:09:55 -0400315 {}, // 2nd hop is not known yet
khenaidoo89b0e942018-10-21 21:11:33 -0400316 }
317
khenaidoo820197c2020-02-13 16:35:33 -0500318 tfd.routes[route.OFPortLink{Ingress: 0, Egress: 10}] = []route.Hop{
khenaidood20a5852018-10-22 22:09:55 -0400319 {}, // 1st hop is wildcard
320 {
khenaidoo89b0e942018-10-21 21:11:33 -0400321 DeviceID: "olt",
Kent Hagerman2a07b862020-06-19 15:23:07 -0400322 Ingress: 1,
323 Egress: 2,
khenaidoo89b0e942018-10-21 21:11:33 -0400324 },
325 }
326
327 // DEFAULT RULES
328
329 tfd.defaultRules = fu.NewDeviceRules()
330 fg := fu.NewFlowsAndGroups()
npujar1d86a522019-11-14 17:11:16 +0530331 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400332 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400333 fu.InPort(2),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300334 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo89b0e942018-10-21 21:11:33 -0400335 },
336 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400337 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
338 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400339 },
340 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800341 fs, err := fu.MkFlowStat(fa)
342 assert.Nil(t, err)
343 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400344 tfd.defaultRules.AddFlowsAndGroup("onu1", fg)
345
346 fg = fu.NewFlowsAndGroups()
347 fa = &fu.FlowArgs{
348 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400349 fu.InPort(2),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300350 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo89b0e942018-10-21 21:11:33 -0400351 },
352 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400353 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 102)),
354 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400355 },
356 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800357 fs, err = fu.MkFlowStat(fa)
358 assert.Nil(t, err)
359 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400360 tfd.defaultRules.AddFlowsAndGroup("onu2", fg)
361
362 fg = fu.NewFlowsAndGroups()
363 fa = &fu.FlowArgs{
364 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400365 fu.InPort(2),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300366 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo89b0e942018-10-21 21:11:33 -0400367 },
368 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400369 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 103)),
370 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400371 },
372 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800373 fs, err = fu.MkFlowStat(fa)
374 assert.Nil(t, err)
375 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400376 tfd.defaultRules.AddFlowsAndGroup("onu3", fg)
377
378 fg = fu.NewFlowsAndGroups()
379 fa = &fu.FlowArgs{
380 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400381 fu.InPort(2),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300382 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo89b0e942018-10-21 21:11:33 -0400383 },
384 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400385 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
386 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400387 },
388 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800389 fs, err = fu.MkFlowStat(fa)
390 assert.Nil(t, err)
391 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400392 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
393
394 //Set up the device graph - flow decomposer uses it only to verify whether a port is a root port.
Kent Hagerman2a07b862020-06-19 15:23:07 -0400395 tfd.deviceRoutes = route.NewDeviceRoutes("ldid", "olt", tfd.dMgr.listDevicePorts)
khenaidoo820197c2020-02-13 16:35:33 -0500396 tfd.deviceRoutes.RootPorts = make(map[uint32]uint32)
397 tfd.deviceRoutes.RootPorts[10] = 10
khenaidoo89b0e942018-10-21 21:11:33 -0400398
Kent Hagerman6031aad2020-07-29 16:36:33 -0400399 tfd.fd = NewFlowDecomposer(func(ctx context.Context, deviceID string) (*voltha.Device, error) {
400 return tfd.dMgr.GetDevice(ctx, &voltha.ID{Id: deviceID})
401 })
khenaidoo89b0e942018-10-21 21:11:33 -0400402
403 return &tfd
404}
405
npujar1d86a522019-11-14 17:11:16 +0530406func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400407 return ""
408}
409
khenaidoo442e7c72020-03-10 16:13:48 -0400410func (tfd *testFlowDecomposer) GetLogicalDevice(ctx context.Context) (*voltha.LogicalDevice, error) {
411 return nil, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400412}
413
khenaidoo820197c2020-02-13 16:35:33 -0500414func (tfd *testFlowDecomposer) GetDeviceRoutes() *route.DeviceRoutes {
415 return tfd.deviceRoutes
khenaidoo89b0e942018-10-21 21:11:33 -0400416}
417
418func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
419 return tfd.defaultRules
420}
421
Rohan Agrawal31f21802020-06-12 05:38:46 +0000422func (tfd *testFlowDecomposer) GetWildcardInputPorts(ctx context.Context, excludePort uint32) map[uint32]struct{} {
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400423 lPorts := make(map[uint32]struct{})
424 for portNo := range tfd.logicalPorts {
425 if portNo != excludePort {
426 lPorts[portNo] = struct{}{}
khenaidoo89b0e942018-10-21 21:11:33 -0400427 }
428 }
429 return lPorts
430}
431
khenaidoo820197c2020-02-13 16:35:33 -0500432func (tfd *testFlowDecomposer) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
433 var portLink route.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400434 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400435 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400436 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400437 portLink.Egress = 10
438 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400439 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400440 }
khenaidoo19d7b632018-10-30 10:49:50 -0400441 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400442 portLink.Ingress = 0
443 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400444 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400445 }
446 for key, val := range tfd.routes {
447 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
khenaidoo820197c2020-02-13 16:35:33 -0500448 return val, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400449 }
450 }
Andrea Campanella408dec62021-11-10 14:32:10 +0100451 return nil, fmt.Errorf("no route from:%d to:%d %w", ingressPortNo, egressPortNo, route.ErrNoRoute)
khenaidoo89b0e942018-10-21 21:11:33 -0400452}
453
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400454func (tfd *testFlowDecomposer) GetNNIPorts() map[uint32]struct{} {
455 nniPorts := make(map[uint32]struct{})
Esin Karaman09959ae2019-11-29 13:59:58 +0000456 for portNo, nni := range tfd.logicalPortsNo {
457 if nni {
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400458 nniPorts[portNo] = struct{}{}
Esin Karaman09959ae2019-11-29 13:59:58 +0000459 }
460 }
461 return nniPorts
462}
463
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400464func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
465
npujar1d86a522019-11-14 17:11:16 +0530466 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400467 KV: fu.OfpFlowModArgs{"priority": 1000},
468 MatchFields: []*ofp.OfpOxmOfbField{
469 fu.InPort(1),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700470 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400471 fu.EthType(0x888e),
472 },
473 Actions: []*ofp.OfpAction{
474 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
475 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
476 },
477 }
478
Scott Bakerfdea1e32020-02-21 15:35:41 -0800479 fs, err := fu.MkFlowStat(fa)
480 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400481 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800482 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400483
Kent Hagerman433a31a2020-05-20 19:04:48 -0400484 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500485 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400486 onu1FlowAndGroup := deviceRules.Rules["onu1"]
487 oltFlowAndGroup := deviceRules.Rules["olt"]
488 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
489 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
490 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
491
npujar1d86a522019-11-14 17:11:16 +0530492 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400493 KV: fu.OfpFlowModArgs{"priority": 1000},
494 MatchFields: []*ofp.OfpOxmOfbField{
495 fu.InPort(1),
496 fu.TunnelId(uint64(1)),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700497 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400498 fu.EthType(0x888e),
499 },
500 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400501 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
502 },
503 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800504 expectedOltFlow, err := fu.MkFlowStat(faParent)
505 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400506 derivedFlow := oltFlowAndGroup.GetFlow(0)
507 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
508
npujar1d86a522019-11-14 17:11:16 +0530509 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400510 KV: fu.OfpFlowModArgs{"priority": 1000},
511 MatchFields: []*ofp.OfpOxmOfbField{
512 fu.InPort(2),
513 fu.TunnelId(uint64(1)),
514 fu.EthType(0x888e),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700515 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400516 },
517 Actions: []*ofp.OfpAction{
518 fu.PushVlan(0x8100),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700519 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400520 fu.Output(1),
521 },
522 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800523 expectedOnuFlow, err := fu.MkFlowStat(faChild)
524 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400525 derivedFlow = onu1FlowAndGroup.GetFlow(0)
526 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
527}
528
529func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
530
npujar1d86a522019-11-14 17:11:16 +0530531 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400532 KV: fu.OfpFlowModArgs{"priority": 1000},
533 MatchFields: []*ofp.OfpOxmOfbField{
534 fu.InPort(1),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300535 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400536 fu.EthType(0x888e),
537 },
538 Actions: []*ofp.OfpAction{
539 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
540 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
541 },
542 }
543
Scott Bakerfdea1e32020-02-21 15:35:41 -0800544 fs, err := fu.MkFlowStat(fa)
545 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400546 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800547 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400548
Kent Hagerman433a31a2020-05-20 19:04:48 -0400549 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500550 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400551 onu1FlowAndGroup := deviceRules.Rules["onu1"]
552 oltFlowAndGroup := deviceRules.Rules["olt"]
553 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
554 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
555 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
556
npujar1d86a522019-11-14 17:11:16 +0530557 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400558 KV: fu.OfpFlowModArgs{"priority": 1000},
559 MatchFields: []*ofp.OfpOxmOfbField{
560 fu.InPort(1),
561 fu.TunnelId(uint64(1)),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700562 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400563 fu.EthType(0x888e),
564 },
565 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400566 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
567 },
568 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800569 expectedOltFlow, err := fu.MkFlowStat(faParent)
570 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400571 derivedFlow := oltFlowAndGroup.GetFlow(0)
572 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
573
npujar1d86a522019-11-14 17:11:16 +0530574 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400575 KV: fu.OfpFlowModArgs{"priority": 1000},
576 MatchFields: []*ofp.OfpOxmOfbField{
577 fu.InPort(2),
578 fu.TunnelId(uint64(1)),
579 fu.EthType(0x888e),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300580 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400581 },
582 Actions: []*ofp.OfpAction{
583 fu.PushVlan(0x8100),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700584 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400585 fu.Output(1),
586 },
587 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800588 expectedOnuFlow, err := fu.MkFlowStat(faChild)
589 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400590 derivedFlow = onu1FlowAndGroup.GetFlow(0)
591 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
592}
593
594func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400595
npujar1d86a522019-11-14 17:11:16 +0530596 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400597 KV: fu.OfpFlowModArgs{"priority": 1000},
598 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400599 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400600 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400601 },
602 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400603 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
604 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400605 },
606 }
607
Scott Bakerfdea1e32020-02-21 15:35:41 -0800608 fs, err := fu.MkFlowStat(fa)
609 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400610 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800611 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400612
Kent Hagerman433a31a2020-05-20 19:04:48 -0400613 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500614 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400615 onu1FlowAndGroup := deviceRules.Rules["onu1"]
616 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400617 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400618 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400619 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
620
npujar1d86a522019-11-14 17:11:16 +0530621 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400622 KV: fu.OfpFlowModArgs{"priority": 1000},
623 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400624 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400625 fu.TunnelId(uint64(1)),
626 fu.EthType(0x888e),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700627 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
khenaidoo89b0e942018-10-21 21:11:33 -0400628 },
629 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400630 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400631 },
632 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800633 expectedOltFlow, err := fu.MkFlowStat(faParent)
634 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400635 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400636 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400637
npujar1d86a522019-11-14 17:11:16 +0530638 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400639 KV: fu.OfpFlowModArgs{"priority": 1000},
640 MatchFields: []*ofp.OfpOxmOfbField{
641 fu.InPort(2),
642 fu.TunnelId(uint64(1)),
643 fu.EthType(0x888e),
644 },
645 Actions: []*ofp.OfpAction{
Girish Gowdra9a50f032020-09-16 13:21:10 -0700646 fu.PushVlan(0x8100),
647 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400648 fu.Output(1),
649 },
650 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800651 expectedOnuFlow, err := fu.MkFlowStat(faChild)
652 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400653 derivedFlow = onu1FlowAndGroup.GetFlow(0)
654 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400655}
656
Marcos Aurelio Carrero (Furukawa)a61a72c2021-01-28 13:48:20 -0300657func TestPppoedReRouteRuleVlanDecomposition(t *testing.T) {
658
659 fa := &fu.FlowArgs{
660 KV: fu.OfpFlowModArgs{"priority": 1000},
661 MatchFields: []*ofp.OfpOxmOfbField{
662 fu.InPort(1),
663 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
664 fu.EthType(0x8863),
665 },
666 Actions: []*ofp.OfpAction{
667 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
668 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
669 },
670 }
671
672 fs, err := fu.MkFlowStat(fa)
673 assert.Nil(t, err)
674 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
675 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
676
677 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
678 assert.Nil(t, err)
679 onu1FlowAndGroup := deviceRules.Rules["onu1"]
680 oltFlowAndGroup := deviceRules.Rules["olt"]
681 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
682 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
683 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
684
685 faParent := &fu.FlowArgs{
686 KV: fu.OfpFlowModArgs{"priority": 1000},
687 MatchFields: []*ofp.OfpOxmOfbField{
688 fu.InPort(1),
689 fu.TunnelId(uint64(1)),
690 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
691 fu.EthType(0x8863),
692 },
693 Actions: []*ofp.OfpAction{
694 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
695 },
696 }
697 expectedOltFlow, err := fu.MkFlowStat(faParent)
698 assert.Nil(t, err)
699 derivedFlow := oltFlowAndGroup.GetFlow(0)
700 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
701
702 faChild := &fu.FlowArgs{
703 KV: fu.OfpFlowModArgs{"priority": 1000},
704 MatchFields: []*ofp.OfpOxmOfbField{
705 fu.InPort(2),
706 fu.TunnelId(uint64(1)),
707 fu.EthType(0x8863),
708 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
709 },
710 Actions: []*ofp.OfpAction{
711 fu.PushVlan(0x8100),
712 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
713 fu.Output(1),
714 },
715 }
716 expectedOnuFlow, err := fu.MkFlowStat(faChild)
717 assert.Nil(t, err)
718 derivedFlow = onu1FlowAndGroup.GetFlow(0)
719 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
720}
721
khenaidoo89b0e942018-10-21 21:11:33 -0400722func TestDhcpReRouteRuleDecomposition(t *testing.T) {
723
npujar1d86a522019-11-14 17:11:16 +0530724 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400725 KV: fu.OfpFlowModArgs{"priority": 1000},
726 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400727 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400728 fu.EthType(0x0800),
729 fu.Ipv4Dst(0xffffffff),
730 fu.IpProto(17),
731 fu.UdpSrc(68),
732 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400733 },
734 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400735 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400736 },
737 }
738
Scott Bakerfdea1e32020-02-21 15:35:41 -0800739 fs, err := fu.MkFlowStat(fa)
740 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400741 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800742 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400743
Kent Hagerman433a31a2020-05-20 19:04:48 -0400744 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500745 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400746 onu1FlowAndGroup := deviceRules.Rules["onu1"]
747 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400748 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
749 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400750 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400751 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
752
npujar1d86a522019-11-14 17:11:16 +0530753 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400754 KV: fu.OfpFlowModArgs{"priority": 1000},
755 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400756 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400757 fu.TunnelId(uint64(1)),
758 fu.EthType(0x0800),
759 fu.Ipv4Dst(0xffffffff),
760 fu.IpProto(17),
761 fu.UdpSrc(68),
762 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400763 },
764 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400765 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400766 },
767 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800768 expectedOltFlow, err := fu.MkFlowStat(faParent)
769 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400770 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400771 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400772
npujar1d86a522019-11-14 17:11:16 +0530773 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400774 KV: fu.OfpFlowModArgs{"priority": 1000},
775 MatchFields: []*ofp.OfpOxmOfbField{
776 fu.InPort(2),
777 fu.TunnelId(uint64(1)),
778 fu.EthType(0x0800),
779 fu.Ipv4Dst(0xffffffff),
780 fu.IpProto(17),
781 fu.UdpSrc(68),
782 fu.UdpDst(67),
783 },
784 Actions: []*ofp.OfpAction{
785 fu.Output(1),
786 },
787 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800788 expectedOnuFlow, err := fu.MkFlowStat(faChild)
789 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400790 derivedFlow = onu1FlowAndGroup.GetFlow(0)
791 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400792}
793
Humera Kouser4ff89012019-08-25 19:01:51 -0400794func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530795 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400796 KV: fu.OfpFlowModArgs{"priority": 1000},
797 MatchFields: []*ofp.OfpOxmOfbField{
798 fu.InPort(10),
799 fu.EthType(0x88CC),
800 },
801 Actions: []*ofp.OfpAction{
802 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
803 },
804 }
805
Scott Bakerfdea1e32020-02-21 15:35:41 -0800806 fs, err := fu.MkFlowStat(fa)
807 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400808 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800809 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Kent Hagerman433a31a2020-05-20 19:04:48 -0400810 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500811 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400812 onu1FlowAndGroup := deviceRules.Rules["onu1"]
813 oltFlowAndGroup := deviceRules.Rules["olt"]
814 assert.Nil(t, onu1FlowAndGroup)
815 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
816 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
817
818 fa = &fu.FlowArgs{
819 KV: fu.OfpFlowModArgs{"priority": 1000},
820 MatchFields: []*ofp.OfpOxmOfbField{
821 fu.InPort(2),
822 fu.EthType(0x88CC),
823 },
824 Actions: []*ofp.OfpAction{
825 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
826 },
827 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800828 expectedOltFlow, err := fu.MkFlowStat(fa)
829 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400830 derivedFlow := oltFlowAndGroup.GetFlow(0)
831 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
832}
833
khenaidood20a5852018-10-22 22:09:55 -0400834func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530835 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400836 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400837 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400838 fu.InPort(1),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300839 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo68c930b2019-05-13 11:46:51 -0400840 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400841 },
842 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400843 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400844 },
845 }
846
npujar1d86a522019-11-14 17:11:16 +0530847 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400848 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400849 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400850 fu.InPort(1),
851 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
852 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400853 },
854 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400855 fu.PushVlan(0x8100),
856 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
857 fu.SetField(fu.VlanPcp(0)),
858 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400859 },
860 }
861
Scott Bakerfdea1e32020-02-21 15:35:41 -0800862 fs, err := fu.MkFlowStat(fa)
863 assert.Nil(t, err)
864 fs2, err := fu.MkFlowStat(fa2)
865 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400866
867 fs.Instructions = []*ofp.OfpInstruction{{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400868 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
869 Data: &ofp.OfpInstruction_GotoTable{
870 GotoTable: &ofp.OfpInstructionGotoTable{
871 TableId: 1,
872 },
873 }}}
Kent Hagerman433a31a2020-05-20 19:04:48 -0400874 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs, fs2.Id: fs2}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400875
Scott Bakerfdea1e32020-02-21 15:35:41 -0800876 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400877
Kent Hagerman433a31a2020-05-20 19:04:48 -0400878 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500879 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400880 onu1FlowAndGroup := deviceRules.Rules["onu1"]
881 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400882 assert.NotNil(t, onu1FlowAndGroup)
883 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400884 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400885 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
886 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
887 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
888
889 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400890 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400891 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400892 fu.InPort(2),
893 fu.TunnelId(uint64(1)),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300894 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo68c930b2019-05-13 11:46:51 -0400895 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400896 },
897 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400898 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
899 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400900 },
901 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400902
khenaidoo3306c992019-05-24 16:57:35 -0400903 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400904 // Form the expected flow
Scott Bakerfdea1e32020-02-21 15:35:41 -0800905 expectedOnu1Flow, err := fu.MkFlowStat(fa)
906 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400907 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
908 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
909 Data: &ofp.OfpInstruction_Actions{
910 Actions: &ofp.OfpInstructionActions{
911 Actions: []*ofp.OfpAction{{
912 Type: 0,
913 Action: &ofp.OfpAction_Output{
914 Output: &ofp.OfpActionOutput{
915 Port: 1,
916 MaxLen: 65509,
917 },
918 }}}}}}}
919
920 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400921 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
922
923 fa = &fu.FlowArgs{
924 KV: fu.OfpFlowModArgs{"priority": 500},
925 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400926 fu.InPort(1),
927 fu.TunnelId(uint64(1)),
928 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
929 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400930 },
931 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400932 fu.PushVlan(0x8100),
933 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
934 fu.SetField(fu.VlanPcp(0)),
935 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400936 },
937 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800938 expectedOltFlow, err := fu.MkFlowStat(fa)
939 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400940 derivedFlow = oltFlowAndGroup.GetFlow(0)
941 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
942}
943
944func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000945 ctx := context.Background()
946 logger.Debugf(ctx, "Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530947 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400948 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400949 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400950 fu.InPort(10),
951 fu.Metadata_ofp((1000 << 32) | 1),
952 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400953 },
954 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400955 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400956 },
957 }
958
npujar1d86a522019-11-14 17:11:16 +0530959 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400960 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400961 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400962 fu.InPort(10),
963 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
964 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400965 },
966 Actions: []*ofp.OfpAction{
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300967 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT))),
khenaidoo68c930b2019-05-13 11:46:51 -0400968 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400969 },
970 }
971
Scott Bakerfdea1e32020-02-21 15:35:41 -0800972 fs1, err := fu.MkFlowStat(fa1)
973 assert.Nil(t, err)
974 fs2, err := fu.MkFlowStat(fa2)
975 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400976 fs1.Instructions = []*ofp.OfpInstruction{{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400977 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
978 Data: &ofp.OfpInstruction_GotoTable{
979 GotoTable: &ofp.OfpInstructionGotoTable{
980 TableId: 1,
981 },
982 }}}
Kent Hagerman433a31a2020-05-20 19:04:48 -0400983 flows := map[uint64]*ofp.OfpFlowStats{fs1.Id: fs1, fs2.Id: fs2}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400984
Scott Bakerfdea1e32020-02-21 15:35:41 -0800985 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400986
Kent Hagerman433a31a2020-05-20 19:04:48 -0400987 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500988 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400989 onu1FlowAndGroup := deviceRules.Rules["onu1"]
990 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400991 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400992 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
993 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
994 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
995
996 fa1 = &fu.FlowArgs{
997 KV: fu.OfpFlowModArgs{"priority": 500},
998 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400999 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -04001000 fu.TunnelId(uint64(10)),
1001 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -04001002 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -04001003 },
1004 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001005 fu.PopVlan(),
1006 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001007 },
1008 }
Manikkaraj kb1a10922019-07-29 12:10:34 -04001009
khenaidood20a5852018-10-22 22:09:55 -04001010 derivedFlow := oltFlowAndGroup.GetFlow(0)
Scott Bakerfdea1e32020-02-21 15:35:41 -08001011 expectedOltFlow, err := fu.MkFlowStat(fa1)
1012 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -04001013 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
1014 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
1015 Data: &ofp.OfpInstruction_Actions{
1016 Actions: &ofp.OfpInstructionActions{
1017 Actions: []*ofp.OfpAction{{
1018 Type: 0,
1019 Action: &ofp.OfpAction_Output{
1020 Output: &ofp.OfpActionOutput{
1021 Port: 1,
1022 MaxLen: 65509,
1023 },
1024 }}}}}}}
1025 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -04001026 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
1027
1028 fa1 = &fu.FlowArgs{
1029 KV: fu.OfpFlowModArgs{"priority": 500},
1030 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001031 fu.InPort(1),
1032 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
1033 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -04001034 },
1035 Actions: []*ofp.OfpAction{
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +03001036 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT))),
khenaidoo68c930b2019-05-13 11:46:51 -04001037 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -04001038 },
1039 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001040 expectedOnu1Flow, err := fu.MkFlowStat(fa1)
1041 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -04001042 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -04001043 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
1044}
1045
1046func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +05301047 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -04001048 KV: fu.OfpFlowModArgs{"priority": 500},
1049 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001050 fu.InPort(10),
1051 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1052 fu.VlanPcp(0),
1053 fu.EthType(0x800),
1054 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001055 },
1056 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001057 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001058 },
1059 }
1060
npujar1d86a522019-11-14 17:11:16 +05301061 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -04001062 GroupId: 10,
1063 Buckets: []*ofp.OfpBucket{
1064 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001065 fu.PopVlan(),
1066 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001067 },
1068 },
1069 },
1070 }
1071
Scott Bakerfdea1e32020-02-21 15:35:41 -08001072 fs, err := fu.MkFlowStat(fa)
1073 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -04001074 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
1075 groups := map[uint32]*ofp.OfpGroupEntry{ga.GroupId: fu.MkGroupStat(ga)}
Scott Bakerfdea1e32020-02-21 15:35:41 -08001076 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -04001077
khenaidoo820197c2020-02-13 16:35:33 -05001078 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
1079 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001080 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -04001081 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1082 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1083
1084 fa = &fu.FlowArgs{
1085 KV: fu.OfpFlowModArgs{"priority": 500},
1086 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +00001087 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -04001088 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1089 fu.VlanPcp(0),
1090 fu.EthType(0x800),
1091 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001092 },
1093 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001094 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001095 },
1096 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001097 expectedOltFlow, err := fu.MkFlowStat(fa)
1098 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001099 derivedFlow := oltFlowAndGroup.GetFlow(0)
1100 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001101}