blob: df209722453092e6714430a54865a9b7f8610bbb [file] [log] [blame]
Naveen Sampath04696f72022-06-13 15:19:14 +05301/*
2* Copyright 2022-present Open Networking Foundation
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
Akash Sonia8246972023-01-03 10:37:08 +053014 */
Naveen Sampath04696f72022-06-13 15:19:14 +053015
16package nbi
17
18import (
19 "bytes"
Tinoj Joseph07cc5372022-07-18 22:53:51 +053020 "context"
Naveen Sampath04696f72022-06-13 15:19:14 +053021 "encoding/json"
22 "net"
23 "net/http"
24 "strconv"
25
Naveen Sampath04696f72022-06-13 15:19:14 +053026 app "voltha-go-controller/internal/pkg/application"
Hitesh Chhabra7d249a02023-07-04 21:33:49 +053027 errorCodes "voltha-go-controller/internal/pkg/errorcodes"
Naveen Sampath04696f72022-06-13 15:19:14 +053028 "voltha-go-controller/internal/pkg/of"
Tinoj Joseph1d108322022-07-13 10:07:39 +053029 "voltha-go-controller/log"
Akash Sonia8246972023-01-03 10:37:08 +053030
31 "github.com/google/gopacket/layers"
32 "github.com/gorilla/mux"
Naveen Sampath04696f72022-06-13 15:19:14 +053033)
34
vinokuma926cb3e2023-03-29 11:41:06 +053035// SubscriberDeviceInfo - Subcriber Device Info
Naveen Sampath04696f72022-06-13 15:19:14 +053036type SubscriberDeviceInfo struct {
37 ID string `json:"id"`
38 NasPortID string `json:"nasPortId"`
Akash Soni53da2852023-03-15 00:31:31 +053039 UplinkPort string `json:"uplinkPort"`
Naveen Sampath04696f72022-06-13 15:19:14 +053040 HardwareIdentifier string `json:"hardwareIdentifier"`
Akash Soni87a19072023-02-28 00:46:59 +053041 IPAddress string `json:"ipAddress"`
Naveen Sampath04696f72022-06-13 15:19:14 +053042 NasID string `json:"nasId"`
43 CircuitID string `json:"circuitId"`
44 RemoteID string `json:"remoteId"`
45 UniTagList []UniTagInformation `json:"uniTagList"`
vinokuma926cb3e2023-03-29 11:41:06 +053046 NniDhcpTrapVid int `json:"nniDhcpTrapVid"`
47 Slot int `json:"slot"`
Naveen Sampath04696f72022-06-13 15:19:14 +053048}
49
vinokuma926cb3e2023-03-29 11:41:06 +053050// UniTagInformation - Service information
Naveen Sampath04696f72022-06-13 15:19:14 +053051type UniTagInformation struct {
vinokuma926cb3e2023-03-29 11:41:06 +053052 UpstreamBandwidthProfile string `json:"upstreamBandwidthProfile"`
53 DownstreamBandwidthProfile string `json:"downstreamBandwidthProfile"`
54 UpstreamOltBandwidthProfile string `json:"upstreamOltBandwidthProfile"`
55 DownstreamOltBandwidthProfile string `json:"downstreamOltBandwidthProfile"`
56 ServiceName string `json:"serviceName"`
57 ConfiguredMacAddress string `json:"configuredMacAddress"`
Naveen Sampath04696f72022-06-13 15:19:14 +053058 UniTagMatch int `json:"uniTagMatch"`
59 PonCTag int `json:"ponCTag"`
60 PonSTag int `json:"ponSTag"`
61 UsPonCTagPriority int `json:"usPonCTagPriority"`
62 UsPonSTagPriority int `json:"usPonSTagPriority"`
63 DsPonCTagPriority int `json:"dsPonCTagPriority"`
64 DsPonSTagPriority int `json:"dsPonSTagPriority"`
65 TechnologyProfileID int `json:"technologyProfileId"`
Naveen Sampath04696f72022-06-13 15:19:14 +053066 EnableMacLearning bool `json:"enableMacLearning"`
Naveen Sampath04696f72022-06-13 15:19:14 +053067 IsDhcpRequired bool `json:"isDhcpRequired"`
68 IsIgmpRequired bool `json:"isIgmpRequired"`
69 IsPppoeRequired bool `json:"isPppoeRequired"`
70}
71
Tinoj Josephec742f62022-09-29 19:11:10 +053072func init() {
Akash Sonia8246972023-01-03 10:37:08 +053073 // Setup this package so that it's log level can be modified at run time
74 var err error
75 logger, err = log.AddPackageWithDefaultParam()
76 if err != nil {
77 panic(err)
78 }
Tinoj Josephec742f62022-09-29 19:11:10 +053079}
80
Naveen Sampath04696f72022-06-13 15:19:14 +053081// SubscriberHandle handle SubscriberInfo Requests
82type SubscriberHandle struct {
83}
84
85// ServeHTTP to serve http request
86func (sh *SubscriberHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
87 logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
88 switch r.Method {
vinokuma926cb3e2023-03-29 11:41:06 +053089 case cPost:
Tinoj Joseph07cc5372022-07-18 22:53:51 +053090 sh.AddSubscriberInfo(context.Background(), w, r)
vinokuma926cb3e2023-03-29 11:41:06 +053091 case cDelete:
Tinoj Joseph07cc5372022-07-18 22:53:51 +053092 sh.DelSubscriberInfo(context.Background(), w, r)
Naveen Sampath04696f72022-06-13 15:19:14 +053093 default:
94 logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
Hitesh Chhabra7d249a02023-07-04 21:33:49 +053095 err := errorCodes.ErrOperationNotSupported
96 http.Error(w, err.Error(), http.StatusBadRequest)
Naveen Sampath04696f72022-06-13 15:19:14 +053097 }
98}
99
Akash Soni634d9bf2023-07-10 12:11:10 +0530100func (sh *SubscriberHandle) StatusServeHTTP(w http.ResponseWriter, r *http.Request) {
101 logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
102 switch r.Method {
103 case cGet:
104 sh.GetSubscriberAndFlowProvisionStatus(context.Background(), w, r)
105 default:
106 logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
107 }
108}
109
Naveen Sampath04696f72022-06-13 15:19:14 +0530110// AddSubscriberInfo to add service
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530111func (sh *SubscriberHandle) AddSubscriberInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
Naveen Sampath04696f72022-06-13 15:19:14 +0530112 // Get the payload to process the request
113 d := new(bytes.Buffer)
Akash Sonia8246972023-01-03 10:37:08 +0530114 if _, err := d.ReadFrom(r.Body); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530115 logger.Errorw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
116 http.Error(w, err.Error(), http.StatusConflict)
Naveen Sampath04696f72022-06-13 15:19:14 +0530117 return
118 }
119
120 // Unmarshal the request into service configuration structure
121 req := &SubscriberDeviceInfo{}
122 if err := json.Unmarshal(d.Bytes(), req); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530123 logger.Errorw(ctx, "Failed to Unmarshal Adding Subscriber", log.Fields{"req": req, "Reason": err.Error()})
Naveen Sampath04696f72022-06-13 15:19:14 +0530124 http.Error(w, err.Error(), http.StatusConflict)
125 return
126 }
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530127 logger.Infow(ctx, "Received-northbound-add-service-request", log.Fields{"req": req})
Naveen Sampath04696f72022-06-13 15:19:14 +0530128
129 //vsCfgList := getVoltServiceFromSrvInfo(req)
130
Akash Soni53da2852023-03-15 00:31:31 +0530131 addAllService(cntx, req)
Naveen Sampath04696f72022-06-13 15:19:14 +0530132}
133
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530134func addAllService(cntx context.Context, srvInfo *SubscriberDeviceInfo) {
Akash Soni6f369452023-09-19 11:18:28 +0530135 var voltAppIntr app.VoltAppInterface
136 voltApp := app.GetApplication()
137 voltAppIntr = voltApp
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530138 if len(srvInfo.UniTagList) == 0 {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530139 logger.Infow(ctx, "Received OLT configuration", log.Fields{"req": srvInfo})
Akash Soni6f369452023-09-19 11:18:28 +0530140 err := voltAppIntr.AddDeviceConfig(cntx, srvInfo.ID, srvInfo.HardwareIdentifier, srvInfo.NasID, srvInfo.IPAddress, srvInfo.UplinkPort, srvInfo.NniDhcpTrapVid)
Akash Sonia8246972023-01-03 10:37:08 +0530141 if err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530142 logger.Warnw(ctx, "Device config addition failed :", log.Fields{"req": srvInfo, "Reason": err.Error()})
Akash Sonia8246972023-01-03 10:37:08 +0530143 }
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530144 return
145 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530146 for _, uniTagInfo := range srvInfo.UniTagList {
Akash Soni6f369452023-09-19 11:18:28 +0530147 var vs app.VoltServiceCfg
Naveen Sampath04696f72022-06-13 15:19:14 +0530148
149 svcname := srvInfo.ID + "_"
150 svcname = svcname + srvInfo.NasPortID + "-"
151 svcname = svcname + strconv.Itoa(uniTagInfo.UniTagMatch) + "-"
152 svcname = svcname + strconv.Itoa(uniTagInfo.PonSTag) + "-"
153 svcname = svcname + strconv.Itoa(uniTagInfo.PonCTag) + "-"
154 vs.Name = svcname + strconv.Itoa(uniTagInfo.TechnologyProfileID)
155
156 vs.Port = srvInfo.NasPortID
157 vs.SVlan = of.VlanType(uniTagInfo.PonSTag)
158 vs.CVlan = of.VlanType(uniTagInfo.PonCTag)
159 vs.UniVlan = of.VlanType(uniTagInfo.UniTagMatch)
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530160 vs.UsPonCTagPriority = of.PbitType(uniTagInfo.UsPonCTagPriority)
161 vs.UsPonSTagPriority = of.PbitType(uniTagInfo.UsPonSTagPriority)
162 vs.DsPonCTagPriority = of.PbitType(uniTagInfo.UsPonCTagPriority)
163 vs.DsPonSTagPriority = of.PbitType(uniTagInfo.UsPonSTagPriority)
Naveen Sampath04696f72022-06-13 15:19:14 +0530164 vs.TechProfileID = uint16(uniTagInfo.TechnologyProfileID)
165 vs.UsMeterProfile = uniTagInfo.UpstreamBandwidthProfile
166 vs.DsMeterProfile = uniTagInfo.DownstreamBandwidthProfile
167 vs.IgmpEnabled = uniTagInfo.IsIgmpRequired
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530168 vs.ServiceType = uniTagInfo.ServiceName
169
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530170 logger.Debugw(ctx, "", log.Fields{"ServiceName": vs.Name})
171
vinokuma926cb3e2023-03-29 11:41:06 +0530172 if uniTagInfo.ServiceName == app.DpuMgmtTraffic ||
173 uniTagInfo.ServiceName == app.DpuAncpTraffic ||
174 uniTagInfo.ServiceName == app.FttbSubscriberTraffic {
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530175 vs.UniVlan = vs.CVlan
176 vs.Pbits = append(vs.Pbits, of.PbitMatchAll)
177 } else {
Akash Sonia8246972023-01-03 10:37:08 +0530178 if uniTagInfo.UsPonSTagPriority == -1 {
179 vs.Pbits = append(vs.Pbits, of.PbitMatchAll)
180 // Process the p-bits received in the request
181 } else {
182 if uniTagInfo.UsPonSTagPriority < 8 {
183 vs.Pbits = append(vs.Pbits, of.PbitType(uniTagInfo.UsPonCTagPriority))
184 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530185
Akash Sonia8246972023-01-03 10:37:08 +0530186 if uniTagInfo.UsPonSTagPriority < 8 && uniTagInfo.UsPonSTagPriority != uniTagInfo.DsPonSTagPriority {
187 vs.Pbits = append(vs.Pbits, of.PbitType(uniTagInfo.DsPonCTagPriority))
188 }
Tinoj Josephec742f62022-09-29 19:11:10 +0530189 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530190 }
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530191 //vs.McastService = uniTagInfo.IsIgmpRequired
192 if vs.IgmpEnabled {
193 vs.MvlanProfileName = "mvlan" + strconv.Itoa(uniTagInfo.PonSTag)
194 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530195 /*
Akash Sonia8246972023-01-03 10:37:08 +0530196 var err error
197 if vs.MacAddr, err = net.ParseMAC(srvInfo.HardwareIdentifier); err != nil {
198 vs.MacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
199 }*/
Naveen Sampath04696f72022-06-13 15:19:14 +0530200
201 vs.MacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
202 if len(vs.Pbits) == 0 {
203 vs.Pbits = append(vs.Pbits, of.PbitMatchNone)
204 }
205
206 vnetName := strconv.FormatUint(uint64(vs.SVlan), 10) + "-"
207 vnetName = vnetName + strconv.FormatUint(uint64(vs.CVlan), 10) + "-"
208 vnetName = vnetName + strconv.FormatUint(uint64(vs.UniVlan), 10)
209
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530210 logger.Debugw(ctx, "", log.Fields{"VnetName": vnetName})
211
Naveen Sampath04696f72022-06-13 15:19:14 +0530212 vnetcfg := app.VnetConfig{
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530213 Name: vnetName,
214 SVlan: vs.SVlan,
215 CVlan: vs.CVlan,
216 UniVlan: vs.UniVlan,
217 SVlanTpid: layers.EthernetTypeDot1Q,
218 DhcpRelay: uniTagInfo.IsDhcpRequired,
219 VnetType: uniTagInfo.ServiceName,
220 UsPonCTagPriority: vs.UsPonCTagPriority,
221 UsPonSTagPriority: vs.UsPonSTagPriority,
222 DsPonCTagPriority: vs.UsPonCTagPriority,
223 DsPonSTagPriority: vs.UsPonSTagPriority,
Naveen Sampath04696f72022-06-13 15:19:14 +0530224 //ONTEtherTypeClassification: req.ONTEtherTypeClassification,
225 //VlanControl: app.VlanControl(req.VlanControl), //TODO
226 }
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530227 if uniTagInfo.EnableMacLearning {
228 vnetcfg.MacLearning = app.Learn
229 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530230 if uniTagInfo.UsPonSTagPriority < 8 {
231 vnetcfg.UsDhcpPbit = append(vnetcfg.UsDhcpPbit, of.PbitType(uniTagInfo.UsPonSTagPriority))
232 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530233 if vs.CVlan != of.VlanAny && vs.SVlan != of.VlanAny {
vinokuma926cb3e2023-03-29 11:41:06 +0530234 if uniTagInfo.ServiceName == app.DpuMgmtTraffic ||
235 uniTagInfo.ServiceName == app.DpuAncpTraffic {
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530236 vnetcfg.VlanControl = app.ONUCVlan
vinokuma926cb3e2023-03-29 11:41:06 +0530237 } else if uniTagInfo.ServiceName == app.FttbSubscriberTraffic {
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530238 vnetcfg.VlanControl = app.OLTSVlan
239 } else {
240 vnetcfg.VlanControl = app.ONUCVlanOLTSVlan
241 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530242 } else if vs.CVlan == of.VlanAny && vs.UniVlan == of.VlanAny {
243 vnetcfg.VlanControl = app.OLTSVlan
244 }
Akash Soni6f369452023-09-19 11:18:28 +0530245 if err := voltAppIntr.AddVnet(cntx, vnetcfg, nil); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530246 logger.Errorw(ctx, "AddVnet Failed", log.Fields{"VnetName": vnetName, "Error": err})
247 }
Akash Soni6f369452023-09-19 11:18:28 +0530248 if err := voltAppIntr.AddService(cntx, vs, nil); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530249 logger.Errorw(ctx, "AddService Failed", log.Fields{"Service": vs.Name, "Error": err.Error()})
Naveen Sampath04696f72022-06-13 15:19:14 +0530250 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530251 }
252}
253
254// DelSubscriberInfo to delete service
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530255func (sh *SubscriberHandle) DelSubscriberInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
Naveen Sampath04696f72022-06-13 15:19:14 +0530256 vars := mux.Vars(r)
257 id := vars["id"]
258
Sridhar Ravindrab8374ae2023-04-14 15:49:25 +0530259 d := new(bytes.Buffer)
260 if _, err := d.ReadFrom(r.Body); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530261 logger.Errorw(ctx, "Error reading buffer", log.Fields{"req id": id, "Reason": err.Error()})
262 w.WriteHeader(http.StatusConflict)
Sridhar Ravindrab8374ae2023-04-14 15:49:25 +0530263 return
264 }
265
266 // Unmarshal the request into service configuration structure
267 req := &SubscriberDeviceInfo{}
268 if err := json.Unmarshal(d.Bytes(), req); err != nil {
269 logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
270 http.Error(w, err.Error(), http.StatusConflict)
271 return
272 }
273
274 for _, uniTagInfo := range req.UniTagList {
275 svcname := req.ID + "_"
276 svcname = svcname + req.NasPortID + "-"
277 svcname = svcname + strconv.Itoa(uniTagInfo.UniTagMatch) + "-"
278 svcname = svcname + strconv.Itoa(uniTagInfo.PonSTag) + "-"
279 svcname = svcname + strconv.Itoa(uniTagInfo.PonCTag) + "-"
280 svcname = svcname + strconv.Itoa(uniTagInfo.TechnologyProfileID)
281
282 if uniTagInfo.ServiceName == app.FttbSubscriberTraffic {
283 id = svcname
284 }
285 }
286
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530287 logger.Infow(ctx, "Received northbound-del-service-req", log.Fields{"ServiceName": id})
Hitesh Chhabra7d249a02023-07-04 21:33:49 +0530288 err := app.GetApplication().DelServiceWithPrefix(cntx, id)
289 if err != nil {
290 logger.Warnw(ctx, "northbound-del-service-req failed, Subscriber not exist", log.Fields{"ServiceName": id})
291 http.Error(w, err.Error(), http.StatusBadRequest)
292 return
293 }
294
295 // HTTP response with 202 accepted for service delete request
296 w.WriteHeader(http.StatusAccepted)
Naveen Sampath04696f72022-06-13 15:19:14 +0530297}
Akash Soni634d9bf2023-07-10 12:11:10 +0530298
299// DelSubscriberInfo to delete service
300func (sh *SubscriberHandle) GetSubscriberAndFlowProvisionStatus(cntx context.Context, w http.ResponseWriter, r *http.Request) {
301 vars := mux.Vars(r)
302 portName := vars["portName"]
303 logger.Debugw(ctx, "Received-northbound-GetSubscriberProvisionStatus-request", log.Fields{"req": portName})
Akash Soni6f369452023-09-19 11:18:28 +0530304 var voltAppIntr app.VoltAppInterface
305 voltApp := app.GetApplication()
306 voltAppIntr = voltApp
307 flowProvisionStatus := voltAppIntr.GetFlowProvisionStatus(portName)
Akash Soni634d9bf2023-07-10 12:11:10 +0530308 flowProvisionStatusRes, err := json.Marshal(flowProvisionStatus)
309 if err != nil {
310 logger.Errorw(ctx, "Error occurred while marshaling flowProvisionStatus response", log.Fields{"Error": err})
311 w.WriteHeader(http.StatusInternalServerError)
312 return
313 }
314 w.Header().Add("Content-Type", "application/json")
315 _, err = w.Write(flowProvisionStatusRes)
316 if err != nil {
317 logger.Errorw(ctx, "error in sending flowProvisionStatus response", log.Fields{"Error": err})
318 w.WriteHeader(http.StatusInternalServerError)
319 }
320}