blob: 333efa8d6447b4adfceefdc93c3249d036684423 [file] [log] [blame]
Kent Hagerman3136fbd2020-05-14 10:30:45 -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 */
16
17package device
18
19import (
20 "context"
Kent Hagerman3136fbd2020-05-14 10:30:45 -040021 "fmt"
Kent Hagermanfa9d6d42020-05-25 11:49:40 -040022
Kent Hagerman3136fbd2020-05-14 10:30:45 -040023 "github.com/opencord/voltha-go/rw_core/route"
khenaidood948f772021-08-11 17:49:24 -040024 "github.com/opencord/voltha-lib-go/v7/pkg/log"
25 ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
26 "github.com/opencord/voltha-protos/v5/go/voltha"
Kent Hagerman3136fbd2020-05-14 10:30:45 -040027)
28
khenaidoo0db4c812020-05-27 15:27:30 -040029// GetRoute returns a route
Kent Hagerman3136fbd2020-05-14 10:30:45 -040030func (agent *LogicalAgent) GetRoute(ctx context.Context, ingressPortNo uint32, egressPortNo uint32) ([]route.Hop, error) {
Rohan Agrawal31f21802020-06-12 05:38:46 +000031 logger.Debugw(ctx, "getting-route", log.Fields{"ingress-port": ingressPortNo, "egress-port": egressPortNo})
Kent Hagerman3136fbd2020-05-14 10:30:45 -040032 routes := make([]route.Hop, 0)
33
34 // Note: A port value of 0 is equivalent to a nil port
35
khenaidoo0db4c812020-05-27 15:27:30 -040036 // Controller-bound flow
Kent Hagerman3136fbd2020-05-14 10:30:45 -040037 if egressPortNo != 0 && ((egressPortNo & 0x7fffffff) == uint32(ofp.OfpPortNo_OFPP_CONTROLLER)) {
Rohan Agrawal31f21802020-06-12 05:38:46 +000038 logger.Debugw(ctx, "controller-flow", log.Fields{"ingressPortNo": ingressPortNo, "egressPortNo": egressPortNo})
Kent Hagerman3136fbd2020-05-14 10:30:45 -040039 if agent.isNNIPort(ingressPortNo) {
40 //This is a trap on the NNI Port
khenaidoo0db4c812020-05-27 15:27:30 -040041 if agent.deviceRoutes.IsRoutesEmpty() {
Kent Hagerman3136fbd2020-05-14 10:30:45 -040042 // If there are no routes set (usually when the logical device has only NNI port(s), then just return an
43 // route with same IngressHop and EgressHop
44 hop := route.Hop{DeviceID: agent.rootDeviceID, Ingress: ingressPortNo, Egress: ingressPortNo}
45 routes = append(routes, hop)
46 routes = append(routes, hop)
47 return routes, nil
48 }
khenaidoo0db4c812020-05-27 15:27:30 -040049
50 // Return a 'half' route to make the flow decomposer logic happy
51 routes, err := agent.deviceRoutes.GetHalfRoute(true, 0, 0)
52 if err != nil {
53 return nil, fmt.Errorf("no upstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
Kent Hagerman3136fbd2020-05-14 10:30:45 -040054 }
khenaidoo0db4c812020-05-27 15:27:30 -040055 return routes, nil
Kent Hagerman3136fbd2020-05-14 10:30:45 -040056 }
khenaidoo0db4c812020-05-27 15:27:30 -040057 // Treat it as if the output port is the first NNI of the OLT
Kent Hagerman3136fbd2020-05-14 10:30:45 -040058 var err error
Kent Hagermanfa9d6d42020-05-25 11:49:40 -040059 if egressPortNo, err = agent.getAnyNNIPort(); err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +000060 logger.Warnw(ctx, "no-nni-port", log.Fields{"error": err})
Kent Hagerman3136fbd2020-05-14 10:30:45 -040061 return nil, err
62 }
63 }
khenaidoo0db4c812020-05-27 15:27:30 -040064
65 //If ingress port is not specified (nil), it may be a wildcarded route if egress port is OFPP_CONTROLLER or a nni
66 // logical port, in which case we need to create a half-route where only the egress hop is filled, the first hop is nil
Kent Hagerman3136fbd2020-05-14 10:30:45 -040067 if ingressPortNo == 0 && agent.isNNIPort(egressPortNo) {
khenaidoo0db4c812020-05-27 15:27:30 -040068 routes, err := agent.deviceRoutes.GetHalfRoute(true, ingressPortNo, egressPortNo)
69 if err != nil {
70 return nil, fmt.Errorf("no upstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
Kent Hagerman3136fbd2020-05-14 10:30:45 -040071 }
khenaidoo0db4c812020-05-27 15:27:30 -040072 return routes, nil
Kent Hagerman3136fbd2020-05-14 10:30:45 -040073 }
khenaidoo0db4c812020-05-27 15:27:30 -040074
Kent Hagerman3136fbd2020-05-14 10:30:45 -040075 //If egress port is not specified (nil), we can also can return a "half" route
76 if egressPortNo == 0 {
khenaidoo0db4c812020-05-27 15:27:30 -040077 routes, err := agent.deviceRoutes.GetHalfRoute(false, ingressPortNo, egressPortNo)
78 if err != nil {
79 return nil, fmt.Errorf("no downstream route from:%d to:%d :%w", ingressPortNo, egressPortNo, route.ErrNoRoute)
Kent Hagerman3136fbd2020-05-14 10:30:45 -040080 }
khenaidoo0db4c812020-05-27 15:27:30 -040081 return routes, nil
Kent Hagerman3136fbd2020-05-14 10:30:45 -040082 }
Kent Hagerman3136fbd2020-05-14 10:30:45 -040083
khenaidoo0db4c812020-05-27 15:27:30 -040084 // Return the pre-calculated route
85 return agent.deviceRoutes.GetRoute(ctx, ingressPortNo, egressPortNo)
Kent Hagerman3136fbd2020-05-14 10:30:45 -040086}
87
88// GetDeviceRoutes returns device graph
89func (agent *LogicalAgent) GetDeviceRoutes() *route.DeviceRoutes {
90 return agent.deviceRoutes
91}
92
Kent Hagerman3136fbd2020-05-14 10:30:45 -040093//rebuildRoutes rebuilds the device routes
94func (agent *LogicalAgent) buildRoutes(ctx context.Context) error {
Rohan Agrawal31f21802020-06-12 05:38:46 +000095 logger.Debugf(ctx, "building-routes", log.Fields{"logical-device-id": agent.logicalDeviceID})
Kent Hagerman3136fbd2020-05-14 10:30:45 -040096 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
97 return err
98 }
99 defer agent.requestQueue.RequestComplete()
100
Rohan Agrawal31f21802020-06-12 05:38:46 +0000101 if err := agent.deviceRoutes.ComputeRoutes(ctx, agent.listLogicalDevicePorts(ctx)); err != nil {
Kent Hagerman3136fbd2020-05-14 10:30:45 -0400102 return err
103 }
Rohan Agrawal31f21802020-06-12 05:38:46 +0000104 if err := agent.deviceRoutes.Print(ctx); err != nil {
Kent Hagerman3136fbd2020-05-14 10:30:45 -0400105 return err
106 }
107 return nil
108}
109
khenaidood948f772021-08-11 17:49:24 -0400110func (agent *LogicalAgent) removeRoutes(ctx context.Context) error {
111 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
112 return err
113 }
114 defer agent.requestQueue.RequestComplete()
115
116 agent.deviceRoutes.RemoveRoutes()
117
118 return nil
119}
120
Kent Hagerman3136fbd2020-05-14 10:30:45 -0400121//updateRoutes updates the device routes
Kent Hagerman2a07b862020-06-19 15:23:07 -0400122func (agent *LogicalAgent) updateRoutes(ctx context.Context, deviceID string, devicePorts map[uint32]*voltha.Port, lp *voltha.LogicalPort, lps map[uint32]*voltha.LogicalPort) error {
123 logger.Debugw(ctx, "updateRoutes", log.Fields{"logical-device-id": agent.logicalDeviceID, "device-id": deviceID, "port:": lp})
khenaidoo0db4c812020-05-27 15:27:30 -0400124
Kent Hagerman2a07b862020-06-19 15:23:07 -0400125 if err := agent.deviceRoutes.AddPort(ctx, lp, deviceID, devicePorts, lps); err != nil {
Kent Hagerman3136fbd2020-05-14 10:30:45 -0400126 return err
127 }
Rohan Agrawal31f21802020-06-12 05:38:46 +0000128 if err := agent.deviceRoutes.Print(ctx); err != nil {
khenaidoo0db4c812020-05-27 15:27:30 -0400129 return err
Kent Hagerman3136fbd2020-05-14 10:30:45 -0400130 }
khenaidoo0db4c812020-05-27 15:27:30 -0400131 return nil
132}
133
134//updateAllRoutes updates the device routes using all the logical ports on that device
Kent Hagerman2a07b862020-06-19 15:23:07 -0400135func (agent *LogicalAgent) updateAllRoutes(ctx context.Context, deviceID string, devicePorts map[uint32]*voltha.Port) error {
136 logger.Debugw(ctx, "updateAllRoutes", log.Fields{"logical-device-id": agent.logicalDeviceID, "device-id": deviceID, "ports-count": len(devicePorts)})
khenaidoo0db4c812020-05-27 15:27:30 -0400137
Kent Hagerman2a07b862020-06-19 15:23:07 -0400138 if err := agent.deviceRoutes.AddAllPorts(ctx, deviceID, devicePorts, agent.listLogicalDevicePorts(ctx)); err != nil {
Kent Hagerman3136fbd2020-05-14 10:30:45 -0400139 return err
140 }
Rohan Agrawal31f21802020-06-12 05:38:46 +0000141 if err := agent.deviceRoutes.Print(ctx); err != nil {
Kent Hagerman3136fbd2020-05-14 10:30:45 -0400142 return err
143 }
144 return nil
145}