blob: 0e0ea1bcf049aeff697980e4d938d953b2244d53 [file] [log] [blame]
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +09001/*
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 core
18
19import (
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090020 "context"
Matteo Scandolo4549d3f2018-10-19 12:48:20 -070021 "errors"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090022 "gerrit.opencord.org/voltha-bbsim/common"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090023 "gerrit.opencord.org/voltha-bbsim/device"
24 "gerrit.opencord.org/voltha-bbsim/protos"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090025 "github.com/google/gopacket"
26 "github.com/google/gopacket/layers"
27 "github.com/google/gopacket/pcap"
28 "google.golang.org/grpc"
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090029 "strconv"
30 "sync"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090031)
32
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090033const (
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090034 UNI_VETH_UP_PFX = "sim_uu"
35 UNI_VETH_DW_PFX = "sim_ud"
36 NNI_VETH_UP_PFX = "sim_nu"
37 NNI_VETH_DW_PFX = "sim_nd"
38 MAX_ONUS_PER_PON = 64 // This value should be the same with the value in AdapterPlatrorm class
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090039)
40
41type Server struct {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090042 wg *sync.WaitGroup
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090043 Olt *device.Olt
44 Onumap map[uint32][]*device.Onu
45 Ioinfos []*Ioinfo
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090046 gRPCserver *grpc.Server
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090047 gRPCAddress string
48 gRPCPort uint32
49 Vethnames []string
50 IndInterval int
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +090051 Processes []string
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +090052 EnableServer *openolt.Openolt_EnableIndicationServer
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090053 CtagMap map[string]uint32
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090054 cancel context.CancelFunc
55 state coreState
56 stateChan chan coreState
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090057}
58
59type Packet struct {
60 Info *Ioinfo
61 Pkt gopacket.Packet
62}
63
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090064type coreState int
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +090065
Keita NISHIMOTO9708e042018-10-27 09:24:44 +090066const (
67 INACTIVE = iota // OLT/ONUs are not instantiated
68 PRE_ACTIVE // Before PacketInDaemon Running
69 ACTIVE // After PacketInDaemon Running
70)
71
72/* coreState
73INACTIVE -> PRE_ACTIVE -> ACTIVE
74 (ActivateOLT) (Enable)
75 <- <-
76 */
77
78
79func NewCore(opt *option) (*Server) {
80 // TODO: make it decent
81 oltid := opt.oltid
82 npon := opt.npon
83 nonus := opt.nonus
84 s := Server{
85 Olt: device.NewOlt(oltid, npon, 1),
86 Onumap: make(map[uint32][]*device.Onu),
87 Ioinfos: []*Ioinfo{},
88 gRPCAddress: opt.address,
89 gRPCPort: opt.port,
90 Vethnames: []string{},
91 IndInterval: opt.intvl,
92 Processes: []string{},
93 EnableServer: new(openolt.Openolt_EnableIndicationServer),
94 state: INACTIVE,
95 stateChan: make(chan coreState, 8),
96 }
97
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090098 nnni := s.Olt.NumNniIntf
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +090099 logger.Info("OLT ID: %d was retrieved.\n", s.Olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900100 for intfid := nnni; intfid < npon+nnni; intfid++ {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900101 s.Onumap[intfid] = device.NewOnus(oltid, intfid, nonus, nnni)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900102 }
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900103
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900104 //TODO: To be fixed because it is hardcoded
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900105 s.CtagMap = make(map[string]uint32)
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700106 for i := 0; i < MAX_ONUS_PER_PON; i++ {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900107 oltid := s.Olt.ID
108 intfid := uint32(1)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900109 sn := convB2S(device.NewSN(oltid, intfid, uint32(i)))
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700110 s.CtagMap[sn] = uint32(900 + i) // This is hard coded for BBWF
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900111 }
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900112 return &s
113}
114
115//Blocking
116func (s *Server) Start () error {
117 s.wg = &sync.WaitGroup{}
118 logger.Debug("Start() Start")
119 defer func(){
120 close(s.stateChan)
121 logger.Debug("Start() Done")
122 }()
123 addressport := s.gRPCAddress + ":" + strconv.Itoa(int(s.gRPCPort))
124 listener, gserver, err := NewGrpcServer(addressport)
125 if err != nil {
126 logger.Error("Failed to create gRPC server", err)
127 return err
128 }
129 s.gRPCserver = gserver
130 openolt.RegisterOpenoltServer(gserver, s)
131 if err := gserver.Serve(listener); err != nil {
132 logger.Error("Failed to run gRPC server", err)
133 return err
134 }
135 s.wg.Wait()
136 return nil
137}
138
139//Non-Blocking
140func (s *Server) Stop () {
141 logger.Debug("Stop() Start")
142 defer logger.Debug("Stop() Done")
143 if s.gRPCserver != nil {
144 s.gRPCserver.Stop()
145 logger.Debug("gRPCserver.Stop()")
146 }
147 s.StopPktInDaemon()
148 return
149}
150
151// Blocking
152func (s *Server) Enable(sv *openolt.Openolt_EnableIndicationServer) error {
153 defer func(){
154 olt := s.Olt
155 olt.InitializeStatus()
156 for intfid, _ := range s.Onumap {
157 for _, onu := range s.Onumap[intfid] {
158 onu.InitializeStatus()
159 }
160 }
161 s.updateState(INACTIVE)
162 logger.Debug("Enable() Done")
163 }()
164 logger.Debug("Enable() Start")
165 s.EnableServer = sv
166 if err := s.activateOLT(*sv); err != nil {
167 return err
168 }
169 s.updateState(PRE_ACTIVE)
170
171 coreCtx := context.Background()
172 coreCtx, corecancel := context.WithCancel(coreCtx)
173 s.cancel = corecancel
174 if err := s.StartPktInDaemon(coreCtx, *sv) ; err != nil {
175 return err
176 }
177 return nil
178}
179
180//Non-Blocking
181func (s *Server) Disable() {
182 defer func(){
183 logger.Debug("Disable() Done")
184 }()
185 logger.Debug("Disable() Start")
186 s.StopPktInDaemon()
187}
188
189func (s *Server) updateState(state coreState){
190 s.state = state
191 s.stateChan <- state
192 logger.Debug("State updated to:%d", state)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900193}
194
195func (s *Server) activateOLT(stream openolt.Openolt_EnableIndicationServer) error {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900196 defer logger.Debug("activateOLT() Done")
197 logger.Debug("activateOLT() Start")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900198 // Activate OLT
199 olt := s.Olt
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900200 if err := sendOltIndUp(stream, olt); err != nil {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900201 return err
202 }
203 olt.OperState = "up"
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900204 *olt.InternalState = device.OLT_UP
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900205 logger.Info("OLT %s sent OltInd.\n", olt.Name)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900206
207 // OLT sends Interface Indication to Adapter
208 if err := sendIntfInd(stream, olt); err != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900209 logger.Error("Fail to sendIntfInd: %v\n", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900210 return err
211 }
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900212 logger.Info("OLT %s sent IntfInd.\n", olt.Name)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900213
214 // OLT sends Operation Indication to Adapter after activating each interface
215 //time.Sleep(IF_UP_TIME * time.Second)
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900216 *olt.InternalState = device.PONIF_UP
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900217 if err := sendOperInd(stream, olt); err != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900218 logger.Error("Fail to sendOperInd: %v\n", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900219 return err
220 }
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900221 logger.Info("OLT %s sent OperInd.\n", olt.Name)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900222
223 // OLT sends ONU Discover Indication to Adapter after ONU discovery
224 for intfid, _ := range s.Onumap {
225 device.UpdateOnusOpStatus(intfid, s.Onumap[intfid], "up")
226 }
227
228 for intfid, _ := range s.Onumap {
229 sendOnuDiscInd(stream, s.Onumap[intfid])
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900230 logger.Info("OLT id:%d sent ONUDiscInd.\n", olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900231 }
232
233 // OLT Sends OnuInd after waiting all of those ONUs up
234 for {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900235 if IsAllOnuActive(s.Onumap) {
236 logger.Debug("All the Onus are Activated.")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900237 break
238 }
239 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900240
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900241 for intfid, _ := range s.Onumap {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900242 sendOnuInd(stream, s.Onumap[intfid], s.IndInterval)
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900243 logger.Info("OLT id:%d sent ONUInd.\n", olt.ID)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900244 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900245 return nil
246}
247
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900248
249// Blocking
250func (s *Server) StartPktInDaemon(ctx context.Context, stream openolt.Openolt_EnableIndicationServer) error {
251 logger.Debug("StartPktInDaemon() Start")
252 defer func(){
253 RemoveVeths(s.Vethnames)
254 s.Vethnames = []string{}
255 s.Ioinfos = []*Ioinfo{}
256 s.wg.Done()
257 s.updateState(PRE_ACTIVE)
258 logger.Debug("StartPktInDaemon() Done")
259 }()
260 s.wg.Add(1)
261 ioinfos, veths, err := createIoinfos(s.Olt.ID, s.Vethnames, s.Onumap)
262 if err != nil {
263 return err
264 }
265 s.Ioinfos = ioinfos
266 s.Vethnames = veths
267 logger.Debug("Created vethnames:%v", s.Vethnames)
268
269 parent := ctx
270 child, cancel := context.WithCancel(parent)
271 s.cancel = cancel
272
273 if err = s.runPacketInDaemon(child, stream); err != nil {
274 return err
275 }
276 return nil
277}
278
279//Non-Blocking
280func (s *Server) StopPktInDaemon() {
281 if s.cancel != nil {
282 cancel := s.cancel
283 cancel()
284 }
285}
286
287func createIoinfos(oltid uint32, Vethnames []string, onumap map[uint32][]*device.Onu) ([]*Ioinfo, []string, error) {
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900288 ioinfos := []*Ioinfo{}
289 var err error
290 for intfid, _ := range onumap {
291 for i := 0; i < len(onumap[intfid]); i++ {
292 var handler *pcap.Handle
293 onuid := onumap[intfid][i].OnuID
294 uniup, unidw := makeUniName(oltid, intfid, onuid)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900295 if handler, Vethnames, err = setupVethHandler(uniup, unidw, Vethnames); err != nil {
296 return ioinfos, Vethnames, err
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900297 }
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900298 iinfo := Ioinfo{Name: uniup, iotype: "uni", ioloc: "inside", intfid: intfid, onuid: onuid, handler: handler}
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900299 ioinfos = append(ioinfos, &iinfo)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900300 oinfo := Ioinfo{Name: unidw, iotype: "uni", ioloc: "outside", intfid: intfid, onuid: onuid, handler: nil}
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900301 ioinfos = append(ioinfos, &oinfo)
302 }
303 }
304
305 var handler *pcap.Handle
306 nniup, nnidw := makeNniName(oltid)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900307 if handler, Vethnames, err = setupVethHandler(nniup, nnidw, Vethnames); err != nil {
308 return ioinfos, Vethnames, err
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900309 }
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900310
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900311 iinfo := Ioinfo{Name: nnidw, iotype: "nni", ioloc: "inside", intfid: 1, handler: handler}
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900312 ioinfos = append(ioinfos, &iinfo)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900313 oinfo := Ioinfo{Name: nniup, iotype: "nni", ioloc: "outside", intfid: 1, handler: nil}
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900314 ioinfos = append(ioinfos, &oinfo)
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900315 return ioinfos, Vethnames, nil
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900316}
317
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900318//Blocking
319func (s *Server) runPacketInDaemon(ctx context.Context, stream openolt.Openolt_EnableIndicationServer) error {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900320 logger.Debug("runPacketInDaemon Start")
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900321 defer logger.Debug("runPacketInDaemon Done")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900322 unichannel := make(chan Packet, 2048)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900323
324 for intfid, _ := range s.Onumap {
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900325 for _, onu := range s.Onumap[intfid] {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900326 onuid := onu.OnuID
327 ioinfo, err := s.identifyUniIoinfo("inside", intfid, onuid)
328 if err != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900329 logger.Error("Fail to identifyUniIoinfo (onuid: %d): %v\n", onuid, err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900330 return err
331 }
332 uhandler := ioinfo.handler
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900333 go RecvWorker(ioinfo, uhandler, unichannel)
334 }
335 }
336
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900337 ioinfo, err := s.IdentifyNniIoinfo("inside")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900338 if err != nil {
339 return err
340 }
341 nhandler := ioinfo.handler
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900342 nnichannel := make(chan Packet, 32)
343 go RecvWorker(ioinfo, nhandler, nnichannel)
344
345 data := &openolt.Indication_PktInd{}
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900346 s.updateState(ACTIVE)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900347 for {
348 select {
349 case unipkt := <-unichannel:
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900350 logger.Debug("Received packet in grpc Server from UNI.")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900351 if unipkt.Info == nil || unipkt.Info.iotype != "uni" {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900352 logger.Info("WARNING: This packet does not come from UNI ")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900353 continue
354 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900355
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900356 intfid := unipkt.Info.intfid
357 onuid := unipkt.Info.onuid
358 gemid, _ := getGemPortID(intfid, onuid)
359 pkt := unipkt.Pkt
360 layerEth := pkt.Layer(layers.LayerTypeEthernet)
361 le, _ := layerEth.(*layers.Ethernet)
362 ethtype := le.EthernetType
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900363
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900364 if ethtype == 0x888e {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900365 logger.Debug("Received upstream packet is EAPOL.")
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900366 //log.Println(unipkt.Pkt.Dump())
367 //log.Println(pkt.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900368 } else if layerDHCP := pkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900369 logger.Debug("Received upstream packet is DHCP.")
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900370
371 //C-TAG
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900372 onu, _ := getOnuByID(s.Onumap, onuid)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900373 sn := convB2S(onu.SerialNumber.VendorSpecific)
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700374 if ctag, ok := s.CtagMap[sn]; ok == true {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900375 tagpkt, err := PushVLAN(pkt, uint16(ctag))
376 if err != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900377 logger.Error("Fail to tag C-tag")
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900378 } else {
379 pkt = tagpkt
380 }
381 } else {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900382 logger.Error("Could not find the onuid %d (SN: %s) in CtagMap %v!\n", onuid, sn, s.CtagMap)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900383 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900384 } else {
385 continue
386 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900387
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900388 logger.Debug("sendPktInd intfid:%d (onuid: %d) gemid:%d\n", intfid, onuid, gemid)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900389 data = &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{IntfType: "pon", IntfId: intfid, GemportId: gemid, Pkt: pkt.Data()}}
390 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900391 logger.Error("Fail to send PktInd indication. %v\n", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900392 return err
393 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900394
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900395 case nnipkt := <-nnichannel:
396 if nnipkt.Info == nil || nnipkt.Info.iotype != "nni" {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900397 logger.Info("WARNING: This packet does not come from NNI ")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900398 continue
399 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900400
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900401 logger.Debug("Received packet in grpc Server from NNI.")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900402 intfid := nnipkt.Info.intfid
403 pkt := nnipkt.Pkt
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900404 logger.Info("sendPktInd intfid:%d\n", intfid)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900405 data = &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{IntfType: "nni", IntfId: intfid, Pkt: pkt.Data()}}
406 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900407 logger.Error("Fail to send PktInd indication. %v\n", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900408 return err
409 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900410
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900411 case <-ctx.Done():
412 logger.Debug("PacketInDaemon thread receives close ")
413 close(unichannel)
414 logger.Debug("Closed unichannel ")
415 close(nnichannel)
416 logger.Debug("Closed nnichannel ")
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900417 return nil
Keita NISHIMOTOc864da22018-10-15 22:41:42 +0900418 }
419 }
Keita NISHIMOTOc864da22018-10-15 22:41:42 +0900420 return nil
421}
422
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900423func (s *Server) onuPacketOut(intfid uint32, onuid uint32, rawpkt gopacket.Packet) error {
424 layerEth := rawpkt.Layer(layers.LayerTypeEthernet)
425 if layerEth != nil {
426 pkt, _ := layerEth.(*layers.Ethernet)
427 ethtype := pkt.EthernetType
428 if ethtype == 0x888e {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900429 logger.Debug("Received downstream packet is EAPOL.")
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900430 //log.Println(rawpkt.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900431 } else if layerDHCP := rawpkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900432 logger.Debug("Received downstream packet is DHCP.")
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900433 //log.Println(rawpkt.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900434 rawpkt, _, _ = PopVLAN(rawpkt)
435 rawpkt, _, _ = PopVLAN(rawpkt)
436 } else {
437 return nil
438 }
439 ioinfo, err := s.identifyUniIoinfo("inside", intfid, onuid)
440 if err != nil {
441 return err
442 }
443 handle := ioinfo.handler
444 SendUni(handle, rawpkt)
445 return nil
446 }
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900447 logger.Info("WARNING: Received packet is not supported")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900448 return nil
449}
450
451func (s *Server) uplinkPacketOut(rawpkt gopacket.Packet) error {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900452 poppkt, _, err := PopVLAN(rawpkt)
453 poppkt, _, err = PopVLAN(poppkt)
454 if err != nil {
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900455 logger.Error("%s", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900456 return err
457 }
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900458 ioinfo, err := s.IdentifyNniIoinfo("inside")
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900459 if err != nil {
460 return err
461 }
462 handle := ioinfo.handler
463 SendNni(handle, poppkt)
464 return nil
465}
466
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900467func IsAllOnuActive(onumap map[uint32][]*device.Onu) bool {
468 for _, onus := range onumap {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900469 for _, onu := range onus {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900470 if onu.GetIntStatus() != device.ONU_ACTIVATED {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900471 return false
472 }
473 }
474 }
475 return true
476}
477
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900478func getGemPortID(intfid uint32, onuid uint32) (uint32, error) {
479 idx := uint32(0)
480 return 1024 + (((MAX_ONUS_PER_PON*intfid + onuid - 1) * 7) + idx), nil
481 //return uint32(1032 + 8 * (vid - 1)), nil
482}
483
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900484func getOnuBySN(onumap map[uint32][]*device.Onu, sn *openolt.SerialNumber) (*device.Onu, error) {
485 for _, onus := range onumap {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900486 for _, onu := range onus {
487 if device.ValidateSN(*sn, *onu.SerialNumber) {
488 return onu, nil
489 }
490 }
491 }
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900492 err := errors.New("No mathced SN is found ")
493 logger.Error("%s", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900494 return nil, err
495}
496
Keita NISHIMOTO9708e042018-10-27 09:24:44 +0900497func getOnuByID(onumap map[uint32][]*device.Onu, onuid uint32) (*device.Onu, error) {
498 for _, onus := range onumap {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900499 for _, onu := range onus {
500 if onu.OnuID == onuid {
501 return onu, nil
502 }
503 }
504 }
Keita NISHIMOTOc66b8eb2018-10-20 07:19:39 +0900505 err := errors.New("No matched OnuID is found ")
506 logger.Error("%s", err)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900507 return nil, err
508}
509
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900510func convB2S(b []byte) string {
511 s := ""
512 for _, i := range b {
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700513 s = s + strconv.FormatInt(int64(i/16), 16) + strconv.FormatInt(int64(i%16), 16)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900514 }
515 return s
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700516}