blob: 2e785fb884a0d8d647255efdf91f71440d29ae3d [file] [log] [blame]
Matteo Scandolo47e69bb2019-08-28 15:41:12 -07001/*
Joey Armstrong2c039362024-02-04 18:51:52 -05002 * Copyright 2018-2024 Open Networking Foundation (ONF) and the ONF Contributors
Matteo Scandolo47e69bb2019-08-28 15:41:12 -07003
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 eapol
18
19import (
Matteo Scandolo40e067f2019-10-16 16:59:41 -070020 "context"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070021 "crypto/md5"
22 "errors"
Shrey Baid688b4242020-07-10 20:40:10 +053023 "net"
24
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070025 "github.com/google/gopacket"
26 "github.com/google/gopacket/layers"
27 "github.com/looplab/fsm"
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070028 bbsim "github.com/opencord/bbsim/internal/bbsim/types"
David K. Bainbridgec415efe2021-08-19 13:05:21 +000029 "github.com/opencord/voltha-protos/v5/go/openolt"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070030 log "github.com/sirupsen/logrus"
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070031)
32
33var eapolLogger = log.WithFields(log.Fields{
34 "module": "EAPOL",
35})
36
37var eapolVersion uint8 = 1
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070038
Elia Battiston536a22b2022-01-10 10:33:15 +010039// constants for the EAPOL state machine states and events
40const (
41 StateCreated = "created"
42 StateAuthStarted = "auth_started"
43 StateStartSent = "eap_start_sent"
44 StateResponseIdentitySent = "eap_response_identity_sent"
45 StateResponseChallengeSent = "eap_response_challenge_sent"
46 StateResponseSuccessReceived = "eap_response_success_received"
47 StateAuthFailed = "auth_failed"
48
49 EventStartAuth = "start_auth"
50 EventStartSent = "eap_start_sent"
51 EventResponseIdentitySent = "eap_response_identity_sent"
52 EventResponseChallengeSent = "eap_response_challenge_sent"
53 EventResponseSuccessReceived = "eap_response_success_received"
54 EventAuthFailed = "auth_failed"
55)
56
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070057func sendEapolPktIn(msg bbsim.ByteMsg, portNo uint32, gemid uint32, stream bbsim.Stream) error {
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -070058 // FIXME unify sendDHCPPktIn and sendEapolPktIn methods
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -070059
60 log.WithFields(log.Fields{
Shrey Baid688b4242020-07-10 20:40:10 +053061 "OnuId": msg.OnuId,
62 "IntfId": msg.IntfId,
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -070063 "GemPort": gemid,
Shrey Baid688b4242020-07-10 20:40:10 +053064 "Type": "EAPOL",
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -070065 }).Trace("sending-pkt")
66
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070067 data := &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{
Matteo Scandolo27428702019-10-11 16:21:16 -070068 IntfType: "pon",
69 IntfId: msg.IntfId,
70 GemportId: uint32(gemid),
71 Pkt: msg.Bytes,
72 PortNo: portNo,
Girish Gowdra62f24292021-05-12 16:28:39 -070073 OnuId: msg.OnuId,
74 UniId: 0, // FIXME: When multi-uni support comes in, this hardcoding has to be removed.
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070075 }}
76
77 if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
78 eapolLogger.Errorf("Fail to send EAPOL PktInd indication. %v", err)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070079 return err
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070080 }
Matteo Scandolo75ed5b92020-09-03 09:03:16 -070081 return nil
Matteo Scandolo47e69bb2019-08-28 15:41:12 -070082}
83
84func getMD5Data(eap *layers.EAP) []byte {
85 i := byte(eap.Id)
86 C := []byte(eap.BaseLayer.Contents)[6:]
87 P := []byte{i, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64} // "password"
88 data := md5.Sum(append(P, C...))
89 ret := make([]byte, 16)
90 for j := 0; j < 16; j++ {
91 ret[j] = data[j]
92 }
93 return ret
94}
95
Matteo Scandolo40e067f2019-10-16 16:59:41 -070096func createEAPChallengeRequest(eapId uint8, payload []byte) *layers.EAP {
97 eap := layers.EAP{
98 Code: layers.EAPCodeRequest,
99 Id: eapId,
100 Length: 22,
101 Type: layers.EAPTypeOTP,
102 TypeData: payload,
103 }
104 return &eap
105}
106
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700107func createEAPChallengeResponse(eapId uint8, payload []byte) *layers.EAP {
108 eap := layers.EAP{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700109 Code: layers.EAPCodeResponse,
110 Id: eapId,
111 Length: 22,
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700112 Type: layers.EAPTypeOTP,
113 TypeData: payload,
114 }
115 return &eap
116}
117
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700118func createEAPIdentityRequest(eapId uint8) *layers.EAP {
119 eap := layers.EAP{Code: layers.EAPCodeRequest,
120 Id: eapId,
121 Length: 9,
122 Type: layers.EAPTypeIdentity,
123 TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
124 return &eap
125}
126
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700127func createEAPIdentityResponse(eapId uint8) *layers.EAP {
128 eap := layers.EAP{Code: layers.EAPCodeResponse,
129 Id: eapId,
130 Length: 9,
131 Type: layers.EAPTypeIdentity,
132 TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
133 return &eap
134}
135
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700136func createEAPSuccess(eapId uint8) *layers.EAP {
137 eap := layers.EAP{
138 Code: layers.EAPCodeSuccess,
139 Id: eapId,
140 Length: 9,
141 Type: layers.EAPTypeNone,
142 TypeData: []byte{0x75, 0x73, 0x65, 0x72}}
143 return &eap
144}
145
Matteo Scandolo8a574812021-05-20 15:18:53 -0700146func createEAPOLPkt(eap *layers.EAP, serviceId uint32, uniId uint32, onuId uint32, intfId uint32, oltId int) []byte {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700147 buffer := gopacket.NewSerializeBuffer()
148 options := gopacket.SerializeOptions{}
149
Matteo Scandolo8a574812021-05-20 15:18:53 -0700150 mac := net.HardwareAddr{0x2e, byte(oltId), byte(intfId), byte(onuId), byte(uniId), byte(serviceId)}
151 //net.HardwareAddr{0x2e, 0x60, byte(0), byte(intfId), byte(onuId), byte(0)},
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700152 ethernetLayer := &layers.Ethernet{
Matteo Scandolo8a574812021-05-20 15:18:53 -0700153 SrcMAC: mac,
154 DstMAC: mac,
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700155 EthernetType: layers.EthernetTypeEAPOL,
156 }
157
Shrey Baid688b4242020-07-10 20:40:10 +0530158 _ = gopacket.SerializeLayers(buffer, options,
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700159 ethernetLayer,
160 &layers.EAPOL{Version: eapolVersion, Type: 0, Length: eap.Length},
161 eap,
162 )
163
164 bytes := buffer.Bytes()
165 return bytes
166}
167
168func extractEAP(pkt gopacket.Packet) (*layers.EAP, error) {
169 layerEAP := pkt.Layer(layers.LayerTypeEAP)
170 eap, _ := layerEAP.(*layers.EAP)
171 if eap == nil {
172 return nil, errors.New("Cannot extract EAP")
173 }
174 return eap, nil
175}
176
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700177func extractEAPOL(pkt gopacket.Packet) (*layers.EAPOL, error) {
178 layerEAPOL := pkt.Layer(layers.LayerTypeEAPOL)
179 eap, _ := layerEAPOL.(*layers.EAPOL)
180 if eap == nil {
181 return nil, errors.New("Cannot extract EAPOL")
182 }
183 return eap, nil
184}
185
186func sendEapolPktOut(client openolt.OpenoltClient, intfId uint32, onuId uint32, pkt []byte) error {
187 onuPacket := openolt.OnuPacket{
188 IntfId: intfId,
189 OnuId: onuId,
190 PortNo: onuId,
191 GemportId: 1,
192 Pkt: pkt,
193 }
194
195 if _, err := client.OnuPacketOut(context.Background(), &onuPacket); err != nil {
196 return err
197 }
198 return nil
199}
200
Matteo Scandolo075b1892019-10-07 12:11:07 -0700201func updateAuthFailed(onuId uint32, ponPortId uint32, serialNumber string, onuStateMachine *fsm.FSM) error {
Elia Battiston536a22b2022-01-10 10:33:15 +0100202 if err := onuStateMachine.Event(EventAuthFailed); err != nil {
Matteo Scandolo075b1892019-10-07 12:11:07 -0700203 eapolLogger.WithFields(log.Fields{
204 "OnuId": onuId,
205 "IntfId": ponPortId,
206 "OnuSn": serialNumber,
207 }).Errorf("Error while transitioning ONU State %v", err)
208 return err
209 }
210 return nil
211}
212
Matteo Scandolo8a574812021-05-20 15:18:53 -0700213func SendEapStart(onuId uint32, ponPortId uint32, serialNumber string, portNo uint32, macAddress net.HardwareAddr, gemPort uint32, uniId uint32, stateMachine *fsm.FSM, stream bbsim.Stream) error {
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700214
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700215 // TODO use createEAPOLPkt
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700216 buffer := gopacket.NewSerializeBuffer()
217 options := gopacket.SerializeOptions{}
218
219 ethernetLayer := &layers.Ethernet{
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700220 SrcMAC: macAddress,
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700221 DstMAC: net.HardwareAddr{0x01, 0x80, 0xC2, 0x00, 0x00, 0x03},
222 EthernetType: layers.EthernetTypeEAPOL,
223 }
224
Shrey Baid688b4242020-07-10 20:40:10 +0530225 _ = gopacket.SerializeLayers(buffer, options,
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700226 ethernetLayer,
227 &layers.EAPOL{Version: eapolVersion, Type: 1, Length: 0},
228 )
229
230 msg := buffer.Bytes()
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700231 // TODO end createEAPOLPkt
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700232
Matteo Scandolo8a574812021-05-20 15:18:53 -0700233 // TODO the adapter uses Onu, Uni and gemPort to route the packet,
234 // stop using PortNo to ensure consistent behavior
235 // requires voltha-protos:4.1.6
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700236 data := &openolt.Indication_PktInd{
237 PktInd: &openolt.PacketIndication{
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700238 IntfType: "pon",
239 IntfId: ponPortId,
Matteo Scandolo4a036262020-08-17 15:56:13 -0700240 GemportId: gemPort,
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700241 Pkt: msg,
Matteo Scandolo27428702019-10-11 16:21:16 -0700242 PortNo: portNo,
Girish Gowdra62f24292021-05-12 16:28:39 -0700243 OnuId: onuId,
244 UniId: uniId,
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700245 },
246 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700247
Matteo Scandolo4a036262020-08-17 15:56:13 -0700248 err := stream.Send(&openolt.Indication{Data: data})
Matteo Scandolo075b1892019-10-07 12:11:07 -0700249 if err != nil {
250 eapolLogger.WithFields(log.Fields{
Matteo Scandolo8a574812021-05-20 15:18:53 -0700251 "OnuId": onuId,
252 "IntfId": ponPortId,
253 "OnuSn": serialNumber,
254 "PortNo": portNo,
255 "UniId": uniId,
256 "GemPortId": gemPort,
Matteo Scandolo075b1892019-10-07 12:11:07 -0700257 }).Errorf("Can't send EapStart Message: %s", err)
258
Matteo Scandolo4a036262020-08-17 15:56:13 -0700259 if err := updateAuthFailed(onuId, ponPortId, serialNumber, stateMachine); err != nil {
Matteo Scandolo075b1892019-10-07 12:11:07 -0700260 return err
261 }
262 return err
263 }
264
Matteo Scandolo27428702019-10-11 16:21:16 -0700265 eapolLogger.WithFields(log.Fields{
Matteo Scandolo8a574812021-05-20 15:18:53 -0700266 "OnuId": onuId,
267 "IntfId": ponPortId,
268 "OnuSn": serialNumber,
269 "PortNo": portNo,
270 "UniId": uniId,
271 "GemPortId": gemPort,
272 }).Debug("Sent EapStart packet")
Matteo Scandolo075b1892019-10-07 12:11:07 -0700273
Elia Battiston536a22b2022-01-10 10:33:15 +0100274 if err := stateMachine.Event(EventStartSent); err != nil {
Matteo Scandolo075b1892019-10-07 12:11:07 -0700275 eapolLogger.WithFields(log.Fields{
Matteo Scandolo8a574812021-05-20 15:18:53 -0700276 "OnuId": onuId,
277 "IntfId": ponPortId,
278 "OnuSn": serialNumber,
279 "PortNo": portNo,
280 "UniId": uniId,
281 "GemPortId": gemPort,
Matteo Scandolo075b1892019-10-07 12:11:07 -0700282 }).Errorf("Error while transitioning ONU State %v", err)
Matteo Scandolo47e69bb2019-08-28 15:41:12 -0700283 return err
284 }
285 return nil
Matteo Scandolo4b3fc7e2019-09-17 16:49:54 -0700286}
Matteo Scandolo075b1892019-10-07 12:11:07 -0700287
Matteo Scandolo8a574812021-05-20 15:18:53 -0700288func HandleNextPacket(onuId uint32, ponPortId uint32, gemPortId uint32, serialNumber string, portNo uint32, uniId uint32, serviceId uint32, oltId int, stateMachine *fsm.FSM, pkt gopacket.Packet, stream bbsim.Stream, client openolt.OpenoltClient) {
289 // TODO add uni port ID and portNo to the logs
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700290 eap, eapErr := extractEAP(pkt)
291
292 eapol, eapolErr := extractEAPOL(pkt)
293
294 if eapErr != nil && eapolErr != nil {
295 log.Fatalf("Failed to Extract EAP: %v - %v", eapErr, eapolErr)
296 return
Matteo Scandolo075b1892019-10-07 12:11:07 -0700297 }
298
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700299 fields := log.Fields{}
300 if eap != nil {
301 fields = log.Fields{
302 "Code": eap.Code,
303 "Type": eap.Type,
304 "OnuId": onuId,
305 "IntfId": ponPortId,
306 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700307 "PortNo": portNo,
308 "UniId": uniId,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700309 }
310 } else if eapol != nil {
311 fields = log.Fields{
312 "Type": eapol.Type,
313 "OnuId": onuId,
314 "IntfId": ponPortId,
315 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700316 "PortNo": portNo,
317 "UniId": uniId,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700318 }
319 }
Matteo Scandolo27428702019-10-11 16:21:16 -0700320
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700321 log.WithFields(fields).Tracef("Handle Next EAPOL Packet")
322
323 if eapol != nil && eapol.Type == layers.EAPOLTypeStart {
324 identityRequest := createEAPIdentityRequest(1)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700325 pkt := createEAPOLPkt(identityRequest, serviceId, uniId, onuId, ponPortId, oltId)
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700326
327 if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
328 log.WithFields(log.Fields{
329 "OnuId": onuId,
330 "IntfId": ponPortId,
331 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700332 "PortNo": portNo,
333 "UniId": uniId,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700334 "error": err,
335 }).Errorf("Error while sending EAPIdentityRequest packet")
336 return
337 }
338
339 log.WithFields(log.Fields{
340 "OnuId": onuId,
341 "IntfId": ponPortId,
342 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700343 "PortNo": portNo,
344 "UniId": uniId,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700345 }).Infof("Sent EAPIdentityRequest packet")
346 return
347 } else if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeIdentity {
Elia Battiston536a22b2022-01-10 10:33:15 +0100348 if state := stateMachine.Current(); state != StateStartSent {
349 log.WithFields(log.Fields{
350 "OnuId": onuId,
351 "IntfId": ponPortId,
352 "OnuSn": serialNumber,
353 "PortNo": portNo,
354 "UniId": uniId,
355 }).Errorf("Received EAPIdentityRequest packet while in state %q, dropped", state)
356
357 if state := stateMachine.Current(); state != StateAuthFailed && state != StateResponseSuccessReceived {
358 _ = updateAuthFailed(onuId, ponPortId, serialNumber, stateMachine)
359 }
360 return
361 }
362
Matteo Scandolo075b1892019-10-07 12:11:07 -0700363 reseap := createEAPIdentityResponse(eap.Id)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700364 pkt := createEAPOLPkt(reseap, serviceId, uniId, onuId, ponPortId, oltId)
Matteo Scandolo075b1892019-10-07 12:11:07 -0700365
366 msg := bbsim.ByteMsg{
367 IntfId: ponPortId,
368 OnuId: onuId,
369 Bytes: pkt,
370 }
371
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700372 if err := sendEapolPktIn(msg, portNo, gemPortId, stream); err != nil {
Elia Battiston536a22b2022-01-10 10:33:15 +0100373 _ = updateAuthFailed(onuId, ponPortId, serialNumber, stateMachine)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700374 return
375 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700376 eapolLogger.WithFields(log.Fields{
377 "OnuId": onuId,
378 "IntfId": ponPortId,
379 "OnuSn": serialNumber,
Matteo Scandolo27428702019-10-11 16:21:16 -0700380 "PortNo": portNo,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700381 "UniId": uniId,
Matteo Scandolo27428702019-10-11 16:21:16 -0700382 }).Debugf("Sent EAPIdentityResponse packet")
Elia Battiston536a22b2022-01-10 10:33:15 +0100383 if err := stateMachine.Event(EventResponseIdentitySent); err != nil {
Matteo Scandolo075b1892019-10-07 12:11:07 -0700384 eapolLogger.WithFields(log.Fields{
385 "OnuId": onuId,
386 "IntfId": ponPortId,
387 "OnuSn": serialNumber,
388 }).Errorf("Error while transitioning ONU State %v", err)
389 }
390
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700391 } else if eap.Code == layers.EAPCodeResponse && eap.Type == layers.EAPTypeIdentity {
392 senddata := getMD5Data(eap)
393 senddata = append([]byte{0x10}, senddata...)
394 challengeRequest := createEAPChallengeRequest(eap.Id, senddata)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700395 pkt := createEAPOLPkt(challengeRequest, serviceId, uniId, onuId, ponPortId, oltId)
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700396
397 if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
398 log.WithFields(log.Fields{
399 "OnuId": onuId,
400 "IntfId": ponPortId,
401 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700402 "PortNo": portNo,
403 "UniId": uniId,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700404 "error": err,
405 }).Errorf("Error while sending EAPChallengeRequest packet")
406 return
407 }
408 log.WithFields(log.Fields{
409 "OnuId": onuId,
410 "IntfId": ponPortId,
411 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700412 "PortNo": portNo,
413 "UniId": uniId,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700414 }).Infof("Sent EAPChallengeRequest packet")
415 return
Matteo Scandolo075b1892019-10-07 12:11:07 -0700416 } else if eap.Code == layers.EAPCodeRequest && eap.Type == layers.EAPTypeOTP {
Elia Battiston536a22b2022-01-10 10:33:15 +0100417 if state := stateMachine.Current(); state != StateResponseIdentitySent {
418 log.WithFields(log.Fields{
419 "OnuId": onuId,
420 "IntfId": ponPortId,
421 "OnuSn": serialNumber,
422 "PortNo": portNo,
423 "UniId": uniId,
424 }).Errorf("Received EAPChallengeRequest packet while in state %q, dropped", state)
425
426 if state := stateMachine.Current(); state != StateAuthFailed && state != StateResponseSuccessReceived {
427 _ = updateAuthFailed(onuId, ponPortId, serialNumber, stateMachine)
428 }
429 return
430 }
431
Matteo Scandolo075b1892019-10-07 12:11:07 -0700432 senddata := getMD5Data(eap)
433 senddata = append([]byte{0x10}, senddata...)
434 sendeap := createEAPChallengeResponse(eap.Id, senddata)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700435 pkt := createEAPOLPkt(sendeap, serviceId, uniId, onuId, ponPortId, oltId)
Matteo Scandolo075b1892019-10-07 12:11:07 -0700436
437 msg := bbsim.ByteMsg{
438 IntfId: ponPortId,
439 OnuId: onuId,
440 Bytes: pkt,
441 }
442
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700443 if err := sendEapolPktIn(msg, portNo, gemPortId, stream); err != nil {
Elia Battiston536a22b2022-01-10 10:33:15 +0100444 _ = updateAuthFailed(onuId, ponPortId, serialNumber, stateMachine)
Matteo Scandolo75ed5b92020-09-03 09:03:16 -0700445 return
446 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700447 eapolLogger.WithFields(log.Fields{
448 "OnuId": onuId,
449 "IntfId": ponPortId,
450 "OnuSn": serialNumber,
Matteo Scandolo27428702019-10-11 16:21:16 -0700451 "PortNo": portNo,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700452 "UniId": uniId,
Matteo Scandolo27428702019-10-11 16:21:16 -0700453 }).Debugf("Sent EAPChallengeResponse packet")
Elia Battiston536a22b2022-01-10 10:33:15 +0100454 if err := stateMachine.Event(EventResponseChallengeSent); err != nil {
Matteo Scandolo075b1892019-10-07 12:11:07 -0700455 eapolLogger.WithFields(log.Fields{
456 "OnuId": onuId,
457 "IntfId": ponPortId,
458 "OnuSn": serialNumber,
459 }).Errorf("Error while transitioning ONU State %v", err)
460 }
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700461 } else if eap.Code == layers.EAPCodeResponse && eap.Type == layers.EAPTypeOTP {
462 eapSuccess := createEAPSuccess(eap.Id)
Matteo Scandolo8a574812021-05-20 15:18:53 -0700463 pkt := createEAPOLPkt(eapSuccess, serviceId, uniId, onuId, ponPortId, oltId)
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700464
465 if err := sendEapolPktOut(client, ponPortId, onuId, pkt); err != nil {
466 log.WithFields(log.Fields{
467 "OnuId": onuId,
468 "IntfId": ponPortId,
469 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700470 "PortNo": portNo,
471 "UniId": uniId,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700472 "error": err,
473 }).Errorf("Error while sending EAPSuccess packet")
474 return
475 }
476
477 log.WithFields(log.Fields{
478 "OnuId": onuId,
479 "IntfId": ponPortId,
480 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700481 "PortNo": portNo,
482 "UniId": uniId,
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700483 }).Infof("Sent EAP Success packet")
484
Matteo Scandolo4a036262020-08-17 15:56:13 -0700485 if err := stateMachine.Event("send_dhcp_flow"); err != nil {
Matteo Scandolo40e067f2019-10-16 16:59:41 -0700486 eapolLogger.WithFields(log.Fields{
487 "OnuId": onuId,
488 "IntfId": ponPortId,
489 "OnuSn": serialNumber,
490 }).Errorf("Error while transitioning ONU State %v", err)
491 }
Matteo Scandolo075b1892019-10-07 12:11:07 -0700492 } else if eap.Code == layers.EAPCodeSuccess && eap.Type == layers.EAPTypeNone {
Elia Battiston536a22b2022-01-10 10:33:15 +0100493 if state := stateMachine.Current(); state != StateResponseChallengeSent {
494 log.WithFields(log.Fields{
495 "OnuId": onuId,
496 "IntfId": ponPortId,
497 "OnuSn": serialNumber,
498 "PortNo": portNo,
499 "UniId": uniId,
500 }).Errorf("Received EAP Success packet while in state %q, dropped", state)
501
502 if state := stateMachine.Current(); state != StateAuthFailed && state != StateResponseSuccessReceived {
503 _ = updateAuthFailed(onuId, ponPortId, serialNumber, stateMachine)
504 }
505 return
506 }
507
Matteo Scandolo075b1892019-10-07 12:11:07 -0700508 eapolLogger.WithFields(log.Fields{
509 "OnuId": onuId,
510 "IntfId": ponPortId,
511 "OnuSn": serialNumber,
Matteo Scandolo27428702019-10-11 16:21:16 -0700512 "PortNo": portNo,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700513 "UniId": uniId,
Matteo Scandolo27428702019-10-11 16:21:16 -0700514 }).Debugf("Received EAPSuccess packet")
Elia Battiston536a22b2022-01-10 10:33:15 +0100515 if err := stateMachine.Event(EventResponseSuccessReceived); err != nil {
Matteo Scandolo075b1892019-10-07 12:11:07 -0700516 eapolLogger.WithFields(log.Fields{
517 "OnuId": onuId,
518 "IntfId": ponPortId,
519 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700520 "PortNo": portNo,
521 "UniId": uniId,
Matteo Scandolo075b1892019-10-07 12:11:07 -0700522 }).Errorf("Error while transitioning ONU State %v", err)
523 }
524 eapolLogger.WithFields(log.Fields{
525 "OnuId": onuId,
526 "IntfId": ponPortId,
527 "OnuSn": serialNumber,
Matteo Scandolo8a574812021-05-20 15:18:53 -0700528 "PortNo": portNo,
529 "UniId": uniId,
Matteo Scandolo075b1892019-10-07 12:11:07 -0700530 }).Infof("EAPOL State machine completed")
531 return
532 }
533}