VOL-1601 Necessary functions for multicast IP to MAC address conversion

Change-Id: Id7884528e1ddca8dd1c008b8013d10d771804098
diff --git a/pkg/flows/flow_utils.go b/pkg/flows/flow_utils.go
index f7d1b43..02a4b0b 100644
--- a/pkg/flows/flow_utils.go
+++ b/pkg/flows/flow_utils.go
@@ -1330,3 +1330,35 @@
 	}
 	return matchFields
 }
+
+//IsMulticastIp returns true if the ip starts with the byte sequence of 1110;
+//false otherwise.
+func IsMulticastIp(ip uint32) bool {
+	return ip>>28 == 14
+}
+
+//ConvertToMulticastMacInt returns equivalent mac address of the given multicast ip address
+func ConvertToMulticastMacInt(ip uint32) uint64 {
+	//get last 23 bits of ip address by ip & 00000000011111111111111111111111
+	theLast23BitsOfIp := ip & 8388607
+	// perform OR with 0x1005E000000 to build mcast mac address
+	return 1101088686080 | uint64(theLast23BitsOfIp)
+}
+
+//ConvertToMulticastMacBytes returns equivalent mac address of the given multicast ip address
+func ConvertToMulticastMacBytes(ip uint32) []byte {
+	mac := ConvertToMulticastMacInt(ip)
+	var b bytes.Buffer
+	// catalyze (48 bits) in binary:111111110000000000000000000000000000000000000000
+	catalyze := uint64(280375465082880)
+	//convert each octet to decimal
+	for i := 0; i < 6; i++ {
+		if i != 0 {
+			catalyze = catalyze >> 8
+		}
+		octet := mac & catalyze
+		octetDecimal := octet >> uint8(40-i*8)
+		b.WriteByte(byte(octetDecimal))
+	}
+	return b.Bytes()
+}
diff --git a/pkg/flows/flow_utils_test.go b/pkg/flows/flow_utils_test.go
index 1721be7..8922a9c 100644
--- a/pkg/flows/flow_utils_test.go
+++ b/pkg/flows/flow_utils_test.go
@@ -16,6 +16,7 @@
 package flows
 
 import (
+	"bytes"
 	"github.com/opencord/voltha-lib-go/v2/pkg/log"
 	ofp "github.com/opencord/voltha-protos/v2/go/openflow_13"
 	"github.com/stretchr/testify/assert"
@@ -693,3 +694,17 @@
 	flowMod = MkSimpleFlowMod(ToOfpOxmField(fa.MatchFields), fa.Actions, fa.Command, fa.KV)
 	assert.True(t, FlowMatchesMod(flow, flowMod))
 }
+
+func TestIsMulticastIpAddress(t *testing.T) {
+	isMcastIp := IsMulticastIp(3776315393) //225.22.0.1
+	assert.True(t, isMcastIp)
+	isMcastIp = IsMulticastIp(3232243777) //192.168.32.65
+	assert.True(t, !isMcastIp)
+}
+
+func TestConvertToMulticastMac(t *testing.T) {
+	mcastIp := uint32(4001431809)                   //238.129.1.1
+	expectedMacInBytes := []byte{1, 0, 94, 1, 1, 1} //01:00:5e:01:01:01
+	macInBytes := ConvertToMulticastMacBytes(mcastIp)
+	assert.True(t, bytes.Compare(macInBytes, expectedMacInBytes) == 0)
+}