blob: 394c9ebb123267e62c7679fbce0fde835cd806fc [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 Scandolo94967142021-05-28 11:37:06 -070039var bandwidthProfiles = map[string][]*SadisBWPEntry{
40 common.BP_FORMAT_MEF: {
41 {ID: "User_Bandwidth1", AIR: 100000, CBS: 10000, CIR: 30000, EBS: 1000, EIR: 100000},
42 {ID: "User_Bandwidth2", AIR: 100000, CBS: 5000, CIR: 100000, EBS: 5000, EIR: 100000},
43 {ID: "User_Bandwidth3", AIR: 100000, CBS: 5000, CIR: 1000000, EBS: 5000, EIR: 1000000},
44 {ID: "Default", AIR: 100000, CBS: 30, CIR: 600, EBS: 30, EIR: 400},
45 },
46 common.BP_FORMAT_IETF: {
47 {ID: "User_Bandwidth1", CBS: 10000, CIR: 30000, GIR: 100000, PIR: 20000, PBS: 1000},
48 {ID: "User_Bandwidth2", CBS: 5000, CIR: 100000, GIR: 100000, PIR: 30000, PBS: 5000},
49 {ID: "User_Bandwidth3", CBS: 5000, CIR: 1000000, GIR: 100000, PIR: 40000, PBS: 5000},
50 {ID: "Default", CBS: 30, CIR: 600, GIR: 0, PIR: 32000, PBS: 30},
51 },
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010052}
53
54// SadisConfig is the top-level SADIS configuration struct
55type SadisConfig struct {
56 Sadis SadisEntries `json:"sadis"`
57 BandwidthProfile BandwidthProfileEntries `json:"bandwidthprofile"`
58}
59
60type SadisEntries struct {
61 Integration SadisIntegration `json:"integration"`
62 Entries []interface{} `json:"entries,omitempty"`
63}
64type BandwidthProfileEntries struct {
65 Integration SadisIntegration `json:"integration"`
Matteo Scandolo51d6a312020-03-12 15:54:43 -070066 Entries []*SadisBWPEntry `json:"entries,omitempty"`
Zdravko Bozakov958d81c2019-12-13 22:09:48 +010067}
68
69type SadisIntegration struct {
70 URL string `json:"url,omitempty"`
71 Cache struct {
72 Enabled bool `json:"enabled"`
73 MaxSize int `json:"maxsize"`
74 TTL string `json:"ttl"`
75 } `json:"cache"`
76}
77
78type SadisOltEntry struct {
79 ID string `json:"id"`
80 HardwareIdentifier string `json:"hardwareIdentifier"`
81 IPAddress string `json:"ipAddress"`
82 NasID string `json:"nasId"`
83 UplinkPort int `json:"uplinkPort"`
84}
85
Anand S Kattib409ee02020-02-20 20:10:00 +053086type SadisOnuEntryV2 struct {
87 ID string `json:"id"`
88 NasPortID string `json:"nasPortId"`
89 CircuitID string `json:"circuitId"`
90 RemoteID string `json:"remoteId"`
Matteo Scandolo4a036262020-08-17 15:56:13 -070091 UniTagList []SadisUniTag `json:"uniTagList"` // this can be SadisUniTagAtt, SadisUniTagDt
Anand S Kattib409ee02020-02-20 20:10:00 +053092}
93
Matteo Scandolo4a036262020-08-17 15:56:13 -070094type SadisUniTag struct {
95 UniTagMatch int `json:"uniTagMatch,omitempty"`
Shrey Baid688b4242020-07-10 20:40:10 +053096 PonCTag int `json:"ponCTag,omitempty"`
97 PonSTag int `json:"ponSTag,omitempty"`
98 TechnologyProfileID int `json:"technologyProfileId,omitempty"`
99 UpstreamBandwidthProfile string `json:"upstreamBandwidthProfile,omitempty"`
100 DownstreamBandwidthProfile string `json:"downstreamBandwidthProfile,omitempty"`
101 IsDhcpRequired bool `json:"isDhcpRequired,omitempty"`
102 IsIgmpRequired bool `json:"isIgmpRequired,omitempty"`
Matteo Scandolo4a036262020-08-17 15:56:13 -0700103 ConfiguredMacAddress string `json:"configuredMacAddress,omitempty"`
Matteo Scandolo8d281372020-09-03 16:23:37 -0700104 UsPonCTagPriority uint8 `json:"usPonCTagPriority,omitempty"`
105 UsPonSTagPriority uint8 `json:"usPonSTagPriority,omitempty"`
106 DsPonCTagPriority uint8 `json:"dsPonCTagPriority,omitempty"`
107 DsPonSTagPriority uint8 `json:"dsPonSTagPriority,omitempty"`
Matteo Scandolo4a036262020-08-17 15:56:13 -0700108 ServiceName string `json:"serviceName,omitempty"`
Matteo Scandolof65e6872020-04-15 15:18:43 -0700109}
110
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100111// SADIS BandwithProfile Entry
112type SadisBWPEntry struct {
Matteo Scandolo94967142021-05-28 11:37:06 -0700113 // common attributes
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100114 ID string `json:"id"`
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100115 CBS int `json:"cbs"`
116 CIR int `json:"cir"`
Matteo Scandolo94967142021-05-28 11:37:06 -0700117 // MEF attributes
118 AIR int `json:"air,omitempty"`
119 EBS int `json:"ebs,omitempty"`
120 EIR int `json:"eir,omitempty"`
121 // IETF attributes
122 GIR int `json:"gir,omitempty"`
123 PIR int `json:"pir,omitempty"`
124 PBS int `json:"pbs,omitempty"`
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100125}
126
127// GetSadisConfig returns a full SADIS configuration struct ready to be marshalled into JSON
Anand S Kattib409ee02020-02-20 20:10:00 +0530128func GetSadisConfig(olt *devices.OltDevice, version string) *SadisConfig {
129 sadisEntries, _ := GetSadisEntries(olt, version)
130 bwpEntries := getBWPEntries(version)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100131
132 conf := &SadisConfig{}
133 conf.Sadis = *sadisEntries
134 conf.BandwidthProfile = *bwpEntries
135
136 return conf
137}
138
Anand S Kattib409ee02020-02-20 20:10:00 +0530139func GetSadisEntries(olt *devices.OltDevice, version string) (*SadisEntries, error) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100140 solt, _ := GetOltEntry(olt)
141
142 entries := []interface{}{}
143 entries = append(entries, solt)
144
Matteo Scandolo4a036262020-08-17 15:56:13 -0700145 a := strings.Split(common.Config.BBSim.SadisRestAddress, ":")
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100146 port := a[len(a)-1]
147
148 integration := SadisIntegration{}
Anand S Kattib409ee02020-02-20 20:10:00 +0530149 integration.URL = "http://bbsim:" + port + "/" + version + "/subscribers/%s"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100150 integration.Cache.Enabled = false
151 integration.Cache.MaxSize = 50
152 integration.Cache.TTL = "PT0m"
153
154 sadis := &SadisEntries{
155 integration,
156 entries,
157 }
158
159 return sadis, nil
160}
161
162func GetOltEntry(olt *devices.OltDevice) (*SadisOltEntry, error) {
163 ip, _ := common.GetIPAddr("nni") // TODO verify which IP to report
164 solt := &SadisOltEntry{
165 ID: olt.SerialNumber,
Matteo Scandolo4a036262020-08-17 15:56:13 -0700166 HardwareIdentifier: common.Config.Olt.DeviceId,
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100167 IPAddress: ip,
168 NasID: olt.SerialNumber,
Anand S Kattib409ee02020-02-20 20:10:00 +0530169 UplinkPort: 1048576, // TODO currently assumes we only have one NNI port
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100170 }
171 return solt, nil
172}
173
Anand S Kattib409ee02020-02-20 20:10:00 +0530174func GetOnuEntryV2(olt *devices.OltDevice, onu *devices.Onu, uniId string) (*SadisOnuEntryV2, error) {
175 uniSuffix := "-" + uniId
176
177 sonuv2 := &SadisOnuEntryV2{
Matteo Scandolodf080442020-10-09 11:57:38 -0700178 ID: onu.Sn() + uniSuffix,
Anand S Kattib409ee02020-02-20 20:10:00 +0530179 }
Matteo Scandolo51d6a312020-03-12 15:54:43 -0700180
Matteo Scandolo4a036262020-08-17 15:56:13 -0700181 // createUniTagList
182 for _, s := range onu.Services {
Matteo Scandolof65e6872020-04-15 15:18:43 -0700183
Matteo Scandolo4a036262020-08-17 15:56:13 -0700184 service := s.(*devices.Service)
185
186 tag := SadisUniTag{
187 ServiceName: service.Name,
188 IsIgmpRequired: service.NeedsIgmp,
189 IsDhcpRequired: service.NeedsDhcp,
190 TechnologyProfileID: service.TechnologyProfileID,
191 UpstreamBandwidthProfile: "User_Bandwidth1",
192 DownstreamBandwidthProfile: "User_Bandwidth2",
193 PonCTag: service.CTag,
194 PonSTag: service.STag,
Matteo Scandolof65e6872020-04-15 15:18:43 -0700195 }
Matteo Scandolo4a036262020-08-17 15:56:13 -0700196
197 if service.UniTagMatch != 0 {
198 tag.UniTagMatch = service.UniTagMatch
Matteo Scandolof65e6872020-04-15 15:18:43 -0700199 }
Matteo Scandolo4a036262020-08-17 15:56:13 -0700200
201 if service.ConfigureMacAddress {
202 tag.ConfiguredMacAddress = service.HwAddress.String()
203 }
204
205 if service.UsPonCTagPriority != 0 {
206 tag.UsPonCTagPriority = service.UsPonCTagPriority
207 }
208
209 if service.UsPonSTagPriority != 0 {
210 tag.UsPonSTagPriority = service.UsPonSTagPriority
211 }
212
213 if service.DsPonCTagPriority != 0 {
214 tag.DsPonCTagPriority = service.DsPonCTagPriority
215 }
216
217 if service.DsPonSTagPriority != 0 {
218 tag.DsPonSTagPriority = service.DsPonSTagPriority
219 }
220
221 sonuv2.UniTagList = append(sonuv2.UniTagList, tag)
Anand S Kattib409ee02020-02-20 20:10:00 +0530222 }
Matteo Scandolo51d6a312020-03-12 15:54:43 -0700223
Anand S Kattib409ee02020-02-20 20:10:00 +0530224 return sonuv2, nil
225}
226
227func getBWPEntries(version string) *BandwidthProfileEntries {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700228 a := strings.Split(common.Config.BBSim.SadisRestAddress, ":")
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100229 port := a[len(a)-1]
230
231 integration := SadisIntegration{}
Anand S Kattib409ee02020-02-20 20:10:00 +0530232 integration.URL = "http://bbsim:" + port + "/" + version + "/bandwidthprofiles/%s"
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100233 integration.Cache.Enabled = true
234 integration.Cache.MaxSize = 40
235 integration.Cache.TTL = "PT1m"
236
237 bwp := &BandwidthProfileEntries{
238 Integration: integration,
239 }
240
241 return bwp
242}
243
Matteo Scandolocedde462021-03-09 17:37:16 -0800244func (s *SadisServer) ServeBaseConfig(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100245 w.Header().Set("Content-Type", "application/json")
246 w.WriteHeader(http.StatusOK)
Anand S Kattib409ee02020-02-20 20:10:00 +0530247 vars := mux.Vars(r)
248
249 if vars["version"] != "v1" && vars["version"] != "v2" {
250 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530251 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530252 return
253 }
254
Matteo Scandolocedde462021-03-09 17:37:16 -0800255 sadisConf := GetSadisConfig(s.Olt, vars["version"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100256
257 sadisJSON, _ := json.Marshal(sadisConf)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100258
Shrey Baid688b4242020-07-10 20:40:10 +0530259 _, _ = w.Write([]byte(sadisJSON))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100260
261}
262
Matteo Scandolocedde462021-03-09 17:37:16 -0800263func (s *SadisServer) ServeStaticConfig(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100264 w.Header().Set("Content-Type", "application/json")
265 w.WriteHeader(http.StatusOK)
Anand S Kattib409ee02020-02-20 20:10:00 +0530266 vars := mux.Vars(r)
Matteo Scandolocedde462021-03-09 17:37:16 -0800267 sadisConf := GetSadisConfig(s.Olt, vars["version"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100268
269 sadisConf.Sadis.Integration.URL = ""
Matteo Scandolocedde462021-03-09 17:37:16 -0800270 for i := range s.Olt.Pons {
271 for _, onu := range s.Olt.Pons[i].Onus {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700272 if vars["version"] == "v2" {
Matteo Scandolocedde462021-03-09 17:37:16 -0800273 sonuV2, _ := GetOnuEntryV2(s.Olt, onu, "1")
Anand S Kattib409ee02020-02-20 20:10:00 +0530274 sadisConf.Sadis.Entries = append(sadisConf.Sadis.Entries, sonuV2)
Anand S Kattib409ee02020-02-20 20:10:00 +0530275 }
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100276 }
277 }
278
279 sadisConf.BandwidthProfile.Integration.URL = ""
Matteo Scandolo94967142021-05-28 11:37:06 -0700280 sadisConf.BandwidthProfile.Entries = bandwidthProfiles[common.Config.BBSim.BandwidthProfileFormat]
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100281
282 sadisJSON, _ := json.Marshal(sadisConf)
283 sadisLogger.Tracef("SADIS JSON: %s", sadisJSON)
284
Shrey Baid688b4242020-07-10 20:40:10 +0530285 _, _ = w.Write([]byte(sadisJSON))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100286
287}
288
Matteo Scandolocedde462021-03-09 17:37:16 -0800289func (s *SadisServer) ServeEntry(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100290 w.Header().Set("Content-Type", "application/json")
291 vars := mux.Vars(r)
292
293 // check if the requested ID is for the OLT
Matteo Scandolocedde462021-03-09 17:37:16 -0800294 if s.Olt.SerialNumber == vars["ID"] {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100295 sadisLogger.WithFields(log.Fields{
Matteo Scandolocedde462021-03-09 17:37:16 -0800296 "OltSn": s.Olt.SerialNumber,
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100297 }).Debug("Received SADIS OLT request")
298
Matteo Scandolocedde462021-03-09 17:37:16 -0800299 sadisConf, _ := GetOltEntry(s.Olt)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100300
301 w.WriteHeader(http.StatusOK)
Shrey Baid688b4242020-07-10 20:40:10 +0530302 _ = json.NewEncoder(w).Encode(sadisConf)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100303 return
304 }
305
306 i := strings.Split(vars["ID"], "-") // split ID to get serial number and uni port
307 if len(i) != 2 {
308 w.WriteHeader(http.StatusUnprocessableEntity)
Shrey Baid688b4242020-07-10 20:40:10 +0530309 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530310 sadisLogger.Warnf("Received invalid SADIS SubscriberId: %s", vars["ID"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100311 return
312 }
313 sn, uni := i[0], i[len(i)-1]
314
Matteo Scandolocedde462021-03-09 17:37:16 -0800315 onu, err := s.Olt.FindOnuBySn(sn)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100316 if err != nil {
317 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530318 _, _ = w.Write([]byte("{}"))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100319 sadisLogger.WithFields(log.Fields{
320 "OnuSn": sn,
321 "OnuId": "NA",
Anand S Kattib409ee02020-02-20 20:10:00 +0530322 }).Warnf("Requested Subscriber entry not found for OnuSn: %s", vars["ID"])
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100323 return
324 }
325
326 sadisLogger.WithFields(log.Fields{
327 "OnuId": onu.ID,
328 "OnuSn": sn,
329 "OnuPortNo": uni,
330 }).Debug("Received SADIS request")
331
Anand S Kattib409ee02020-02-20 20:10:00 +0530332 if vars["version"] == "v1" {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700333 // TODO format error
334 w.WriteHeader(http.StatusBadRequest)
335 _ = 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 +0530336 } else if vars["version"] == "v2" {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700337 w.WriteHeader(http.StatusOK)
Matteo Scandolocedde462021-03-09 17:37:16 -0800338 sadisConf, _ := GetOnuEntryV2(s.Olt, onu, uni)
Shrey Baid688b4242020-07-10 20:40:10 +0530339 _ = json.NewEncoder(w).Encode(sadisConf)
Anand S Kattib409ee02020-02-20 20:10:00 +0530340 }
341
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100342}
343
Matteo Scandolocedde462021-03-09 17:37:16 -0800344func (s *SadisServer) ServeBWPEntry(w http.ResponseWriter, r *http.Request) {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100345 w.Header().Set("Content-Type", "application/json")
346 vars := mux.Vars(r)
347 id := vars["ID"]
Anand S Kattib409ee02020-02-20 20:10:00 +0530348
349 if vars["version"] != "v1" && vars["version"] != "v2" {
350 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530351 _, _ = w.Write([]byte("{}"))
Anand S Kattib409ee02020-02-20 20:10:00 +0530352 return
353 }
354
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100355 sadisLogger.Debugf("Received request for SADIS bandwidth profile %s", id)
356
Matteo Scandolo94967142021-05-28 11:37:06 -0700357 for _, bwpEntry := range bandwidthProfiles[common.Config.BBSim.BandwidthProfileFormat] {
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100358 if bwpEntry.ID == id {
359 w.WriteHeader(http.StatusOK)
Shrey Baid688b4242020-07-10 20:40:10 +0530360 _ = json.NewEncoder(w).Encode(bwpEntry)
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100361 return
362 }
363 }
364
365 w.WriteHeader(http.StatusNotFound)
Shrey Baid688b4242020-07-10 20:40:10 +0530366 _, _ = w.Write([]byte("{}"))
Zdravko Bozakov958d81c2019-12-13 22:09:48 +0100367}