blob: 4cb6d7fb6fd690b3a896f0d42549482ff4d1904f [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"
khenaidood948f772021-08-11 17:49:24 -040025 fu "github.com/opencord/voltha-lib-go/v7/pkg/flows"
26 ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
27 "github.com/opencord/voltha-protos/v5/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),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300335 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
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),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300351 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
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),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300367 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
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),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300383 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo89b0e942018-10-21 21:11:33 -0400384 },
385 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400386 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 104)),
387 fu.Output(1),
khenaidoo89b0e942018-10-21 21:11:33 -0400388 },
389 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800390 fs, err = fu.MkFlowStat(fa)
391 assert.Nil(t, err)
392 fg.AddFlow(fs)
khenaidoo89b0e942018-10-21 21:11:33 -0400393 tfd.defaultRules.AddFlowsAndGroup("onu4", fg)
394
395 //Set up the device graph - flow decomposer uses it only to verify whether a port is a root port.
Kent Hagerman2a07b862020-06-19 15:23:07 -0400396 tfd.deviceRoutes = route.NewDeviceRoutes("ldid", "olt", tfd.dMgr.listDevicePorts)
khenaidoo820197c2020-02-13 16:35:33 -0500397 tfd.deviceRoutes.RootPorts = make(map[uint32]uint32)
398 tfd.deviceRoutes.RootPorts[10] = 10
khenaidoo89b0e942018-10-21 21:11:33 -0400399
Kent Hagerman6031aad2020-07-29 16:36:33 -0400400 tfd.fd = NewFlowDecomposer(func(ctx context.Context, deviceID string) (*voltha.Device, error) {
401 return tfd.dMgr.GetDevice(ctx, &voltha.ID{Id: deviceID})
402 })
khenaidoo89b0e942018-10-21 21:11:33 -0400403
404 return &tfd
405}
406
npujar1d86a522019-11-14 17:11:16 +0530407func (tfd *testFlowDecomposer) GetDeviceLogicalID() string {
khenaidoo89b0e942018-10-21 21:11:33 -0400408 return ""
409}
410
khenaidoo442e7c72020-03-10 16:13:48 -0400411func (tfd *testFlowDecomposer) GetLogicalDevice(ctx context.Context) (*voltha.LogicalDevice, error) {
412 return nil, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400413}
414
khenaidoo820197c2020-02-13 16:35:33 -0500415func (tfd *testFlowDecomposer) GetDeviceRoutes() *route.DeviceRoutes {
416 return tfd.deviceRoutes
khenaidoo89b0e942018-10-21 21:11:33 -0400417}
418
419func (tfd *testFlowDecomposer) GetAllDefaultRules() *fu.DeviceRules {
420 return tfd.defaultRules
421}
422
Rohan Agrawal31f21802020-06-12 05:38:46 +0000423func (tfd *testFlowDecomposer) GetWildcardInputPorts(ctx context.Context, excludePort uint32) map[uint32]struct{} {
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400424 lPorts := make(map[uint32]struct{})
425 for portNo := range tfd.logicalPorts {
426 if portNo != excludePort {
427 lPorts[portNo] = struct{}{}
khenaidoo89b0e942018-10-21 21:11:33 -0400428 }
429 }
430 return lPorts
431}
432
khenaidoo820197c2020-02-13 16:35:33 -0500433func (tfd *testFlowDecomposer) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
434 var portLink route.OFPortLink
khenaidoo19d7b632018-10-30 10:49:50 -0400435 if egressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400436 portLink.Egress = 0
khenaidoo19d7b632018-10-30 10:49:50 -0400437 } else if egressPortNo&0x7fffffff == uint32(ofp.OfpPortNo_OFPP_CONTROLLER) {
khenaidoo89b0e942018-10-21 21:11:33 -0400438 portLink.Egress = 10
439 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400440 portLink.Egress = egressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400441 }
khenaidoo19d7b632018-10-30 10:49:50 -0400442 if ingressPortNo == 0 {
khenaidoo89b0e942018-10-21 21:11:33 -0400443 portLink.Ingress = 0
444 } else {
khenaidoo19d7b632018-10-30 10:49:50 -0400445 portLink.Ingress = ingressPortNo
khenaidoo89b0e942018-10-21 21:11:33 -0400446 }
447 for key, val := range tfd.routes {
448 if key.Ingress == portLink.Ingress && key.Egress == portLink.Egress {
khenaidoo820197c2020-02-13 16:35:33 -0500449 return val, nil
khenaidoo89b0e942018-10-21 21:11:33 -0400450 }
451 }
khenaidoo820197c2020-02-13 16:35:33 -0500452 return nil, status.Errorf(codes.FailedPrecondition, "no route from:%d to:%d", ingressPortNo, egressPortNo)
khenaidoo89b0e942018-10-21 21:11:33 -0400453}
454
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400455func (tfd *testFlowDecomposer) GetNNIPorts() map[uint32]struct{} {
456 nniPorts := make(map[uint32]struct{})
Esin Karaman09959ae2019-11-29 13:59:58 +0000457 for portNo, nni := range tfd.logicalPortsNo {
458 if nni {
Kent Hagermanfa9d6d42020-05-25 11:49:40 -0400459 nniPorts[portNo] = struct{}{}
Esin Karaman09959ae2019-11-29 13:59:58 +0000460 }
461 }
462 return nniPorts
463}
464
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400465func TestEapolReRouteRuleVlanDecomposition(t *testing.T) {
466
npujar1d86a522019-11-14 17:11:16 +0530467 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400468 KV: fu.OfpFlowModArgs{"priority": 1000},
469 MatchFields: []*ofp.OfpOxmOfbField{
470 fu.InPort(1),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700471 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400472 fu.EthType(0x888e),
473 },
474 Actions: []*ofp.OfpAction{
475 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
476 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
477 },
478 }
479
Scott Bakerfdea1e32020-02-21 15:35:41 -0800480 fs, err := fu.MkFlowStat(fa)
481 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400482 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800483 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400484
Kent Hagerman433a31a2020-05-20 19:04:48 -0400485 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500486 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400487 onu1FlowAndGroup := deviceRules.Rules["onu1"]
488 oltFlowAndGroup := deviceRules.Rules["olt"]
489 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
490 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
491 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
492
npujar1d86a522019-11-14 17:11:16 +0530493 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400494 KV: fu.OfpFlowModArgs{"priority": 1000},
495 MatchFields: []*ofp.OfpOxmOfbField{
496 fu.InPort(1),
497 fu.TunnelId(uint64(1)),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700498 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400499 fu.EthType(0x888e),
500 },
501 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400502 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
503 },
504 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800505 expectedOltFlow, err := fu.MkFlowStat(faParent)
506 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400507 derivedFlow := oltFlowAndGroup.GetFlow(0)
508 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
509
npujar1d86a522019-11-14 17:11:16 +0530510 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400511 KV: fu.OfpFlowModArgs{"priority": 1000},
512 MatchFields: []*ofp.OfpOxmOfbField{
513 fu.InPort(2),
514 fu.TunnelId(uint64(1)),
515 fu.EthType(0x888e),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700516 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400517 },
518 Actions: []*ofp.OfpAction{
519 fu.PushVlan(0x8100),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700520 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400521 fu.Output(1),
522 },
523 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800524 expectedOnuFlow, err := fu.MkFlowStat(faChild)
525 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400526 derivedFlow = onu1FlowAndGroup.GetFlow(0)
527 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
528}
529
530func TestEapolReRouteRuleZeroVlanDecomposition(t *testing.T) {
531
npujar1d86a522019-11-14 17:11:16 +0530532 fa := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400533 KV: fu.OfpFlowModArgs{"priority": 1000},
534 MatchFields: []*ofp.OfpOxmOfbField{
535 fu.InPort(1),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300536 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400537 fu.EthType(0x888e),
538 },
539 Actions: []*ofp.OfpAction{
540 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
541 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
542 },
543 }
544
Scott Bakerfdea1e32020-02-21 15:35:41 -0800545 fs, err := fu.MkFlowStat(fa)
546 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400547 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800548 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400549
Kent Hagerman433a31a2020-05-20 19:04:48 -0400550 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500551 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400552 onu1FlowAndGroup := deviceRules.Rules["onu1"]
553 oltFlowAndGroup := deviceRules.Rules["olt"]
554 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
555 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
556 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
557
npujar1d86a522019-11-14 17:11:16 +0530558 faParent := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400559 KV: fu.OfpFlowModArgs{"priority": 1000},
560 MatchFields: []*ofp.OfpOxmOfbField{
561 fu.InPort(1),
562 fu.TunnelId(uint64(1)),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700563 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400564 fu.EthType(0x888e),
565 },
566 Actions: []*ofp.OfpAction{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400567 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
568 },
569 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800570 expectedOltFlow, err := fu.MkFlowStat(faParent)
571 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400572 derivedFlow := oltFlowAndGroup.GetFlow(0)
573 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
574
npujar1d86a522019-11-14 17:11:16 +0530575 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400576 KV: fu.OfpFlowModArgs{"priority": 1000},
577 MatchFields: []*ofp.OfpOxmOfbField{
578 fu.InPort(2),
579 fu.TunnelId(uint64(1)),
580 fu.EthType(0x888e),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300581 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400582 },
583 Actions: []*ofp.OfpAction{
584 fu.PushVlan(0x8100),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700585 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400586 fu.Output(1),
587 },
588 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800589 expectedOnuFlow, err := fu.MkFlowStat(faChild)
590 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400591 derivedFlow = onu1FlowAndGroup.GetFlow(0)
592 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
593}
594
595func TestEapolReRouteRuleNoVlanDecomposition(t *testing.T) {
khenaidoo89b0e942018-10-21 21:11:33 -0400596
npujar1d86a522019-11-14 17:11:16 +0530597 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400598 KV: fu.OfpFlowModArgs{"priority": 1000},
599 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400600 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400601 fu.EthType(0x888e),
khenaidoo89b0e942018-10-21 21:11:33 -0400602 },
603 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400604 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
605 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400606 },
607 }
608
Scott Bakerfdea1e32020-02-21 15:35:41 -0800609 fs, err := fu.MkFlowStat(fa)
610 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400611 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800612 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400613
Kent Hagerman433a31a2020-05-20 19:04:48 -0400614 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500615 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400616 onu1FlowAndGroup := deviceRules.Rules["onu1"]
617 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400618 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400619 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400620 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
621
npujar1d86a522019-11-14 17:11:16 +0530622 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400623 KV: fu.OfpFlowModArgs{"priority": 1000},
624 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400625 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400626 fu.TunnelId(uint64(1)),
627 fu.EthType(0x888e),
Girish Gowdra9a50f032020-09-16 13:21:10 -0700628 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
khenaidoo89b0e942018-10-21 21:11:33 -0400629 },
630 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400631 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400632 },
633 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800634 expectedOltFlow, err := fu.MkFlowStat(faParent)
635 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400636 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400637 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400638
npujar1d86a522019-11-14 17:11:16 +0530639 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400640 KV: fu.OfpFlowModArgs{"priority": 1000},
641 MatchFields: []*ofp.OfpOxmOfbField{
642 fu.InPort(2),
643 fu.TunnelId(uint64(1)),
644 fu.EthType(0x888e),
645 },
646 Actions: []*ofp.OfpAction{
Girish Gowdra9a50f032020-09-16 13:21:10 -0700647 fu.PushVlan(0x8100),
648 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400649 fu.Output(1),
650 },
651 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800652 expectedOnuFlow, err := fu.MkFlowStat(faChild)
653 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400654 derivedFlow = onu1FlowAndGroup.GetFlow(0)
655 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400656}
657
Marcos Aurelio Carrero (Furukawa)a61a72c2021-01-28 13:48:20 -0300658func TestPppoedReRouteRuleVlanDecomposition(t *testing.T) {
659
660 fa := &fu.FlowArgs{
661 KV: fu.OfpFlowModArgs{"priority": 1000},
662 MatchFields: []*ofp.OfpOxmOfbField{
663 fu.InPort(1),
664 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
665 fu.EthType(0x8863),
666 },
667 Actions: []*ofp.OfpAction{
668 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
669 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
670 },
671 }
672
673 fs, err := fu.MkFlowStat(fa)
674 assert.Nil(t, err)
675 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
676 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
677
678 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
679 assert.Nil(t, err)
680 onu1FlowAndGroup := deviceRules.Rules["onu1"]
681 oltFlowAndGroup := deviceRules.Rules["olt"]
682 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
683 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
684 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
685
686 faParent := &fu.FlowArgs{
687 KV: fu.OfpFlowModArgs{"priority": 1000},
688 MatchFields: []*ofp.OfpOxmOfbField{
689 fu.InPort(1),
690 fu.TunnelId(uint64(1)),
691 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
692 fu.EthType(0x8863),
693 },
694 Actions: []*ofp.OfpAction{
695 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
696 },
697 }
698 expectedOltFlow, err := fu.MkFlowStat(faParent)
699 assert.Nil(t, err)
700 derivedFlow := oltFlowAndGroup.GetFlow(0)
701 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
702
703 faChild := &fu.FlowArgs{
704 KV: fu.OfpFlowModArgs{"priority": 1000},
705 MatchFields: []*ofp.OfpOxmOfbField{
706 fu.InPort(2),
707 fu.TunnelId(uint64(1)),
708 fu.EthType(0x8863),
709 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 50),
710 },
711 Actions: []*ofp.OfpAction{
712 fu.PushVlan(0x8100),
713 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
714 fu.Output(1),
715 },
716 }
717 expectedOnuFlow, err := fu.MkFlowStat(faChild)
718 assert.Nil(t, err)
719 derivedFlow = onu1FlowAndGroup.GetFlow(0)
720 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
721}
722
khenaidoo89b0e942018-10-21 21:11:33 -0400723func TestDhcpReRouteRuleDecomposition(t *testing.T) {
724
npujar1d86a522019-11-14 17:11:16 +0530725 fa := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400726 KV: fu.OfpFlowModArgs{"priority": 1000},
727 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400728 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400729 fu.EthType(0x0800),
730 fu.Ipv4Dst(0xffffffff),
731 fu.IpProto(17),
732 fu.UdpSrc(68),
733 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400734 },
735 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400736 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400737 },
738 }
739
Scott Bakerfdea1e32020-02-21 15:35:41 -0800740 fs, err := fu.MkFlowStat(fa)
741 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400742 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800743 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidoo89b0e942018-10-21 21:11:33 -0400744
Kent Hagerman433a31a2020-05-20 19:04:48 -0400745 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500746 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400747 onu1FlowAndGroup := deviceRules.Rules["onu1"]
748 oltFlowAndGroup := deviceRules.Rules["olt"]
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400749 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
750 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
Manikkaraj kb1a10922019-07-29 12:10:34 -0400751 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
khenaidoo89b0e942018-10-21 21:11:33 -0400752 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
753
npujar1d86a522019-11-14 17:11:16 +0530754 faParent := &fu.FlowArgs{
khenaidoo89b0e942018-10-21 21:11:33 -0400755 KV: fu.OfpFlowModArgs{"priority": 1000},
756 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400757 fu.InPort(1),
khenaidoo68c930b2019-05-13 11:46:51 -0400758 fu.TunnelId(uint64(1)),
759 fu.EthType(0x0800),
760 fu.Ipv4Dst(0xffffffff),
761 fu.IpProto(17),
762 fu.UdpSrc(68),
763 fu.UdpDst(67),
khenaidoo89b0e942018-10-21 21:11:33 -0400764 },
765 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400766 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
khenaidoo89b0e942018-10-21 21:11:33 -0400767 },
768 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800769 expectedOltFlow, err := fu.MkFlowStat(faParent)
770 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -0400771 derivedFlow := oltFlowAndGroup.GetFlow(0)
khenaidoo89b0e942018-10-21 21:11:33 -0400772 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400773
npujar1d86a522019-11-14 17:11:16 +0530774 faChild := &fu.FlowArgs{
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400775 KV: fu.OfpFlowModArgs{"priority": 1000},
776 MatchFields: []*ofp.OfpOxmOfbField{
777 fu.InPort(2),
778 fu.TunnelId(uint64(1)),
779 fu.EthType(0x0800),
780 fu.Ipv4Dst(0xffffffff),
781 fu.IpProto(17),
782 fu.UdpSrc(68),
783 fu.UdpDst(67),
784 },
785 Actions: []*ofp.OfpAction{
786 fu.Output(1),
787 },
788 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800789 expectedOnuFlow, err := fu.MkFlowStat(faChild)
790 assert.Nil(t, err)
Matt Jeanneretb423bad2019-10-10 20:42:19 -0400791 derivedFlow = onu1FlowAndGroup.GetFlow(0)
792 assert.Equal(t, expectedOnuFlow.String(), derivedFlow.String())
khenaidoo89b0e942018-10-21 21:11:33 -0400793}
794
Humera Kouser4ff89012019-08-25 19:01:51 -0400795func TestLldpReRouteRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530796 fa := &fu.FlowArgs{
Humera Kouser4ff89012019-08-25 19:01:51 -0400797 KV: fu.OfpFlowModArgs{"priority": 1000},
798 MatchFields: []*ofp.OfpOxmOfbField{
799 fu.InPort(10),
800 fu.EthType(0x88CC),
801 },
802 Actions: []*ofp.OfpAction{
803 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
804 },
805 }
806
Scott Bakerfdea1e32020-02-21 15:35:41 -0800807 fs, err := fu.MkFlowStat(fa)
808 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400809 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
Scott Bakerfdea1e32020-02-21 15:35:41 -0800810 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
Kent Hagerman433a31a2020-05-20 19:04:48 -0400811 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500812 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400813 onu1FlowAndGroup := deviceRules.Rules["onu1"]
814 oltFlowAndGroup := deviceRules.Rules["olt"]
815 assert.Nil(t, onu1FlowAndGroup)
816 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
817 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
818
819 fa = &fu.FlowArgs{
820 KV: fu.OfpFlowModArgs{"priority": 1000},
821 MatchFields: []*ofp.OfpOxmOfbField{
822 fu.InPort(2),
823 fu.EthType(0x88CC),
824 },
825 Actions: []*ofp.OfpAction{
826 fu.Output(uint32(ofp.OfpPortNo_OFPP_CONTROLLER)),
827 },
828 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800829 expectedOltFlow, err := fu.MkFlowStat(fa)
830 assert.Nil(t, err)
Humera Kouser4ff89012019-08-25 19:01:51 -0400831 derivedFlow := oltFlowAndGroup.GetFlow(0)
832 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
833}
834
khenaidood20a5852018-10-22 22:09:55 -0400835func TestUnicastUpstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +0530836 fa := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400837 KV: fu.OfpFlowModArgs{"priority": 5000, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400838 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400839 fu.InPort(1),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300840 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo68c930b2019-05-13 11:46:51 -0400841 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400842 },
843 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400844 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
khenaidood20a5852018-10-22 22:09:55 -0400845 },
846 }
847
npujar1d86a522019-11-14 17:11:16 +0530848 fa2 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400849 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 1},
khenaidood20a5852018-10-22 22:09:55 -0400850 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400851 fu.InPort(1),
852 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
853 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400854 },
855 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400856 fu.PushVlan(0x8100),
857 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
858 fu.SetField(fu.VlanPcp(0)),
859 fu.Output(10),
khenaidood20a5852018-10-22 22:09:55 -0400860 },
861 }
862
Scott Bakerfdea1e32020-02-21 15:35:41 -0800863 fs, err := fu.MkFlowStat(fa)
864 assert.Nil(t, err)
865 fs2, err := fu.MkFlowStat(fa2)
866 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -0400867
868 fs.Instructions = []*ofp.OfpInstruction{{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400869 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
870 Data: &ofp.OfpInstruction_GotoTable{
871 GotoTable: &ofp.OfpInstructionGotoTable{
872 TableId: 1,
873 },
874 }}}
Kent Hagerman433a31a2020-05-20 19:04:48 -0400875 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs, fs2.Id: fs2}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400876
Scott Bakerfdea1e32020-02-21 15:35:41 -0800877 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400878
Kent Hagerman433a31a2020-05-20 19:04:48 -0400879 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500880 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400881 onu1FlowAndGroup := deviceRules.Rules["onu1"]
882 oltFlowAndGroup := deviceRules.Rules["olt"]
Manikkaraj kb1a10922019-07-29 12:10:34 -0400883 assert.NotNil(t, onu1FlowAndGroup)
884 assert.NotNil(t, onu1FlowAndGroup.Flows)
khenaidoo3306c992019-05-24 16:57:35 -0400885 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400886 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
887 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
888 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
889
890 fa = &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400891 KV: fu.OfpFlowModArgs{"priority": 5000},
khenaidood20a5852018-10-22 22:09:55 -0400892 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400893 fu.InPort(2),
894 fu.TunnelId(uint64(1)),
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300895 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
khenaidoo68c930b2019-05-13 11:46:51 -0400896 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400897 },
898 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400899 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
900 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400901 },
902 }
Manikkaraj kb1a10922019-07-29 12:10:34 -0400903
khenaidoo3306c992019-05-24 16:57:35 -0400904 derivedFlow := onu1FlowAndGroup.GetFlow(0)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400905 // Form the expected flow
Scott Bakerfdea1e32020-02-21 15:35:41 -0800906 expectedOnu1Flow, err := fu.MkFlowStat(fa)
907 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -0400908 expectedOnu1Flow.Instructions = []*ofp.OfpInstruction{{
909 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
910 Data: &ofp.OfpInstruction_Actions{
911 Actions: &ofp.OfpInstructionActions{
912 Actions: []*ofp.OfpAction{{
913 Type: 0,
914 Action: &ofp.OfpAction_Output{
915 Output: &ofp.OfpActionOutput{
916 Port: 1,
917 MaxLen: 65509,
918 },
919 }}}}}}}
920
921 expectedOnu1Flow.Id = derivedFlow.Id // Assign same flow ID as derived flowID to match completely
khenaidood20a5852018-10-22 22:09:55 -0400922 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
923
924 fa = &fu.FlowArgs{
925 KV: fu.OfpFlowModArgs{"priority": 500},
926 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400927 fu.InPort(1),
928 fu.TunnelId(uint64(1)),
929 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
930 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400931 },
932 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400933 fu.PushVlan(0x8100),
934 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 1000)),
935 fu.SetField(fu.VlanPcp(0)),
936 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -0400937 },
938 }
Scott Bakerfdea1e32020-02-21 15:35:41 -0800939 expectedOltFlow, err := fu.MkFlowStat(fa)
940 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400941 derivedFlow = oltFlowAndGroup.GetFlow(0)
942 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
943}
944
945func TestUnicastDownstreamRuleDecomposition(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000946 ctx := context.Background()
947 logger.Debugf(ctx, "Starting Test Unicast Downstream")
npujar1d86a522019-11-14 17:11:16 +0530948 fa1 := &fu.FlowArgs{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400949 KV: fu.OfpFlowModArgs{"priority": 500, "table_id": 0},
khenaidood20a5852018-10-22 22:09:55 -0400950 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400951 fu.InPort(10),
952 fu.Metadata_ofp((1000 << 32) | 1),
953 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400954 },
955 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -0400956 fu.PopVlan(),
khenaidood20a5852018-10-22 22:09:55 -0400957 },
958 }
959
ssiddiqui21e54c32021-07-27 11:30:46 +0530960 // If table-id is provided in the flow-args, the same is also used as go-to-next table
npujar1d86a522019-11-14 17:11:16 +0530961 fa2 := &fu.FlowArgs{
ssiddiqui21e54c32021-07-27 11:30:46 +0530962 KV: fu.OfpFlowModArgs{"priority": 500 /*"table_id": 1*/},
khenaidood20a5852018-10-22 22:09:55 -0400963 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -0400964 fu.InPort(10),
965 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
966 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -0400967 },
968 Actions: []*ofp.OfpAction{
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +0300969 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT))),
khenaidoo68c930b2019-05-13 11:46:51 -0400970 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -0400971 },
972 }
973
Scott Bakerfdea1e32020-02-21 15:35:41 -0800974 fs1, err := fu.MkFlowStat(fa1)
975 assert.Nil(t, err)
976 fs2, err := fu.MkFlowStat(fa2)
977 assert.Nil(t, err)
ssiddiqui21e54c32021-07-27 11:30:46 +0530978 // Table-1, without next table
979 fs2.TableId = 1
980
Kent Hagerman433a31a2020-05-20 19:04:48 -0400981 fs1.Instructions = []*ofp.OfpInstruction{{
Manikkaraj kb1a10922019-07-29 12:10:34 -0400982 Type: uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE),
983 Data: &ofp.OfpInstruction_GotoTable{
984 GotoTable: &ofp.OfpInstructionGotoTable{
985 TableId: 1,
986 },
987 }}}
Kent Hagerman433a31a2020-05-20 19:04:48 -0400988 flows := map[uint64]*ofp.OfpFlowStats{fs1.Id: fs1, fs2.Id: fs2}
Manikkaraj kb1a10922019-07-29 12:10:34 -0400989
Scott Bakerfdea1e32020-02-21 15:35:41 -0800990 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -0400991
Kent Hagerman433a31a2020-05-20 19:04:48 -0400992 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
khenaidoo820197c2020-02-13 16:35:33 -0500993 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -0400994 onu1FlowAndGroup := deviceRules.Rules["onu1"]
995 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidoo3306c992019-05-24 16:57:35 -0400996 assert.Equal(t, 1, onu1FlowAndGroup.Flows.Len())
khenaidood20a5852018-10-22 22:09:55 -0400997 assert.Equal(t, 0, onu1FlowAndGroup.Groups.Len())
998 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
999 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1000
1001 fa1 = &fu.FlowArgs{
1002 KV: fu.OfpFlowModArgs{"priority": 500},
1003 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001004 fu.InPort(2),
Manikkaraj kb1a10922019-07-29 12:10:34 -04001005 fu.TunnelId(uint64(10)),
1006 fu.Metadata_ofp(4294967296001),
khenaidoo68c930b2019-05-13 11:46:51 -04001007 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -04001008 },
1009 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001010 fu.PopVlan(),
1011 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001012 },
1013 }
Manikkaraj kb1a10922019-07-29 12:10:34 -04001014
khenaidood20a5852018-10-22 22:09:55 -04001015 derivedFlow := oltFlowAndGroup.GetFlow(0)
Scott Bakerfdea1e32020-02-21 15:35:41 -08001016 expectedOltFlow, err := fu.MkFlowStat(fa1)
1017 assert.Nil(t, err)
Manikkaraj kb1a10922019-07-29 12:10:34 -04001018 expectedOltFlow.Instructions = []*ofp.OfpInstruction{{
1019 Type: uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS),
1020 Data: &ofp.OfpInstruction_Actions{
1021 Actions: &ofp.OfpInstructionActions{
1022 Actions: []*ofp.OfpAction{{
1023 Type: 0,
1024 Action: &ofp.OfpAction_Output{
1025 Output: &ofp.OfpActionOutput{
1026 Port: 1,
1027 MaxLen: 65509,
1028 },
1029 }}}}}}}
1030 expectedOltFlow.Id = derivedFlow.Id
khenaidood20a5852018-10-22 22:09:55 -04001031 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
1032
1033 fa1 = &fu.FlowArgs{
1034 KV: fu.OfpFlowModArgs{"priority": 500},
1035 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001036 fu.InPort(1),
1037 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101),
1038 fu.VlanPcp(0),
khenaidood20a5852018-10-22 22:09:55 -04001039 },
1040 Actions: []*ofp.OfpAction{
Andrey Pozolotin34dd63f2021-05-31 21:26:40 +03001041 fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT))),
khenaidoo68c930b2019-05-13 11:46:51 -04001042 fu.Output(2),
khenaidood20a5852018-10-22 22:09:55 -04001043 },
1044 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001045 expectedOnu1Flow, err := fu.MkFlowStat(fa1)
1046 assert.Nil(t, err)
khenaidoo3306c992019-05-24 16:57:35 -04001047 derivedFlow = onu1FlowAndGroup.GetFlow(0)
khenaidood20a5852018-10-22 22:09:55 -04001048 assert.Equal(t, expectedOnu1Flow.String(), derivedFlow.String())
1049}
1050
1051func TestMulticastDownstreamRuleDecomposition(t *testing.T) {
npujar1d86a522019-11-14 17:11:16 +05301052 fa := &fu.FlowArgs{
khenaidood20a5852018-10-22 22:09:55 -04001053 KV: fu.OfpFlowModArgs{"priority": 500},
1054 MatchFields: []*ofp.OfpOxmOfbField{
khenaidoo68c930b2019-05-13 11:46:51 -04001055 fu.InPort(10),
1056 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1057 fu.VlanPcp(0),
1058 fu.EthType(0x800),
1059 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001060 },
1061 Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001062 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001063 },
1064 }
1065
npujar1d86a522019-11-14 17:11:16 +05301066 ga := &fu.GroupArgs{
khenaidood20a5852018-10-22 22:09:55 -04001067 GroupId: 10,
1068 Buckets: []*ofp.OfpBucket{
1069 {Actions: []*ofp.OfpAction{
khenaidoo68c930b2019-05-13 11:46:51 -04001070 fu.PopVlan(),
1071 fu.Output(1),
khenaidood20a5852018-10-22 22:09:55 -04001072 },
1073 },
1074 },
1075 }
1076
Scott Bakerfdea1e32020-02-21 15:35:41 -08001077 fs, err := fu.MkFlowStat(fa)
1078 assert.Nil(t, err)
Kent Hagerman433a31a2020-05-20 19:04:48 -04001079 flows := map[uint64]*ofp.OfpFlowStats{fs.Id: fs}
1080 groups := map[uint32]*ofp.OfpGroupEntry{ga.GroupId: fu.MkGroupStat(ga)}
Scott Bakerfdea1e32020-02-21 15:35:41 -08001081 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
khenaidood20a5852018-10-22 22:09:55 -04001082
khenaidoo820197c2020-02-13 16:35:33 -05001083 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, groups)
1084 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001085 oltFlowAndGroup := deviceRules.Rules["olt"]
khenaidood20a5852018-10-22 22:09:55 -04001086 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1087 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1088
1089 fa = &fu.FlowArgs{
1090 KV: fu.OfpFlowModArgs{"priority": 500},
1091 MatchFields: []*ofp.OfpOxmOfbField{
Esin Karaman09959ae2019-11-29 13:59:58 +00001092 fu.InPort(10),
khenaidoo68c930b2019-05-13 11:46:51 -04001093 fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 170),
1094 fu.VlanPcp(0),
1095 fu.EthType(0x800),
1096 fu.Ipv4Dst(0xe00a0a0a),
khenaidood20a5852018-10-22 22:09:55 -04001097 },
1098 Actions: []*ofp.OfpAction{
Esin Karaman09959ae2019-11-29 13:59:58 +00001099 fu.Group(10),
khenaidood20a5852018-10-22 22:09:55 -04001100 },
1101 }
Scott Bakerfdea1e32020-02-21 15:35:41 -08001102 expectedOltFlow, err := fu.MkFlowStat(fa)
1103 assert.Nil(t, err)
khenaidood20a5852018-10-22 22:09:55 -04001104 derivedFlow := oltFlowAndGroup.GetFlow(0)
1105 assert.Equal(t, expectedOltFlow.String(), derivedFlow.String())
khenaidood20a5852018-10-22 22:09:55 -04001106}
ssiddiqui21e54c32021-07-27 11:30:46 +05301107
1108func TestMplsUpstreamFlowDecomposition(t *testing.T) {
1109 // Note: Olt-Nni=10
1110 // Onu1-Uni=1
1111
1112 /*
1113 ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:UNI, VLAN_VID:ANY], treatment=[immediate=[],
1114 transition=TABLE:1, meter=METER:1, metadata=METADATA:4100010000/0]
1115 */
1116
1117 // Here, 'table_id=1' is present to add go-to-table action
1118 faOnu := &fu.FlowArgs{
1119 KV: fu.OfpFlowModArgs{"priority": 1000, "table_id": 1, "meter_id": 1, "write_metadata": 4100100000},
1120 MatchFields: []*ofp.OfpOxmOfbField{
1121 fu.InPort(1), // Onu Uni
1122 fu.VlanVid(4096),
1123 },
1124 Actions: []*ofp.OfpAction{},
1125 }
1126 fsOnu, err := fu.MkFlowStat(faOnu)
1127 assert.NoError(t, err)
1128 assert.NotNil(t, fsOnu)
1129 // Update table-id
1130 fsOnu.TableId = 0
1131
1132 /*
1133 ADDED, bytes=0, packets=0, table=1, priority=1000, selector=[IN_PORT:32, VLAN_VID:ANY], treatment=[immediate=[VLAN_PUSH:vlan,
1134 VLAN_ID:2, MPLS_PUSH:mpls_unicast, MPLS_LABEL:YYY,MPLS_BOS:true, MPLS_PUSH:mpls_unicast ,MPLS_LABEL:XXX, MPLS_BOS:false,
1135 EXTENSION:of:0000000000000227/VolthaPushL2Header{​​​​​​​}​​​​​​​, ETH_SRC:OLT_MAC, ETH_DST:LEAF_MAC, TTL:64, OUTPUT:65536],
1136 meter=METER:1, metadata=METADATA:4100000000/0]
1137 */
1138 faOlt := &fu.FlowArgs{
1139 KV: fu.OfpFlowModArgs{"priority": 1000, "meter_id": 1, "write_metadata": 4100000000},
1140 MatchFields: []*ofp.OfpOxmOfbField{
1141 fu.InPort(1), // Onu-Uni
1142 fu.VlanVid(4096),
1143 },
1144 Actions: []*ofp.OfpAction{
1145 fu.PushVlan(0x8100),
1146 fu.SetField(fu.VlanVid(2)),
1147 fu.SetField(fu.EthSrc(1111)),
1148 fu.SetField(fu.EthDst(2222)),
1149 fu.PushVlan(0x8847),
1150 fu.SetField(fu.MplsLabel(100)),
1151 fu.SetField(fu.MplsBos(1)),
1152 fu.PushVlan(0x8847),
1153 fu.SetField(fu.MplsLabel(200)),
1154 fu.MplsTtl(64),
1155 fu.Output(10), // Olt-Nni
1156 },
1157 }
1158
1159 fsOlt, err := fu.MkFlowStat(faOlt)
1160 assert.NoError(t, err)
1161 assert.NotNil(t, fsOlt)
1162 // Update table-id
1163 // table-id is skipped in flow-args above as that would also add the go-to-table action
1164 fsOlt.TableId = 1
1165
1166 flows := map[uint64]*ofp.OfpFlowStats{fsOnu.Id: fsOnu, fsOlt.Id: fsOlt}
1167
1168 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
1169
1170 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
1171 assert.Nil(t, err)
1172 onuFlowAndGroup := deviceRules.Rules["onu1"]
1173 oltFlowAndGroup := deviceRules.Rules["olt"]
1174 assert.NotNil(t, onuFlowAndGroup)
1175 assert.NotNil(t, onuFlowAndGroup.Flows)
1176 assert.Equal(t, 1, onuFlowAndGroup.Flows.Len())
1177 assert.Equal(t, 0, onuFlowAndGroup.Groups.Len())
1178 assert.Equal(t, 1, oltFlowAndGroup.Flows.Len())
1179 assert.Equal(t, 0, oltFlowAndGroup.Groups.Len())
1180
1181 // Form expected ONU flow args
1182 expectedOnufa := &fu.FlowArgs{
1183 KV: fu.OfpFlowModArgs{"priority": 1000, "meter_id": 1, "write_metadata": 4100100000},
1184 MatchFields: []*ofp.OfpOxmOfbField{
1185 fu.InPort(2), // Onu Uni
1186 fu.TunnelId(uint64(1)),
1187 fu.VlanVid(4096),
1188 },
1189 Actions: []*ofp.OfpAction{
1190 fu.Output(1),
1191 },
1192 }
1193
1194 // Form the expected ONU flow
1195 expectedOnuFlow, err := fu.MkFlowStat(expectedOnufa)
1196 assert.Nil(t, err)
1197 assert.NotNil(t, expectedOnuFlow)
1198 expectedOnuFlow.TableId = 0
1199
1200 derivedOnuFlow := onuFlowAndGroup.GetFlow(0)
1201 expectedOnuFlow.Id = derivedOnuFlow.Id // Assign same flow ID as derived flowID to match completely
1202 assert.Equal(t, expectedOnuFlow.String(), derivedOnuFlow.String())
1203
1204 expectedOltfa := &fu.FlowArgs{
1205 KV: fu.OfpFlowModArgs{"priority": 1000, "meter_id": 1, "write_metadata": 4100000000},
1206 MatchFields: []*ofp.OfpOxmOfbField{
1207 fu.InPort(1), // Onu-Uni
1208 fu.TunnelId(uint64(1)),
1209 fu.VlanVid(4096),
1210 },
1211 Actions: []*ofp.OfpAction{
1212 fu.PushVlan(0x8100),
1213 fu.SetField(fu.VlanVid(2)),
1214 fu.SetField(fu.EthSrc(1111)),
1215 fu.SetField(fu.EthDst(2222)),
1216 fu.PushVlan(0x8847),
1217 fu.SetField(fu.MplsLabel(100)),
1218 fu.SetField(fu.MplsBos(1)),
1219 fu.PushVlan(0x8847),
1220 fu.SetField(fu.MplsLabel(200)),
1221 fu.MplsTtl(64),
1222 fu.Output(2), // Olt-Nni
1223 },
1224 }
1225
1226 expectedOltFlow, err := fu.MkFlowStat(expectedOltfa)
1227 assert.NoError(t, err)
1228 assert.NotNil(t, expectedOltFlow)
1229
1230 derivedOltFlow := oltFlowAndGroup.GetFlow(0)
1231 expectedOltFlow.Id = derivedOltFlow.Id
1232 assert.Equal(t, expectedOltFlow.String(), derivedOltFlow.String())
1233}
1234
1235func TestMplsDownstreamFlowDecomposition(t *testing.T) {
1236 faOltSingleMplsLable := &fu.FlowArgs{
1237 KV: fu.OfpFlowModArgs{"priority": 1000, "table_id": 1},
1238 MatchFields: []*ofp.OfpOxmOfbField{
1239 fu.InPort(10),
1240 fu.Metadata_ofp((1000 << 32) | 1),
1241 fu.EthType(0x8847),
1242 fu.MplsBos(1),
1243 fu.EthSrc(2222),
1244 },
1245 Actions: []*ofp.OfpAction{
1246 {Type: ofp.OfpActionType_OFPAT_DEC_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: 62}}},
1247 fu.PopMpls(0x8847),
1248 },
1249 }
1250 fsOltSingleMplsLabel, err := fu.MkFlowStat(faOltSingleMplsLable)
1251 assert.NoError(t, err)
1252 assert.NotNil(t, fsOltSingleMplsLabel)
1253 fsOltSingleMplsLabel.TableId = 0
1254
1255 flows := map[uint64]*ofp.OfpFlowStats{fsOltSingleMplsLabel.Id: fsOltSingleMplsLabel}
1256
1257 tfd := newTestFlowDecomposer(t, newTestDeviceManager())
1258
1259 deviceRules, err := tfd.fd.DecomposeRules(context.Background(), tfd, flows, nil)
1260 assert.Nil(t, err)
1261 assert.NotNil(t, deviceRules)
1262 oltFlowAndGroup := deviceRules.Rules["olt"]
1263 assert.NotNil(t, oltFlowAndGroup)
1264
1265 derivedFlow := oltFlowAndGroup.GetFlow(0)
1266 assert.NotNil(t, derivedFlow)
1267
1268 // Formulate expected
1269 expectedFa := &fu.FlowArgs{
1270 KV: fu.OfpFlowModArgs{"priority": 1000},
1271 MatchFields: []*ofp.OfpOxmOfbField{
1272 fu.InPort(2),
1273 fu.TunnelId(10),
1274 fu.Metadata_ofp((1000 << 32) | 1),
1275 fu.EthType(0x8847),
1276 fu.MplsBos(1),
1277 fu.EthSrc(2222),
1278 },
1279 Actions: []*ofp.OfpAction{
1280 {Type: ofp.OfpActionType_OFPAT_DEC_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: 62}}},
1281 fu.PopMpls(0x8847),
1282 fu.Output(1),
1283 },
1284 }
1285 expectedFs, err := fu.MkFlowStat(expectedFa)
1286 assert.NoError(t, err)
1287 expectedFs.Id = derivedFlow.Id
1288
1289 assert.Equal(t, expectedFs.String(), derivedFlow.String())
1290
1291 // Formulate Mpls double label
1292 faOltDoubleMplsLabel := &fu.FlowArgs{
1293 KV: fu.OfpFlowModArgs{"priority": 1000, "table_id": 1},
1294 MatchFields: []*ofp.OfpOxmOfbField{
1295 fu.InPort(10),
1296 fu.EthType(0x8847),
1297 fu.EthSrc(2222),
1298 },
1299 Actions: []*ofp.OfpAction{
1300 {Type: ofp.OfpActionType_OFPAT_DEC_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: 62}}},
1301 fu.PopMpls(0x8847),
1302 fu.PopMpls(0x8847),
1303 },
1304 }
1305 fsOltDoubleMplsLabel, err := fu.MkFlowStat(faOltDoubleMplsLabel)
1306 assert.NoError(t, err)
1307 assert.NotNil(t, fsOltDoubleMplsLabel)
1308
1309 flows2 := map[uint64]*ofp.OfpFlowStats{fsOltDoubleMplsLabel.Id: fsOltDoubleMplsLabel}
1310 assert.NotNil(t, flows2)
1311
1312 deviceRules, err = tfd.fd.DecomposeRules(context.Background(), tfd, flows2, nil)
1313 assert.NoError(t, err)
1314 assert.NotNil(t, deviceRules)
1315 oltFlowAndGroup = deviceRules.Rules["olt"]
1316 assert.NotNil(t, oltFlowAndGroup)
1317 derivedFlow = oltFlowAndGroup.GetFlow(0)
1318 assert.NotNil(t, derivedFlow)
1319
1320 expectedFa = &fu.FlowArgs{
1321 KV: fu.OfpFlowModArgs{"priority": 1000},
1322 MatchFields: []*ofp.OfpOxmOfbField{
1323 fu.InPort(2),
1324 fu.TunnelId(10),
1325 fu.EthType(0x8847),
1326 fu.EthSrc(2222),
1327 },
1328 Actions: []*ofp.OfpAction{
1329 {Type: ofp.OfpActionType_OFPAT_DEC_MPLS_TTL, Action: &ofp.OfpAction_MplsTtl{MplsTtl: &ofp.OfpActionMplsTtl{MplsTtl: 62}}},
1330 fu.PopMpls(0x8847),
1331 fu.PopMpls(0x8847),
1332 fu.Output(1),
1333 },
1334 }
1335 expectedFs, err = fu.MkFlowStat(expectedFa)
1336 assert.NoError(t, err)
1337 assert.NotNil(t, expectedFs)
1338 expectedFs.Id = derivedFlow.Id
1339 assert.Equal(t, expectedFs.String(), derivedFlow.String())
1340
1341 //olt downstream flows (table-id=1)
1342 faOlt := &fu.FlowArgs{
1343 KV: fu.OfpFlowModArgs{"priority": 1000, "table_id": 2, "meter_id": 1},
1344 MatchFields: []*ofp.OfpOxmOfbField{
1345 fu.InPort(10),
1346 fu.VlanVid(2),
1347 },
1348 Actions: []*ofp.OfpAction{
1349 fu.PopVlan(),
1350 },
1351 }
1352 fsOlt, err := fu.MkFlowStat(faOlt)
1353 assert.NoError(t, err)
1354 assert.NotNil(t, fsOlt)
1355 fsOlt.TableId = 1
1356
1357 flows3 := map[uint64]*ofp.OfpFlowStats{fsOlt.Id: fsOlt}
1358 assert.NotNil(t, flows3)
1359 deviceRules, err = tfd.fd.DecomposeRules(context.Background(), tfd, flows3, nil)
1360 assert.NoError(t, err)
1361 assert.NotNil(t, deviceRules)
1362 oltFlowAndGroup = deviceRules.Rules["olt"]
1363 assert.NotNil(t, oltFlowAndGroup)
1364 derivedFlow = oltFlowAndGroup.GetFlow(0)
1365 assert.NotNil(t, derivedFlow)
1366
1367 faOltExpected := &fu.FlowArgs{
1368 KV: fu.OfpFlowModArgs{"priority": 1000, "meter_id": 1},
1369 MatchFields: []*ofp.OfpOxmOfbField{
1370 fu.InPort(2),
1371 fu.TunnelId(10),
1372 fu.VlanVid(2),
1373 },
1374 Actions: []*ofp.OfpAction{
1375 fu.PopVlan(),
1376 fu.Output(1),
1377 },
1378 }
1379 fsOltExpected, err := fu.MkFlowStat(faOltExpected)
1380 assert.NoError(t, err)
1381 assert.NotNil(t, fsOltExpected)
1382 fsOltExpected.Id = derivedFlow.Id
1383 assert.Equal(t, fsOltExpected.String(), derivedFlow.String())
1384
1385 // Onu Downstream
1386 faOnu := &fu.FlowArgs{
1387 KV: fu.OfpFlowModArgs{"priority": 1000, "meter_id": 1},
1388 MatchFields: []*ofp.OfpOxmOfbField{
1389 fu.InPort(10),
1390 fu.Metadata_ofp((1000 << 32) | 1),
1391 fu.VlanVid(4096),
1392 },
1393 Actions: []*ofp.OfpAction{
1394 fu.Output(1),
1395 },
1396 }
1397 fsOnu, err := fu.MkFlowStat(faOnu)
1398 assert.NoError(t, err)
1399 fsOnu.TableId = 2
1400
1401 flows4 := map[uint64]*ofp.OfpFlowStats{fsOnu.Id: fsOnu}
1402 assert.NotNil(t, flows4)
1403 deviceRules, err = tfd.fd.DecomposeRules(context.Background(), tfd, flows4, nil)
1404 assert.NoError(t, err)
1405 assert.NotNil(t, deviceRules)
1406 onuFlowAndGroup := deviceRules.Rules["onu1"]
1407 assert.NotNil(t, onuFlowAndGroup)
1408 derivedFlow = onuFlowAndGroup.GetFlow(0)
1409 assert.NotNil(t, derivedFlow)
1410
1411 faExpected := &fu.FlowArgs{
1412 KV: fu.OfpFlowModArgs{"priority": 1000, "meter_id": 1},
1413 MatchFields: []*ofp.OfpOxmOfbField{
1414 fu.InPort(1),
1415 fu.Metadata_ofp((1000 << 32) | 1),
1416 fu.VlanVid(4096),
1417 },
1418 Actions: []*ofp.OfpAction{
1419 fu.Output(2),
1420 },
1421 }
1422 fsExpected, err := fu.MkFlowStat(faExpected)
1423 assert.NoError(t, err)
1424 assert.NotNil(t, fsExpected)
1425 fsExpected.Id = derivedFlow.Id
1426
1427 assert.Equal(t, fsExpected.String(), derivedFlow.String())
1428}