Updated Adapter to support to handle DHCP trap on NNI and packet-in/out and Bug Fixing.
Tested EAPOL/DHCP/HSIA functionality E2E with EdgeCore OLT and TWSH ONU KIT.
patch: PON port is derived from platform and sent to core and bug fixes
Retested EAPOL/DHCP/HSIA use case end to end with EdgeCore OLT and TWSH ONU KIT
Change-Id: I99df82fd7a1385c10878f6fe09ce0d30c48d8e99
diff --git a/adaptercore/device_handler.go b/adaptercore/device_handler.go
index 3bb34db..866f815 100644
--- a/adaptercore/device_handler.go
+++ b/adaptercore/device_handler.go
@@ -27,6 +27,7 @@
"github.com/gogo/protobuf/proto"
"github.com/golang/protobuf/ptypes"
+ "github.com/mdlayher/ethernet"
com "github.com/opencord/voltha-go/adapters/common"
"github.com/opencord/voltha-go/common/log"
rsrcMgr "github.com/opencord/voltha-openolt-adapter/adaptercore/resourcemanager"
@@ -128,12 +129,7 @@
} else {
operStatus = voltha.OperStatus_DISCOVERED
}
- // portNum := IntfIdToPortNo(intfId,portType)
- portNum := intfId
- if portType == voltha.Port_ETHERNET_NNI {
- portNum = IntfIdToPortNo(intfId, portType)
- }
- // portNum := IntfIdToPortNo(intfId,portType)
+ portNum := IntfIdToPortNo(intfId, portType)
label := GetportLabel(portNum, portType)
if len(label) == 0 {
log.Errorw("Invalid-port-label", log.Fields{"portNum": portNum, "portType": portType})
@@ -251,6 +247,7 @@
case *oop.Indication_PktInd:
pktInd := indication.GetPktInd()
log.Infow("Received pakcet indication ", log.Fields{"PktInd": pktInd})
+ go dh.handlePacketIndication(pktInd)
case *oop.Indication_PortStats:
portStats := indication.GetPortStats()
log.Infow("Received port stats indication", log.Fields{"PortStats": portStats})
@@ -311,7 +308,7 @@
log.Errorw("Device info is nil", log.Fields{})
return errors.New("Failed to get device info from OLT")
}
-
+ log.Debugw("Fetched device info", log.Fields{"deviceInfo": deviceInfo})
dh.device.Root = true
dh.device.Vendor = deviceInfo.Vendor
dh.device.Model = deviceInfo.Model
@@ -319,7 +316,7 @@
dh.device.SerialNumber = deviceInfo.DeviceSerialNumber
dh.device.HardwareVersion = deviceInfo.HardwareVersion
dh.device.FirmwareVersion = deviceInfo.FirmwareVersion
- // TODO : Check whether this MAC address is learnt from SDPON or need to send from device
+ // FIXME: Remove Hardcodings
dh.device.MacAddress = "0a:0b:0c:0d:0e:0f"
// Synchronous call to update device - this method is run in its own go routine
@@ -394,10 +391,10 @@
func (dh *DeviceHandler) omciIndication(omciInd *oop.OmciIndication) error {
log.Debugw("omci indication", log.Fields{"intfId": omciInd.IntfId, "onuId": omciInd.OnuId})
- // ponPort := IntfIdToPortNo(omciInd.GetIntfId(),voltha.Port_PON_OLT)
+ ponPort := IntfIdToPortNo(omciInd.GetIntfId(), voltha.Port_PON_OLT)
kwargs := make(map[string]interface{})
kwargs["onu_id"] = omciInd.OnuId
- kwargs["parent_port_no"] = omciInd.GetIntfId()
+ kwargs["parent_port_no"] = ponPort
if onuDevice, err := dh.coreProxy.GetChildDevice(nil, dh.device.Id, kwargs); err != nil {
log.Errorw("onu not found", log.Fields{"intfId": omciInd.IntfId, "onuId": omciInd.OnuId})
@@ -416,7 +413,6 @@
// Process_inter_adapter_message process inter adater message
func (dh *DeviceHandler) Process_inter_adapter_message(msg *ic.InterAdapterMessage) error {
- // TODO
log.Debugw("Process_inter_adapter_message", log.Fields{"msgId": msg.Header.Id})
if msg.Header.Type == ic.InterAdapterMessageType_OMCI_REQUEST {
msgId := msg.Header.Id
@@ -462,6 +458,7 @@
func (dh *DeviceHandler) activateONU(intfId uint32, onuId int64, serialNum *oop.SerialNumber, serialNumber string) {
log.Debugw("activate-onu", log.Fields{"intfId": intfId, "onuId": onuId, "serialNum": serialNum, "serialNumber": serialNumber})
+ dh.flowMgr.UpdateOnuInfo(intfId, uint32(onuId), serialNumber)
// TODO: need resource manager
var pir uint32 = 1000000
Onu := oop.Onu{IntfId: intfId, OnuId: uint32(onuId), SerialNumber: serialNum, Pir: pir}
@@ -473,10 +470,8 @@
}
func (dh *DeviceHandler) onuDiscIndication(onuDiscInd *oop.OnuDiscIndication, onuId uint32, sn string) error {
- //channelId := MkUniPortNum(onuDiscInd.GetIntfId(), onuId, uint32(0))
- //parentPortNo := IntfIdToPortNo(onuDiscInd.GetIntfId(),voltha.Port_PON_OLT)
channelId := onuDiscInd.GetIntfId()
- parentPortNo := onuDiscInd.GetIntfId()
+ parentPortNo := IntfIdToPortNo(onuDiscInd.GetIntfId(), voltha.Port_PON_OLT)
if err := dh.coreProxy.ChildDeviceDetected(nil, dh.device.Id, int(parentPortNo), "brcm_openomci_onu", int(channelId), string(onuDiscInd.SerialNumber.GetVendorId()), sn, int64(onuId)); err != nil {
log.Errorw("Create onu error", log.Fields{"parent_id": dh.device.Id, "ponPort": onuDiscInd.GetIntfId(), "onuId": onuId, "sn": sn, "error": err})
return err
@@ -484,7 +479,7 @@
kwargs := make(map[string]interface{})
kwargs["onu_id"] = onuId
- kwargs["parent_port_no"] = onuDiscInd.GetIntfId()
+ kwargs["parent_port_no"] = parentPortNo
for i := 0; i < 10; i++ {
if onuDevice, _ := dh.coreProxy.GetChildDevice(nil, dh.device.Id, kwargs); onuDevice != nil {
@@ -503,19 +498,18 @@
serialNumber := dh.stringifySerialNumber(onuInd.SerialNumber)
kwargs := make(map[string]interface{})
- // ponPort := IntfIdToPortNo(onuInd.GetIntfId(),voltha.Port_PON_OLT)
+ ponPort := IntfIdToPortNo(onuInd.GetIntfId(), voltha.Port_PON_OLT)
if serialNumber != "" {
kwargs["serial_number"] = serialNumber
} else {
kwargs["onu_id"] = onuInd.OnuId
- kwargs["parent_port_no"] = onuInd.GetIntfId()
+ kwargs["parent_port_no"] = ponPort
}
if onuDevice, _ := dh.coreProxy.GetChildDevice(nil, dh.device.Id, kwargs); onuDevice != nil {
- //if intfIdFromPortNo(onuDevice.ParentPortNo) != onuInd.GetIntfId() {
- if onuDevice.ParentPortNo != onuInd.GetIntfId() {
+ if onuDevice.ParentPortNo != ponPort {
//log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{"previousIntfId": intfIdFromPortNo(onuDevice.ParentPortNo), "currentIntfId": onuInd.GetIntfId()})
- log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{"previousIntfId": onuDevice.ParentPortNo, "currentIntfId": onuInd.GetIntfId()})
+ log.Warnw("ONU-is-on-a-different-intf-id-now", log.Fields{"previousIntfId": onuDevice.ParentPortNo, "currentIntfId": ponPort})
}
if onuDevice.ProxyAddress.OnuId != onuInd.OnuId {
@@ -608,6 +602,15 @@
return onuDevice
}
+func (dh *DeviceHandler) SendPacketInToCore(logicalPort uint32, packetPayload []byte) {
+ log.Debugw("SendPacketInToCore", log.Fields{"port": logicalPort, "packetPayload": packetPayload})
+ if err := dh.coreProxy.SendPacketIn(nil, dh.device.Id, logicalPort, packetPayload); err != nil {
+ log.Errorw("Error sending packetin to core", log.Fields{"error": err})
+ return
+ }
+ log.Debug("Sent packet-in to core successfully")
+}
+
func (dh *DeviceHandler) UpdateFlowsIncrementally(device *voltha.Device, flows *of.FlowChanges, groups *of.FlowGroupChanges) error {
log.Debugw("In UpdateFlowsIncrementally", log.Fields{"deviceId": device.Id, "flows": flows, "groups": groups})
if flows != nil {
@@ -683,3 +686,73 @@
return nil
}
+
+func (dh *DeviceHandler) handlePacketIndication(packetIn *oop.PacketIndication) {
+ log.Debugw("Received packet-in", log.Fields{"packet-indication": *packetIn})
+ logicalPortNum, err := dh.flowMgr.GetLogicalPortFromPacketIn(packetIn)
+ if err != nil {
+ log.Errorw("Error getting logical port from packet-in", log.Fields{"error": err})
+ return
+ }
+ log.Debugw("sending packet-in to core", log.Fields{"logicalPortNum": logicalPortNum, "packet": *packetIn})
+ if err := dh.coreProxy.SendPacketIn(nil, dh.device.Id, logicalPortNum, packetIn.Pkt); err != nil {
+ log.Errorw("Error sending packet-in to core", log.Fields{"error": err})
+ return
+ }
+ log.Debug("Success sending packet-in to core!")
+}
+
+func (dh *DeviceHandler) PacketOut(egress_port_no int, packet *of.OfpPacketOut) error {
+ log.Debugw("PacketOut", log.Fields{"deviceId": dh.deviceId, "egress_port_no": egress_port_no, "pkt-length": len(packet.Data)})
+ var etherFrame ethernet.Frame
+ err := (ðerFrame).UnmarshalBinary(packet.Data)
+ if err != nil {
+ log.Errorw("Failed to unmarshal into ethernet frame", log.Fields{"err": err, "pkt-length": len(packet.Data)})
+ return err
+ }
+ log.Debugw("Ethernet Frame", log.Fields{"Frame": etherFrame})
+ egressPortType := IntfIdToPortTypeName(uint32(egress_port_no))
+ if egressPortType == voltha.Port_ETHERNET_UNI {
+ if etherFrame.VLAN != nil { // If double tag, remove the outer tag
+ nextEthType := (uint16(packet.Data[16]) << 8) | uint16(packet.Data[17])
+ if nextEthType == 0x8100 {
+ etherFrame.VLAN = nil
+ packet.Data, err = etherFrame.MarshalBinary()
+ if err != nil {
+ log.Fatalf("failed to marshal frame: %v", err)
+ return err
+ }
+ if err := (ðerFrame).UnmarshalBinary(packet.Data); err != nil {
+ log.Fatalf("failed to unmarshal frame: %v", err)
+ return err
+ }
+ log.Debug("Double tagged packet , removed outer vlan", log.Fields{"New frame": etherFrame})
+ }
+ }
+ intfId := IntfIdFromUniPortNum(uint32(egress_port_no))
+ onuId := OnuIdFromPortNum(uint32(egress_port_no))
+ uniId := UniIdFromPortNum(uint32(egress_port_no))
+ /*gemPortId, err := dh.flowMgr.GetPacketOutGemPortId(intfId, onuId, uint32(egress_port_no))
+ if err != nil{
+ log.Errorw("Error while getting gemport to packet-out",log.Fields{"error": err})
+ return err
+ }*/
+ onuPkt := oop.OnuPacket{IntfId: intfId, OnuId: onuId, PortNo: uint32(egress_port_no), Pkt: packet.Data}
+ log.Debug("sending-packet-to-ONU", log.Fields{"egress_port_no": egress_port_no, "IntfId": intfId, "onuId": onuId,
+ "uniId": uniId, "packet": packet.Data})
+ if _, err := dh.Client.OnuPacketOut(context.Background(), &onuPkt); err != nil {
+ log.Errorw("Error while sending packet-out to ONU", log.Fields{"error": err})
+ return err
+ }
+ } else if egressPortType == voltha.Port_ETHERNET_NNI {
+ uplinkPkt := oop.UplinkPacket{IntfId: IntfIdFromNniPortNum(uint32(egress_port_no)), Pkt: packet.Data}
+ log.Debug("sending-packet-to-uplink", log.Fields{"uplink_pkt": uplinkPkt})
+ if _, err := dh.Client.UplinkPacketOut(context.Background(), &uplinkPkt); err != nil {
+ log.Errorw("Error while sending packet-out to uplink", log.Fields{"error": err})
+ return err
+ }
+ } else {
+ log.Warnw("Packet-out-to-this-interface-type-not-implemented", log.Fields{"egress_port_no": egress_port_no, "egressPortType": egressPortType})
+ }
+ return nil
+}