blob: 4391414ad55c6ef2e18ecd86f774894f2e0e265e [file] [log] [blame]
Matteo Scandolo4a036262020-08-17 15:56:13 -07001/*
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 devices
18
19import (
Matteo Scandolo618a6582020-09-09 12:21:29 -070020 "encoding/hex"
Matteo Scandolo4a036262020-08-17 15:56:13 -070021 "github.com/looplab/fsm"
22 "github.com/opencord/bbsim/internal/bbsim/packetHandlers"
23 "github.com/opencord/bbsim/internal/bbsim/responders/dhcp"
24 "github.com/opencord/bbsim/internal/bbsim/responders/eapol"
Matteo Scandolo618a6582020-09-09 12:21:29 -070025 "github.com/opencord/bbsim/internal/bbsim/responders/igmp"
Matteo Scandolo4a036262020-08-17 15:56:13 -070026 bbsimTypes "github.com/opencord/bbsim/internal/bbsim/types"
Matteo Scandolo76c3ff62020-09-24 18:03:01 -070027 "github.com/opencord/bbsim/internal/common"
Matteo Scandolo4a036262020-08-17 15:56:13 -070028 log "github.com/sirupsen/logrus"
29 "net"
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -070030 "time"
Matteo Scandolo4a036262020-08-17 15:56:13 -070031)
32
33var serviceLogger = log.WithFields(log.Fields{
34 "module": "SERVICE",
35})
36
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -070037// time to wait before fail EAPOL/DHCP
38// (it's a variable and not a constant so it can be overridden in the tests)
Matteo Scandolo24a88c42020-09-17 14:55:28 -070039var eapolWaitTime = 60 * time.Second
40var dhcpWaitTime = 60 * time.Second
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -070041
Matteo Scandolo4a036262020-08-17 15:56:13 -070042type ServiceIf interface {
Matteo Scandolobd875b32020-09-18 17:46:31 -070043 HandlePackets() // start listening on the PacketCh
44 HandleAuth() // Sends the EapoStart packet
45 HandleDhcp(pbit uint8, cTag int) // Sends the DHCPDiscover packet
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070046
Matteo Scandoloadc72a82020-09-08 18:46:08 -070047 Initialize(stream bbsimTypes.Stream)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070048 Disable()
Matteo Scandolo4a036262020-08-17 15:56:13 -070049}
50
51type Service struct {
52 Name string
53 HwAddress net.HardwareAddr
54 Onu *Onu
55 CTag int
56 STag int
57 NeedsEapol bool
58 NeedsDhcp bool
59 NeedsIgmp bool
60 TechnologyProfileID int
61 UniTagMatch int
62 ConfigureMacAddress bool
Matteo Scandolo8d281372020-09-03 16:23:37 -070063 UsPonCTagPriority uint8
64 UsPonSTagPriority uint8
65 DsPonCTagPriority uint8
66 DsPonSTagPriority uint8
Matteo Scandolo4a036262020-08-17 15:56:13 -070067
68 // state
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070069 GemPort uint32
70 InternalState *fsm.FSM
71 EapolState *fsm.FSM
72 DHCPState *fsm.FSM
Matteo Scandolo618a6582020-09-09 12:21:29 -070073 IGMPState *fsm.FSM
Matteo Scandolof9d43412021-01-12 11:11:34 -080074 Channel chan bbsimTypes.Message // drive Service lifecycle
75 PacketCh chan bbsimTypes.OnuPacketMessage // handle packets
76 Stream bbsimTypes.Stream // the gRPC stream to communicate with the adapter, created in the initialize transition
Matteo Scandolo4a036262020-08-17 15:56:13 -070077}
78
79func NewService(name string, hwAddress net.HardwareAddr, onu *Onu, cTag int, sTag int,
80 needsEapol bool, needsDchp bool, needsIgmp bool, tpID int, uniTagMatch int, configMacAddress bool,
Matteo Scandolo8d281372020-09-03 16:23:37 -070081 usPonCTagPriority uint8, usPonSTagPriority uint8, dsPonCTagPriority uint8, dsPonSTagPriority uint8) (*Service, error) {
Matteo Scandolo4a036262020-08-17 15:56:13 -070082
83 service := Service{
84 Name: name,
85 HwAddress: hwAddress,
86 Onu: onu,
87 CTag: cTag,
88 STag: sTag,
89 NeedsEapol: needsEapol,
90 NeedsDhcp: needsDchp,
91 NeedsIgmp: needsIgmp,
92 TechnologyProfileID: tpID,
93 UniTagMatch: uniTagMatch,
94 ConfigureMacAddress: configMacAddress,
95 UsPonCTagPriority: usPonCTagPriority,
96 UsPonSTagPriority: usPonSTagPriority,
97 DsPonCTagPriority: dsPonCTagPriority,
98 DsPonSTagPriority: dsPonSTagPriority,
Matteo Scandolo4a036262020-08-17 15:56:13 -070099 }
100
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700101 service.InternalState = fsm.NewFSM(
102 "created",
103 fsm.Events{
104 {Name: "initialized", Src: []string{"created", "disabled"}, Dst: "initialized"},
105 {Name: "disabled", Src: []string{"initialized"}, Dst: "disabled"},
106 },
107 fsm.Callbacks{
108 "enter_state": func(e *fsm.Event) {
109 service.logStateChange("InternalState", e.Src, e.Dst)
110 },
111 "enter_initialized": func(e *fsm.Event) {
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700112
113 stream, ok := e.Args[0].(bbsimTypes.Stream)
114 if !ok {
115 serviceLogger.Fatal("initialize invoke with wrong arguments")
116 }
117
118 service.Stream = stream
119
Matteo Scandolof9d43412021-01-12 11:11:34 -0800120 service.PacketCh = make(chan bbsimTypes.OnuPacketMessage)
121 service.Channel = make(chan bbsimTypes.Message)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700122
123 go service.HandlePackets()
124 go service.HandleChannel()
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700125 },
126 "enter_disabled": func(e *fsm.Event) {
127 // reset the state machines
128 service.EapolState.SetState("created")
129 service.DHCPState.SetState("created")
130
131 // stop listening for packets
132 close(service.PacketCh)
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700133 close(service.Channel)
134
135 service.PacketCh = nil
136 service.Channel = nil
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700137 },
138 },
139 )
140
Matteo Scandolo4a036262020-08-17 15:56:13 -0700141 service.EapolState = fsm.NewFSM(
142 "created",
143 fsm.Events{
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700144 {Name: "start_auth", Src: []string{"created", "eap_response_success_received", "auth_failed"}, Dst: "auth_started"},
Matteo Scandolo4a036262020-08-17 15:56:13 -0700145 {Name: "eap_start_sent", Src: []string{"auth_started"}, Dst: "eap_start_sent"},
146 {Name: "eap_response_identity_sent", Src: []string{"eap_start_sent"}, Dst: "eap_response_identity_sent"},
147 {Name: "eap_response_challenge_sent", Src: []string{"eap_response_identity_sent"}, Dst: "eap_response_challenge_sent"},
148 {Name: "eap_response_success_received", Src: []string{"eap_response_challenge_sent"}, Dst: "eap_response_success_received"},
149 {Name: "auth_failed", Src: []string{"auth_started", "eap_start_sent", "eap_response_identity_sent", "eap_response_challenge_sent"}, Dst: "auth_failed"},
150 },
151 fsm.Callbacks{
152 "enter_state": func(e *fsm.Event) {
153 service.logStateChange("EapolState", e.Src, e.Dst)
154 },
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700155 "before_start_auth": func(e *fsm.Event) {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800156 msg := bbsimTypes.Message{
157 Type: bbsimTypes.StartEAPOL,
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700158 }
159 service.Channel <- msg
160 },
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700161 "enter_auth_started": func(e *fsm.Event) {
162 go func() {
163
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700164 for {
165 select {
166 case <-service.Onu.PonPort.Olt.enableContext.Done():
167 // if the OLT is disabled, then cancel
Matteo Scandolo6e7afb02020-09-24 11:32:18 -0700168 return
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700169 case <-time.After(eapolWaitTime):
170 if service.EapolState.Current() != "eap_response_success_received" {
171 serviceLogger.WithFields(log.Fields{
172 "OnuId": service.Onu.ID,
173 "IntfId": service.Onu.PonPortID,
174 "OnuSn": service.Onu.Sn(),
175 "Name": service.Name,
176 "EapolState": service.EapolState.Current(),
177 }).Warn("EAPOL failed, resetting EAPOL State")
Matteo Scandolo76c3ff62020-09-24 18:03:01 -0700178
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700179 _ = service.EapolState.Event("auth_failed")
Matteo Scandolo76c3ff62020-09-24 18:03:01 -0700180 if common.Config.BBSim.AuthRetry {
181 _ = service.EapolState.Event("start_auth")
182 }
183
Matteo Scandolo6e7afb02020-09-24 11:32:18 -0700184 return
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700185 }
186 }
187
188 }
189 }()
190 },
Matteo Scandolo4a036262020-08-17 15:56:13 -0700191 },
192 )
193
194 service.DHCPState = fsm.NewFSM(
195 "created",
196 fsm.Events{
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700197 // TODO only allow transitions to dhcp_start from success or failure, not in-between states
198 // TODO forcefully fail DHCP if we don't get an ack in X seconds
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700199 {Name: "start_dhcp", Src: []string{"created", "dhcp_ack_received", "dhcp_failed"}, Dst: "dhcp_started"},
Matteo Scandolo4a036262020-08-17 15:56:13 -0700200 {Name: "dhcp_discovery_sent", Src: []string{"dhcp_started"}, Dst: "dhcp_discovery_sent"},
201 {Name: "dhcp_request_sent", Src: []string{"dhcp_discovery_sent"}, Dst: "dhcp_request_sent"},
202 {Name: "dhcp_ack_received", Src: []string{"dhcp_request_sent"}, Dst: "dhcp_ack_received"},
203 {Name: "dhcp_failed", Src: []string{"dhcp_started", "dhcp_discovery_sent", "dhcp_request_sent"}, Dst: "dhcp_failed"},
204 },
205 fsm.Callbacks{
206 "enter_state": func(e *fsm.Event) {
207 service.logStateChange("DHCPState", e.Src, e.Dst)
208 },
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700209 "before_start_dhcp": func(e *fsm.Event) {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800210 msg := bbsimTypes.Message{
211 Type: bbsimTypes.StartDHCP,
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700212 }
213 service.Channel <- msg
214 },
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700215 "enter_dhcp_started": func(e *fsm.Event) {
216 go func() {
217
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700218 for {
219 select {
220 case <-service.Onu.PonPort.Olt.enableContext.Done():
221 // if the OLT is disabled, then cancel
Matteo Scandolo6e7afb02020-09-24 11:32:18 -0700222 return
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700223 case <-time.After(dhcpWaitTime):
224 if service.DHCPState.Current() != "dhcp_ack_received" {
225 serviceLogger.WithFields(log.Fields{
226 "OnuId": service.Onu.ID,
227 "IntfId": service.Onu.PonPortID,
228 "OnuSn": service.Onu.Sn(),
229 "Name": service.Name,
230 "DHCPState": service.DHCPState.Current(),
231 }).Warn("DHCP failed, resetting DHCP State")
Matteo Scandolo76c3ff62020-09-24 18:03:01 -0700232
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700233 _ = service.DHCPState.Event("dhcp_failed")
Matteo Scandolo76c3ff62020-09-24 18:03:01 -0700234 if common.Config.BBSim.DhcpRetry {
235 _ = service.DHCPState.Event("start_dhcp")
236 }
237
Matteo Scandolo6e7afb02020-09-24 11:32:18 -0700238 return
Matteo Scandoloe9f5a6b2020-09-16 15:54:38 -0700239 }
240 }
241
242 }
243 }()
244 },
Matteo Scandolo4a036262020-08-17 15:56:13 -0700245 },
246 )
247
Matteo Scandolo618a6582020-09-09 12:21:29 -0700248 service.IGMPState = fsm.NewFSM(
249 "created",
250 fsm.Events{
251 {Name: "igmp_join_start", Src: []string{"created", "igmp_left", "igmp_join_error", "igmp_join_started"}, Dst: "igmp_join_started"},
252 {Name: "igmp_join_startv3", Src: []string{"igmp_left", "igmp_join_error", "igmp_join_started"}, Dst: "igmp_join_started"},
253 {Name: "igmp_join_error", Src: []string{"igmp_join_started"}, Dst: "igmp_join_error"},
254 {Name: "igmp_leave", Src: []string{"igmp_join_started"}, Dst: "igmp_left"},
255 },
256 fsm.Callbacks{
257 "igmp_join_start": func(e *fsm.Event) {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800258 igmpInfo, _ := e.Args[0].(bbsimTypes.IgmpMessage)
259 msg := bbsimTypes.Message{
260 Type: bbsimTypes.IGMPMembershipReportV2,
261 Data: bbsimTypes.IgmpMessage{
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000262 GroupAddress: igmpInfo.GroupAddress,
263 },
Matteo Scandolo618a6582020-09-09 12:21:29 -0700264 }
265 service.Channel <- msg
266 },
267 "igmp_leave": func(e *fsm.Event) {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800268 igmpInfo, _ := e.Args[0].(bbsimTypes.IgmpMessage)
269 msg := bbsimTypes.Message{
270 Type: bbsimTypes.IGMPLeaveGroup,
271 Data: bbsimTypes.IgmpMessage{
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000272 GroupAddress: igmpInfo.GroupAddress,
273 },
274 }
Matteo Scandolo618a6582020-09-09 12:21:29 -0700275 service.Channel <- msg
276 },
277 "igmp_join_startv3": func(e *fsm.Event) {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800278 igmpInfo, _ := e.Args[0].(bbsimTypes.IgmpMessage)
279 msg := bbsimTypes.Message{
280 Type: bbsimTypes.IGMPMembershipReportV3,
281 Data: bbsimTypes.IgmpMessage{
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000282 GroupAddress: igmpInfo.GroupAddress,
283 },
Matteo Scandolo618a6582020-09-09 12:21:29 -0700284 }
285 service.Channel <- msg
286 },
287 },
288 )
289
Matteo Scandolo4a036262020-08-17 15:56:13 -0700290 return &service, nil
291}
292
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700293// HandleAuth is used to start EAPOL for a particular Service when the corresponding flow is received
294func (s *Service) HandleAuth() {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700295
296 if !s.NeedsEapol {
297 serviceLogger.WithFields(log.Fields{
298 "OnuId": s.Onu.ID,
299 "IntfId": s.Onu.PonPortID,
300 "OnuSn": s.Onu.Sn(),
301 "Name": s.Name,
302 "NeedsEapol": s.NeedsEapol,
303 }).Debug("Won't start authentication as EAPOL is not required")
304 return
305 }
306
Matteo Scandolo4a036262020-08-17 15:56:13 -0700307 if err := s.EapolState.Event("start_auth"); err != nil {
308 serviceLogger.WithFields(log.Fields{
309 "OnuId": s.Onu.ID,
310 "IntfId": s.Onu.PonPortID,
311 "OnuSn": s.Onu.Sn(),
312 "Name": s.Name,
313 "err": err.Error(),
314 }).Error("Can't start auth for this Service")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700315 }
316}
317
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700318// HandleDhcp is used to start DHCP for a particular Service when the corresponding flow is received
Matteo Scandolobd875b32020-09-18 17:46:31 -0700319func (s *Service) HandleDhcp(pbit uint8, cTag int) {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700320
Matteo Scandolobd875b32020-09-18 17:46:31 -0700321 if s.CTag != cTag || (s.UsPonCTagPriority != pbit && pbit != 255) {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700322 serviceLogger.WithFields(log.Fields{
323 "OnuId": s.Onu.ID,
324 "IntfId": s.Onu.PonPortID,
325 "OnuSn": s.Onu.Sn(),
326 "Name": s.Name,
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700327 }).Trace("DHCP flow is not for this service, ignoring")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700328 return
329 }
330
Matteo Scandolo4a036262020-08-17 15:56:13 -0700331 if !s.NeedsDhcp {
332 serviceLogger.WithFields(log.Fields{
333 "OnuId": s.Onu.ID,
334 "IntfId": s.Onu.PonPortID,
335 "OnuSn": s.Onu.Sn(),
336 "Name": s.Name,
337 "NeedsDhcp": s.NeedsDhcp,
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700338 }).Trace("Won't start DHCP as it is not required")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700339 return
340 }
341
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700342 // TODO check if the DHCP flow was received before starting auth
Matteo Scandolo4a036262020-08-17 15:56:13 -0700343
344 if err := s.DHCPState.Event("start_dhcp"); err != nil {
345 serviceLogger.WithFields(log.Fields{
346 "OnuId": s.Onu.ID,
347 "IntfId": s.Onu.PonPortID,
348 "OnuSn": s.Onu.Sn(),
349 "Name": s.Name,
350 "err": err.Error(),
351 }).Error("Can't start DHCP for this Service")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700352 }
353}
354
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700355func (s *Service) HandlePackets() {
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700356 serviceLogger.WithFields(log.Fields{
357 "OnuId": s.Onu.ID,
358 "IntfId": s.Onu.PonPortID,
359 "OnuSn": s.Onu.Sn(),
360 "GemPortId": s.GemPort,
361 "Name": s.Name,
362 }).Debug("Listening on Service Packet Channel")
363
364 defer func() {
365 serviceLogger.WithFields(log.Fields{
366 "OnuId": s.Onu.ID,
367 "IntfId": s.Onu.PonPortID,
368 "OnuSn": s.Onu.Sn(),
369 "GemPortId": s.GemPort,
370 "Name": s.Name,
371 }).Debug("Done Listening on Service Packet Channel")
372 }()
373
374 for msg := range s.PacketCh {
375 serviceLogger.WithFields(log.Fields{
376 "OnuId": s.Onu.ID,
377 "IntfId": s.Onu.PonPortID,
378 "OnuSn": s.Onu.Sn(),
379 "Name": s.Name,
380 "messageType": msg.Type,
Matteo Scandolo7f656fb2020-09-08 15:18:15 -0700381 }).Trace("Received message on Service Packet Channel")
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700382
383 if msg.Type == packetHandlers.EAPOL {
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700384 eapol.HandleNextPacket(msg.OnuId, msg.IntfId, s.GemPort, s.Onu.Sn(), s.Onu.PortNo, s.EapolState, msg.Packet, s.Stream, nil)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700385 } else if msg.Type == packetHandlers.DHCP {
Matteo Scandolo24a88c42020-09-17 14:55:28 -0700386 _ = dhcp.HandleNextPacket(s.Onu.ID, s.Onu.PonPortID, s.Name, s.Onu.Sn(), s.Onu.PortNo, s.CTag, s.GemPort, s.HwAddress, s.DHCPState, msg.Packet, s.UsPonCTagPriority, s.Stream)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700387 } else if msg.Type == packetHandlers.IGMP {
388 log.Warn(hex.EncodeToString(msg.Packet.Data()))
389 _ = igmp.HandleNextPacket(s.Onu.PonPortID, s.Onu.ID, s.Onu.Sn(), s.Onu.PortNo, s.GemPort, s.HwAddress, msg.Packet, s.CTag, s.UsPonCTagPriority, s.Stream)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700390 }
391 }
392}
393
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700394func (s *Service) HandleChannel() {
395 serviceLogger.WithFields(log.Fields{
396 "OnuId": s.Onu.ID,
397 "IntfId": s.Onu.PonPortID,
398 "OnuSn": s.Onu.Sn(),
399 "GemPortId": s.GemPort,
400 "Name": s.Name,
401 }).Debug("Listening on Service Channel")
402
403 defer func() {
404 serviceLogger.WithFields(log.Fields{
405 "OnuId": s.Onu.ID,
406 "IntfId": s.Onu.PonPortID,
407 "OnuSn": s.Onu.Sn(),
408 "GemPortId": s.GemPort,
409 "Name": s.Name,
410 }).Debug("Done Listening on Service Channel")
411 }()
412 for msg := range s.Channel {
Matteo Scandolo618a6582020-09-09 12:21:29 -0700413 switch msg.Type {
Matteo Scandolof9d43412021-01-12 11:11:34 -0800414 case bbsimTypes.StartEAPOL:
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700415 if err := s.handleEapolStart(s.Stream); err != nil {
416 serviceLogger.WithFields(log.Fields{
417 "OnuId": s.Onu.ID,
418 "IntfId": s.Onu.PonPortID,
419 "OnuSn": s.Onu.Sn(),
420 "Name": s.Name,
421 "err": err,
422 }).Error("Error while sending EapolStart packet")
423 _ = s.EapolState.Event("auth_failed")
424 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800425 case bbsimTypes.StartDHCP:
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700426 if err := s.handleDHCPStart(s.Stream); err != nil {
427 serviceLogger.WithFields(log.Fields{
428 "OnuId": s.Onu.ID,
429 "IntfId": s.Onu.PonPortID,
430 "OnuSn": s.Onu.Sn(),
431 "Name": s.Name,
432 "err": err,
433 }).Error("Error while sending DHCPDiscovery packet")
434 _ = s.DHCPState.Event("dhcp_failed")
Matteo Scandolo618a6582020-09-09 12:21:29 -0700435
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700436 }
Matteo Scandolof9d43412021-01-12 11:11:34 -0800437 case bbsimTypes.IGMPMembershipReportV2:
438 igmpInfo, _ := msg.Data.(bbsimTypes.IgmpMessage)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700439 serviceLogger.WithFields(log.Fields{
440 "OnuId": s.Onu.ID,
441 "IntfId": s.Onu.PonPortID,
442 "OnuSn": s.Onu.Sn(),
443 "Name": s.Name,
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000444 }).Debug("Received IGMPMembershipReportV2 message on ONU channel")
445 _ = igmp.SendIGMPMembershipReportV2(s.Onu.PonPortID, s.Onu.ID, s.Onu.Sn(), s.Onu.PortNo, s.GemPort, s.HwAddress, s.CTag, s.UsPonCTagPriority, s.Stream, igmpInfo.GroupAddress)
Matteo Scandolof9d43412021-01-12 11:11:34 -0800446 case bbsimTypes.IGMPLeaveGroup:
447 igmpInfo, _ := msg.Data.(bbsimTypes.IgmpMessage)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700448 serviceLogger.WithFields(log.Fields{
449 "OnuId": s.Onu.ID,
450 "IntfId": s.Onu.PonPortID,
451 "OnuSn": s.Onu.Sn(),
452 "Name": s.Name,
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000453 }).Debug("Received IGMPLeaveGroupV2 message on ONU channel")
454 _ = igmp.SendIGMPLeaveGroupV2(s.Onu.PonPortID, s.Onu.ID, s.Onu.Sn(), s.Onu.PortNo, s.GemPort, s.HwAddress, s.CTag, s.UsPonCTagPriority, s.Stream, igmpInfo.GroupAddress)
Matteo Scandolof9d43412021-01-12 11:11:34 -0800455 case bbsimTypes.IGMPMembershipReportV3:
456 igmpInfo, _ := msg.Data.(bbsimTypes.IgmpMessage)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700457 serviceLogger.WithFields(log.Fields{
458 "OnuId": s.Onu.ID,
459 "IntfId": s.Onu.PonPortID,
460 "OnuSn": s.Onu.Sn(),
461 "Name": s.Name,
Onur Kalinagac9f9faca2021-01-21 14:04:34 +0000462 }).Debug("Received IGMPMembershipReportV3 message on ONU channel")
463 _ = igmp.SendIGMPMembershipReportV3(s.Onu.PonPortID, s.Onu.ID, s.Onu.Sn(), s.Onu.PortNo, s.GemPort, s.HwAddress, s.CTag, s.UsPonCTagPriority, s.Stream, igmpInfo.GroupAddress)
Matteo Scandolo618a6582020-09-09 12:21:29 -0700464
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700465 }
466 }
467}
468
469func (s *Service) Initialize(stream bbsimTypes.Stream) {
470 if err := s.InternalState.Event("initialized", stream); err != nil {
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700471 serviceLogger.WithFields(log.Fields{
472 "OnuId": s.Onu.ID,
473 "IntfId": s.Onu.PonPortID,
474 "OnuSn": s.Onu.Sn(),
475 "Name": s.Name,
476 "Err": err,
477 }).Error("Cannot initialize service")
478 }
479}
480
481func (s *Service) Disable() {
482 if err := s.InternalState.Event("disabled"); err != nil {
483 serviceLogger.WithFields(log.Fields{
484 "OnuId": s.Onu.ID,
485 "IntfId": s.Onu.PonPortID,
486 "OnuSn": s.Onu.Sn(),
487 "Name": s.Name,
488 "Err": err,
489 }).Error("Cannot disable service")
490 }
491}
492
Matteo Scandolo4a036262020-08-17 15:56:13 -0700493func (s *Service) handleEapolStart(stream bbsimTypes.Stream) error {
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700494 // TODO fail Auth if it does not succeed in 30 seconds
Matteo Scandolo4a036262020-08-17 15:56:13 -0700495 serviceLogger.WithFields(log.Fields{
496 "OnuId": s.Onu.ID,
497 "IntfId": s.Onu.PonPortID,
498 "OnuSn": s.Onu.Sn(),
499 "GemPort": s.GemPort,
500 "Name": s.Name,
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700501 }).Trace("handleEapolStart")
Matteo Scandolo4a036262020-08-17 15:56:13 -0700502
503 if err := eapol.SendEapStart(s.Onu.ID, s.Onu.PonPortID, s.Onu.Sn(), s.Onu.PortNo,
504 s.HwAddress, s.GemPort, s.EapolState, stream); err != nil {
505 serviceLogger.WithFields(log.Fields{
506 "OnuId": s.Onu.ID,
507 "IntfId": s.Onu.PonPortID,
508 "OnuSn": s.Onu.Sn(),
509 "GemPort": s.GemPort,
510 "Name": s.Name,
511 }).Error("handleEapolStart")
512 return err
513 }
514 return nil
515}
516
517func (s *Service) handleDHCPStart(stream bbsimTypes.Stream) error {
Matteo Scandoloadc72a82020-09-08 18:46:08 -0700518 // TODO fail DHCP if it does not succeed in 30 seconds
Matteo Scandolo4a036262020-08-17 15:56:13 -0700519 serviceLogger.WithFields(log.Fields{
520 "OnuId": s.Onu.ID,
521 "IntfId": s.Onu.PonPortID,
522 "OnuSn": s.Onu.Sn(),
523 "Name": s.Name,
524 "GemPortId": s.GemPort,
525 }).Debugf("HandleDHCPStart")
526
Matteo Scandolo24a88c42020-09-17 14:55:28 -0700527 if err := dhcp.SendDHCPDiscovery(s.Onu.PonPortID, s.Onu.ID, s.Name, int(s.CTag), s.GemPort,
Matteo Scandolo8d281372020-09-03 16:23:37 -0700528 s.Onu.Sn(), s.Onu.PortNo, s.DHCPState, s.HwAddress, s.UsPonCTagPriority, stream); err != nil {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700529 serviceLogger.WithFields(log.Fields{
530 "OnuId": s.Onu.ID,
531 "IntfId": s.Onu.PonPortID,
532 "OnuSn": s.Onu.Sn(),
533 "Name": s.Name,
534 "GemPortId": s.GemPort,
535 }).Error("HandleDHCPStart")
536 return err
537 }
538 return nil
539}
540
Matteo Scandolo4a036262020-08-17 15:56:13 -0700541func (s *Service) logStateChange(stateMachine string, src string, dst string) {
542 serviceLogger.WithFields(log.Fields{
543 "OnuId": s.Onu.ID,
544 "IntfId": s.Onu.PonPortID,
545 "OnuSn": s.Onu.Sn(),
546 "Name": s.Name,
547 }).Debugf("Changing Service.%s InternalState from %s to %s", stateMachine, src, dst)
548}