blob: bf094506fc55c0087cb4e5555627849f52eb8db5 [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 "voltha-go-controller/internal/pkg/application"
27 app "voltha-go-controller/internal/pkg/application"
Hitesh Chhabra7d249a02023-07-04 21:33:49 +053028 errorCodes "voltha-go-controller/internal/pkg/errorcodes"
Naveen Sampath04696f72022-06-13 15:19:14 +053029 "voltha-go-controller/internal/pkg/of"
Tinoj Joseph1d108322022-07-13 10:07:39 +053030 "voltha-go-controller/log"
Akash Sonia8246972023-01-03 10:37:08 +053031
32 "github.com/google/gopacket/layers"
33 "github.com/gorilla/mux"
Naveen Sampath04696f72022-06-13 15:19:14 +053034)
35
vinokuma926cb3e2023-03-29 11:41:06 +053036// SubscriberDeviceInfo - Subcriber Device Info
Naveen Sampath04696f72022-06-13 15:19:14 +053037type SubscriberDeviceInfo struct {
38 ID string `json:"id"`
39 NasPortID string `json:"nasPortId"`
Akash Soni53da2852023-03-15 00:31:31 +053040 UplinkPort string `json:"uplinkPort"`
Naveen Sampath04696f72022-06-13 15:19:14 +053041 HardwareIdentifier string `json:"hardwareIdentifier"`
Akash Soni87a19072023-02-28 00:46:59 +053042 IPAddress string `json:"ipAddress"`
Naveen Sampath04696f72022-06-13 15:19:14 +053043 NasID string `json:"nasId"`
44 CircuitID string `json:"circuitId"`
45 RemoteID string `json:"remoteId"`
46 UniTagList []UniTagInformation `json:"uniTagList"`
vinokuma926cb3e2023-03-29 11:41:06 +053047 NniDhcpTrapVid int `json:"nniDhcpTrapVid"`
48 Slot int `json:"slot"`
Naveen Sampath04696f72022-06-13 15:19:14 +053049}
50
vinokuma926cb3e2023-03-29 11:41:06 +053051// UniTagInformation - Service information
Naveen Sampath04696f72022-06-13 15:19:14 +053052type UniTagInformation struct {
vinokuma926cb3e2023-03-29 11:41:06 +053053 UpstreamBandwidthProfile string `json:"upstreamBandwidthProfile"`
54 DownstreamBandwidthProfile string `json:"downstreamBandwidthProfile"`
55 UpstreamOltBandwidthProfile string `json:"upstreamOltBandwidthProfile"`
56 DownstreamOltBandwidthProfile string `json:"downstreamOltBandwidthProfile"`
57 ServiceName string `json:"serviceName"`
58 ConfiguredMacAddress string `json:"configuredMacAddress"`
Naveen Sampath04696f72022-06-13 15:19:14 +053059 UniTagMatch int `json:"uniTagMatch"`
60 PonCTag int `json:"ponCTag"`
61 PonSTag int `json:"ponSTag"`
62 UsPonCTagPriority int `json:"usPonCTagPriority"`
63 UsPonSTagPriority int `json:"usPonSTagPriority"`
64 DsPonCTagPriority int `json:"dsPonCTagPriority"`
65 DsPonSTagPriority int `json:"dsPonSTagPriority"`
66 TechnologyProfileID int `json:"technologyProfileId"`
Naveen Sampath04696f72022-06-13 15:19:14 +053067 EnableMacLearning bool `json:"enableMacLearning"`
Naveen Sampath04696f72022-06-13 15:19:14 +053068 IsDhcpRequired bool `json:"isDhcpRequired"`
69 IsIgmpRequired bool `json:"isIgmpRequired"`
70 IsPppoeRequired bool `json:"isPppoeRequired"`
71}
72
Tinoj Josephec742f62022-09-29 19:11:10 +053073func init() {
Akash Sonia8246972023-01-03 10:37:08 +053074 // Setup this package so that it's log level can be modified at run time
75 var err error
76 logger, err = log.AddPackageWithDefaultParam()
77 if err != nil {
78 panic(err)
79 }
Tinoj Josephec742f62022-09-29 19:11:10 +053080}
81
Naveen Sampath04696f72022-06-13 15:19:14 +053082// SubscriberHandle handle SubscriberInfo Requests
83type SubscriberHandle struct {
84}
85
86// ServeHTTP to serve http request
87func (sh *SubscriberHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
88 logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
89 switch r.Method {
vinokuma926cb3e2023-03-29 11:41:06 +053090 case cPost:
Tinoj Joseph07cc5372022-07-18 22:53:51 +053091 sh.AddSubscriberInfo(context.Background(), w, r)
vinokuma926cb3e2023-03-29 11:41:06 +053092 case cDelete:
Tinoj Joseph07cc5372022-07-18 22:53:51 +053093 sh.DelSubscriberInfo(context.Background(), w, r)
Naveen Sampath04696f72022-06-13 15:19:14 +053094 default:
95 logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
Hitesh Chhabra7d249a02023-07-04 21:33:49 +053096 err := errorCodes.ErrOperationNotSupported
97 http.Error(w, err.Error(), http.StatusBadRequest)
Naveen Sampath04696f72022-06-13 15:19:14 +053098 }
99}
100
Akash Soni634d9bf2023-07-10 12:11:10 +0530101func (sh *SubscriberHandle) StatusServeHTTP(w http.ResponseWriter, r *http.Request) {
102 logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
103 switch r.Method {
104 case cGet:
105 sh.GetSubscriberAndFlowProvisionStatus(context.Background(), w, r)
106 default:
107 logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
108 }
109}
110
Naveen Sampath04696f72022-06-13 15:19:14 +0530111// AddSubscriberInfo to add service
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530112func (sh *SubscriberHandle) AddSubscriberInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
Naveen Sampath04696f72022-06-13 15:19:14 +0530113 // Get the payload to process the request
114 d := new(bytes.Buffer)
Akash Sonia8246972023-01-03 10:37:08 +0530115 if _, err := d.ReadFrom(r.Body); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530116 logger.Errorw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
117 http.Error(w, err.Error(), http.StatusConflict)
Naveen Sampath04696f72022-06-13 15:19:14 +0530118 return
119 }
120
121 // Unmarshal the request into service configuration structure
122 req := &SubscriberDeviceInfo{}
123 if err := json.Unmarshal(d.Bytes(), req); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530124 logger.Errorw(ctx, "Failed to Unmarshal Adding Subscriber", log.Fields{"req": req, "Reason": err.Error()})
Naveen Sampath04696f72022-06-13 15:19:14 +0530125 http.Error(w, err.Error(), http.StatusConflict)
126 return
127 }
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530128 logger.Infow(ctx, "Received-northbound-add-service-request", log.Fields{"req": req})
Naveen Sampath04696f72022-06-13 15:19:14 +0530129
130 //vsCfgList := getVoltServiceFromSrvInfo(req)
131
Akash Soni53da2852023-03-15 00:31:31 +0530132 addAllService(cntx, req)
Naveen Sampath04696f72022-06-13 15:19:14 +0530133}
134
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530135func addAllService(cntx context.Context, srvInfo *SubscriberDeviceInfo) {
Naveen Sampath04696f72022-06-13 15:19:14 +0530136 //vsCfgList := getVoltServiceFromSrvInfo(srvInfo)
Tinoj Joseph50d722c2022-12-06 22:53:22 +0530137 va := app.GetApplication()
138 if len(srvInfo.UniTagList) == 0 {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530139 logger.Infow(ctx, "Received OLT configuration", log.Fields{"req": srvInfo})
Akash Sonia8246972023-01-03 10:37:08 +0530140 err := va.AddDeviceConfig(cntx, srvInfo.ID, srvInfo.HardwareIdentifier, srvInfo.NasID, srvInfo.IPAddress, srvInfo.UplinkPort, srvInfo.NniDhcpTrapVid)
141 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 {
147 var vs application.VoltServiceCfg
148
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 }
245
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530246 if err := app.GetApplication().AddVnet(cntx, vnetcfg, nil); err != nil {
Naveen Sampath04696f72022-06-13 15:19:14 +0530247 logger.Errorw(ctx, "AddVnet Failed", log.Fields{"VnetName": vnetName, "Error": err})
248 }
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530249 if err := app.GetApplication().AddService(cntx, vs, nil); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530250 logger.Errorw(ctx, "AddService Failed", log.Fields{"Service": vs.Name, "Error": err.Error()})
Naveen Sampath04696f72022-06-13 15:19:14 +0530251 }
Naveen Sampath04696f72022-06-13 15:19:14 +0530252 }
253}
254
255// DelSubscriberInfo to delete service
Tinoj Joseph07cc5372022-07-18 22:53:51 +0530256func (sh *SubscriberHandle) DelSubscriberInfo(cntx context.Context, w http.ResponseWriter, r *http.Request) {
Naveen Sampath04696f72022-06-13 15:19:14 +0530257 vars := mux.Vars(r)
258 id := vars["id"]
259
Sridhar Ravindrab8374ae2023-04-14 15:49:25 +0530260 d := new(bytes.Buffer)
261 if _, err := d.ReadFrom(r.Body); err != nil {
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530262 logger.Errorw(ctx, "Error reading buffer", log.Fields{"req id": id, "Reason": err.Error()})
263 w.WriteHeader(http.StatusConflict)
Sridhar Ravindrab8374ae2023-04-14 15:49:25 +0530264 return
265 }
266
267 // Unmarshal the request into service configuration structure
268 req := &SubscriberDeviceInfo{}
269 if err := json.Unmarshal(d.Bytes(), req); err != nil {
270 logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
271 http.Error(w, err.Error(), http.StatusConflict)
272 return
273 }
274
275 for _, uniTagInfo := range req.UniTagList {
276 svcname := req.ID + "_"
277 svcname = svcname + req.NasPortID + "-"
278 svcname = svcname + strconv.Itoa(uniTagInfo.UniTagMatch) + "-"
279 svcname = svcname + strconv.Itoa(uniTagInfo.PonSTag) + "-"
280 svcname = svcname + strconv.Itoa(uniTagInfo.PonCTag) + "-"
281 svcname = svcname + strconv.Itoa(uniTagInfo.TechnologyProfileID)
282
283 if uniTagInfo.ServiceName == app.FttbSubscriberTraffic {
284 id = svcname
285 }
286 }
287
Hitesh Chhabra8c3f1662023-07-19 13:15:16 +0530288 logger.Infow(ctx, "Received northbound-del-service-req", log.Fields{"ServiceName": id})
Hitesh Chhabra7d249a02023-07-04 21:33:49 +0530289 err := app.GetApplication().DelServiceWithPrefix(cntx, id)
290 if err != nil {
291 logger.Warnw(ctx, "northbound-del-service-req failed, Subscriber not exist", log.Fields{"ServiceName": id})
292 http.Error(w, err.Error(), http.StatusBadRequest)
293 return
294 }
295
296 // HTTP response with 202 accepted for service delete request
297 w.WriteHeader(http.StatusAccepted)
Naveen Sampath04696f72022-06-13 15:19:14 +0530298}
Akash Soni634d9bf2023-07-10 12:11:10 +0530299
300// DelSubscriberInfo to delete service
301func (sh *SubscriberHandle) GetSubscriberAndFlowProvisionStatus(cntx context.Context, w http.ResponseWriter, r *http.Request) {
302 vars := mux.Vars(r)
303 portName := vars["portName"]
304 logger.Debugw(ctx, "Received-northbound-GetSubscriberProvisionStatus-request", log.Fields{"req": portName})
305 flowProvisionStatus := app.GetApplication().GetFlowProvisionStatus(cntx, portName)
306 flowProvisionStatusRes, err := json.Marshal(flowProvisionStatus)
307 if err != nil {
308 logger.Errorw(ctx, "Error occurred while marshaling flowProvisionStatus response", log.Fields{"Error": err})
309 w.WriteHeader(http.StatusInternalServerError)
310 return
311 }
312 w.Header().Add("Content-Type", "application/json")
313 _, err = w.Write(flowProvisionStatusRes)
314 if err != nil {
315 logger.Errorw(ctx, "error in sending flowProvisionStatus response", log.Fields{"Error": err})
316 w.WriteHeader(http.StatusInternalServerError)
317 }
318}