blob: 76c219f0a2f0ea9968c6a3ecf59d2ac6d99e2ba3 [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 (
Matteo Scandolo4549d3f2018-10-19 12:48:20 -070020 "errors"
21 "log"
22 "strconv"
23 "sync"
24 "time"
25
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090026 "gerrit.opencord.org/voltha-bbsim/device"
27 "gerrit.opencord.org/voltha-bbsim/protos"
28 "gerrit.opencord.org/voltha-bbsim/setup"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090029 "github.com/google/gopacket"
30 "github.com/google/gopacket/layers"
31 "github.com/google/gopacket/pcap"
32 "google.golang.org/grpc"
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090033)
34
35type Mode int
36
37const MAX_ONUS_PER_PON = 64 // This value should be the same with the value in AdapterPlatrorm class
38
39const (
40 DEFAULT Mode = iota
41 AAA
42 BOTH
43)
44
45type Server struct {
46 Olt *device.Olt
47 Onumap map[uint32][]*device.Onu
48 Ioinfos []*Ioinfo
49 Endchan chan int
50 Mode Mode
51 AAAWait int
52 DhcpWait int
53 DhcpServerIP string
Matteo Scandolo4549d3f2018-10-19 12:48:20 -070054 Delay int
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090055 gRPCserver *grpc.Server
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +090056 VethEnv []string
57 TestFlag bool
58 Processes []string
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +090059 EnableServer *openolt.Openolt_EnableIndicationServer
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090060 CtagMap map[string]uint32
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090061}
62
63type Packet struct {
64 Info *Ioinfo
65 Pkt gopacket.Packet
66}
67
Matteo Scandolo4549d3f2018-10-19 12:48:20 -070068func (s *Server) Initialize() {
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +090069 s.VethEnv = []string{}
70 s.Endchan = make(chan int)
71 s.TestFlag = false
72 s.Processes = []string{}
73 s.Ioinfos = []*Ioinfo{}
74}
75
Matteo Scandolo4549d3f2018-10-19 12:48:20 -070076func Create(oltid uint32, npon uint32, nonus uint32, aaawait int, dhcpwait int, ip string, delay int, g *grpc.Server, mode Mode, e chan int) *Server {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090077 s := new(Server)
78 s.Olt = device.CreateOlt(oltid, npon, 1)
79 nnni := s.Olt.NumNniIntf
80 log.Printf("OLT ID: %d was retrieved.\n", s.Olt.ID)
81 s.Onumap = make(map[uint32][]*device.Onu)
82 s.AAAWait = aaawait
83 s.DhcpWait = dhcpwait
84 s.DhcpServerIP = ip
85 s.gRPCserver = g
Matteo Scandolo4549d3f2018-10-19 12:48:20 -070086 s.Delay = delay
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090087 s.Mode = mode
88 s.Endchan = e
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +090089 s.VethEnv = []string{}
90 s.TestFlag = false
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +090091 for intfid := nnni; intfid < npon+nnni; intfid++ {
92 s.Onumap[intfid] = device.CreateOnus(oltid, intfid, nonus, nnni)
93 }
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +090094 s.EnableServer = new(openolt.Openolt_EnableIndicationServer)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090095
96 //TODO: To be fixed
97 s.CtagMap = make(map[string]uint32)
Matteo Scandolo4549d3f2018-10-19 12:48:20 -070098 for i := 0; i < MAX_ONUS_PER_PON; i++ {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +090099 oltid := s.Olt.ID
100 intfid := uint32(1)
101 sn := convB2S(device.CreateSN(oltid, intfid, uint32(i)))
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700102 s.CtagMap[sn] = uint32(900 + i) // This is hard coded for BBWF
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900103 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900104 return s
105}
106
107func (s *Server) activateOLT(stream openolt.Openolt_EnableIndicationServer) error {
108 // Activate OLT
109 olt := s.Olt
110 oltid := olt.ID
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900111 wg := &sync.WaitGroup{}
112
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900113 if err := sendOltIndUp(stream, olt); err != nil {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900114 return err
115 }
116 olt.OperState = "up"
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900117 *olt.InternalState = device.OLT_UP
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900118 log.Printf("OLT %s sent OltInd.\n", olt.Name)
119
120 // OLT sends Interface Indication to Adapter
121 if err := sendIntfInd(stream, olt); err != nil {
122 log.Printf("[ERROR] Fail to sendIntfInd: %v\n", err)
123 return err
124 }
125 log.Printf("OLT %s sent IntfInd.\n", olt.Name)
126
127 // OLT sends Operation Indication to Adapter after activating each interface
128 //time.Sleep(IF_UP_TIME * time.Second)
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900129 *olt.InternalState = device.PONIF_UP
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900130 if err := sendOperInd(stream, olt); err != nil {
131 log.Printf("[ERROR] Fail to sendOperInd: %v\n", err)
132 return err
133 }
134 log.Printf("OLT %s sent OperInd.\n", olt.Name)
135
136 // OLT sends ONU Discover Indication to Adapter after ONU discovery
137 for intfid, _ := range s.Onumap {
138 device.UpdateOnusOpStatus(intfid, s.Onumap[intfid], "up")
139 }
140
141 for intfid, _ := range s.Onumap {
142 sendOnuDiscInd(stream, s.Onumap[intfid])
143 log.Printf("OLT id:%d sent ONUDiscInd.\n", olt.ID)
144 }
145
146 // OLT Sends OnuInd after waiting all of those ONUs up
147 for {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900148 if s.IsAllOnuActive(s.Onumap) {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900149 break
150 }
151 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900152
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900153 for intfid, _ := range s.Onumap {
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700154 sendOnuInd(stream, s.Onumap[intfid], s.Delay)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900155 log.Printf("OLT id:%d sent ONUInd.\n", olt.ID)
156 }
157
158 if s.Mode == DEFAULT {
159 //EnableIndication's stream should be kept even after activateOLT() is finished.
160 //Otherwise, OpenOLT adapter sends EnableIndication again.
161 <-s.Endchan
162 log.Println("core server thread receives close !")
163 } else if s.Mode == AAA || s.Mode == BOTH {
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900164 s.TestFlag = true
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900165 var err error
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900166 s.Ioinfos, s.VethEnv, err = createIoinfos(oltid, s.VethEnv, s.Onumap)
167 log.Println("s.VethEnv", s.VethEnv)
168 if err != nil {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900169 return err
170 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900171
172 errchan := make(chan error)
173 go func() {
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700174 <-errchan
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900175 close(s.Endchan)
176 }()
177
178 wg.Add(1)
179 go func() {
180 defer func() {
181 log.Println("runPacketInDaemon Done")
182 wg.Done()
183 }()
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900184
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900185 err := s.runPacketInDaemon(stream)
186 if err != nil {
187 errchan <- err
188 return
189 }
190 }()
191
192 wg.Add(1)
193 go func() {
194 defer func() {
195 log.Println("exeAAATest Done")
196 wg.Done()
197 }()
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900198
199 err = s.exeAAATest()
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900200 if err != nil {
201 errchan <- err
202 return
203 }
Keita NISHIMOTOc864da22018-10-15 22:41:42 +0900204
205 if s.Mode == BOTH {
206 go func() {
207 defer func() {
208 log.Println("exeDHCPTest Done")
209 }()
Keita NISHIMOTOc864da22018-10-15 22:41:42 +0900210
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900211 err := s.exeDHCPTest()
Keita NISHIMOTOc864da22018-10-15 22:41:42 +0900212 if err != nil {
213 errchan <- err
214 return
215 }
216 }()
217 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900218 }()
219 wg.Wait()
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900220 cleanUpVeths(s.VethEnv) // Grace teardown
221 pnames := s.Processes
222 killProcesses(pnames)
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900223 log.Println("Grace shutdown down")
224 }
225 return nil
226}
227
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700228func createIoinfos(oltid uint32, vethenv []string, onumap map[uint32][]*device.Onu) ([]*Ioinfo, []string, error) {
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900229 ioinfos := []*Ioinfo{}
230 var err error
231 for intfid, _ := range onumap {
232 for i := 0; i < len(onumap[intfid]); i++ {
233 var handler *pcap.Handle
234 onuid := onumap[intfid][i].OnuID
235 uniup, unidw := makeUniName(oltid, intfid, onuid)
236 if handler, vethenv, err = setupVethHandler(uniup, unidw, vethenv); err != nil {
237 return ioinfos, vethenv, err
238 }
239 iinfo := Ioinfo{name: uniup, iotype: "uni", ioloc: "inside", intfid: intfid, onuid: onuid, handler: handler}
240 ioinfos = append(ioinfos, &iinfo)
241 oinfo := Ioinfo{name: unidw, iotype: "uni", ioloc: "outside", intfid: intfid, onuid: onuid, handler: nil}
242 ioinfos = append(ioinfos, &oinfo)
243 }
244 }
245
246 var handler *pcap.Handle
247 nniup, nnidw := makeNniName(oltid)
248 if handler, vethenv, err = setupVethHandler(nniup, nnidw, vethenv); err != nil {
249 return ioinfos, vethenv, err
250 }
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900251
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900252 iinfo := Ioinfo{name: nnidw, iotype: "nni", ioloc: "inside", intfid: 1, handler: handler}
253 ioinfos = append(ioinfos, &iinfo)
254 oinfo := Ioinfo{name: nniup, iotype: "nni", ioloc: "outside", intfid: 1, handler: nil}
255 ioinfos = append(ioinfos, &oinfo)
256 return ioinfos, vethenv, nil
257}
258
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900259func (s *Server) runPacketInDaemon(stream openolt.Openolt_EnableIndicationServer) error {
260 log.Println("runPacketInDaemon Start")
261 unichannel := make(chan Packet, 2048)
262 flag := false
263
264 for intfid, _ := range s.Onumap {
265 for _, onu := range s.Onumap[intfid] { //TODO: should be updated for multiple-Interface
266 onuid := onu.OnuID
267 ioinfo, err := s.identifyUniIoinfo("inside", intfid, onuid)
268 if err != nil {
269 log.Printf("[ERROR] Fail to identifyUniIoinfo (onuid: %d): %v\n", onuid, err)
270 return err
271 }
272 uhandler := ioinfo.handler
273 defer uhandler.Close()
274 go RecvWorker(ioinfo, uhandler, unichannel)
275 }
276 }
277
278 ioinfo, err := s.identifyNniIoinfo("inside")
279 if err != nil {
280 return err
281 }
282 nhandler := ioinfo.handler
283 defer nhandler.Close()
284 nnichannel := make(chan Packet, 32)
285 go RecvWorker(ioinfo, nhandler, nnichannel)
286
287 data := &openolt.Indication_PktInd{}
288 for {
289 select {
290 case unipkt := <-unichannel:
291 log.Println("Received packet in grpc Server from UNI.")
292 if unipkt.Info == nil || unipkt.Info.iotype != "uni" {
293 log.Println("[WARNING] This packet does not come from UNI !")
294 continue
295 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900296
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900297 intfid := unipkt.Info.intfid
298 onuid := unipkt.Info.onuid
299 gemid, _ := getGemPortID(intfid, onuid)
300 pkt := unipkt.Pkt
301 layerEth := pkt.Layer(layers.LayerTypeEthernet)
302 le, _ := layerEth.(*layers.Ethernet)
303 ethtype := le.EthernetType
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900304
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900305 if ethtype == 0x888e {
306 log.Printf("Received upstream packet is EAPOL.")
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900307 //log.Println(unipkt.Pkt.Dump())
308 //log.Println(pkt.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900309 } else if layerDHCP := pkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
310 log.Printf("Received upstream packet is DHCP.")
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900311
312 //C-TAG
313 onu, _ := s.getOnuByID(onuid)
314 sn := convB2S(onu.SerialNumber.VendorSpecific)
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700315 if ctag, ok := s.CtagMap[sn]; ok == true {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900316 tagpkt, err := PushVLAN(pkt, uint16(ctag))
317 if err != nil {
318 log.Println("Error happend in C-tag tagging")
319 } else {
320 pkt = tagpkt
321 }
322 } else {
323 log.Printf("Could not find the onuid %d (SN: %s) in CtagMap %v!\n", onuid, sn, s.CtagMap)
324 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900325 } else {
326 continue
327 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900328
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900329 log.Printf("sendPktInd intfid:%d (onuid: %d) gemid:%d\n", intfid, onuid, gemid)
330 data = &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{IntfType: "pon", IntfId: intfid, GemportId: gemid, Pkt: pkt.Data()}}
331 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
332 log.Printf("[ERROR] Failed to send PktInd indication. %v\n", err)
333 return err
334 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900335
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900336 case nnipkt := <-nnichannel:
337 if nnipkt.Info == nil || nnipkt.Info.iotype != "nni" {
338 log.Println("[WARNING] This packet does not come from NNI !")
339 continue
340 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900341
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900342 log.Println("Received packet in grpc Server from NNI.")
343 intfid := nnipkt.Info.intfid
344 pkt := nnipkt.Pkt
345 log.Printf("sendPktInd intfid:%d\n", intfid)
346 data = &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{IntfType: "nni", IntfId: intfid, Pkt: pkt.Data()}}
347 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
348 log.Printf("[ERROR] Failed to send PktInd indication. %v\n", err)
349 return err
350 }
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900351
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900352 case <-s.Endchan:
353 if flag == false {
354 log.Println("PacketInDaemon thread receives close !")
355 close(unichannel)
356 log.Println("Closed unichannel !")
357 close(nnichannel)
358 log.Println("Closed nnichannel !")
359 flag = true
360 return nil
361 }
362 }
363 }
364 return nil
365}
366
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900367func (s *Server) exeAAATest() error {
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900368 log.Println("exeAAATest starts to sleep....")
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900369 infos, err := s.getUniIoinfos("outside")
370 if err != nil {
371 return err
372 }
373
374 univeths := []string{}
375 for _, info := range infos {
376 univeths = append(univeths, info.name)
377 }
378
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700379 for {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900380 select {
381 case <-s.Endchan:
382 log.Println("exeAAATest thread receives close !")
383 return nil
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700384 case <-time.After(time.Second * time.Duration(s.AAAWait)):
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900385 log.Println("exeAAATest Start")
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700386 err = setup.ActivateWPASups(univeths, s.Delay)
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900387 if err != nil {
388 return err
389 }
390 s.Processes = append(s.Processes, "wpa_supplicant")
391 log.Println("s.Processes:", s.Processes)
392 return nil
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900393 }
394 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900395 return nil
396}
397
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900398func (s *Server) exeDHCPTest() error {
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900399 log.Println("exeDHCPTest starts to sleep....")
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900400 info, err := s.identifyNniIoinfo("outside")
401
402 if err != nil {
403 return err
404 }
405
406 err = setup.ActivateDHCPServer(info.name, s.DhcpServerIP)
407 if err != nil {
408 return err
409 }
410 s.Processes = append(s.Processes, "dhcpd")
411
412 infos, err := s.getUniIoinfos("outside")
413 if err != nil {
414 return err
415 }
416
417 univeths := []string{}
418 for _, info := range infos {
419 univeths = append(univeths, info.name)
420 }
421
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700422 for {
Keita NISHIMOTOc864da22018-10-15 22:41:42 +0900423 select {
424 case <-s.Endchan:
425 log.Println("exeDHCPTest thread receives close !")
426 return nil
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700427 case <-time.After(time.Second * time.Duration(s.DhcpWait)):
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900428 log.Println("exeDHCPTest Start")
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700429 err = setup.ActivateDHCPClients(univeths, s.Delay)
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900430 if err != nil {
431 return err
432 }
433 s.Processes = append(s.Processes, "dhclient")
434 log.Println("s.Processes:", s.Processes)
435 return nil
Keita NISHIMOTOc864da22018-10-15 22:41:42 +0900436 }
437 }
Keita NISHIMOTOc864da22018-10-15 22:41:42 +0900438 return nil
439}
440
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900441func (s *Server) onuPacketOut(intfid uint32, onuid uint32, rawpkt gopacket.Packet) error {
442 layerEth := rawpkt.Layer(layers.LayerTypeEthernet)
443 if layerEth != nil {
444 pkt, _ := layerEth.(*layers.Ethernet)
445 ethtype := pkt.EthernetType
446 if ethtype == 0x888e {
447 log.Printf("Received downstream packet is EAPOL.")
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900448 //log.Println(rawpkt.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900449 } else if layerDHCP := rawpkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
450 log.Printf("Received downstream packet is DHCP.")
Keita NISHIMOTO9c6f6f12018-10-18 04:56:34 +0900451 //log.Println(rawpkt.Dump())
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900452 rawpkt, _, _ = PopVLAN(rawpkt)
453 rawpkt, _, _ = PopVLAN(rawpkt)
454 } else {
455 return nil
456 }
457 ioinfo, err := s.identifyUniIoinfo("inside", intfid, onuid)
458 if err != nil {
459 return err
460 }
461 handle := ioinfo.handler
462 SendUni(handle, rawpkt)
463 return nil
464 }
465 log.Printf("[WARNING] Received packet is not supported")
466 return nil
467}
468
469func (s *Server) uplinkPacketOut(rawpkt gopacket.Packet) error {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900470 poppkt, _, err := PopVLAN(rawpkt)
471 poppkt, _, err = PopVLAN(poppkt)
472 if err != nil {
473 log.Println(err)
474 return err
475 }
476 ioinfo, err := s.identifyNniIoinfo("inside")
477 if err != nil {
478 return err
479 }
480 handle := ioinfo.handler
481 SendNni(handle, poppkt)
482 return nil
483}
484
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700485func (s *Server) IsAllOnuActive(regonus map[uint32][]*device.Onu) bool {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900486 for _, onus := range regonus {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900487 for _, onu := range onus {
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900488 if onu.GetIntStatus() != device.ONU_ACTIVATED {
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900489 return false
490 }
491 }
492 }
493 return true
494}
495
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900496func getGemPortID(intfid uint32, onuid uint32) (uint32, error) {
497 idx := uint32(0)
498 return 1024 + (((MAX_ONUS_PER_PON*intfid + onuid - 1) * 7) + idx), nil
499 //return uint32(1032 + 8 * (vid - 1)), nil
500}
501
502func (s *Server) getOnuBySN(sn *openolt.SerialNumber) (*device.Onu, error) {
503 for _, onus := range s.Onumap {
504 for _, onu := range onus {
505 if device.ValidateSN(*sn, *onu.SerialNumber) {
506 return onu, nil
507 }
508 }
509 }
510 err := errors.New("No mathced SN is found !")
511 log.Println(err)
512 return nil, err
513}
514
515func (s *Server) getOnuByID(onuid uint32) (*device.Onu, error) {
516 for _, onus := range s.Onumap {
517 for _, onu := range onus {
518 if onu.OnuID == onuid {
519 return onu, nil
520 }
521 }
522 }
523 err := errors.New("No matched OnuID is found !")
524 log.Println(err)
525 return nil, err
526}
527
528func makeUniName(oltid uint32, intfid uint32, onuid uint32) (upif string, dwif string) {
529 upif = setup.UNI_VETH_UP_PFX + strconv.Itoa(int(oltid)) + "_" + strconv.Itoa(int(intfid)) + "_" + strconv.Itoa(int(onuid))
530 dwif = setup.UNI_VETH_DW_PFX + strconv.Itoa(int(oltid)) + "_" + strconv.Itoa(int(intfid)) + "_" + strconv.Itoa(int(onuid))
531 return
532}
533
534func makeNniName(oltid uint32) (upif string, dwif string) {
535 upif = setup.NNI_VETH_UP_PFX + strconv.Itoa(int(oltid))
536 dwif = setup.NNI_VETH_DW_PFX + strconv.Itoa(int(oltid))
537 return
538}
539
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900540func cleanUpVeths(vethenv []string) error {
541 if len(vethenv) > 0 {
542 log.Println("cleanUp veths !")
543 setup.TearVethDown(vethenv)
544 }
545 return nil
546}
547
548func killProcesses(pnames []string) error {
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700549 for _, pname := range pnames {
Keita NISHIMOTOca4da5f2018-10-15 22:48:52 +0900550 setup.KillProcess(pname)
551 }
Keita NISHIMOTO3b8b9c02018-10-09 09:40:01 +0900552 return nil
553}
554
555func setupVethHandler(inveth string, outveth string, vethenv []string) (*pcap.Handle, []string, error) {
556 log.Printf("setupVethHandler: %s and %s\n", inveth, outveth)
557 err1 := setup.CreateVethPairs(inveth, outveth)
558 vethenv = append(vethenv, inveth)
559 if err1 != nil {
560 setup.RemoveVeths(vethenv)
561 return nil, vethenv, err1
562 }
563 handler, err2 := getVethHandler(inveth)
564 if err2 != nil {
565 setup.RemoveVeths(vethenv)
566 return nil, vethenv, err2
567 }
568 return handler, vethenv, nil
569}
570
571func getVethHandler(vethname string) (*pcap.Handle, error) {
572 var (
573 device string = vethname
574 snapshot_len int32 = 1518
575 promiscuous bool = false
576 err error
577 timeout time.Duration = pcap.BlockForever
578 )
579 handle, err := pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
580 if err != nil {
581 return nil, err
582 }
583 log.Printf("Server handle created for %s\n", vethname)
584 return handle, nil
585}
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900586
587func convB2S(b []byte) string {
588 s := ""
589 for _, i := range b {
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700590 s = s + strconv.FormatInt(int64(i/16), 16) + strconv.FormatInt(int64(i%16), 16)
Keita NISHIMOTOb8417492018-10-19 17:37:38 +0900591 }
592 return s
Matteo Scandolo4549d3f2018-10-19 12:48:20 -0700593}