[VOL-2890] Using unique MacAddresses for different OLTs

Change-Id: Idf2bf9b0b9712a8dfafc96ecc802deded79bdbad
diff --git a/internal/bbsim/devices/onu.go b/internal/bbsim/devices/onu.go
index 3763429..56fba07 100644
--- a/internal/bbsim/devices/onu.go
+++ b/internal/bbsim/devices/onu.go
@@ -98,7 +98,7 @@
 		CTag:                cTag,
 		Auth:                auth,
 		Dhcp:                dhcp,
-		HwAddress:           net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, byte(pon.ID), byte(id)},
+		HwAddress:           net.HardwareAddr{0x2e, 0x60, 0x70, byte(olt.ID), byte(pon.ID), byte(id)},
 		PortNo:              0,
 		tid:                 0x1,
 		hpTid:               0x8000,
@@ -359,7 +359,7 @@
 			case StartDHCP:
 				log.Infof("Receive StartDHCP message on ONU Channel")
 				// FIXME use id, ponId as SendEapStart
-				dhcp.SendDHCPDiscovery(o.PonPortID, o.ID, o.Sn(), o.PortNo, o.InternalState, o.HwAddress, o.CTag, stream)
+				dhcp.SendDHCPDiscovery(o.PonPort.Olt.ID, o.PonPortID, o.ID, o.Sn(), o.PortNo, o.InternalState, o.HwAddress, o.CTag, stream)
 			case OnuPacketOut:
 
 				msg, _ := message.Data.(OnuPacketMessage)
@@ -375,7 +375,7 @@
 				} else if msg.Type == packetHandlers.DHCP {
 					// NOTE here we receive packets going from the DHCP Server to the ONU
 					// for now we expect them to be double-tagged, but ideally the should be single tagged
-					dhcp.HandleNextPacket(o.ID, o.PonPortID, o.Sn(), o.PortNo, o.HwAddress, o.CTag, o.InternalState, msg.Packet, stream)
+					dhcp.HandleNextPacket(o.PonPort.Olt.ID, o.ID, o.PonPortID, o.Sn(), o.PortNo, o.HwAddress, o.CTag, o.InternalState, msg.Packet, stream)
 				}
 			case OnuPacketIn:
 				// NOTE we only receive BBR packets here.
diff --git a/internal/bbsim/devices/onu_test.go b/internal/bbsim/devices/onu_test.go
new file mode 100644
index 0000000..6d4804c
--- /dev/null
+++ b/internal/bbsim/devices/onu_test.go
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package devices
+
+import (
+	"gotest.tools/assert"
+	"testing"
+)
+
+func Test_Onu_CreateOnu(t *testing.T) {
+
+	olt := OltDevice{
+		ID: 0,
+	}
+	pon := PonPort{
+		ID:  1,
+		Olt: &olt,
+	}
+
+	onu := CreateONU(&olt, pon, 1, 900, 900, true, false,0,false)
+
+	assert.Equal(t, onu.Sn(), "BBSM00000101")
+	assert.Equal(t, onu.STag, 900)
+	assert.Equal(t, onu.CTag, 900)
+	assert.Equal(t, onu.Auth, true)
+	assert.Equal(t, onu.Dhcp, false)
+	assert.Equal(t, onu.HwAddress.String(), "2e:60:70:00:01:01")
+}
\ No newline at end of file
diff --git a/internal/bbsim/responders/dhcp/dhcp.go b/internal/bbsim/responders/dhcp/dhcp.go
index c7db7eb..628084b 100644
--- a/internal/bbsim/responders/dhcp/dhcp.go
+++ b/internal/bbsim/responders/dhcp/dhcp.go
@@ -55,12 +55,12 @@
 	layers.DHCPOptNTPServers,
 }
 
