[ONOS-7627] Support the creation of sr-iov port type for LiquidIO smart NIC

Change-Id: I6d55d1dfd26ec6ed0b9df9fdeea31749b0c49b7c
diff --git a/apps/openstacknetworking/app/BUCK b/apps/openstacknetworking/app/BUCK
index 34933f4..6136f8f 100644
--- a/apps/openstacknetworking/app/BUCK
+++ b/apps/openstacknetworking/app/BUCK
@@ -11,6 +11,8 @@
     '//cli:onos-cli',
     '//apps/openstacknode/api:onos-apps-openstacknode-api',
     '//apps/openstacknetworking/api:onos-apps-openstacknetworking-api',
+    '//protocols/ovsdb/api:onos-protocols-ovsdb-api',
+    '//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc',
     '//lib:openstack4j-core',
     '//lib:openstack4j-http-connector',
     '//lib:openstack4j-httpclient',
diff --git a/apps/openstacknetworking/app/pom.xml b/apps/openstacknetworking/app/pom.xml
index 13ac53c..fbc27fb 100644
--- a/apps/openstacknetworking/app/pom.xml
+++ b/apps/openstacknetworking/app/pom.xml
@@ -115,6 +115,11 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
+            <artifactId>onos-protocols-ovsdb-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
             <artifactId>onos-core-common</artifactId>
             <classifier>tests</classifier>
             <scope>test</scope>
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackDirectPortListCommand.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackDirectPortListCommand.java
new file mode 100644
index 0000000..319a7fa
--- /dev/null
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackDirectPortListCommand.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.onosproject.openstacknetworking.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.openstack4j.model.network.IP;
+import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.Port;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.onosproject.openstacknetworking.api.Constants.DIRECT;
+import static org.onosproject.openstacknetworking.api.Constants.PCISLOT;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getIntfNameFromPciAddress;
+
+/**
+ * Lists OpenStack direct ports.
+ */
+@Command(scope = "onos", name = "openstack-direct-ports",
+        description = "Lists all OpenStack direct ports")
+public class OpenstackDirectPortListCommand extends AbstractShellCommand {
+    private static final String UNBOUND = "unbound";
+    private static final String FORMAT = "%-40s%-20s%-20s%-20s%-20s%-20s";
+
+    @Override
+    protected void execute() {
+        OpenstackNetworkService service = AbstractShellCommand.get(OpenstackNetworkService.class);
+
+        List<Port> ports = service.ports().stream()
+
+                .filter(port -> port.getvNicType().equals(DIRECT))
+                .filter(port -> port.isAdminStateUp() && !port.getVifType().equals(UNBOUND))
+                .collect(Collectors.toList());
+
+
+        print(FORMAT, "ID", "Network", "MAC", "FIXED IPs", "PCI Slot", "Interface");
+        for (Port port: ports) {
+            List<String> fixedIps = port.getFixedIps().stream()
+                    .map(IP::getIpAddress)
+                    .collect(Collectors.toList());
+
+            Network osNet = service.network(port.getNetworkId());
+            print(FORMAT, port.getId(),
+                    osNet.getName(),
+                    port.getMacAddress(),
+                    fixedIps.isEmpty() ? "" : fixedIps,
+                    port.getProfile() == null ? "" : port.getProfile().get(PCISLOT).toString(),
+                    getIntfNameFromPciAddress(port));
+        }
+    }
+}
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenStackSwitchingDirectPortProvider.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenStackSwitchingDirectPortProvider.java
new file mode 100644
index 0000000..bd8473c
--- /dev/null
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenStackSwitchingDirectPortProvider.java
@@ -0,0 +1,246 @@
+/*
+ * 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 org.onosproject.openstacknetworking.impl;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.openstacknetworking.api.InstancePort;
+import org.onosproject.openstacknetworking.api.InstancePortService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
+import org.onosproject.ovsdb.controller.OvsdbController;
+import org.openstack4j.model.network.Port;
+import org.openstack4j.model.network.State;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Dictionary;
+import java.util.Objects;
+import java.util.Optional;
+
+import static org.onosproject.openstacknetworking.api.Constants.DIRECT;
+import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getIntfNameFromPciAddress;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
+
+@Component(immediate = true)
+public final class OpenStackSwitchingDirectPortProvider {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final String OVSDB_PORT = "ovsdbPortNum";
+    private static final int DEFAULT_OVSDB_PORT = 6640;
+    private static final String UNBOUND = "unbound";
+    private static final String PORT_NAME = "portName";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackNetworkService osNetworkService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackNodeService osNodeService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LeadershipService leadershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OvsdbController ovsdbController;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InstancePortService instancePortService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ComponentConfigService componentConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Property(name = OVSDB_PORT, intValue = DEFAULT_OVSDB_PORT,
+            label = "OVSDB server listen port")
+    private int ovsdbPort = DEFAULT_OVSDB_PORT;
+
+    private final OpenstackNetworkListener openstackNetworkListener = new InternalOpenstackNetworkListener();
+
+    private NodeId localNodeId;
+    private ApplicationId appId;
+
+    @Activate
+    void activate() {
+        appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
+        localNodeId = clusterService.getLocalNode().id();
+        leadershipService.runForLeadership(appId.name());
+        osNetworkService.addListener(openstackNetworkListener);
+        componentConfigService.registerProperties(getClass());
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    void deactivate() {
+        leadershipService.withdraw(appId.name());
+        osNetworkService.removeListener(openstackNetworkListener);
+        componentConfigService.unregisterProperties(getClass(), false);
+
+        log.info("Stopped");
+    }
+
+
+    @Modified
+    protected void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        int updatedOvsdbPort = Tools.getIntegerProperty(properties, OVSDB_PORT);
+        if (!Objects.equals(updatedOvsdbPort, ovsdbPort)) {
+            ovsdbPort = updatedOvsdbPort;
+        }
+
+        log.info("Modified");
+    }
+    private void processPortAdded(Port port) {
+        if (!port.getvNicType().equals(DIRECT)) {
+            log.trace("processPortAdded skipped because of unsupported vNicType: {}", port.getvNicType());
+            return;
+        } else if (!port.isAdminStateUp() || port.getVifType().equals(UNBOUND)) {
+            log.trace("processPortAdded skipped because of status: {}, adminStateUp: {}, vifType: {}",
+                    port.getState(), port.isAdminStateUp(), port.getVifType());
+            return;
+        } else {
+            InstancePort instancePort = instancePortService.instancePort(port.getId());
+            //Skip this if the instance port for the port id is already created.
+            if (instancePort != null) {
+                return;
+            }
+
+            Optional<OpenstackNode> osNode = osNodeService.completeNodes(COMPUTE).stream()
+                    .filter(node -> node.hostname().equals(port.getHostId()))
+                    .findAny();
+            if (!osNode.isPresent()) {
+                log.error("processPortAdded failed because openstackNode doesn't exist that matches hostname {}",
+                        port.getHostId());
+                return;
+            }
+            log.trace("Retrieved openstackNode: {}", osNode.get().toString());
+
+            String intfName = getIntfNameFromPciAddress(port);
+            if (intfName == null) {
+                log.error("Failed to execute processPortAdded because of null interface name");
+                return;
+            }
+
+            log.trace("Retrieved interface name: {}", intfName);
+
+            osNodeService.addVfPort(osNode.get(), intfName);
+        }
+    }
+
+    private void processPortRemoved(Port port) {
+        if (!port.getvNicType().equals(DIRECT)) {
+            log.trace("processPortRemoved skipped because of unsupported vNicType: {}", port.getvNicType());
+            return;
+        } else if (instancePortService.instancePort(port.getId()) == null) {
+            log.trace("processPortRemoved skipped because no instance port exist for portId: {}", port.getId());
+            return;
+        } else {
+            InstancePort instancePort = instancePortService.instancePort(port.getId());
+            if (instancePort == null) {
+                return;
+            }
+            DeviceId deviceId = instancePort.deviceId();
+            if (deviceId == null) {
+                return;
+            }
+            OpenstackNode osNode = osNodeService.node(deviceId);
+            if (osNode == null) {
+                return;
+            }
+
+            Optional<org.onosproject.net.Port> removedPort = deviceService.getPorts(deviceId).stream()
+                    .filter(p -> Objects.equals(p.number(), instancePort.portNumber()))
+                    .findAny();
+
+            if (!removedPort.isPresent()) {
+                log.error("Failed to execute processPortAdded because port number doesn't exist");
+                return;
+            }
+
+            String intfName = removedPort.get().annotations().value(PORT_NAME);
+
+            if (intfName == null) {
+                log.error("Failed to execute processPortAdded because of null interface name");
+                return;
+            }
+            log.trace("Retrieved interface name: {}", intfName);
+
+            osNodeService.removeVfPort(osNode, intfName);
+        }
+    }
+
+    private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
+        @Override
+        public boolean isRelevant(OpenstackNetworkEvent event) {
+            // do not allow to proceed without leadership
+            NodeId leader = leadershipService.getLeader(appId.name());
+            if (!Objects.equals(localNodeId, leader)) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void event(OpenstackNetworkEvent event) {
+            switch (event.type()) {
+                case OPENSTACK_PORT_UPDATED:
+                    if (event.port().getState() == State.DOWN) {
+                        processPortRemoved(event.port());
+                    } else {
+                        processPortAdded(event.port());
+                    }
+                    break;
+                case OPENSTACK_PORT_REMOVED:
+                    processPortRemoved(event.port());
+                    break;
+                default:
+                    break;
+
+            }
+        }
+    }
+}
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
index 94669ed..359d34e 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
@@ -69,6 +69,10 @@
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
+import static org.onosproject.openstacknetworking.api.Constants.DIRECT;
+import static org.onosproject.openstacknetworking.api.Constants.PCISLOT;
+import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_PREFIX_MAP;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getIntfNameFromPciAddress;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -105,6 +109,8 @@
     private static final String ERR_NOT_FOUND = " does not exist";
     private static final String ERR_IN_USE = " still in use";
     private static final String ERR_DUPLICATE = " already exists";
+    private static final String PORT_NAME_PREFIX_VM = "tap";
+
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
@@ -312,11 +318,28 @@
         if (Strings.isNullOrEmpty(portName)) {
             return null;
         }
-        Optional<Port> osPort = osNetworkStore.ports()
-                .stream()
-                .filter(p -> p.getId().contains(portName.substring(3)))
-                .findFirst();
-        return osPort.orElse(null);
+
+        if (port.annotations().value(PORT_NAME).startsWith(PORT_NAME_PREFIX_VM)) {
+            Optional<Port> osPort = osNetworkStore.ports()
+                    .stream()
+                    .filter(p -> p.getId().contains(portName.substring(3)))
+                    .findFirst();
+            return osPort.orElse(null);
+        } else if (isDirectPort(portName)) {
+            //Additional prefixes will be added
+            Optional<Port> osPort = osNetworkStore.ports()
+                    .stream()
+                    .filter(p -> p.getvNicType().equals(DIRECT) && p.getProfile().get(PCISLOT) != null)
+                    .filter(p -> getIntfNameFromPciAddress(p).equals(portName))
+                    .findFirst();
+            return osPort.orElse(null);
+        } else {
+            return null;
+        }
+    }
+
+    private boolean isDirectPort(String portName) {
+        return PORT_NAME_PREFIX_MAP.values().stream().filter(p -> portName.startsWith(p)).findAny().isPresent();
     }
 
     @Override
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index 1c7b2ec..164b25b 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -213,7 +213,6 @@
             setRouterAdminRules(network.getProviderSegID(), network.getNetworkType(), !osRouter.isAdminStateUp());
         });
 
-
         ExternalPeerRouter externalPeerRouter = osNetworkAdminService.externalPeerRouter(exGateway);
         VlanId vlanId = externalPeerRouter == null ? VlanId.NONE : externalPeerRouter.externalPeerRouterVlanId();
 
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
index 14ee117..538a5fd 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
@@ -64,6 +64,7 @@
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
 import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
+import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_PREFIX_MAP;
 import static org.onosproject.openstacknetworking.impl.HostBasedInstancePort.ANNOTATION_CREATE_TIME;
 import static org.onosproject.openstacknetworking.impl.HostBasedInstancePort.ANNOTATION_NETWORK_ID;
 import static org.onosproject.openstacknetworking.impl.HostBasedInstancePort.ANNOTATION_PORT_ID;
@@ -75,6 +76,7 @@
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     private static final String PORT_NAME_PREFIX_VM = "tap";
+    private static final String PORT_NAME_PREFIX_CAVIUM = "enp";
     private static final String ERR_ADD_HOST = "Failed to add host: ";
     private static final String ANNOTATION_SEGMENT_ID = "segId";
     private static final String SONA_HOST_SCHEME = "sona";
@@ -229,11 +231,16 @@
             String portName = port.annotations().value(PORT_NAME);
 
             return !Strings.isNullOrEmpty(portName) &&
-                    portName.startsWith(PORT_NAME_PREFIX_VM);
+                    (portName.startsWith(PORT_NAME_PREFIX_VM) || isDirectPort(portName));
+        }
+
+        private boolean isDirectPort(String portName) {
+            return PORT_NAME_PREFIX_MAP.values().stream().filter(p -> portName.startsWith(p)).findAny().isPresent();
         }
 
         @Override
         public void event(DeviceEvent event) {
+            log.info("Device event occurred with type {}", event.type());
             switch (event.type()) {
                 case PORT_UPDATED:
                     if (!event.port().isEnabled()) {
@@ -335,6 +342,19 @@
                         processPortAdded(port);
                     });
 
+            PORT_NAME_PREFIX_MAP.values().forEach(portNamePrefix -> {
+                deviceService.getPorts(osNode.intgBridge()).stream()
+                        .filter(port -> port.annotations().value(PORT_NAME)
+                                .startsWith(portNamePrefix) &&
+                                port.isEnabled())
+                        .forEach(port -> {
+                            log.debug("Instance port {} is detected from {}",
+                                    port.annotations().value(portNamePrefix),
+                                    osNode.hostname());
+                            processPortAdded(port);
+                        });
+            });
+
             Tools.stream(hostService.getHosts())
                     .filter(host -> deviceService.getPort(
                             host.location().deviceId(),
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
index 98fc0a9..7111820 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
@@ -22,6 +22,7 @@
 import org.onosproject.openstacknode.api.OpenstackNode;
 import org.openstack4j.core.transport.ObjectMapperSingleton;
 import org.openstack4j.model.ModelEntity;
+import org.openstack4j.model.network.Port;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,6 +34,9 @@
 import java.util.TreeMap;
 
 import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
+import static org.onosproject.openstacknetworking.api.Constants.PCISLOT;
+import static org.onosproject.openstacknetworking.api.Constants.PCI_VENDOR_INFO;
+import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_PREFIX_MAP;
 
 /**
  * An utility that used in openstack networking app.
@@ -41,6 +45,11 @@
 
     protected static final Logger log = LoggerFactory.getLogger(OpenstackNetworkingUtil.class);
 
+    private static final int HEX_RADIX = 16;
+    private static final int ZERO_FUNCTION_NUMBER = 0;
+    private static final String PREFIX_DEVICE_NUMBER = "s";
+    private static final String PREFIX_FUNCTION_NUMBER = "f";
+
     /**
      * Prevents object instantiation from external.
      */
