Add support for vlan(set lan command)

Resolves openbmc/openbmc#1899

Change-Id: I3c436045676bc96e5d91fd9420509bc991549a13
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/apphandler.cpp b/apphandler.cpp
index 7b30edd..2251e8c 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -17,7 +17,6 @@
 #include <phosphor-logging/elog-errors.hpp>
 #include "xyz/openbmc_project/Common/error.hpp"
 
-
 extern sd_bus *bus;
 
 constexpr auto app_obj = "/org/openbmc/NetworkManager/Interface";
@@ -535,6 +534,7 @@
     std::string ipaddress;
     std::string gateway;
     uint8_t prefix {};
+    uint32_t vlanID {};
 
     // Todo: parse the request data if needed.
 
@@ -574,9 +574,21 @@
             ipaddress = channelConfig.ipaddr;
             prefix = ipmi::network::toPrefix(AF_INET, channelConfig.netmask);
             gateway = channelConfig.gateway;
+
+            if (channelConfig.vlanID != ipmi::network::VLAN_ID_MASK)
+            {
+                //get the first twelve bits which is vlan id
+                //not interested in rest of the bits.
+                vlanID = channelConfig.vlanID & ipmi::network::VLAN_ID_MASK;
+                channelConfig.vlanID = le32toh(channelConfig.vlanID);
+            }
+
         }
         else
         {
+            // We have partial filled cache so get the remaning
+            // info from the system.
+
             // gets the network data from the system as user has
             // not given all the data then use the data fetched from the
             // system but it is implementation dependent,IPMI spec doesn't
@@ -585,7 +597,6 @@
             // if system is not having any ip object don't throw error,
             try
             {
-
                 auto ipObjectInfo = ipmi::getDbusObject(bus,
                         ipmi::network::IP_INTERFACE,
                         ipmi::network::ROOT,
@@ -605,6 +616,18 @@
                     ipmi::network::toPrefix(AF_INET,
                                             channelConfig.netmask);
 
+                if (channelConfig.vlanID != ipmi::network::VLAN_ID_MASK)
+                {
+                    //get the first twelve bits which is vlan id
+                    //not interested in rest of the bits.
+                    vlanID = channelConfig.vlanID & ipmi::network::VLAN_ID_MASK;
+                    channelConfig.vlanID = le32toh(channelConfig.vlanID);
+                }
+                else
+                {
+                    vlanID = ipmi::network::getVLAN(ipObjectInfo.first);
+                }
+
             }
             catch (InternalFailure& e)
             {
@@ -626,7 +649,7 @@
         }
 
         // Currently network manager doesn't support purging of all the
-        // ip addresses from the parent interface,
+        // ip addresses and the vlan interfaces from the parent interface,
         // TODO once the support is there, will make the change here.
         // https://github.com/openbmc/openbmc/issues/2141.
 
@@ -634,11 +657,24 @@
         // Multiple interface through
         // https://github.com/openbmc/openbmc/issues/2138
 
-        //delete all the ipv4  addresses
-
+        //delete all the vlan interfaces
+        //delete all the ipv4 addresses
+        ipmi::deleteAllDbusObjects(bus, ipmi::network::ROOT,
+                                   ipmi::network::VLAN_INTERFACE);
         ipmi::deleteAllDbusObjects(bus, ipmi::network::ROOT,
                                    ipmi::network::IP_INTERFACE,
                                    ipmi::network::IP_TYPE);
+        if (vlanID)
+        {
+            ipmi::network::createVLAN(bus, ipmi::network::SERVICE,
+                                      ipmi::network::ROOT,
+                                      ipmi::network::INTERFACE, vlanID);
+
+            networkInterfaceObject = ipmi::getDbusObject(
+                    bus,
+                    ipmi::network::VLAN_INTERFACE,
+                    ipmi::network::ROOT);
+        }
 
         ipmi::network::createIP(bus, networkInterfaceObject.second,
                                 networkInterfaceObject.first,
@@ -664,6 +700,7 @@
     return rc;
 }
 
+
 // ATTENTION: This ipmi function is very hardcoded on purpose
 // OpenBMC does not fully support IPMI.  This command is useful
 // to have around because it enables testing of interfaces with