-func createDefaultDHCPReq(intfId uint32, onuId uint32, mac net.HardwareAddr) layers.DHCPv4 {
+func createDefaultDHCPReq(oltId int, intfId uint32, onuId uint32, mac net.HardwareAddr) layers.DHCPv4 {
 	// NOTE we want to generate a unique XID, the easiest way is to concat the PON ID and the ONU ID
 	// we increment them by one otherwise:
-	// - PON: 0 ONU: 62 = 062 -> 62
-	// - PON: 6 ONU: 2 = 62 -> 62
-	xid, err := strconv.Atoi(fmt.Sprintf("%d%d", intfId+1, onuId+1))
+	// - OLT: 0 PON: 0 ONU: 62 = 062 -> 62
+	// - OLT: 0 PON: 6 ONU: 2 = 62 -> 62
+	xid, err := strconv.Atoi(fmt.Sprintf("%d%d%d", oltId+1, intfId+1, onuId+1))
 	if err != nil {
 		log.Fatal("Can't generate unique XID for ONU")
 	}
@@ -97,8 +97,8 @@
 	return opts
 }
 
-func createDHCPDisc(intfId uint32, onuId uint32, macAddress net.HardwareAddr) *layers.DHCPv4 {
-	dhcpLayer := createDefaultDHCPReq(intfId, onuId, macAddress)
+func createDHCPDisc(oltId int, intfId uint32, onuId uint32, macAddress net.HardwareAddr) *layers.DHCPv4 {
+	dhcpLayer := createDefaultDHCPReq(oltId, intfId, onuId, macAddress)
 	defaultOpts := createDefaultOpts(intfId, onuId)
 	dhcpLayer.Options = append([]layers.DHCPOption{layers.DHCPOption{
 		Type:   layers.DHCPOptMessageType,
@@ -107,7 +107,7 @@
 	}}, defaultOpts...)
 
 	data := []byte{0xcd, 0x28, 0xcb, 0xcc, 0x00, 0x01, 0x00, 0x01,
-		0x23, 0xed, 0x11, 0xec, 0x4e, 0xfc, 0xcd, 0x28, byte(intfId), byte(onuId)}
+		0x23, 0xed, 0x11, 0xec, 0x4e, 0xfc, 0xcd, 0x28, byte(intfId), byte(onuId)} //FIXME use the OLT-ID in here
 	dhcpLayer.Options = append(dhcpLayer.Options, layers.DHCPOption{
 		Type:   layers.DHCPOptClientID,
 		Data:   data,
@@ -117,8 +117,8 @@
 	return &dhcpLayer
 }
 
-func createDHCPReq(intfId uint32, onuId uint32, macAddress net.HardwareAddr, offeredIp net.IP) *layers.DHCPv4 {
-	dhcpLayer := createDefaultDHCPReq(intfId, onuId, macAddress)
+func createDHCPReq(oltId int, intfId uint32, onuId uint32, macAddress net.HardwareAddr, offeredIp net.IP) *layers.DHCPv4 {
+	dhcpLayer := createDefaultDHCPReq(oltId, intfId, onuId, macAddress)
 	defaultOpts := createDefaultOpts(intfId, onuId)
 
 	dhcpLayer.Options = append(defaultOpts, layers.DHCPOption{
@@ -266,8 +266,8 @@
 	return nil
 }
 
-func sendDHCPRequest(ponPortId uint32, onuId uint32, serialNumber string, portNo uint32, cTag int, onuStateMachine *fsm.FSM, onuHwAddress net.HardwareAddr, offeredIp net.IP, stream openolt.Openolt_EnableIndicationServer) error {
-	dhcp := createDHCPReq(ponPortId, onuId, onuHwAddress, offeredIp)
+func sendDHCPRequest(oltId int, ponPortId uint32, onuId uint32, serialNumber string, portNo uint32, cTag int, onuStateMachine *fsm.FSM, onuHwAddress net.HardwareAddr, offeredIp net.IP, stream openolt.Openolt_EnableIndicationServer) error {
+	dhcp := createDHCPReq(oltId, ponPortId, onuId, onuHwAddress, offeredIp)
 	pkt, err := serializeDHCPPacket(ponPortId, onuId, cTag, onuHwAddress, dhcp)
 
 	if err != nil {
@@ -324,8 +324,8 @@
 	return nil
 }
 
-func SendDHCPDiscovery(ponPortId uint32, onuId uint32, serialNumber string, portNo uint32, onuStateMachine *fsm.FSM, onuHwAddress net.HardwareAddr, cTag int, stream bbsim.Stream) error {
-	dhcp := createDHCPDisc(ponPortId, onuId, onuHwAddress)
+func SendDHCPDiscovery(oltId int, ponPortId uint32, onuId uint32, serialNumber string, portNo uint32, onuStateMachine *fsm.FSM, onuHwAddress net.HardwareAddr, cTag int, stream bbsim.Stream) error {
+	dhcp := createDHCPDisc(oltId, ponPortId, onuId, onuHwAddress)
 	pkt, err := serializeDHCPPacket(ponPortId, onuId, cTag, onuHwAddress, dhcp)
 
 	if err != nil {
@@ -376,7 +376,7 @@
 }
 
 // FIXME cTag is not used here
-func HandleNextPacket(onuId uint32, ponPortId uint32, serialNumber string, portNo uint32, onuHwAddress net.HardwareAddr, cTag int, onuStateMachine *fsm.FSM, pkt gopacket.Packet, stream openolt.Openolt_EnableIndicationServer) error {
+func HandleNextPacket(oltId int, onuId uint32, ponPortId uint32, serialNumber string, portNo uint32, onuHwAddress net.HardwareAddr, cTag int, onuStateMachine *fsm.FSM, pkt gopacket.Packet, stream openolt.Openolt_EnableIndicationServer) error {
 
 	dhcpLayer, err := GetDhcpLayer(pkt)
 	if err != nil {
@@ -406,7 +406,7 @@
 	if dhcpLayer.Operation == layers.DHCPOpReply {
 		if dhcpMessageType == layers.DHCPMsgTypeOffer {
 			offeredIp := dhcpLayer.YourClientIP
-			if err := sendDHCPRequest(ponPortId, onuId, serialNumber, portNo, cTag, onuStateMachine, onuHwAddress, offeredIp, stream); err != nil {
+			if err := sendDHCPRequest(oltId, ponPortId, onuId, serialNumber, portNo, cTag, onuStateMachine, onuHwAddress, offeredIp, stream); err != nil {
 				dhcpLogger.WithFields(log.Fields{
 					"OnuId":  onuId,
 					"IntfId": ponPortId,
diff --git a/internal/bbsim/responders/dhcp/dhcp_test.go b/internal/bbsim/responders/dhcp/dhcp_test.go
index b507a2b..03e40b7 100644
--- a/internal/bbsim/responders/dhcp/dhcp_test.go
+++ b/internal/bbsim/responders/dhcp/dhcp_test.go
@@ -63,6 +63,7 @@
 	var onuId uint32 = 1
 	var gemPortId uint16 = 1
 	var ponPortId uint32 = 0
+	var oltId int = 1
 	var serialNumber = "BBSM00000001"
 	var mac = net.HardwareAddr{0x2e, 0x60, 0x70, 0x13, byte(ponPortId), byte(onuId)}
 	var portNo uint32 = 16
@@ -80,7 +81,7 @@
 		fail:  false,
 	}
 
-	if err := SendDHCPDiscovery(ponPortId, onuId, serialNumber, portNo, dhcpStateMachine, mac, 1, stream); err != nil {
+	if err := SendDHCPDiscovery(oltId, ponPortId, onuId, serialNumber, portNo, dhcpStateMachine, mac, 1, stream); err != nil {
 		t.Errorf("SendDHCPDiscovery returned an error: %v", err)
 		t.Fail()
 	}