blob: 6f8c80c3ff259d995c6df8dff64363571c8dc2e7 [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"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080025 fu "github.com/opencord/voltha-lib-go/v3/pkg/flows"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080026 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
27 "github.com/opencord/voltha-protos/v3/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),
471 fu.VlanVid(50),
472 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)),
498 fu.VlanVid(50),
499 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),
516 },
517 Actions: []*ofp.OfpAction{
518 fu.PushVlan(0x8100),
519 fu.SetField(fu.VlanVid(50)),
520 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),
535 fu.VlanVid(0),
536 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)),
562 fu.VlanVid(0),
563 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),
580 },
581 Actions: []*ofp.OfpAction{
582 fu.PushVlan(0x8100),
583 fu.SetField(fu.VlanVid(0)),
584 fu.Output(1),
585 },
586 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800587 expectedOnuFlow, err := fu.MkFlowStat(faChild)
588 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400589 derivedFlow = onu1FlowAndGroup.GetFlow(0)
590 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
591}
592
593func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400594
npujar1d86a522019-11-14 17:11:16 +0530595 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400596 KV: fu.OfpFlowModArgs{"priority": 1000},
597 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400598 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400599 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400600 },
601 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400602 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
603 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400604 },
605 }
606
Scott Bakerfdea1e32020-02-21 15:35:41 -0800607 fs, err := fu.MkFlowStat(fa)
608 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400609 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800610 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400611
Kent Hagerman433a31a2020-05-20 19:04:48 -0400612 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500613 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400614 onu1FlowAndGroup := deviceRules.Rules["onu1"]
615 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400616 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400617 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400618 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
619
npujar1d86a522019-11-14 17:11:16 +0530620 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400621 KV: fu.OfpFlowModArgs{"priority": 1000},
622 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400623 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400624 fu.TunnelId(uint64(1)),
625 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400626 },
627 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400628 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400629 },
630 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800631 expectedOltFlow, err := fu.MkFlowStat(faParent)
632 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400633 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400634 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400635
npujar1d86a522019-11-14 17:11:16 +0530636 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400637 KV: fu.OfpFlowModArgs{"priority": 1000},
638 MatchFields: []*ofp.OfpOxmOfbField{
639 fu.InPort(2),
640 fu.TunnelId(uint64(1)),
641 fu.EthType(0x888e),
642 },
643 Actions: []*ofp.OfpAction{
644 fu.Output(1),
645 },
646 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800647 expectedOnuFlow, err := fu.MkFlowStat(faChild)
648 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400649 derivedFlow = onu1FlowAndGroup.GetFlow(0)
650 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400651}
652
653func TestDhcpReRouteRuleDecomposition(t *testing.T) {
654
npujar1d86a522019-11-14 17:11:16 +0530655 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400656 KV: fu.OfpFlowModArgs{"priority": 1000},
657 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400658 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400659 fu.EthType(0x0800),
660 fu.Ipv4Dst(0xffffffff),
661 fu.IpProto(17),
662 fu.UdpSrc(68),
663 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400664 },
665 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400666 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400667 },
668 }
669
Scott Bakerfdea1e32020-02-21 15:35:41 -0800670 fs, err := fu.MkFlowStat(fa)
671 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400672 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800673 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400674
Kent Hagerman433a31a2020-05-20 19:04:48 -0400675 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500676 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400677 onu1FlowAndGroup := deviceRules.Rules["onu1"]
678 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400679 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
680 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400681 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400682 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
683
npujar1d86a522019-11-14 17:11:16 +0530684 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400685 KV: fu.OfpFlowModArgs{"priority": 1000},
686 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400687 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400688 fu.TunnelId(uint64(1)),
689 fu.EthType(0x0800),
690 fu.Ipv4Dst(0xffffffff),
691 fu.IpProto(17),
692 fu.UdpSrc(68),
693 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400694 },
695 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400696 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400697 },
698 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800699 expectedOltFlow, err := fu.MkFlowStat(faParent)
700 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400701 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400702 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400703
npujar1d86a522019-11-14 17:11:16 +0530704 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400705 KV: fu.OfpFlowModArgs{"priority": 1000},
706 MatchFields: []*ofp.OfpOxmOfbField{
707 fu.InPort(2),
708 fu.TunnelId(uint64(1)),
709 fu.EthType(0x0800),
710 fu.Ipv4Dst(0xffffffff),
711 fu.IpProto(17),
712 fu.UdpSrc(68),
713 fu.UdpDst(67),
714 },
715 Actions: []*ofp.OfpAction{
716 fu.Output(1),
717 },
718 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800719 expectedOnuFlow, err := fu.MkFlowStat(faChild)
720 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400721 derivedFlow = onu1FlowAndGroup.GetFlow(0)
722 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400723}
724
Humera Kouser4ff89012019-08-25 19:01:51 -0400725func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530726 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400727 KV: fu.OfpFlowModArgs{"priority": 1000},
728 MatchFields: []*ofp.OfpOxmOfbField{
729 fu.InPort(10),
730 fu.EthType(0x88CC),
731 },
732 Actions: []*ofp.OfpAction{
733 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
734 },
735 }
736
Scott Bakerfdea1e32020-02-21 15:35:41 -0800737 fs, err := fu.MkFlowStat(fa)
738 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400739 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800740 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Kent Hagerman433a31a2020-05-20 19:04:48 -0400741 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500742 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400743 onu1FlowAndGroup := deviceRules.Rules["onu1"]
744 oltFlowAndGroup := deviceRules.Rules["olt"]
745 assert.Nil(t, onu1FlowAndGroup)
746 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
747 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
748
749 fa = &fu.FlowArgs{
750 KV: fu.OfpFlowModArgs{"priority": 1000},
751 MatchFields: []*ofp.OfpOxmOfbField{
752 fu.InPort(2),
753 fu.EthType(0x88CC),
754 },
755 Actions: []*ofp.OfpAction{
756 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
757 },
758 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800759 expectedOltFlow, err := fu.MkFlowStat(fa)
760 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400761 derivedFlow := oltFlowAndGroup.GetFlow(0)
762 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
763}
764
khenaidood20a5852018-10-22 22:09:55 -0400765func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530766 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400767 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400768 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400769 fu.InPort(1),
770 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
771 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400772 },
773 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400774 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400775 },
776 }
777
npujar1d86a522019-11-14 17:11:16 +0530778 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400779 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400780 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400781 fu.InPort(1),
782 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
783 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400784 },
785 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400786 fu.PushVlan(0x8100),
787 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
788 fu.SetField(fu.VlanPcp(0)),
789 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400790 },
791 }
792
Scott Bakerfdea1e32020-02-21 15:35:41 -0800793 fs, err := fu.MkFlowStat(fa)
794 assert.Nil(t, err)
795 fs2, err := fu.MkFlowStat(fa2)
796 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400797
798 fs.Instructions = []*ofp.OfpInstruction{{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400799 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
800 Data: &ofp.OfpInstruction_GotoTable{
801 GotoTable: &ofp.OfpInstructionGotoTable{
802 TableId: 1,
803 },
804 }}}
Kent Hagerman433a31a2020-05-20 19:04:48 -0400805 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs, fs2.Id: fs2}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400806
Scott Bakerfdea1e32020-02-21 15:35:41 -0800807 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400808
Kent Hagerman433a31a2020-05-20 19:04:48 -0400809 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500810 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400811 onu1FlowAndGroup := deviceRules.Rules["onu1"]
812 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400813 assert.NotNil(t, onu1FlowAndGroup)
814 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400815 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400816 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
817 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
818 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
819
820 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400821 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400822 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400823 fu.InPort(2),
824 fu.TunnelId(uint64(1)),
825 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0),
826 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400827 },
828 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400829 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
830 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400831 },
832 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400833
khenaidoo3306c992019-05-24 16:57:35 -0400834 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400835 // Form the expected flow
Scott Bakerfdea1e32020-02-21 15:35:41 -0800836 expectedOnu1Flow, err := fu.MkFlowStat(fa)
837 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400838 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
839 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
840 Data: &ofp.OfpInstruction_Actions{
841 Actions: &ofp.OfpInstructionActions{
842 Actions: []*ofp.OfpAction{{
843 Type: 0,
844 Action: &ofp.OfpAction_Output{
845 Output: &ofp.OfpActionOutput{
846 Port: 1,
847 MaxLen: 65509,
848 },
849 }}}}}}}
850
851 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400852 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
853
854 fa = &fu.FlowArgs{
855 KV: fu.OfpFlowModArgs{"priority": 500},
856 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400857 fu.InPort(1),
858 fu.TunnelId(uint64(1)),
859 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
860 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400861 },
862 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400863 fu.PushVlan(0x8100),
864 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
865 fu.SetField(fu.VlanPcp(0)),
866 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400867 },
868 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800869 expectedOltFlow, err := fu.MkFlowStat(fa)
870 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400871 derivedFlow = oltFlowAndGroup.GetFlow(0)
872 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
873}
874
875func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000876 ctx := context.Background()
877 logger.Debugf(ctx, "Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530878 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400879 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400880 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400881 fu.InPort(10),
882 fu.Metadata_ofp((1000 << 32) | 1),
883 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400884 },
885 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400886 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400887 },
888 }
889
npujar1d86a522019-11-14 17:11:16 +0530890 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400891 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400892 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400893 fu.InPort(10),
894 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
895 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) | 0)),
899 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400900 },
901 }
902
Scott Bakerfdea1e32020-02-21 15:35:41 -0800903 fs1, err := fu.MkFlowStat(fa1)
904 assert.Nil(t, err)
905 fs2, err := fu.MkFlowStat(fa2)
906 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400907 fs1.Instructions = []*ofp.OfpInstruction{{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400908 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
909 Data: &ofp.OfpInstruction_GotoTable{
910 GotoTable: &ofp.OfpInstructionGotoTable{
911 TableId: 1,
912 },
913 }}}
Kent Hagerman433a31a2020-05-20 19:04:48 -0400914 flows := map[uint64]*ofp.OfpFlowStats{fs1.Id: fs1, fs2.Id: fs2}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400915
Scott Bakerfdea1e32020-02-21 15:35:41 -0800916 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400917
Kent Hagerman433a31a2020-05-20 19:04:48 -0400918 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500919 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400920 onu1FlowAndGroup := deviceRules.Rules["onu1"]
921 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400922 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400923 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
924 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
925 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
926
927 fa1 = &fu.FlowArgs{
928 KV: fu.OfpFlowModArgs{"priority": 500},
929 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400930 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -0400931 fu.TunnelId(uint64(10)),
932 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -0400933 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400934 },
935 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400936 fu.PopVlan(),
937 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400938 },
939 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400940
khenaidood20a5852018-10-22 22:09:55 -0400941 derivedFlow := oltFlowAndGroup.GetFlow(0)
Scott Bakerfdea1e32020-02-21 15:35:41 -0800942 expectedOltFlow, err := fu.MkFlowStat(fa1)
943 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400944 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
945 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
946 Data: &ofp.OfpInstruction_Actions{
947 Actions: &ofp.OfpInstructionActions{
948 Actions: []*ofp.OfpAction{{
949 Type: 0,
950 Action: &ofp.OfpAction_Output{
951 Output: &ofp.OfpActionOutput{
952 Port: 1,
953 MaxLen: 65509,
954 },
955 }}}}}}}
956 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -0400957 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
958
959 fa1 = &fu.FlowArgs{
960 KV: fu.OfpFlowModArgs{"priority": 500},
961 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400962 fu.InPort(1),
963 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
964 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400965 },
966 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400967 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 0)),
968 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400969 },
970 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800971 expectedOnu1Flow, err := fu.MkFlowStat(fa1)
972 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400973 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -0400974 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
975}
976
977func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530978 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -0400979 KV: fu.OfpFlowModArgs{"priority": 500},
980 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400981 fu.InPort(10),
982 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
983 fu.VlanPcp(0),
984 fu.EthType(0x800),
985 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -0400986 },
987 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400988 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -0400989 },
990 }
991
npujar1d86a522019-11-14 17:11:16 +0530992 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -0400993 GroupId: 10,
994 Buckets: []*ofp.OfpBucket{
995 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400996 fu.PopVlan(),
997 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400998 },
999 },
1000 },
1001 }
1002
Scott Bakerfdea1e32020-02-21 15:35:41 -08001003 fs, err := fu.MkFlowStat(fa)
1004 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -04001005 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
1006 groups := map[uint32]*ofp.OfpGroupEntry{ga.GroupId: fu.MkGroupStat(ga)}
Scott Bakerfdea1e32020-02-21 15:35:41 -08001007 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -04001008
khenaidoo820197c2020-02-13 16:35:33 -05001009 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
1010 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001011 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -04001012 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1013 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1014
1015 fa = &fu.FlowArgs{
1016 KV: fu.OfpFlowModArgs{"priority": 500},
1017 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +00001018 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -04001019 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1020 fu.VlanPcp(0),
1021 fu.EthType(0x800),
1022 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001023 },
1024 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001025 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001026 },
1027 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001028 expectedOltFlow, err := fu.MkFlowStat(fa)
1029 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001030 derivedFlow := oltFlowAndGroup.GetFlow(0)
1031 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001032}