ncsi: make Interface virtual

Now that we have encapsulation for passing NCSI commands and responses
to/from an interface, we can make the Interface object virtual, and have
the Netlink implementation as a subclass.

We keep the netlink-specific operations in NetlinkInterface; getInfo(),
setChannel(), clearInterface(), and the channel/package mask operations
are all netlink-specific items to control kernel state.

Change-Id: I30b9cec41712d2e32d12685dd8406e08c6dea1f0
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
diff --git a/src/ncsi_util.cpp b/src/ncsi_util.cpp
index d8ad3b2..c9ac7b5 100644
--- a/src/ncsi_util.cpp
+++ b/src/ncsi_util.cpp
@@ -272,7 +272,7 @@
     return static_cast<int>(NL_STOP);
 };
 
-int applyCmd(Interface& interface, const NetlinkCommand& cmd,
+int applyCmd(NetlinkInterface& interface, const NetlinkCommand& cmd,
              int package = DEFAULT_VALUE, int channel = DEFAULT_VALUE,
              int flags = NONE, CallBack function = nullptr, void* arg = nullptr)
 {
@@ -422,10 +422,17 @@
 
 std::string to_string(Interface& interface)
 {
-    return std::to_string(interface.ifindex);
+    return interface.toString();
 }
 
-std::optional<NCSIResponse> Interface::sendCommand(NCSICommand& cmd)
+NetlinkInterface::NetlinkInterface(int ifindex) : ifindex(ifindex) {}
+
+std::string NetlinkInterface::toString()
+{
+    return std::to_string(ifindex);
+}
+
+std::optional<NCSIResponse> NetlinkInterface::sendCommand(NCSICommand& cmd)
 {
     lg2::debug("Send Command, CHANNEL : {CHANNEL} , PACKAGE : {PACKAGE}, "
                "INTERFACE: {INTERFACE}",
@@ -448,7 +455,7 @@
     return ctx.resp;
 }
 
-int Interface::setChannel(int package, int channel)
+int NetlinkInterface::setChannel(int package, int channel)
 {
     lg2::debug("Set CHANNEL : {CHANNEL} , PACKAGE : {PACKAGE}, INTERFACE : "
                "{INTERFACE}",
@@ -460,7 +467,7 @@
     return internal::applyCmd(*this, cmd, package, channel);
 }
 
-int Interface::clearInterface()
+int NetlinkInterface::clearInterface()
 {
     lg2::debug("ClearInterface , INTERFACE : {INTERFACE}", "INTERFACE", this);
 
@@ -468,7 +475,7 @@
     return internal::applyCmd(*this, cmd);
 }
 
-std::optional<InterfaceInfo> Interface::getInfo(int package)
+std::optional<InterfaceInfo> NetlinkInterface::getInfo(int package)
 {
     int rc, flags = package == DEFAULT_VALUE ? NLM_F_DUMP : NONE;
     InterfaceInfo info;
@@ -493,7 +500,7 @@
     return info;
 }
 
-int Interface::setPackageMask(unsigned int mask)
+int NetlinkInterface::setPackageMask(unsigned int mask)
 {
     lg2::debug("Set Package Mask , INTERFACE: {INTERFACE} MASK: {MASK}",
                "INTERFACE", this, "MASK", lg2::hex, mask);
@@ -506,7 +513,7 @@
     return internal::applyCmd(*this, cmd);
 }
 
-int Interface::setChannelMask(int package, unsigned int mask)
+int NetlinkInterface::setChannelMask(int package, unsigned int mask)
 {
     lg2::debug(
         "Set Channel Mask , INTERFACE: {INTERFACE}, PACKAGE : {PACKAGE} MASK: {MASK}",