@@ -125,4 +134,51 @@
         }
         return gw;
     }
+
+    /**
+     * Extract the interface name with the supplied port.
+     *
+     * @param port port
+     * @return interface name
+     */
+    public static String getIntfNameFromPciAddress(Port port) {
+        if (port.getProfile() != null && port.getProfile().get(PCISLOT) == null) {
+            log.error("Failed to retrieve the interface name because of no pci_slot information from the port");
+            return null;
+        }
+        String busNumHex = port.getProfile().get(PCISLOT).toString().split(":")[1];
+        String busNumDecimal = String.valueOf(Integer.parseInt(busNumHex, HEX_RADIX));
+
+        String deviceNumHex = port.getProfile().get(PCISLOT).toString()
+                .split(":")[2]
+                .split("\\.")[0];
+        String deviceNumDecimal = String.valueOf(Integer.parseInt(deviceNumHex, HEX_RADIX));
+
+        String functionNumHex = port.getProfile().get(PCISLOT).toString()
+                .split(":")[2]
+                .split("\\.")[1];
+        String functionNumDecimal = String.valueOf(Integer.parseInt(functionNumHex, HEX_RADIX));
+
+        String intfName;
+
+        String vendorInfoForPort = String.valueOf(port.getProfile().get(PCI_VENDOR_INFO));
+
+        if (vendorInfoForPort == null) {
+            log.error("Failed to retrieve the interface name because of no pci vendor information from the port");
+            return null;
+        }
+        String portNamePrefix = PORT_NAME_PREFIX_MAP.get(vendorInfoForPort);
+        if (vendorInfoForPort == null) {
+            log.error("Failed to retrieve the interface name because of no prefix information from the port");
+            return null;
+        }
+        if (functionNumDecimal.equals(ZERO_FUNCTION_NUMBER)) {
+            intfName = portNamePrefix + busNumDecimal + PREFIX_DEVICE_NUMBER + deviceNumDecimal;
+        } else {
+            intfName = portNamePrefix + busNumDecimal + PREFIX_DEVICE_NUMBER + deviceNumDecimal
+                    + PREFIX_FUNCTION_NUMBER + functionNumDecimal;
+        }
+
+        return intfName;
+    }
 }
