blob: 4cca904bb41b1d5255cc1f63525438f33558b6ee [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
Akash Sonief452f12024-12-12 18:20:28 +0530170 // Check if the service already exists for same Uniport and TechProfID
171 if voltApp.CheckServiceExists(vs.Port, vs.TechProfileID) {
172 logger.Warnw(ctx, "Service already exists for same port and TP Id", log.Fields{"ServiceName": vs.Name, "Port": vs.Port, "TechProfileID": vs.TechProfileID, "SVlan": vs.SVlan})
173 continue
174 }
175
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530176 logger.Debugw(ctx, "", log.Fields{"ServiceName": vs.Name})
177
vinokuma926cb3e2023-03-29 11:41:06 +0530178 if uniTagInfo.ServiceName == app.DpuMgmtTraffic ||
179 uniTagInfo.ServiceName == app.DpuAncpTraffic ||
180 uniTagInfo.ServiceName == app.FttbSubscriberTraffic {
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530181 vs.UniVlan = vs.CVlan
182 vs.Pbits = append(vs.Pbits, of.PbitMatchAll)
183 } else {
Akash Sonia8246972023-01-03 10:37:08 +0530184 if uniTagInfo.UsPonSTagPriority == -1 {
185 vs.Pbits = append(vs.Pbits, of.PbitMatchAll)
186 // Process the p-bits received in the request
187 } else {
188 if uniTagInfo.UsPonSTagPriority < 8 {
189 vs.Pbits = append(vs.Pbits, of.PbitType(uniTagInfo.UsPonCTagPriority))
190 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530191
Akash Sonia8246972023-01-03 10:37:08 +0530192 if uniTagInfo.UsPonSTagPriority < 8 && uniTagInfo.UsPonSTagPriority != uniTagInfo.DsPonSTagPriority {
193 vs.Pbits = append(vs.Pbits, of.PbitType(uniTagInfo.DsPonCTagPriority))
194 }
Tinoj Josephec742f62022-09-29 19:11:10 +0530195 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530196 }
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530197 //vs.McastService = uniTagInfo.IsIgmpRequired
198 if vs.IgmpEnabled {
199 vs.MvlanProfileName = "mvlan" + strconv.Itoa(uniTagInfo.PonSTag)
200 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530201 /*
Akash Sonia8246972023-01-03 10:37:08 +0530202 var err error
203 if vs.MacAddr, err = net.ParseMAC(srvInfo.HardwareIdentifier); err != nil {
204 vs.MacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
205 }*/
Naveen Sampath04696f72022-06-13 15:19:14 +0530206
207 vs.MacAddr, _ = net.ParseMAC("00:00:00:00:00:00")
208 if len(vs.Pbits) == 0 {
209 vs.Pbits = append(vs.Pbits, of.PbitMatchNone)
210 }
211
212 vnetName := strconv.FormatUint(uint64(vs.SVlan), 10) + "-"
213 vnetName = vnetName + strconv.FormatUint(uint64(vs.CVlan), 10) + "-"
214 vnetName = vnetName + strconv.FormatUint(uint64(vs.UniVlan), 10)
215
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530216 logger.Debugw(ctx, "", log.Fields{"VnetName": vnetName})
217
Naveen Sampath04696f72022-06-13 15:19:14 +0530218 vnetcfg := app.VnetConfig{
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530219 Name: vnetName,
220 SVlan: vs.SVlan,
221 CVlan: vs.CVlan,
222 UniVlan: vs.UniVlan,
223 SVlanTpid: layers.EthernetTypeDot1Q,
224 DhcpRelay: uniTagInfo.IsDhcpRequired,
225 VnetType: uniTagInfo.ServiceName,
226 UsPonCTagPriority: vs.UsPonCTagPriority,
227 UsPonSTagPriority: vs.UsPonSTagPriority,
228 DsPonCTagPriority: vs.UsPonCTagPriority,
229 DsPonSTagPriority: vs.UsPonSTagPriority,
Naveen Sampath04696f72022-06-13 15:19:14 +0530230 //ONTEtherTypeClassification: req.ONTEtherTypeClassification,
231 //VlanControl: app.VlanControl(req.VlanControl), //TODO
232 }
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530233 if uniTagInfo.EnableMacLearning {
234 vnetcfg.MacLearning = app.Learn
235 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530236 if uniTagInfo.UsPonSTagPriority < 8 {
237 vnetcfg.UsDhcpPbit = append(vnetcfg.UsDhcpPbit, of.PbitType(uniTagInfo.UsPonSTagPriority))
238 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530239 if vs.CVlan != of.VlanAny && vs.SVlan != of.VlanAny {
vinokuma926cb3e2023-03-29 11:41:06 +0530240 if uniTagInfo.ServiceName == app.DpuMgmtTraffic ||
241 uniTagInfo.ServiceName == app.DpuAncpTraffic {
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530242 vnetcfg.VlanControl = app.ONUCVlan
vinokuma926cb3e2023-03-29 11:41:06 +0530243 } else if uniTagInfo.ServiceName == app.FttbSubscriberTraffic {
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530244 vnetcfg.VlanControl = app.OLTSVlan
245 } else {
246 vnetcfg.VlanControl = app.ONUCVlanOLTSVlan
247 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530248 } else if vs.CVlan == of.VlanAny && vs.UniVlan == of.VlanAny {
249 vnetcfg.VlanControl = app.OLTSVlan
250 }
Akash Soni6f369452023-09-19 11:18:28 +0530251 if err := voltAppIntr.AddVnet(cntx, vnetcfg, nil); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530252 logger.Errorw(ctx, "AddVnet Failed", log.Fields{"VnetName": vnetName, "Error": err})
253 }
Akash Soni6f369452023-09-19 11:18:28 +0530254 if err := voltAppIntr.AddService(cntx, vs, nil); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530255 logger.Errorw(ctx, "AddService Failed", log.Fields{"Service": vs.Name, "Error": err.Error()})
Naveen Sampath04696f72022-06-13 15:19:14 +0530256 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530257 }
258}
259
260// DelSubscriberInfo to delete service
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530261func (sh *SubscriberHandle) DelSubscriberInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
Naveen Sampath04696f72022-06-13 15:19:14 +0530262 vars := mux.Vars(r)
263 id := vars["id"]
264
Sridhar Ravindrab8374ae2023-04-14 15:49:25 +0530265 d := new(bytes.Buffer)
266 if _, err := d.ReadFrom(r.Body); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530267 logger.Errorw(ctx, "Error reading buffer", log.Fields{"req id": id, "Reason": err.Error()})
268 w.WriteHeader(http.StatusConflict)
Sridhar Ravindrab8374ae2023-04-14 15:49:25 +0530269 return
270 }
271
272 // Unmarshal the request into service configuration structure
273 req := &SubscriberDeviceInfo{}
274 if err := json.Unmarshal(d.Bytes(), req); err != nil {
275 logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
276 http.Error(w, err.Error(), http.StatusConflict)
277 return
278 }
279
280 for _, uniTagInfo := range req.UniTagList {
281 svcname := req.ID + "_"
282 svcname = svcname + req.NasPortID + "-"
283 svcname = svcname + strconv.Itoa(uniTagInfo.UniTagMatch) + "-"
284 svcname = svcname + strconv.Itoa(uniTagInfo.PonSTag) + "-"
285 svcname = svcname + strconv.Itoa(uniTagInfo.PonCTag) + "-"
286 svcname = svcname + strconv.Itoa(uniTagInfo.TechnologyProfileID)
287
288 if uniTagInfo.ServiceName == app.FttbSubscriberTraffic {
289 id = svcname
290 }
291 }
292
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530293 logger.Infow(ctx, "Received northbound-del-service-req", log.Fields{"ServiceName": id})
Hitesh Chhabra7d249a02023-07-04 21:33:49 +0530294 err := app.GetApplication().DelServiceWithPrefix(cntx, id)
295 if err != nil {
296 logger.Warnw(ctx, "northbound-del-service-req failed, Subscriber not exist", log.Fields{"ServiceName": id})
297 http.Error(w, err.Error(), http.StatusBadRequest)
298 return
299 }
300
301 // HTTP response with 202 accepted for service delete request
302 w.WriteHeader(http.StatusAccepted)
Naveen Sampath04696f72022-06-13 15:19:14 +0530303}
Akash Soni634d9bf2023-07-10 12:11:10 +0530304
305// DelSubscriberInfo to delete service
306func (sh *SubscriberHandle) GetSubscriberAndFlowProvisionStatus(cntx context.Context, w http.ResponseWriter, r *http.Request) {
307 vars := mux.Vars(r)
308 portName := vars["portName"]
309 logger.Debugw(ctx, "Received-northbound-GetSubscriberProvisionStatus-request", log.Fields{"req": portName})
Akash Soni6f369452023-09-19 11:18:28 +0530310 var voltAppIntr app.VoltAppInterface
311 voltApp := app.GetApplication()
312 voltAppIntr = voltApp
313 flowProvisionStatus := voltAppIntr.GetFlowProvisionStatus(portName)
Akash Soni634d9bf2023-07-10 12:11:10 +0530314 flowProvisionStatusRes, err := json.Marshal(flowProvisionStatus)
315 if err != nil {
316 logger.Errorw(ctx, "Error occurred while marshaling flowProvisionStatus response", log.Fields{"Error": err})
317 w.WriteHeader(http.StatusInternalServerError)
318 return
319 }
320 w.Header().Add("Content-Type", "application/json")
321 _, err = w.Write(flowProvisionStatusRes)
322 if err != nil {
323 logger.Errorw(ctx, "error in sending flowProvisionStatus response", log.Fields{"Error": err})
324 w.WriteHeader(http.StatusInternalServerError)
325 }
326}