blob: 4b9ccb38d94c3aa9be2f8a5c239b271452cf289e [file] [log] [blame]
Zdravko Bozakov958d81c2019-12-13 22:09:48 +01001/*
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 sadis
18
19import (
20 "encoding/json"
21 "net/http"
22 "strings"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010023
24 "github.com/gorilla/mux"
25 "github.com/opencord/bbsim/internal/bbsim/devices"
26 "github.com/opencord/bbsim/internal/common"
27 log "github.com/sirupsen/logrus"
28)
29
30var sadisLogger = log.WithFields(log.Fields{
31 "module": "SADIS",
32})
33
Matteo Scandolocedde462021-03-09 17:37:16 -080034type SadisServer struct {
35 Olt *devices.OltDevice
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010036}
37
38// bandwidthProfiles contains some dummy profiles
Matteo Scandolo51d6a312020-03-12 15:54:43 -070039var bandwidthProfiles = []*SadisBWPEntry{
Shrey Baid688b4242020-07-10 20:40:10 +053040 {ID: "User_Bandwidth1", AIR: 100000, CBS: 10000, CIR: 30000, EBS: 1000, EIR: 100000},
41 {ID: "User_Bandwidth2", AIR: 100000, CBS: 5000, CIR: 100000, EBS: 5000, EIR: 100000},
42 {ID: "User_Bandwidth3", AIR: 100000, CBS: 5000, CIR: 1000000, EBS: 5000, EIR: 1000000},
43 {ID: "Default", AIR: 100000, CBS: 30, CIR: 600, EBS: 30, EIR: 400},
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010044}
45
46// SadisConfig is the top-level SADIS configuration struct
47type SadisConfig struct {
48 Sadis SadisEntries `json:"sadis"`
49 BandwidthProfile BandwidthProfileEntries `json:"bandwidthprofile"`
50}
51
52type SadisEntries struct {
53 Integration SadisIntegration `json:"integration"`
54 Entries []interface{} `json:"entries,omitempty"`
55}
56type BandwidthProfileEntries struct {
57 Integration SadisIntegration `json:"integration"`
Matteo Scandolo51d6a312020-03-12 15:54:43 -070058 Entries []*SadisBWPEntry `json:"entries,omitempty"`
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010059}
60
61type SadisIntegration struct {
62 URL string `json:"url,omitempty"`
63 Cache struct {
64 Enabled bool `json:"enabled"`
65 MaxSize int `json:"maxsize"`
66 TTL string `json:"ttl"`
67 } `json:"cache"`
68}
69
70type SadisOltEntry struct {
71 ID string `json:"id"`
72 HardwareIdentifier string `json:"hardwareIdentifier"`
73 IPAddress string `json:"ipAddress"`
74 NasID string `json:"nasId"`
75 UplinkPort int `json:"uplinkPort"`
76}
77
Anand S Kattib409ee02020-02-20 20:10:00 +053078type SadisOnuEntryV2 struct {
79 ID string `json:"id"`
80 NasPortID string `json:"nasPortId"`
81 CircuitID string `json:"circuitId"`
82 RemoteID string `json:"remoteId"`
Matteo Scandolo4a036262020-08-17 15:56:13 -070083 UniTagList []SadisUniTag `json:"uniTagList"` // this can be SadisUniTagAtt, SadisUniTagDt
Anand S Kattib409ee02020-02-20 20:10:00 +053084}
85
Matteo Scandolo4a036262020-08-17 15:56:13 -070086type SadisUniTag struct {
87 UniTagMatch int `json:"uniTagMatch,omitempty"`
Shrey Baid688b4242020-07-10 20:40:10 +053088 PonCTag int `json:"ponCTag,omitempty"`
89 PonSTag int `json:"ponSTag,omitempty"`
90 TechnologyProfileID int `json:"technologyProfileId,omitempty"`
91 UpstreamBandwidthProfile string `json:"upstreamBandwidthProfile,omitempty"`
92 DownstreamBandwidthProfile string `json:"downstreamBandwidthProfile,omitempty"`
93 IsDhcpRequired bool `json:"isDhcpRequired,omitempty"`
94 IsIgmpRequired bool `json:"isIgmpRequired,omitempty"`
Matteo Scandolo4a036262020-08-17 15:56:13 -070095 ConfiguredMacAddress string `json:"configuredMacAddress,omitempty"`
Matteo Scandolo8d281372020-09-03 16:23:37 -070096 UsPonCTagPriority uint8 `json:"usPonCTagPriority,omitempty"`
97 UsPonSTagPriority uint8 `json:"usPonSTagPriority,omitempty"`
98 DsPonCTagPriority uint8 `json:"dsPonCTagPriority,omitempty"`
99 DsPonSTagPriority uint8 `json:"dsPonSTagPriority,omitempty"`
Matteo Scandolo4a036262020-08-17 15:56:13 -0700100 ServiceName string `json:"serviceName,omitempty"`
Matteo Scandolof65e6872020-04-15 15:18:43 -0700101}
102
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100103// SADIS BandwithProfile Entry
104type SadisBWPEntry struct {
105 ID string `json:"id"`
106 AIR int `json:"air"`
107 CBS int `json:"cbs"`
108 CIR int `json:"cir"`
109 EBS int `json:"ebs"`
110 EIR int `json:"eir"`
111}
112
113// GetSadisConfig returns a full SADIS configuration struct ready to be marshalled into JSON
Anand S Kattib409ee02020-02-20 20:10:00 +0530114func GetSadisConfig(olt *devices.OltDevice, version string) *SadisConfig {
115 sadisEntries, _ := GetSadisEntries(olt, version)
116 bwpEntries := getBWPEntries(version)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100117
118 conf := &SadisConfig{}
119 conf.Sadis = *sadisEntries
120 conf.BandwidthProfile = *bwpEntries
121
122 return conf
123}
124
Anand S Kattib409ee02020-02-20 20:10:00 +0530125func GetSadisEntries(olt *devices.OltDevice, version string) (*SadisEntries, error) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100126 solt, _ := GetOltEntry(olt)
127
128 entries := []interface{}{}
129 entries = append(entries, solt)
130
Matteo Scandolo4a036262020-08-17 15:56:13 -0700131 a := strings.Split(common.Config.BBSim.SadisRestAddress, ":")
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100132 port := a[len(a)-1]
133
134 integration := SadisIntegration{}
Anand S Kattib409ee02020-02-20 20:10:00 +0530135 integration.URL = "http://bbsim:" + port + "/" + version + "/subscribers/%s"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100136 integration.Cache.Enabled = false
137 integration.Cache.MaxSize = 50
138 integration.Cache.TTL = "PT0m"
139
140 sadis := &SadisEntries{
141 integration,
142 entries,
143 }
144
145 return sadis, nil
146}
147
148func GetOltEntry(olt *devices.OltDevice) (*SadisOltEntry, error) {
149 ip, _ := common.GetIPAddr("nni") // TODO verify which IP to report
150 solt := &SadisOltEntry{
151 ID: olt.SerialNumber,
Matteo Scandolo4a036262020-08-17 15:56:13 -0700152 HardwareIdentifier: common.Config.Olt.DeviceId,
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100153 IPAddress: ip,
154 NasID: olt.SerialNumber,
Anand S Kattib409ee02020-02-20 20:10:00 +0530155 UplinkPort: 1048576, // TODO currently assumes we only have one NNI port
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100156 }
157 return solt, nil
158}
159
Anand S Kattib409ee02020-02-20 20:10:00 +0530160func GetOnuEntryV2(olt *devices.OltDevice, onu *devices.Onu, uniId string) (*SadisOnuEntryV2, error) {
161 uniSuffix := "-" + uniId
162
163 sonuv2 := &SadisOnuEntryV2{
Matteo Scandolodf080442020-10-09 11:57:38 -0700164 ID: onu.Sn() + uniSuffix,
Anand S Kattib409ee02020-02-20 20:10:00 +0530165 }
Matteo Scandolo51d6a312020-03-12 15:54:43 -0700166
Matteo Scandolo4a036262020-08-17 15:56:13 -0700167 // createUniTagList
168 for _, s := range onu.Services {
Matteo Scandolof65e6872020-04-15 15:18:43 -0700169
Matteo Scandolo4a036262020-08-17 15:56:13 -0700170 service := s.(*devices.Service)
171
172 tag := SadisUniTag{
173 ServiceName: service.Name,
174 IsIgmpRequired: service.NeedsIgmp,
175 IsDhcpRequired: service.NeedsDhcp,
176 TechnologyProfileID: service.TechnologyProfileID,
177 UpstreamBandwidthProfile: "User_Bandwidth1",
178 DownstreamBandwidthProfile: "User_Bandwidth2",
179 PonCTag: service.CTag,
180 PonSTag: service.STag,
Matteo Scandolof65e6872020-04-15 15:18:43 -0700181 }
Matteo Scandolo4a036262020-08-17 15:56:13 -0700182
183 if service.UniTagMatch != 0 {
184 tag.UniTagMatch = service.UniTagMatch
Matteo Scandolof65e6872020-04-15 15:18:43 -0700185 }
Matteo Scandolo4a036262020-08-17 15:56:13 -0700186
187 if service.ConfigureMacAddress {
188 tag.ConfiguredMacAddress = service.HwAddress.String()
189 }
190
191 if service.UsPonCTagPriority != 0 {
192 tag.UsPonCTagPriority = service.UsPonCTagPriority
193 }
194
195 if service.UsPonSTagPriority != 0 {
196 tag.UsPonSTagPriority = service.UsPonSTagPriority
197 }
198
199 if service.DsPonCTagPriority != 0 {
200 tag.DsPonCTagPriority = service.DsPonCTagPriority
201 }
202
203 if service.DsPonSTagPriority != 0 {
204 tag.DsPonSTagPriority = service.DsPonSTagPriority
205 }
206
207 sonuv2.UniTagList = append(sonuv2.UniTagList, tag)
Anand S Kattib409ee02020-02-20 20:10:00 +0530208 }
Matteo Scandolo51d6a312020-03-12 15:54:43 -0700209
Anand S Kattib409ee02020-02-20 20:10:00 +0530210 return sonuv2, nil
211}
212
213func getBWPEntries(version string) *BandwidthProfileEntries {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700214 a := strings.Split(common.Config.BBSim.SadisRestAddress, ":")
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100215 port := a[len(a)-1]
216
217 integration := SadisIntegration{}
Anand S Kattib409ee02020-02-20 20:10:00 +0530218 integration.URL = "http://bbsim:" + port + "/" + version + "/bandwidthprofiles/%s"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100219 integration.Cache.Enabled = true
220 integration.Cache.MaxSize = 40
221 integration.Cache.TTL = "PT1m"
222
223 bwp := &BandwidthProfileEntries{
224 Integration: integration,
225 }
226
227 return bwp
228}
229
Matteo Scandolocedde462021-03-09 17:37:16 -0800230func (s *SadisServer) ServeBaseConfig(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100231 w.Header().Set("Content-Type", "application/json")
232 w.WriteHeader(http.StatusOK)
Anand S Kattib409ee02020-02-20 20:10:00 +0530233 vars := mux.Vars(r)
234
235 if vars["version"] != "v1" && vars["version"] != "v2" {
236 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530237 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530238 return
239 }
240
Matteo Scandolocedde462021-03-09 17:37:16 -0800241 sadisConf := GetSadisConfig(s.Olt, vars["version"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100242
243 sadisJSON, _ := json.Marshal(sadisConf)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100244
Shrey Baid688b4242020-07-10 20:40:10 +0530245 _, _ = w.Write([]byte(sadisJSON))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100246
247}
248
Matteo Scandolocedde462021-03-09 17:37:16 -0800249func (s *SadisServer) ServeStaticConfig(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100250 w.Header().Set("Content-Type", "application/json")
251 w.WriteHeader(http.StatusOK)
Anand S Kattib409ee02020-02-20 20:10:00 +0530252 vars := mux.Vars(r)
Matteo Scandolocedde462021-03-09 17:37:16 -0800253 sadisConf := GetSadisConfig(s.Olt, vars["version"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100254
255 sadisConf.Sadis.Integration.URL = ""
Matteo Scandolocedde462021-03-09 17:37:16 -0800256 for i := range s.Olt.Pons {
257 for _, onu := range s.Olt.Pons[i].Onus {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700258 if vars["version"] == "v2" {
Matteo Scandolocedde462021-03-09 17:37:16 -0800259 sonuV2, _ := GetOnuEntryV2(s.Olt, onu, "1")
Anand S Kattib409ee02020-02-20 20:10:00 +0530260 sadisConf.Sadis.Entries = append(sadisConf.Sadis.Entries, sonuV2)
Anand S Kattib409ee02020-02-20 20:10:00 +0530261 }
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100262 }
263 }
264
265 sadisConf.BandwidthProfile.Integration.URL = ""
266 sadisConf.BandwidthProfile.Entries = bandwidthProfiles
267
268 sadisJSON, _ := json.Marshal(sadisConf)
269 sadisLogger.Tracef("SADIS JSON: %s", sadisJSON)
270
Shrey Baid688b4242020-07-10 20:40:10 +0530271 _, _ = w.Write([]byte(sadisJSON))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100272
273}
274
Matteo Scandolocedde462021-03-09 17:37:16 -0800275func (s *SadisServer) ServeEntry(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100276 w.Header().Set("Content-Type", "application/json")
277 vars := mux.Vars(r)
278
279 // check if the requested ID is for the OLT
Matteo Scandolocedde462021-03-09 17:37:16 -0800280 if s.Olt.SerialNumber == vars["ID"] {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100281 sadisLogger.WithFields(log.Fields{
Matteo Scandolocedde462021-03-09 17:37:16 -0800282 "OltSn": s.Olt.SerialNumber,
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100283 }).Debug("Received SADIS OLT request")
284
Matteo Scandolocedde462021-03-09 17:37:16 -0800285 sadisConf, _ := GetOltEntry(s.Olt)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100286
287 w.WriteHeader(http.StatusOK)
Shrey Baid688b4242020-07-10 20:40:10 +0530288 _ = json.NewEncoder(w).Encode(sadisConf)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100289 return
290 }
291
292 i := strings.Split(vars["ID"], "-") // split ID to get serial number and uni port
293 if len(i) != 2 {
294 w.WriteHeader(http.StatusUnprocessableEntity)
Shrey Baid688b4242020-07-10 20:40:10 +0530295 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530296 sadisLogger.Warnf("Received invalid SADIS SubscriberId: %s", vars["ID"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100297 return
298 }
299 sn, uni := i[0], i[len(i)-1]
300
Matteo Scandolocedde462021-03-09 17:37:16 -0800301 onu, err := s.Olt.FindOnuBySn(sn)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100302 if err != nil {
303 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530304 _, _ = w.Write([]byte("{}"))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100305 sadisLogger.WithFields(log.Fields{
306 "OnuSn": sn,
307 "OnuId": "NA",
Anand S Kattib409ee02020-02-20 20:10:00 +0530308 }).Warnf("Requested Subscriber entry not found for OnuSn: %s", vars["ID"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100309 return
310 }
311
312 sadisLogger.WithFields(log.Fields{
313 "OnuId": onu.ID,
314 "OnuSn": sn,
315 "OnuPortNo": uni,
316 }).Debug("Received SADIS request")
317
Anand S Kattib409ee02020-02-20 20:10:00 +0530318 if vars["version"] == "v1" {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700319 // TODO format error
320 w.WriteHeader(http.StatusBadRequest)
321 _ = json.NewEncoder(w).Encode("Sadis v1 is not supported anymore, please go back to an earlier BBSim version")
Anand S Kattib409ee02020-02-20 20:10:00 +0530322 } else if vars["version"] == "v2" {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700323 w.WriteHeader(http.StatusOK)
Matteo Scandolocedde462021-03-09 17:37:16 -0800324 sadisConf, _ := GetOnuEntryV2(s.Olt, onu, uni)
Shrey Baid688b4242020-07-10 20:40:10 +0530325 _ = json.NewEncoder(w).Encode(sadisConf)
Anand S Kattib409ee02020-02-20 20:10:00 +0530326 }
327
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100328}
329
Matteo Scandolocedde462021-03-09 17:37:16 -0800330func (s *SadisServer) ServeBWPEntry(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100331 w.Header().Set("Content-Type", "application/json")
332 vars := mux.Vars(r)
333 id := vars["ID"]
Anand S Kattib409ee02020-02-20 20:10:00 +0530334
335 if vars["version"] != "v1" && vars["version"] != "v2" {
336 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530337 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530338 return
339 }
340
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100341 sadisLogger.Debugf("Received request for SADIS bandwidth profile %s", id)
342
Matteo Scandolo51d6a312020-03-12 15:54:43 -0700343 for _, bwpEntry := range bandwidthProfiles {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100344 if bwpEntry.ID == id {
345 w.WriteHeader(http.StatusOK)
Shrey Baid688b4242020-07-10 20:40:10 +0530346 _ = json.NewEncoder(w).Encode(bwpEntry)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100347 return
348 }
349 }
350
351 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530352 _, _ = w.Write([]byte("{}"))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100353}