diff --git a/apps/openstacknetworking/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/openstacknetworking/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index d3884df..3d6edff 100644
--- a/apps/openstacknetworking/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/apps/openstacknetworking/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -22,6 +22,9 @@
             <action class="org.onosproject.openstacknetworking.cli.OpenstackPortListCommand"/>
         </command>
         <command>
+            <action class="org.onosproject.openstacknetworking.cli.OpenstackDirectPortListCommand"/>
+        </command>
+        <command>
             <action class="org.onosproject.openstacknetworking.cli.OpenstackRouterListCommand"/>
         </command>
         <command>
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManagerTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManagerTest.java
index 866aa55..8104c65 100644
--- a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManagerTest.java
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManagerTest.java
@@ -632,6 +632,14 @@
         }
 
         @Override
+        public void addVfPort(OpenstackNode osNode, String portName) {
+        }
+
+        @Override
+        public void removeVfPort(OpenstackNode osNode, String portName) {
+        }
+
+        @Override
         public void addListener(OpenstackNodeListener listener) {
             listeners.add(listener);
         }
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackNodeServiceAdapter.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackNodeServiceAdapter.java
index a738c09..cbd4802 100644
--- a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackNodeServiceAdapter.java
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackNodeServiceAdapter.java
@@ -58,6 +58,15 @@
     }
 
     @Override
+    public void addVfPort(OpenstackNode osNode, String portName) {
+    }
+
+    @Override
+    public void removeVfPort(OpenstackNode osNode, String portName) {
+    }
+
+
+    @Override
     public void addListener(OpenstackNodeListener listener) {
 
     }