diff --git a/VERSION b/VERSION
index 66ce77b..9fe9ff9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-7.0.0
+7.0.1
diff --git a/pkg/platform/common.go b/pkg/platform/common.go
new file mode 100644
index 0000000..dbef567
--- /dev/null
+++ b/pkg/platform/common.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020-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 platform
+
+import (
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+)
+
+var logger log.CLogger
+
+func init() {
+	// Setup this package so that it's log level can be modified at run time
+	var err error
+	logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
+	if err != nil {
+		panic(err)
+	}
+}
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
new file mode 100644
index 0000000..470d4a9
--- /dev/null
+++ b/pkg/platform/platform.go
@@ -0,0 +1,271 @@
+/*
+ * 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 platform
+
+import (
+	"context"
+
+	"github.com/opencord/voltha-lib-go/v7/pkg/flows"
+	"github.com/opencord/voltha-lib-go/v7/pkg/log"
+	ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
+	"github.com/opencord/voltha-protos/v5/go/voltha"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+/*=====================================================================
+Logical (OF) UNI port number
+
+    OpenFlow port number corresponding to PON UNI
+
+     20        12              4      0
+    +--+--------+--------------+------+
+    |0 | pon id |    onu id    |uni id|
+    +--+--------+--------------+------+
+
+    pon id = 8 bits = 256 PON ports
+    onu id = 8 bits = 256 ONUs per PON port
+
+Logical (OF) NNI port number
+
+    OpenFlow port number corresponding to PON NNI
+
+     20                             0
+    +--+----------------------------+
+    |1 |                    intf_id |
+    +--+----------------------------+
+
+    No overlap with UNI port number space
+
+
+PON OLT (OF) port number
+
+    OpenFlow port number corresponding to PON OLT ports
+
+     31     28                                 0
+    +--------+------------------------~~~------+
+    |  0x2   |          pon intf id            |
+    +--------+------------------------~~~------+
+*/
+
+const (
+	// Number of bits for the physical UNI of the ONUs
+	bitsForUniID = 4
+	// Number of bits for the ONU ID
+	bitsForONUID = 8
+	// Number of bits for PON ID
+	bitsForPONID = 8
+	// MaxOnusPerPon is Max number of ONUs on any PON port
+	MaxOnusPerPon = (1 << bitsForONUID)
+	// MaxPonsPerOlt is Max number of PON ports on any OLT
+	MaxPonsPerOlt = (1 << bitsForPONID)
+	// MaxUnisPerOnu is the Max number of UNI ports on any ONU
+	MaxUnisPerOnu = (1 << bitsForUniID)
+	// Bit position where the differentiation bit is located
+	nniUniDiffPos = (bitsForUniID + bitsForONUID + bitsForPONID)
+	// Bit position where the marker for PON port type of OF port is present
+	ponIntfMarkerPos = 28
+	// Value of marker used to distinguish PON port type of OF port
+	ponIntfMarkerValue = 0x2
+	// Number of bits for NNI ID
+	bitsforNNIID = 20
+	// minNniIntPortNum is used to store start range of nni port number (1 << 20) 1048576
+	minNniIntPortNum = (1 << bitsforNNIID)
+	// maxNniPortNum is used to store the maximum range of nni port number ((1 << 21)-1) 2097151
+	maxNniPortNum = ((1 << (bitsforNNIID + 1)) - 1)
+	// minPonIntfPortNum stores the minimum pon port number
+	minPonIntfPortNum = ponIntfMarkerValue << ponIntfMarkerPos
+	// maxPonIntfPortNum stores the maximum pon port number
+	maxPonIntfPortNum = (ponIntfMarkerValue << ponIntfMarkerPos) | (1 << bitsForPONID)
+	upstream          = "upstream"
+	downstream        = "downstream"
+)
+
+//MinUpstreamPortID value
+var MinUpstreamPortID = 0xfffd
+
+//MaxUpstreamPortID value
+var MaxUpstreamPortID = 0xfffffffd
+
+var controllerPorts = []uint32{0xfffd, 0x7ffffffd, 0xfffffffd}
+
+//MkUniPortNum returns new UNIportNum based on intfID, inuID and uniID
+func MkUniPortNum(ctx context.Context, intfID, onuID, uniID uint32) uint32 {
+	var limit = int(onuID)
+	if limit > MaxOnusPerPon {
+		logger.Warn(ctx, "exceeded-the-max-onus-per-pon")
+	}
+	return (intfID << (bitsForUniID + bitsForONUID)) | (onuID << bitsForUniID) | uniID
+}
+
+//OnuIDFromPortNum returns ONUID derived from portNumber
+func OnuIDFromPortNum(portNum uint32) uint32 {
+	return (portNum >> bitsForUniID) & (MaxOnusPerPon - 1)
+}
+
+//IntfIDFromUniPortNum returns IntfID derived from portNum
+func IntfIDFromUniPortNum(portNum uint32) uint32 {
+	return (portNum >> (bitsForUniID + bitsForONUID)) & (MaxPonsPerOlt - 1)
+}
+
+//UniIDFromPortNum return UniID derived from portNum
+func UniIDFromPortNum(portNum uint32) uint32 {
+	return (portNum) & (MaxUnisPerOnu - 1)
+}
+
+//IntfIDToPortNo returns portId derived from intftype, intfId and portType
+func IntfIDToPortNo(intfID uint32, intfType voltha.Port_PortType) uint32 {
+	if (intfType) == voltha.Port_ETHERNET_NNI {
+		return (1 << nniUniDiffPos) | intfID
+	}
+	if (intfType) == voltha.Port_PON_OLT {
+		return (ponIntfMarkerValue << ponIntfMarkerPos) | intfID
+	}
+	return 0
+}
+
+//PortNoToIntfID returns portnumber derived from interfaceID
+func PortNoToIntfID(portno uint32, intfType voltha.Port_PortType) uint32 {
+	if (intfType) == voltha.Port_ETHERNET_NNI {
+		return (1 << nniUniDiffPos) ^ portno
+	}
+	if (intfType) == voltha.Port_PON_OLT {
+		return (ponIntfMarkerValue << ponIntfMarkerPos) ^ portno
+	}
+	return 0
+}
+
+//IntfIDFromNniPortNum returns Intf ID derived from portNum
+func IntfIDFromNniPortNum(ctx context.Context, portNum uint32) (uint32, error) {
+	if portNum < minNniIntPortNum || portNum > maxNniPortNum {
+		logger.Errorw(ctx, "nniportnumber-is-not-in-valid-range", log.Fields{"portnum": portNum})
+		return uint32(0), status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", portNum)
+	}
+	return (portNum & 0xFFFF), nil
+}
+
+//IntfIDFromPonPortNum returns Intf ID derived from portNum
+func IntfIDFromPonPortNum(ctx context.Context, portNum uint32) (uint32, error) {
+	if portNum < minPonIntfPortNum || portNum > maxPonIntfPortNum {
+		logger.Errorw(ctx, "ponportnumber-is-not-in-valid-range", log.Fields{"portnum": portNum})
+		return uint32(0), status.Errorf(codes.InvalidArgument, "invalid-pon-port-number:%d", portNum)
+	}
+	return (portNum & 0x7FFF), nil
+}
+
+//IntfIDToPortTypeName returns port type derived from the intfId
+func IntfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
+	if ((ponIntfMarkerValue << ponIntfMarkerPos) ^ intfID) < MaxPonsPerOlt {
+		return voltha.Port_PON_OLT
+	}
+	if (intfID & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos) {
+		return voltha.Port_ETHERNET_NNI
+	}
+	return voltha.Port_ETHERNET_UNI
+}
+
+//ExtractAccessFromFlow returns AccessDevice information
+func ExtractAccessFromFlow(inPort, outPort uint32) (uint32, uint32, uint32, uint32) {
+	if IsUpstream(outPort) {
+		return inPort, IntfIDFromUniPortNum(inPort), OnuIDFromPortNum(inPort), UniIDFromPortNum(inPort)
+	}
+	return outPort, IntfIDFromUniPortNum(outPort), OnuIDFromPortNum(outPort), UniIDFromPortNum(outPort)
+}
+
+//IsUpstream returns true for Upstream and false for downstream
+func IsUpstream(outPort uint32) bool {
+	for _, port := range controllerPorts {
+		if port == outPort {
+			return true
+		}
+	}
+	return (outPort & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos)
+}
+
+//IsControllerBoundFlow returns true/false
+func IsControllerBoundFlow(outPort uint32) bool {
+	for _, port := range controllerPorts {
+		if port == outPort {
+			return true
+		}
+	}
+	return false
+}
+
+//OnuIDFromUniPortNum returns onuId from give portNum information.
+func OnuIDFromUniPortNum(portNum uint32) uint32 {
+	return (portNum >> bitsForUniID) & (MaxOnusPerPon - 1)
+}
+
+//FlowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID, uniID, inPort and ethType
+func FlowExtractInfo(ctx context.Context, flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, uint32, uint32, uint32, error) {
+	var uniPortNo uint32
+	var ponIntf uint32
+	var onuID uint32
+	var uniID uint32
+	var inPort uint32
+	var ethType uint32
+
+	if flowDirection == upstream {
+		if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
+			for _, field := range flows.GetOfbFields(flow) {
+				if field.GetType() == flows.IN_PORT {
+					uniPortNo = field.GetPort()
+					break
+				}
+			}
+		}
+	} else if flowDirection == downstream {
+		if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
+			for _, field := range flows.GetOfbFields(flow) {
+				if field.GetType() == flows.METADATA {
+					for _, action := range flows.GetActions(flow) {
+						if action.Type == flows.OUTPUT {
+							if out := action.GetOutput(); out != nil {
+								uniPortNo = out.GetPort()
+							}
+							break
+						}
+					}
+				} else if field.GetType() == flows.IN_PORT {
+					inPort = field.GetPort()
+				} else if field.GetType() == flows.ETH_TYPE {
+					ethType = field.GetEthType()
+				}
+			}
+		}
+	}
+
+	if uniPortNo == 0 {
+		return 0, 0, 0, 0, 0, 0, status.Errorf(codes.NotFound, "uni-not-found-flow-diraction:%s", flowDirection)
+	}
+
+	ponIntf = IntfIDFromUniPortNum(uniPortNo)
+	onuID = OnuIDFromUniPortNum(uniPortNo)
+	uniID = UniIDFromPortNum(uniPortNo)
+
+	logger.Debugw(ctx, "flow-extract-info-result",
+		log.Fields{
+			"uniportno": uniPortNo,
+			"pon-intf":  ponIntf,
+			"onu-id":    onuID,
+			"uni-id":    uniID,
+			"inport":    inPort,
+			"ethtype":   ethType})
+
+	return uniPortNo, ponIntf, onuID, uniID, inPort, ethType, nil
+}
diff --git a/pkg/platform/platform_test.go b/pkg/platform/platform_test.go
new file mode 100644
index 0000000..676ab0c
--- /dev/null
+++ b/pkg/platform/platform_test.go
@@ -0,0 +1,384 @@
+/*
+ * 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 core provides the utility for olt devices, flows and statistics
+package platform
+
+import (
+	"context"
+	fu "github.com/opencord/voltha-lib-go/v7/pkg/flows"
+	ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
+	"github.com/opencord/voltha-protos/v5/go/voltha"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+	"math"
+	"reflect"
+	"testing"
+)
+
+func TestMkUniPortNum(t *testing.T) {
+	type args struct {
+		intfID uint32
+		onuID  uint32
+		uniID  uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+		// TODO: Add test cases.
+		{"MkUniPortNum-1", args{1, 1, 1}, ((1 * 4096) + (1 * 16) + 1)},
+		{"MkUniPortNum-2", args{4, 5, 6}, ((4 * 4096) + (5 * 16) + 6)},
+		// Negative test cases to cover the log.warn
+		{"MkUniPortNum-3", args{4, 130, 6}, ((4 * 4096) + (130 * 16) + 6)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MkUniPortNum(context.Background(), tt.args.intfID, tt.args.onuID, tt.args.uniID); got != tt.want {
+				t.Errorf("MkUniPortNum() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestOnuIDFromPortNum(t *testing.T) {
+	type args struct {
+		portNum uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+		// TODO: Add test cases.
+		{"OnuIDFromPortNum-1", args{portNum: 8096}, ((8096 / 16) & 255)},
+		{"OnuIDFromPortNum-2", args{portNum: 9095}, ((9095 / 16) & 255)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := OnuIDFromPortNum(tt.args.portNum); got != tt.want {
+				t.Errorf("OnuIDFromPortNum() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestIntfIDFromUniPortNum(t *testing.T) {
+	type args struct {
+		portNum uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+		// TODO: Add test cases.
+		{"IntfIDFromUniPortNum-1", args{portNum: 8096}, ((8096 / 4096) & 15)},
+		// Negative Testcase
+		{"IntfIDFromUniPortNum-2", args{portNum: 1024}, ((1024 / 4096) & 15)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IntfIDFromUniPortNum(tt.args.portNum); got != tt.want {
+				t.Errorf("IntfIDFromUniPortNum() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestUniIDFromPortNum(t *testing.T) {
+	type args struct {
+		portNum uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+
+		// TODO: Add test cases.
+		{"UniIDFromPortNum-1", args{portNum: 8096}, (8096 & 15)},
+		{"UniIDFromPortNum-2", args{portNum: 1024}, (1024 & 15)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := UniIDFromPortNum(tt.args.portNum); got != tt.want {
+				t.Errorf("UniIDFromPortNum() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestIntfIDToPortNo(t *testing.T) {
+	type args struct {
+		intfID   uint32
+		intfType voltha.Port_PortType
+	}
+	tests := []struct {
+		name string
+		args args
+		want uint32
+	}{
+		// TODO: Add test cases.
+		{"IntfIDToPortNo-1", args{intfID: 120, intfType: voltha.Port_ETHERNET_NNI}, (uint32(math.Pow(2, 20)) + 120)},
+		{"IntfIDToPortNo-2", args{intfID: 1024, intfType: voltha.Port_ETHERNET_UNI}, 0},
+		{"IntfIDToPortNo-3", args{intfID: 456, intfType: voltha.Port_PON_OLT}, (uint32(2*math.Pow(2, 28)) + 456)},
+		{"IntfIDToPortNo-4", args{intfID: 28, intfType: voltha.Port_PON_ONU}, 0},
+		{"IntfIDToPortNo-5", args{intfID: 45, intfType: voltha.Port_UNKNOWN}, 0},
+		{"IntfIDToPortNo-6", args{intfID: 45, intfType: voltha.Port_VENET_OLT}, 0},
+		{"IntfIDToPortNo-7", args{intfID: 45, intfType: voltha.Port_VENET_ONU}, 0},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IntfIDToPortNo(tt.args.intfID, tt.args.intfType); got != tt.want {
+				t.Errorf("IntfIDToPortNo() = %v, want %v", got, tt.want)
+			} else {
+				t.Logf("Expected %v , Actual %v \n", tt.want, got)
+			}
+		})
+	}
+}
+
+func TestIntfIDFromNniPortNum(t *testing.T) {
+	type args struct {
+		portNum uint32
+	}
+
+	tests := []struct {
+		name    string
+		args    args
+		want    uint32
+		wantErr error
+	}{
+		// TODO: Add test cases.
+		{"IntfIDFromNniPortNum-01", args{portNum: 8081}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 8081)},
+		{"IntfIDFromNniPortNum-02", args{portNum: 9090}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 9090)},
+		{"IntfIDFromNniPortNum-03", args{portNum: 0}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 0)},
+		{"IntfIDFromNniPortNum-04", args{portNum: 65535}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 65535)},
+		{"IntfIDFromNniPortNum-05", args{portNum: 1048575}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 1048575)},
+		{"IntfIDFromNniPortNum-06", args{portNum: 1048576}, 0, nil},
+		{"IntfIDFromNniPortNum-07", args{portNum: 1048577}, 1, nil},
+		{"IntfIDFromNniPortNum-08", args{portNum: 1048578}, 2, nil},
+		{"IntfIDFromNniPortNum-09", args{portNum: 1048579}, 3, nil},
+		{"IntfIDFromNniPortNum-10", args{portNum: 2097150}, 65534, nil},
+		{"IntfIDFromNniPortNum-11", args{portNum: 2097151}, 65535, nil},
+		{"IntfIDFromNniPortNum-12", args{portNum: 3000000}, 0, status.Errorf(codes.InvalidArgument, "nni-port-number-out-of-range:%d", 3000000)},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := IntfIDFromNniPortNum(context.Background(), tt.args.portNum)
+			if got != tt.want {
+				t.Errorf("IntfIDFromNniPortNum(): FOR[%v] WANT[%v and %v] GOT[%v and %v]",
+					tt.args.portNum, tt.want, tt.wantErr, got, err)
+			}
+		})
+	}
+}
+
+func TestIntfIDToPortTypeName(t *testing.T) {
+	type args struct {
+		intfID uint32
+	}
+	input := uint32(2*math.Pow(2, 28)) | 3
+	tests := []struct {
+		name string
+		args args
+		want voltha.Port_PortType
+	}{
+		// TODO: Add test cases.
+		{"IntfIDToPortTypeName-1", args{intfID: 1048576}, voltha.Port_ETHERNET_NNI},
+		{"IntfIDToPortTypeName-2", args{intfID: 1000}, voltha.Port_ETHERNET_UNI},
+		{"IntfIDToPortTypeName-2", args{intfID: input}, voltha.Port_PON_OLT},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IntfIDToPortTypeName(tt.args.intfID); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("IntfIDToPortTypeName() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestExtractAccessFromFlow(t *testing.T) {
+	type args struct {
+		inPort  uint32
+		outPort uint32
+	}
+	tests := []struct {
+		name   string
+		args   args
+		port   uint32
+		IntfID uint32
+		onuID  uint32
+		uniID  uint32
+	}{
+		// TODO: Add test cases.
+		{"ExtractAccessFromFlow-1", args{inPort: 100, outPort: 1048576}, 100, 0, 6, 4},
+		{"ExtractAccessFromFlow-2", args{inPort: 1048576, outPort: 10}, 10, 0, 0, 10},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, got1, got2, got3 := ExtractAccessFromFlow(tt.args.inPort, tt.args.outPort)
+			if got != tt.port {
+				t.Errorf("ExtractAccessFromFlow() got = %v, want %v", got, tt.port)
+			}
+			if got1 != tt.IntfID {
+				t.Errorf("ExtractAccessFromFlow() got1 = %v, want %v", got1, tt.IntfID)
+			}
+			if got2 != tt.onuID {
+				t.Errorf("ExtractAccessFromFlow() got2 = %v, want %v", got2, tt.onuID)
+			}
+			if got3 != tt.uniID {
+				t.Errorf("ExtractAccessFromFlow() got3 = %v, want %v", got3, tt.uniID)
+			}
+		})
+	}
+	//t.Error()
+}
+
+func TestIsUpstream(t *testing.T) {
+	type args struct {
+		outPort uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		// TODO: Add test cases.
+		{"TestIsUpstream-1", args{outPort: 65533}, true},
+		{"TestIsUpstream-2", args{outPort: 1048576}, true},
+		{"TestIsUpstream-3", args{outPort: 1048577}, true},
+		{"TestIsUpstream-4", args{outPort: 1048578}, true},
+		{"TestIsUpstream-6", args{outPort: 1000}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsUpstream(tt.args.outPort); got != tt.want {
+				t.Errorf("IsUpstream() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestIsControllerBoundFlow(t *testing.T) {
+	type args struct {
+		outPort uint32
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		// TODO: Add test cases.
+		{"IsControllerBoundFlow-1", args{outPort: 65533}, true},
+		{"IsControllerBoundFlow-2", args{outPort: 65536}, false},
+		{"IsControllerBoundFlow-3", args{outPort: 65537}, false},
+		{"IsControllerBoundFlow-4", args{outPort: 65538}, false},
+		{"IsControllerBoundFlow-5", args{outPort: 65539}, false},
+		{"IsControllerBoundFlow-6", args{outPort: 1000}, false},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := IsControllerBoundFlow(tt.args.outPort); got != tt.want {
+				t.Errorf("IsControllerBoundFlow() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestFlowExtractInfo(t *testing.T) {
+	fa := &fu.FlowArgs{
+		MatchFields: []*ofp.OfpOxmOfbField{
+			fu.InPort(2),
+			fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA | 2)),
+			fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT)),
+			fu.EthType(2048),
+		},
+
+		Actions: []*ofp.OfpAction{
+			fu.SetField(fu.Metadata_ofp(uint64(ofp.OfpInstructionType_OFPIT_WRITE_METADATA))),
+			fu.SetField(fu.VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 101)),
+			fu.Output(1),
+		},
+	}
+	ofpstats, _ := fu.MkFlowStat(fa)
+	type args struct {
+		flow          *ofp.OfpFlowStats
+		flowDirection string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    uint32
+		want1   uint32
+		want2   uint32
+		want3   uint32
+		want4   uint32
+		want5   uint32
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+		{"FlowExtractInfo-1", args{flow: ofpstats, flowDirection: "upstream"}, 2, 0, 0, 2, 0, 0, false},
+
+		// Negative Testcases
+		{"FlowExtractInfo-2", args{flow: ofpstats, flowDirection: "downstream"}, 1, 0, 0, 1, 2, 2048, false},
+		{"FlowExtractInfo-3", args{flow: nil, flowDirection: "downstream"}, 0, 0, 0, 0, 0, 0, true},
+		{"FlowExtractInfo-4", args{flow: &ofp.OfpFlowStats{}, flowDirection: "downstream"}, 0, 0, 0, 0, 0, 0, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, got1, got2, got3, got4, got5, err := FlowExtractInfo(context.Background(), tt.args.flow, tt.args.flowDirection)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("FlowExtractInfo() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("FlowExtractInfo() got = %v, want %v", got, tt.want)
+				return
+			}
+			if got1 != tt.want1 {
+				t.Errorf("FlowExtractInfo() got1 = %v, want %v", got1, tt.want1)
+				return
+			}
+			if got2 != tt.want2 {
+				t.Errorf("FlowExtractInfo() got2 = %v, want %v", got2, tt.want2)
+				return
+			}
+			if got3 != tt.want3 {
+				t.Errorf("FlowExtractInfo() got3 = %v, want %v", got3, tt.want3)
+				return
+			}
+			if got4 != tt.want4 {
+				t.Errorf("FlowExtractInfo() got4 = %v, want %v", got4, tt.want4)
+				return
+			}
+			if got5 != tt.want5 {
+				t.Errorf("FlowExtractInfo() got5 = %v, want %v", got5, tt.want5)
+				return
+			}
+		})
+	}
+}
