VOM: support for pipes 83/13483/4
authorNeale Ranns <neale.ranns@cisco.com>
Wed, 11 Apr 2018 15:08:30 +0000 (08:08 -0700)
committerNeale Ranns <nranns@cisco.com>
Tue, 17 Jul 2018 08:53:33 +0000 (08:53 +0000)
Change-Id: I5c381dfe2f926f94a34ee8ed8f1b9ec6038d5fe2
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
84 files changed:
extras/vom/vom/Makefile.am
extras/vom/vom/acl_binding_cmds.cpp
extras/vom/vom/acl_binding_cmds.hpp
extras/vom/vom/acl_ethertype_cmds.cpp
extras/vom/vom/acl_ethertype_cmds.hpp
extras/vom/vom/acl_list_cmds.cpp
extras/vom/vom/acl_list_cmds.hpp
extras/vom/vom/arp_proxy_binding_cmds.cpp
extras/vom/vom/arp_proxy_binding_cmds.hpp
extras/vom/vom/arp_proxy_config_cmds.cpp
extras/vom/vom/arp_proxy_config_cmds.hpp
extras/vom/vom/bond_group_binding.cpp
extras/vom/vom/bond_group_binding_cmds.cpp
extras/vom/vom/bond_group_binding_cmds.hpp
extras/vom/vom/bond_interface_cmds.cpp
extras/vom/vom/bridge_domain_arp_entry_cmds.cpp
extras/vom/vom/bridge_domain_arp_entry_cmds.hpp
extras/vom/vom/bridge_domain_cmds.cpp
extras/vom/vom/bridge_domain_cmds.hpp
extras/vom/vom/bridge_domain_entry_cmds.cpp
extras/vom/vom/bridge_domain_entry_cmds.hpp
extras/vom/vom/dhcp_client_cmds.cpp
extras/vom/vom/dhcp_client_cmds.hpp
extras/vom/vom/event_cmd.hpp
extras/vom/vom/gbp_contract_cmds.cpp
extras/vom/vom/gbp_contract_cmds.hpp
extras/vom/vom/gbp_endpoint_cmds.cpp
extras/vom/vom/gbp_endpoint_cmds.hpp
extras/vom/vom/gbp_endpoint_group_cmds.cpp
extras/vom/vom/gbp_endpoint_group_cmds.hpp
extras/vom/vom/gbp_recirc_cmds.cpp
extras/vom/vom/gbp_recirc_cmds.hpp
extras/vom/vom/gbp_subnet_cmds.cpp
extras/vom/vom/gbp_subnet_cmds.hpp
extras/vom/vom/hw_cmds.cpp
extras/vom/vom/hw_cmds.hpp
extras/vom/vom/interface.hpp
extras/vom/vom/interface_cmds.cpp
extras/vom/vom/interface_cmds.hpp
extras/vom/vom/interface_factory.cpp
extras/vom/vom/interface_factory.hpp
extras/vom/vom/interface_ip6_nd.hpp
extras/vom/vom/interface_ip6_nd_cmds.cpp
extras/vom/vom/interface_span_cmds.cpp
extras/vom/vom/interface_span_cmds.hpp
extras/vom/vom/interface_types.cpp
extras/vom/vom/ip_unnumbered_cmds.cpp
extras/vom/vom/ip_unnumbered_cmds.hpp
extras/vom/vom/l2_binding_cmds.cpp
extras/vom/vom/l2_binding_cmds.hpp
extras/vom/vom/l2_emulation_cmds.cpp
extras/vom/vom/l2_emulation_cmds.hpp
extras/vom/vom/l2_xconnect_cmds.cpp
extras/vom/vom/l2_xconnect_cmds.hpp
extras/vom/vom/l3_binding_cmds.cpp
extras/vom/vom/l3_binding_cmds.hpp
extras/vom/vom/lldp_binding_cmds.cpp
extras/vom/vom/lldp_binding_cmds.hpp
extras/vom/vom/lldp_global_cmds.cpp
extras/vom/vom/lldp_global_cmds.hpp
extras/vom/vom/nat_binding_cmds.cpp
extras/vom/vom/nat_binding_cmds.hpp
extras/vom/vom/nat_static_cmds.cpp
extras/vom/vom/nat_static_cmds.hpp
extras/vom/vom/neighbour_cmds.cpp
extras/vom/vom/neighbour_cmds.hpp
extras/vom/vom/pipe.cpp [new file with mode: 0644]
extras/vom/vom/pipe.hpp [new file with mode: 0644]
extras/vom/vom/pipe_cmds.cpp [new file with mode: 0644]
extras/vom/vom/pipe_cmds.hpp [new file with mode: 0644]
extras/vom/vom/route_cmds.cpp
extras/vom/vom/route_cmds.hpp
extras/vom/vom/route_domain_cmds.cpp
extras/vom/vom/route_domain_cmds.hpp
extras/vom/vom/rpc_cmd.hpp
extras/vom/vom/sub_interface_cmds.cpp
extras/vom/vom/tap_interface_cmds.cpp
extras/vom/vom/types.hpp
extras/vom/vom/vxlan_tunnel.cpp
extras/vom/vom/vxlan_tunnel_cmds.cpp
src/vnet/devices/pipe/pipe.api
src/vnet/devices/pipe/pipe_api.c
test/ext/vom_test.cpp
test/test_pipe.py

index 6c24d01..f976b6f 100644 (file)
@@ -127,6 +127,8 @@ libvom_la_SOURCES =                         \
        neighbour_cmds.cpp              \
        object_base.cpp                 \
        om.cpp                          \
+       pipe.cpp                        \
+       pipe_cmds.cpp                   \
        prefix.cpp                      \
        ra_config.cpp                   \
        ra_prefix.cpp                   \
@@ -214,6 +216,7 @@ vominclude_HEADERS =                        \
        neighbour.hpp                   \
        object_base.hpp                 \
        om.hpp                          \
+       pipe.hpp                        \
        prefix.hpp                      \
        ra_config.hpp                   \
        ra_prefix.hpp                   \
index 8c33cd4..062c1b9 100644 (file)
@@ -34,9 +34,7 @@ l3_bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 template <>
@@ -64,9 +62,7 @@ l3_unbind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 template <>
@@ -116,9 +112,7 @@ l2_bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 template <>
@@ -145,9 +139,7 @@ l2_unbind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 template <>
index b9af66e..8515b41 100644 (file)
@@ -29,7 +29,7 @@ namespace binding_cmds {
  * A command class that binds the ACL to the interface
  */
 template <typename BIND>
-class bind_cmd : public rpc_cmd<HW::item<bool>, rc_t, BIND>
+class bind_cmd : public rpc_cmd<HW::item<bool>, BIND>
 {
 public:
   /**
@@ -39,7 +39,7 @@ public:
            const direction_t& direction,
            const handle_t& itf,
            const handle_t& acl)
-    : rpc_cmd<HW::item<bool>, rc_t, BIND>(item)
+    : rpc_cmd<HW::item<bool>, BIND>(item)
     , m_direction(direction)
     , m_itf(itf)
     , m_acl(acl)
@@ -85,7 +85,7 @@ private:
  * A command class that binds the ACL to the interface
  */
 template <typename BIND>
-class unbind_cmd : public rpc_cmd<HW::item<bool>, rc_t, BIND>
+class unbind_cmd : public rpc_cmd<HW::item<bool>, BIND>
 {
 public:
   /**
@@ -95,7 +95,7 @@ public:
              const direction_t& direction,
              const handle_t& itf,
              const handle_t& acl)
-    : rpc_cmd<HW::item<bool>, rc_t, BIND>(item)
+    : rpc_cmd<HW::item<bool>, BIND>(item)
     , m_direction(direction)
     , m_itf(itf)
     , m_acl(acl)
index c05a428..0fa1d6d 100644 (file)
@@ -58,9 +58,7 @@ bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index f72a3fb..a294a75 100644 (file)
@@ -28,9 +28,8 @@ namespace acl_ethertype_cmds {
 /**
  * A command class that binds the ethertype list to the interface
  */
-class bind_cmd : public rpc_cmd<HW::item<bool>,
-                                rc_t,
-                                vapi::Acl_interface_set_etype_whitelist>
+class bind_cmd
+  : public rpc_cmd<HW::item<bool>, vapi::Acl_interface_set_etype_whitelist>
 {
 public:
   /**
@@ -69,9 +68,8 @@ private:
 /**
  * A command class that unbinds the ethertype list to the interface
  */
-class unbind_cmd : public rpc_cmd<HW::item<bool>,
-                                  rc_t,
-                                  vapi::Acl_interface_set_etype_whitelist>
+class unbind_cmd
+  : public rpc_cmd<HW::item<bool>, vapi::Acl_interface_set_etype_whitelist>
 {
 public:
   /**
index 2e59763..343b2e5 100644 (file)
@@ -74,7 +74,8 @@ l3_update_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
+
   if (m_hw_item.rc() == rc_t::OK)
     insert_acl();
 
@@ -140,7 +141,8 @@ l2_update_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
+
   if (m_hw_item.rc() == rc_t::OK)
     insert_acl();
 
index d24e752..ec69773 100644 (file)
@@ -29,8 +29,7 @@ namespace list_cmds {
  * A command class that Create the list
  */
 template <typename RULE, typename UPDATE>
-class update_cmd
-  : public rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, UPDATE>
+class update_cmd : public rpc_cmd<HW::item<handle_t>, UPDATE>
 {
 public:
   typedef typename list<RULE>::rules_t cmd_rules_t;
@@ -42,7 +41,7 @@ public:
   update_cmd(HW::item<handle_t>& item,
              const cmd_key_t& key,
              const cmd_rules_t& rules)
-    : rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, UPDATE>(item)
+    : rpc_cmd<HW::item<handle_t>, UPDATE>(item)
     , m_key(key)
     , m_rules(rules)
   {
@@ -78,7 +77,7 @@ public:
 
   void succeeded()
   {
-    rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, UPDATE>::succeeded();
+    rpc_cmd<HW::item<handle_t>, UPDATE>::succeeded();
     list<RULE>::add(m_key, this->item());
   }
 
@@ -124,14 +123,14 @@ private:
  * A cmd class that Deletes an ACL
  */
 template <typename RULE, typename DELETE>
-class delete_cmd : public rpc_cmd<HW::item<handle_t>, rc_t, DELETE>
+class delete_cmd : public rpc_cmd<HW::item<handle_t>, DELETE>
 {
 public:
   /**
    * Constructor
    */
   delete_cmd(HW::item<handle_t>& item)
-    : rpc_cmd<HW::item<handle_t>, rc_t, DELETE>(item)
+    : rpc_cmd<HW::item<handle_t>, DELETE>(item)
   {
   }
 
index 2314d53..6da956c 100644 (file)
@@ -41,9 +41,7 @@ bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index fcf0a4a..cafc142 100644 (file)
@@ -27,7 +27,7 @@ namespace arp_proxy_binding_cmds {
  * A command class that binds the LLDP config to the interface
  */
 class bind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Proxy_arp_intfc_enable_disable>
+  : public rpc_cmd<HW::item<bool>, vapi::Proxy_arp_intfc_enable_disable>
 {
 public:
   /**
@@ -60,7 +60,7 @@ private:
  * A cmd class that Unbinds ArpProxy Config from an interface
  */
 class unbind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Proxy_arp_intfc_enable_disable>
+  : public rpc_cmd<HW::item<bool>, vapi::Proxy_arp_intfc_enable_disable>
 {
 public:
   /**
index 122c51b..deb52c4 100644 (file)
@@ -48,7 +48,7 @@ config_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
+  wait();
 
   return (rc_t::OK);
 }
index 77abc74..d1a0a42 100644 (file)
@@ -27,7 +27,7 @@ namespace arp_proxy_config_cmds {
 /**
  * A command class that adds the ARP Proxy config
  */
-class config_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Proxy_arp_add_del>
+class config_cmd : public rpc_cmd<HW::item<bool>, vapi::Proxy_arp_add_del>
 {
 public:
   /**
@@ -62,8 +62,7 @@ private:
 /**
  * A cmd class that Unconfigs ArpProxy Config from an interface
  */
-class unconfig_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Proxy_arp_add_del>
+class unconfig_cmd : public rpc_cmd<HW::item<bool>, vapi::Proxy_arp_add_del>
 {
 public:
   /**
index 60721dd..e5d4f38 100644 (file)
@@ -161,7 +161,7 @@ bond_group_binding::event_handler::order() const
    * We want enslaved interfaces bind to bond after interface
    * but before anything else.
    */
-  return (dependency_t::BOND_BINDING);
+  return (dependency_t::VIRTUAL_INTERFACE);
 }
 
 void
index 3ffe981..b257f77 100644 (file)
@@ -45,9 +45,7 @@ bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 71c4f9f..3d9bfee 100644 (file)
@@ -26,7 +26,7 @@ namespace bond_group_binding_cmds {
 /**
  * A command class that binds the slave interface to the bond interface
  */
-class bind_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Bond_enslave>
+class bind_cmd : public rpc_cmd<HW::item<bool>, vapi::Bond_enslave>
 {
 public:
   /**
@@ -65,7 +65,7 @@ private:
 /**
  * A cmd class that detach slave from a bond interface
  */
-class unbind_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Bond_detach_slave>
+class unbind_cmd : public rpc_cmd<HW::item<bool>, vapi::Bond_detach_slave>
 {
 public:
   /**
index d59560d..a43a832 100644 (file)
@@ -51,7 +51,8 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
+
   if (m_hw_item.rc() == rc_t::OK) {
     insert_interface();
   }
index 824dcad..d404d5d 100644 (file)
@@ -49,9 +49,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 094de4c..9637e37 100644 (file)
@@ -27,7 +27,7 @@ namespace bridge_domain_arp_entry_cmds {
 /**
 * A command class that creates or updates the bridge domain ARP Entry
 */
-class create_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Bd_ip_mac_add_del>
+class create_cmd : public rpc_cmd<HW::item<bool>, vapi::Bd_ip_mac_add_del>
 {
 public:
   /**
@@ -62,7 +62,7 @@ private:
 /**
  * A cmd class that deletes a bridge domain ARP entry
  */
-class delete_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Bd_ip_mac_add_del>
+class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Bd_ip_mac_add_del>
 {
 public:
   /**
index d1d536f..0e533be 100644 (file)
@@ -55,9 +55,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
index 3257d83..0ab1bfa 100644 (file)
@@ -28,7 +28,7 @@ namespace bridge_domain_cmds {
  * A command class that creates an Bridge-Domain
  */
 class create_cmd
-  : public rpc_cmd<HW::item<uint32_t>, rc_t, vapi::Bridge_domain_add_del>
+  : public rpc_cmd<HW::item<uint32_t>, vapi::Bridge_domain_add_del>
 {
 public:
   /**
@@ -77,7 +77,7 @@ private:
  * A cmd class that Delete an Bridge-Domain
  */
 class delete_cmd
-  : public rpc_cmd<HW::item<uint32_t>, rc_t, vapi::Bridge_domain_add_del>
+  : public rpc_cmd<HW::item<uint32_t>, vapi::Bridge_domain_add_del>
 {
 public:
   /**
index f2a3ed9..ffdd02d 100644 (file)
@@ -51,9 +51,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index dc46719..dfee04f 100644 (file)
@@ -28,7 +28,7 @@ namespace bridge_domain_entry_cmds {
 /**
 * A command class that creates or updates the bridge_domain
 */
-class create_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::L2fib_add_del>
+class create_cmd : public rpc_cmd<HW::item<bool>, vapi::L2fib_add_del>
 {
 public:
   /**
@@ -65,7 +65,7 @@ private:
 /**
  * A cmd class that deletes a bridge_domain
  */
-class delete_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::L2fib_add_del>
+class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::L2fib_add_del>
 {
 public:
   /**
index 181a15f..9b632fe 100644 (file)
@@ -63,9 +63,7 @@ bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index e7db38f..89fe7ee 100644 (file)
@@ -29,7 +29,7 @@ namespace dhcp_client_cmds {
 /**
   * A command class that binds the DHCP config to the interface
   */
-class bind_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Dhcp_client_config>
+class bind_cmd : public rpc_cmd<HW::item<bool>, vapi::Dhcp_client_config>
 {
 public:
   /**
@@ -80,8 +80,7 @@ private:
 /**
  * A cmd class that Unbinds Dhcp Config from an interface
  */
-class unbind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Dhcp_client_config>
+class unbind_cmd : public rpc_cmd<HW::item<bool>, vapi::Dhcp_client_config>
 {
 public:
   /**
index a0e9b4a..1120f75 100644 (file)
@@ -36,14 +36,14 @@ namespace VOM {
  * The client can then 'pop' these events from this command object.
  */
 template <typename WANT, typename EVENT>
-class event_cmd : public rpc_cmd<HW::item<bool>, rc_t, WANT>
+class event_cmd : public rpc_cmd<HW::item<bool>, WANT>
 {
 public:
   /**
    * Default constructor
    */
   event_cmd(HW::item<bool>& b)
-    : rpc_cmd<HW::item<bool>, rc_t, WANT>(b)
+    : rpc_cmd<HW::item<bool>, WANT>(b)
   {
   }
 
index a98dc62..dea5350 100644 (file)
@@ -49,9 +49,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -94,9 +92,7 @@ delete_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 705c1a0..31b9a00 100644 (file)
@@ -27,8 +27,7 @@ namespace gbp_contract_cmds {
 /**
 * A command class that creates or updates the GBP contract
 */
-class create_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_contract_add_del>
+class create_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_contract_add_del>
 {
 public:
   /**
@@ -63,8 +62,7 @@ private:
 /**
  * A cmd class that deletes a GBP contract
  */
-class delete_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_contract_add_del>
+class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_contract_add_del>
 {
 public:
   /**
index 88d2f37..1f9078f 100644 (file)
@@ -54,9 +54,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -97,9 +95,7 @@ delete_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 2893ef5..dea4c2c 100644 (file)
@@ -27,8 +27,7 @@ namespace gbp_endpoint_cmds {
 /**
 * A command class that creates or updates the GBP endpoint
 */
-class create_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_endpoint_add_del>
+class create_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_endpoint_add_del>
 {
 public:
   /**
@@ -65,8 +64,7 @@ private:
 /**
  * A cmd class that deletes a GBP endpoint
  */
-class delete_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_endpoint_add_del>
+class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_endpoint_add_del>
 {
 public:
   /**
index 55e81d3..a7b46f8 100644 (file)
@@ -53,9 +53,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -92,9 +90,7 @@ delete_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 4da3a42..4cf88cf 100644 (file)
@@ -28,7 +28,7 @@ namespace gbp_endpoint_group_cmds {
 * A command class that creates or updates the GBP endpoint_group
 */
 class create_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_endpoint_group_add_del>
+  : public rpc_cmd<HW::item<bool>, vapi::Gbp_endpoint_group_add_del>
 {
 public:
   /**
@@ -66,7 +66,7 @@ private:
  * A cmd class that deletes a GBP endpoint_group
  */
 class delete_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_endpoint_group_add_del>
+  : public rpc_cmd<HW::item<bool>, vapi::Gbp_endpoint_group_add_del>
 {
 public:
   /**
index 757fcb9..b14697c 100644 (file)
@@ -49,9 +49,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -88,9 +86,7 @@ delete_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index fe17834..3c25d44 100644 (file)
@@ -27,8 +27,7 @@ namespace gbp_recirc_cmds {
 /**
 * A command class that creates or updates the GBP recirc
 */
-class create_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_recirc_add_del>
+class create_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_recirc_add_del>
 {
 public:
   /**
@@ -63,8 +62,7 @@ private:
 /**
  * A cmd class that deletes a GBP recirc
  */
-class delete_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_recirc_add_del>
+class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_recirc_add_del>
 {
 public:
   /**
index d087e5c..3816a59 100644 (file)
@@ -57,9 +57,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -105,9 +103,7 @@ delete_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 3dbc8db..118303b 100644 (file)
@@ -27,8 +27,7 @@ namespace gbp_subnet_cmds {
 /**
 * A command class that creates or updates the GBP subnet
 */
-class create_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_subnet_add_del>
+class create_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_subnet_add_del>
 {
 public:
   /**
@@ -67,8 +66,7 @@ private:
 /**
  * A cmd class that deletes a GBP subnet
  */
-class delete_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Gbp_subnet_add_del>
+class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Gbp_subnet_add_del>
 {
 public:
   /**
index e628c35..429c123 100644 (file)
@@ -30,9 +30,7 @@ poll::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
index b499cce..c10f71e 100644 (file)
@@ -27,7 +27,7 @@ namespace hw_cmds {
 /**
 *A command poll the HW for liveness
 */
-class poll : public rpc_cmd<HW::item<bool>, rc_t, vapi::Control_ping>
+class poll : public rpc_cmd<HW::item<bool>, vapi::Control_ping>
 {
 public:
   /**
index 92e14a7..a46b114 100644 (file)
@@ -114,6 +114,16 @@ public:
      */
     const static type_t BOND;
 
+    /**
+     * pipe-parent type
+     */
+    const static type_t PIPE;
+
+    /**
+     * pipe-end type
+     */
+    const static type_t PIPE_END;
+
     /**
      * Convert VPP's name of the interface to a type
      */
@@ -271,11 +281,11 @@ public:
    * A base class for interface Create commands
    */
   template <typename MSG>
-  class create_cmd : public rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>
+  class create_cmd : public rpc_cmd<HW::item<handle_t>, MSG>
   {
   public:
     create_cmd(HW::item<handle_t>& item, const std::string& name)
-      : rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>(item)
+      : rpc_cmd<HW::item<handle_t>, MSG>(item)
       , m_name(name)
     {
     }
@@ -298,7 +308,7 @@ public:
      */
     void succeeded()
     {
-      rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>::succeeded();
+      rpc_cmd<HW::item<handle_t>, MSG>::succeeded();
       interface::add(m_name, this->item());
     }
 
@@ -321,9 +331,7 @@ public:
         handle = sw_if_index;
       }
 
-      HW::item<handle_t> res(handle, rc);
-
-      this->fulfill(res);
+      this->fulfill(HW::item<handle_t>(handle, rc));
 
       return (VAPI_OK);
     }
@@ -339,17 +347,17 @@ public:
    * Base class for intterface Delete commands
    */
   template <typename MSG>
-  class delete_cmd : public rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>
+  class delete_cmd : public rpc_cmd<HW::item<handle_t>, MSG>
   {
   public:
     delete_cmd(HW::item<handle_t>& item, const std::string& name)
-      : rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>(item)
+      : rpc_cmd<HW::item<handle_t>, MSG>(item)
       , m_name(name)
     {
     }
 
     delete_cmd(HW::item<handle_t>& item)
-      : rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>(item)
+      : rpc_cmd<HW::item<handle_t>, MSG>(item)
       , m_name()
     {
     }
@@ -471,6 +479,7 @@ protected:
    */
   void set(const handle_t& handle);
   friend class interface_factory;
+  friend class pipe;
 
   /**
    * The SW interface handle VPP has asigned to the interface
index e78ed46..9e27725 100644 (file)
@@ -37,7 +37,7 @@ loopback_create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
 
   if (m_hw_item.rc() == rc_t::OK) {
     insert_interface();
@@ -74,7 +74,7 @@ af_packet_create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
 
   if (m_hw_item.rc() == rc_t::OK) {
     insert_interface();
@@ -120,7 +120,7 @@ vhost_create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
 
   if (m_hw_item.rc() == rc_t::OK) {
     insert_interface();
@@ -257,9 +257,7 @@ state_change_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -299,9 +297,7 @@ set_table_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
@@ -338,9 +334,7 @@ set_mac_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
@@ -380,9 +374,7 @@ collect_detail_stats_change_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
@@ -691,9 +683,7 @@ set_tag::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  wait();
-
-  return rc_t::OK;
+  return (wait());
 }
 std::string
 set_tag::to_string() const
index 1d0c4f5..b646e4e 100644 (file)
@@ -177,7 +177,7 @@ public:
  * A command class to set tag on interfaces
  */
 class set_tag
-  : public rpc_cmd<HW::item<handle_t>, rc_t, vapi::Sw_interface_tag_add_del>
+  : public rpc_cmd<HW::item<handle_t>, vapi::Sw_interface_tag_add_del>
 {
 public:
   /**
@@ -211,7 +211,6 @@ private:
  * A cmd class that changes the admin state
  */
 class state_change_cmd : public rpc_cmd<HW::item<interface::admin_state_t>,
-                                        rc_t,
                                         vapi::Sw_interface_set_flags>
 {
 public:
@@ -246,9 +245,8 @@ private:
 /**
  * A command class that binds an interface to an L3 table
  */
-class set_table_cmd : public rpc_cmd<HW::item<route::table_id_t>,
-                                     rc_t,
-                                     vapi::Sw_interface_set_table>
+class set_table_cmd
+  : public rpc_cmd<HW::item<route::table_id_t>, vapi::Sw_interface_set_table>
 {
 public:
   /**
@@ -289,9 +287,8 @@ private:
 /**
  * A command class that changes the MAC address on an interface
  */
-class set_mac_cmd : public rpc_cmd<HW::item<l2_address_t>,
-                                   rc_t,
-                                   vapi::Sw_interface_set_mac_address>
+class set_mac_cmd
+  : public rpc_cmd<HW::item<l2_address_t>, vapi::Sw_interface_set_mac_address>
 {
 public:
   /**
@@ -327,7 +324,6 @@ private:
  */
 class collect_detail_stats_change_cmd
   : public rpc_cmd<HW::item<interface::stats_type_t>,
-                   rc_t,
                    vapi::Collect_detailed_interface_stats>
 {
 public:
@@ -474,9 +470,7 @@ private:
  * A command class represents our desire to recieve interface stats
  */
 class stats_disable_cmd
-  : public rpc_cmd<HW::item<bool>,
-                   rc_t,
-                   vapi::Want_per_interface_combined_stats>
+  : public rpc_cmd<HW::item<bool>, vapi::Want_per_interface_combined_stats>
 {
 public:
   /**
index c417c1c..f442513 100644 (file)
@@ -79,6 +79,12 @@ interface_factory::new_interface(const vapi_payload_sw_interface_details& vd)
     sp = interface::find(hdl);
     if (sp && !tag.empty())
       sp->set(tag);
+  } else if (interface::type_t::PIPE == type) {
+    /*
+     * there's not enough information in a SW interface record to
+     * construct a pipe. so skip it. They have
+     * their own dump routines
+     */
   } else if ((name.find(".") != std::string::npos) && (0 != vd.sub_id)) {
     /*
      * Sub-interface
@@ -228,6 +234,24 @@ interface_factory::new_bond_member_interface(
   bond_member bm(*itf, mode, rate);
   return (bm);
 }
+
+std::shared_ptr<pipe>
+interface_factory::new_pipe_interface(const vapi_payload_pipe_details& payload)
+{
+  std::shared_ptr<pipe> sp;
+
+  handle_t hdl(payload.sw_if_index);
+  pipe::handle_pair_t hdl_pair(payload.pipe_sw_if_index[0],
+                               payload.pipe_sw_if_index[1]);
+
+  sp = pipe(payload.instance, interface::admin_state_t::UP).singular();
+
+  sp->set(hdl);
+  sp->set_ends(hdl_pair);
+
+  return (sp);
+}
+
 }; // namespace VOM
 
 /*
index 1bb60a8..120816b 100644 (file)
 
 #include <vapi/vapi.hpp>
 
+#include "vom/bond_interface.hpp"
 #include "vom/bond_member.hpp"
 #include "vom/interface.hpp"
+#include "vom/pipe.hpp"
 #include "vom/tap_interface.hpp"
 
 #include <vapi/af_packet.api.vapi.hpp>
 #include <vapi/bond.api.vapi.hpp>
 #include <vapi/interface.api.vapi.hpp>
+#include <vapi/pipe.api.vapi.hpp>
 #include <vapi/tap.api.vapi.hpp>
 #include <vapi/tapv2.api.vapi.hpp>
 #include <vapi/vhost_user.api.vapi.hpp>
@@ -57,6 +60,9 @@ public:
 
   static bond_member new_bond_member_interface(
     const vapi_payload_sw_interface_slave_details& vd);
+
+  static std::shared_ptr<pipe> new_pipe_interface(
+    const vapi_payload_pipe_details& payload);
 };
 };
 
index 22f545a..fa5a479 100644 (file)
@@ -131,14 +131,14 @@ public:
   /**
    * A functor class that binds the ra config to the interface
    */
-  class config_cmd : public rpc_cmd<HW::item<bool>, rc_t, CMD>
+  class config_cmd : public rpc_cmd<HW::item<bool>, CMD>
   {
   public:
     /**
      * Constructor
      */
     config_cmd(HW::item<bool>& item, const handle_t& itf, const class_t& cls)
-      : rpc_cmd<HW::item<bool>, rc_t, CMD>(item)
+      : rpc_cmd<HW::item<bool>, CMD>(item)
       , m_itf(itf)
       , m_cls(cls)
     {
@@ -184,14 +184,14 @@ public:
   /**
    * A cmd class that Unbinds L3 Config from an interface
    */
-  class unconfig_cmd : public rpc_cmd<HW::item<bool>, rc_t, CMD>
+  class unconfig_cmd : public rpc_cmd<HW::item<bool>, CMD>
   {
   public:
     /**
      * Constructor
      */
     unconfig_cmd(HW::item<bool>& item, const handle_t& itf, const class_t& cls)
-      : rpc_cmd<HW::item<bool>, rc_t, CMD>(item)
+      : rpc_cmd<HW::item<bool>, CMD>(item)
       , m_itf(itf)
       , m_cls(cls)
     {
index c6f53f0..b890963 100644 (file)
@@ -31,9 +31,7 @@ ip6nd_ra_config::config_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 template <>
@@ -68,9 +66,7 @@ ip6nd_ra_prefix::config_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 template <>
index 3b8b8d2..72bd610 100644 (file)
@@ -51,9 +51,7 @@ config_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index fa8096e..e83ed72 100644 (file)
@@ -29,7 +29,7 @@ namespace interface_span_cmds {
  * A command class that configures the interface span
  */
 class config_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_span_enable_disable>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_span_enable_disable>
 {
 public:
   /**
@@ -73,7 +73,7 @@ private:
  * A cmd class that Unconfigs interface span
  */
 class unconfig_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_span_enable_disable>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_span_enable_disable>
 {
 public:
   /**
index b20a385..7340037 100644 (file)
@@ -29,6 +29,8 @@ const interface::type_t interface::type_t::TAP(7, "TAP");
 const interface::type_t interface::type_t::TAPV2(8, "TAPV2");
 const interface::type_t interface::type_t::VHOST(9, "VHOST");
 const interface::type_t interface::type_t::BOND(10, "Bond");
+const interface::type_t interface::type_t::PIPE(11, "Pipe");
+const interface::type_t interface::type_t::PIPE_END(12, "Pipe-end");
 
 const interface::oper_state_t interface::oper_state_t::DOWN(0, "down");
 const interface::oper_state_t interface::oper_state_t::UP(1, "up");
@@ -66,6 +68,8 @@ interface::type_t::from_string(const std::string& str)
     return interface::type_t::TAPV2;
   } else if (str.find("bvi") != std::string::npos) {
     return interface::type_t::BVI;
+  } else if (str.find("pipe") != std::string::npos) {
+    return interface::type_t::PIPE;
   }
 
   return interface::type_t::UNKNOWN;
index fa7a115..227a150 100644 (file)
@@ -47,9 +47,7 @@ config_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 4003013..fdd0052 100644 (file)
@@ -29,7 +29,7 @@ namespace ip_unnumbered_cmds {
 *A command class that configures the IP unnumbered
 */
 class config_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_set_unnumbered>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_set_unnumbered>
 {
 public:
   /**
@@ -66,7 +66,7 @@ private:
  * A cmd class that Unconfigs L3 Config from an interface
  */
 class unconfig_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_set_unnumbered>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_set_unnumbered>
 {
 public:
   /**
index 0f91e4b..c072f67 100644 (file)
@@ -49,9 +49,7 @@ bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
@@ -142,9 +140,7 @@ set_vtr_op_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  wait();
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
index d105c18..3d138b1 100644 (file)
@@ -29,7 +29,7 @@ namespace l2_binding_cmds {
  * A functor class that binds L2 configuration to an interface
  */
 class bind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_set_l2_bridge>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_set_l2_bridge>
 {
 public:
   /**
@@ -72,7 +72,7 @@ private:
  * A cmd class that Unbinds L2 configuration from an interface
  */
 class unbind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_set_l2_bridge>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_set_l2_bridge>
 {
 public:
   /**
@@ -118,7 +118,6 @@ private:
  * A cmd class sets the VTR operation
  */
 class set_vtr_op_cmd : public rpc_cmd<HW::item<l2_binding::l2_vtr_op_t>,
-                                      rc_t,
                                       vapi::L2_interface_vlan_tag_rewrite>
 {
 public:
index 27f8483..fac764a 100644 (file)
@@ -42,9 +42,7 @@ enable_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
index aeff3a8..aab4af5 100644 (file)
@@ -27,7 +27,7 @@ namespace l2_emulation_cmds {
 /**
  * A functor class that enable L2 emulation to an interface
  */
-class enable_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::L2_emulation>
+class enable_cmd : public rpc_cmd<HW::item<bool>, vapi::L2_emulation>
 {
 public:
   /**
@@ -59,7 +59,7 @@ private:
 /**
  * A cmd class that Unbinds L2 configuration from an interface
  */
-class disable_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::L2_emulation>
+class disable_cmd : public rpc_cmd<HW::item<bool>, vapi::L2_emulation>
 {
 public:
   /**
index dc2c40c..37eca9e 100644 (file)
@@ -44,7 +44,7 @@ bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
+  wait();
 
   return (rc_t::OK);
 }
index fbb869f..db0e721 100644 (file)
@@ -30,7 +30,7 @@ namespace l2_xconnect_cmds {
  * A functor class that binds L2 configuration to an interface
  */
 class bind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_set_l2_xconnect>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_set_l2_xconnect>
 {
 public:
   /**
@@ -70,7 +70,7 @@ private:
  * A cmd class that Unbinds L2 configuration from an interface
  */
 class unbind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_set_l2_xconnect>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_set_l2_xconnect>
 {
 public:
   /**
index 66691f8..4afe13e 100644 (file)
@@ -48,9 +48,7 @@ bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 1387bc4..b7a30f8 100644 (file)
@@ -30,7 +30,7 @@ namespace l3_binding_cmds {
  * A functor class that binds the L3 config to the interface
  */
 class bind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_add_del_address>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_add_del_address>
 {
 public:
   /**
@@ -70,7 +70,7 @@ private:
  * A cmd class that Unbinds L3 Config from an interface
  */
 class unbind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_add_del_address>
+  : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_add_del_address>
 {
 public:
   /**
index 7dacdaf..8c27579 100644 (file)
@@ -49,9 +49,7 @@ bind_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index b303801..77ba8ee 100644 (file)
@@ -28,8 +28,7 @@ namespace lldp_binding_cmds {
 /**
 *A command class that binds the LLDP config to the interface
 */
-class bind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_set_lldp>
+class bind_cmd : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_set_lldp>
 {
 public:
   /**
@@ -68,8 +67,7 @@ private:
 /**
  * A cmd class that Unbinds Lldp Config from an interface
  */
-class unbind_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Sw_interface_set_lldp>
+class unbind_cmd : public rpc_cmd<HW::item<bool>, vapi::Sw_interface_set_lldp>
 {
 public:
   /**
index 8237114..7ea9b78 100644 (file)
@@ -48,9 +48,7 @@ config_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 621e73f..732c700 100644 (file)
@@ -28,7 +28,7 @@ namespace lldp_global_cmds {
 /**
  * A command class that binds the LLDP global to the interface
  */
-class config_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Lldp_config>
+class config_cmd : public rpc_cmd<HW::item<bool>, vapi::Lldp_config>
 {
 public:
   /**
index 4d98268..d67a082 100644 (file)
@@ -44,9 +44,7 @@ bind_44_input_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -86,9 +84,7 @@ unbind_44_input_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -128,9 +124,7 @@ bind_44_output_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -170,9 +164,7 @@ unbind_44_output_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -276,7 +268,7 @@ bind_66_input_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
+  wait();
 
   return rc_t::OK;
 }
@@ -318,7 +310,7 @@ unbind_66_input_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
+  wait();
 
   return rc_t::OK;
 }
index aa5a200..9b59d0d 100644 (file)
@@ -28,7 +28,7 @@ namespace nat_binding_cmds {
  * A functor class that binds a NAT configuration to an input interface
  */
 class bind_44_input_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Nat44_interface_add_del_feature>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat44_interface_add_del_feature>
 {
 public:
   /**
@@ -68,7 +68,7 @@ private:
  * A cmd class that unbinds a NAT configuration from an input interface
  */
 class unbind_44_input_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Nat44_interface_add_del_feature>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat44_interface_add_del_feature>
 {
 public:
   /**
@@ -108,9 +108,7 @@ private:
  * A functor class that binds a NAT configuration to an output interface
  */
 class bind_44_output_cmd
-  : public rpc_cmd<HW::item<bool>,
-                   rc_t,
-                   vapi::Nat44_interface_add_del_output_feature>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat44_interface_add_del_output_feature>
 {
 public:
   /**
@@ -150,9 +148,7 @@ private:
  * A cmd class that unbinds a NAT configuration from an output interface
  */
 class unbind_44_output_cmd
-  : public rpc_cmd<HW::item<bool>,
-                   rc_t,
-                   vapi::Nat44_interface_add_del_output_feature>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat44_interface_add_del_output_feature>
 {
 public:
   /**
@@ -260,7 +256,7 @@ private:
 * A functor class that binds a NAT configuration to an input interface
 */
 class bind_66_input_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Nat66_add_del_interface>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat66_add_del_interface>
 {
 public:
   /**
@@ -300,7 +296,7 @@ private:
  * A cmd class that unbinds a NAT configuration from an input interface
  */
 class unbind_66_input_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Nat66_add_del_interface>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat66_add_del_interface>
 {
 public:
   /**
index a80e474..299f2f5 100644 (file)
@@ -55,9 +55,7 @@ create_44_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
@@ -178,9 +176,7 @@ create_66_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index 95061ca..8d514d8 100644 (file)
@@ -28,7 +28,7 @@ namespace nat_static_cmds {
  * A command class that creates NAT 44 static mapping
  */
 class create_44_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Nat44_add_del_static_mapping>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat44_add_del_static_mapping>
 {
 public:
   /**
@@ -64,7 +64,7 @@ private:
  * A cmd class that deletes a NAT 44 static mapping
  */
 class delete_44_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Nat44_add_del_static_mapping>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat44_add_del_static_mapping>
 {
 public:
   /**
@@ -133,7 +133,7 @@ private:
  * A command class that creates NAT 66 static mapping
  */
 class create_66_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Nat66_add_del_static_mapping>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat66_add_del_static_mapping>
 {
 public:
   /**
@@ -169,7 +169,7 @@ private:
  * A cmd class that deletes a NAT 66 static mapping
  */
 class delete_66_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Nat66_add_del_static_mapping>
+  : public rpc_cmd<HW::item<bool>, vapi::Nat66_add_del_static_mapping>
 {
 public:
   /**
index 63534f3..9bd3292 100644 (file)
@@ -49,9 +49,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index fe6dd15..388dbf1 100644 (file)
@@ -27,8 +27,8 @@ namespace neighbour_cmds {
 /**
  * A command class that creates or updates the bridge domain ARP Entry
  */
-class create_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Ip_neighbor_add_del>
+class create_cmd : public rpc_cmd<HW::item<bool>,
+                                  vapi::Ip_neighbor_add_del>
 {
 public:
   /**
@@ -63,8 +63,8 @@ private:
 /**
  * A cmd class that deletes a bridge domain ARP entry
  */
-class delete_cmd
-  : public rpc_cmd<HW::item<bool>, rc_t, vapi::Ip_neighbor_add_del>
+class delete_cmd : public rpc_cmd<HW::item<bool>,
+                                  vapi::Ip_neighbor_add_del>
 {
 public:
   /**
diff --git a/extras/vom/vom/pipe.cpp b/extras/vom/vom/pipe.cpp
new file mode 100644 (file)
index 0000000..9e10aeb
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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.
+ */
+
+#include "vom/pipe.hpp"
+#include "vom/interface_factory.hpp"
+#include "vom/pipe_cmds.hpp"
+#include "vom/singular_db_funcs.hpp"
+
+namespace VOM {
+
+typedef enum end_t_ {
+  EAST = 0,
+  WEST,
+} end_t;
+#define N_ENDS (WEST + 1)
+
+pipe::event_handler pipe::m_evh;
+
+static const std::string
+pipe_mk_name(uint32_t instance)
+{
+  return ("pipe" + std::to_string(instance));
+}
+
+/**
+ * Construct a new object matching the desried state
+ */
+pipe::pipe(uint32_t instance, admin_state_t state)
+  : interface(pipe_mk_name(instance), type_t::PIPE, state)
+  , m_instance(instance)
+{
+}
+
+pipe::~pipe()
+{
+  sweep();
+  release();
+}
+
+pipe::pipe(const pipe& o)
+  : interface(o)
+  , m_instance(o.m_instance)
+{
+}
+
+std::string
+pipe::to_string(void) const
+{
+  std::ostringstream s;
+
+  s << "[pipe: " << interface::to_string() << " instance:" << m_instance
+    << " ends:[" << m_hdl_pair.rc().to_string() << " "
+    << m_hdl_pair.data().first << ", " << m_hdl_pair.data().second << "]]";
+
+  return (s.str());
+}
+
+std::queue<cmd*>&
+pipe::mk_create_cmd(std::queue<cmd*>& q)
+{
+  q.push(new pipe_cmds::create_cmd(m_hdl, m_name, m_instance, m_hdl_pair));
+
+  return (q);
+}
+
+std::queue<cmd*>&
+pipe::mk_delete_cmd(std::queue<cmd*>& q)
+{
+  q.push(new pipe_cmds::delete_cmd(m_hdl, m_hdl_pair));
+
+  return (q);
+}
+
+std::shared_ptr<pipe>
+pipe::singular() const
+{
+  return std::dynamic_pointer_cast<pipe>(singular_i());
+}
+
+std::shared_ptr<interface>
+pipe::singular_i() const
+{
+  return m_db.find_or_add(key(), *this);
+}
+
+std::shared_ptr<pipe>
+pipe::find(const key_t& k)
+{
+  return std::dynamic_pointer_cast<pipe>(m_db.find(k));
+}
+
+std::shared_ptr<interface>
+pipe::west()
+{
+  if (!m_ends[WEST]) {
+    if (rc_t::OK == m_hdl_pair.rc()) {
+      m_ends[WEST] = pipe_end(*this, WEST).singular();
+      m_ends[WEST]->set(m_hdl_pair.data().first);
+    }
+  }
+
+  return (m_ends[WEST]);
+}
+
+std::shared_ptr<interface>
+pipe::east()
+{
+  if (!m_ends[EAST]) {
+    if (rc_t::OK == m_hdl_pair.rc()) {
+      m_ends[EAST] = pipe_end(*this, EAST).singular();
+      m_ends[EAST]->set(m_hdl_pair.data().first);
+    }
+  }
+
+  return (m_ends[EAST]);
+}
+
+pipe::pipe_end::pipe_end(const pipe& p, uint8_t id)
+  : interface(p.name() + "." + std::to_string(id),
+              interface::type_t::PIPE_END,
+              interface::admin_state_t::UP)
+  , m_pipe(p.singular())
+{
+}
+
+std::queue<cmd*>&
+pipe::pipe_end::mk_create_cmd(std::queue<cmd*>& q)
+{
+  return (q);
+}
+
+std::queue<cmd*>&
+pipe::pipe_end::mk_delete_cmd(std::queue<cmd*>& q)
+{
+  return (q);
+}
+
+void
+pipe::set_ends(const handle_pair_t& p)
+{
+  if (handle_t::INVALID != p.first && handle_t::INVALID != p.second) {
+    m_hdl_pair = { p, rc_t::OK };
+  } else {
+    m_hdl_pair = { p, rc_t::INVALID };
+  }
+}
+
+pipe::event_handler::event_handler()
+{
+  OM::register_listener(this);
+  inspect::register_handler({ "pipe" }, "pipes", this);
+}
+
+void
+pipe::event_handler::handle_replay()
+{
+  // m_db.replay();
+}
+
+void
+pipe::event_handler::handle_populate(const client_db::key_t& key)
+{
+  std::shared_ptr<pipe_cmds::dump_cmd> cmd =
+    std::make_shared<pipe_cmds::dump_cmd>();
+
+  HW::enqueue(cmd);
+  HW::write();
+
+  for (auto& record : *cmd) {
+    std::shared_ptr<pipe> sp;
+
+    sp = interface_factory::new_pipe_interface(record.get_payload());
+
+    VOM_LOG(log_level_t::DEBUG) << " pipe-dump: " << sp->to_string();
+    OM::commit(key, *sp);
+  }
+}
+
+dependency_t
+pipe::event_handler::order() const
+{
+  return (dependency_t::VIRTUAL_INTERFACE);
+}
+
+void
+pipe::event_handler::show(std::ostream& os)
+{
+  db_dump(m_db, os);
+}
+
+}; // namespace VOM
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
diff --git a/extras/vom/vom/pipe.hpp b/extras/vom/vom/pipe.hpp
new file mode 100644 (file)
index 0000000..7da3a1f
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * 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.
+ */
+
+#ifndef __VOM_PIPE_H__
+#define __VOM_PIPE_H__
+
+#include "vom/interface.hpp"
+
+namespace VOM {
+/**
+ * A Pipe interface.
+ * A pipe is composed for 3 'interfaces'.
+ *  1) the 'parent' interface - this is used as the 'key' for the pipe
+ *  2) the two 'ends' of the pipe - these are used to RX/TX packets
+ *     form/to. The ends are retreivable using the east()/west() functions.
+ *     The east and west end are exactly equivalent, they are merely
+ *     named differently for logical purposes.
+ */
+class pipe : public interface
+{
+public:
+  typedef std::pair<handle_t, handle_t> handle_pair_t;
+
+  /**
+   * Construct a new object matching the desried state
+   */
+  pipe(uint32_t instance, admin_state_t state);
+
+  /**
+   * Destructor
+   */
+  ~pipe();
+
+  /**
+   * Copy Constructor
+   */
+  pipe(const pipe& o);
+
+  /**
+   * comparison operator - for UT
+   */
+  bool operator==(const pipe& s) const;
+
+  /**
+   * Return the matching 'singular instance' of the sub-interface
+   */
+  std::shared_ptr<pipe> singular() const;
+
+  /**
+   * Find a subinterface from its key
+   */
+  static std::shared_ptr<pipe> find(const key_t& k);
+
+  /**
+   * The interface that is the east end of the pipe
+   */
+  std::shared_ptr<interface> east();
+
+  /**
+   * The interface that is the west end of the pipe.
+   * The east and west end are exactly equivalent, they are merely
+   * named differently for logical purposes.
+   */
+  std::shared_ptr<interface> west();
+
+  virtual std::string to_string(void) const;
+
+  void set_ends(const handle_pair_t& p);
+
+private:
+  /**
+   * The interface type that forms the ends of the pipe
+   */
+  class pipe_end : public interface
+  {
+  public:
+    pipe_end(const pipe& p, uint8_t id);
+
+  private:
+    virtual std::queue<cmd*>& mk_create_cmd(std::queue<cmd*>& cmds);
+    virtual std::queue<cmd*>& mk_delete_cmd(std::queue<cmd*>& cmds);
+
+    std::shared_ptr<pipe> m_pipe;
+  };
+
+  /**
+*Class definition for listeners to OM events
+*/
+  class event_handler : public OM::listener, public inspect::command_handler
+  {
+  public:
+    event_handler();
+    virtual ~event_handler() = default;
+
+    /**
+     * Handle a populate event
+     */
+    void handle_populate(const client_db::key_t& key);
+
+    /**
+     * Handle a replay event
+     */
+    void handle_replay();
+
+    /**
+     * Show the object in the Singular DB
+     */
+    void show(std::ostream& os);
+
+    /**
+     * Get the sortable Id of the listener
+     */
+    dependency_t order() const;
+  };
+  static event_handler m_evh;
+
+  /**
+   * Return the matching 'instance' of the pipe
+   *  over-ride from the base class
+   */
+  std::shared_ptr<interface> singular_i() const;
+
+  /**
+   * Virtual functions to construct an interface create commands.
+   */
+  virtual std::queue<cmd*>& mk_create_cmd(std::queue<cmd*>& cmds);
+
+  /**
+   * Virtual functions to construct an interface delete commands.
+   */
+  virtual std::queue<cmd*>& mk_delete_cmd(std::queue<cmd*>& cmds);
+
+  /**
+   * the handles that are set during the create command
+   */
+  HW::item<handle_pair_t> m_hdl_pair;
+
+  /**
+   * The ends of the pipe
+   */
+  std::shared_ptr<interface> m_ends[2];
+
+  /**
+   * Instance number
+   */
+  uint32_t m_instance;
+};
+
+}; // namespace VOM
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
+
+#endif
diff --git a/extras/vom/vom/pipe_cmds.cpp b/extras/vom/vom/pipe_cmds.cpp
new file mode 100644 (file)
index 0000000..9215efe
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * 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.
+ */
+
+#include "vom/pipe_cmds.hpp"
+
+DEFINE_VAPI_MSG_IDS_PIPE_API_JSON;
+
+namespace VOM {
+namespace pipe_cmds {
+
+create_cmd::create_cmd(HW::item<handle_t>& item,
+                       const std::string& name,
+                       uint32_t instance,
+                       HW::item<pipe::handle_pair_t>& ends)
+  : interface::create_cmd<vapi::Pipe_create>(item, name)
+  , m_hdl_pair(ends)
+  , m_instance(instance)
+{
+}
+
+bool
+create_cmd::operator==(const create_cmd& other) const
+{
+  return (m_name == other.m_name);
+}
+
+vapi_error_e
+create_cmd::operator()(vapi::Pipe_create& reply)
+{
+  auto& payload = reply.get_response().get_payload();
+
+  VOM_LOG(log_level_t::DEBUG) << to_string() << " " << payload.retval;
+
+  const rc_t& rc = rc_t::from_vpp_retval(payload.retval);
+
+  m_hdl_pair = { pipe::handle_pair_t(payload.pipe_sw_if_index[0],
+                                     payload.pipe_sw_if_index[1]),
+                 rc };
+
+  fulfill(HW::item<handle_t>(payload.sw_if_index, rc));
+
+  return (VAPI_OK);
+}
+rc_t
+create_cmd::issue(connection& con)
+{
+  msg_t req(con.ctx(), std::ref(*this));
+
+  auto& payload = req.get_request().get_payload();
+
+  payload.is_specified = 1;
+  payload.user_instance = m_instance;
+
+  VAPI_CALL(req.execute());
+
+  if (rc_t::OK == wait()) {
+    insert_interface();
+  }
+
+  return rc_t::OK;
+}
+
+std::string
+create_cmd::to_string() const
+{
+  std::ostringstream s;
+
+  s << "pipe-create: " << m_name << " instance:" << m_instance;
+
+  return (s.str());
+}
+
+delete_cmd::delete_cmd(HW::item<handle_t>& item,
+                       HW::item<pipe::handle_pair_t>& end_pair)
+  : interface::delete_cmd<vapi::Pipe_delete>(item)
+  , m_hdl_pair(end_pair)
+{
+}
+
+bool
+delete_cmd::operator==(const delete_cmd& other) const
+{
+  return (m_hw_item == other.m_hw_item);
+}
+
+rc_t
+delete_cmd::issue(connection& con)
+{
+  msg_t req(con.ctx(), std::ref(*this));
+
+  VAPI_CALL(req.execute());
+
+  wait();
+  m_hw_item.set(rc_t::NOOP);
+  m_hdl_pair.set(rc_t::NOOP);
+
+  remove_interface();
+
+  return (rc_t::OK);
+}
+
+std::string
+delete_cmd::to_string() const
+{
+  return ("pipe-delete");
+}
+
+bool
+dump_cmd::operator==(const dump_cmd& other) const
+{
+  return (true);
+}
+
+rc_t
+dump_cmd::issue(connection& con)
+{
+  m_dump.reset(new msg_t(con.ctx(), std::ref(*this)));
+
+  VAPI_CALL(m_dump->execute());
+
+  wait();
+
+  return rc_t::OK;
+}
+
+std::string
+dump_cmd::to_string() const
+{
+  return ("pipe-dump");
+}
+
+} // namespace pipe_cmds
+} // namespace VOM
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
diff --git a/extras/vom/vom/pipe_cmds.hpp b/extras/vom/vom/pipe_cmds.hpp
new file mode 100644 (file)
index 0000000..8c26fd6
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * 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.
+ */
+
+#ifndef __VOM_PIPE_CMDS_H__
+#define __VOM_PIPE_CMDS_H__
+
+#include "vom/dump_cmd.hpp"
+#include "vom/pipe.hpp"
+#include "vom/rpc_cmd.hpp"
+
+#include <vapi/pipe.api.vapi.hpp>
+
+namespace VOM {
+namespace pipe_cmds {
+/**
+ * A functor class that creates an interface
+ */
+class create_cmd : public interface::create_cmd<vapi::Pipe_create>
+{
+public:
+  /**
+   * Cstrunctor taking the reference to the parent
+   * and the sub-interface's VLAN
+   */
+  create_cmd(HW::item<handle_t>& item,
+             const std::string& name,
+             uint32_t instance,
+             HW::item<pipe::handle_pair_t>& ends);
+
+  /**
+   * Issue the command to VPP/HW
+   */
+  rc_t issue(connection& con);
+
+  /**
+   * convert to string format for debug purposes
+   */
+  std::string to_string() const;
+
+  /**
+   * Comparison operator - only used for UT
+   */
+  bool operator==(const create_cmd& i) const;
+
+  virtual vapi_error_e operator()(vapi::Pipe_create& reply);
+
+private:
+  HW::item<pipe::handle_pair_t>& m_hdl_pair;
+  uint32_t m_instance;
+};
+
+/**
+ * A cmd class that Delete an interface
+ */
+class delete_cmd : public interface::delete_cmd<vapi::Pipe_delete>
+{
+public:
+  /**
+   * Constructor
+   */
+  delete_cmd(HW::item<handle_t>& item, HW::item<pipe::handle_pair_t>& end_pair);
+
+  /**
+   * Issue the command to VPP/HW
+   */
+  rc_t issue(connection& con);
+
+  /**
+   * convert to string format for debug purposes
+   */
+  std::string to_string() const;
+
+  /**
+   * Comparison operator - only used for UT
+   */
+  bool operator==(const delete_cmd& i) const;
+
+private:
+  HW::item<pipe::handle_pair_t>& m_hdl_pair;
+};
+
+/**
+ * A cmd class that Dumps all the Vpp interfaces
+ */
+class dump_cmd : public VOM::dump_cmd<vapi::Pipe_dump>
+{
+public:
+  /**
+   * Default Constructor
+   */
+  dump_cmd() = default;
+
+  /**
+   * Issue the command to VPP/HW
+   */
+  rc_t issue(connection& con);
+  /**
+   * convert to string format for debug purposes
+   */
+  std::string to_string() const;
+
+  /**
+   * Comparison operator - only used for UT
+   */
+  bool operator==(const dump_cmd& i) const;
+};
+
+}; // namespace pipe_cmds
+}; // namespace VOM
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "mozilla")
+ * End:
+ */
+
+#endif
index 83d44cc..240592f 100644 (file)
@@ -100,9 +100,7 @@ update_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return rc_t::OK;
+  return (wait());
 }
 
 std::string
index f2c10ff..2e6ce73 100644 (file)
@@ -29,7 +29,7 @@ namespace ip_route_cmds {
 /**
  * A command class that creates or updates the route
  */
-class update_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Ip_add_del_route>
+class update_cmd : public rpc_cmd<HW::item<bool>, vapi::Ip_add_del_route>
 {
 public:
   /**
@@ -64,7 +64,7 @@ private:
 /**
  * A cmd class that deletes a route
  */
-class delete_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Ip_add_del_route>
+class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Ip_add_del_route>
 {
 public:
   /**
index 845497f..9eb5043 100644 (file)
@@ -45,9 +45,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item.set(wait());
-
-  return (rc_t::OK);
+  return (wait());
 }
 
 std::string
index f3911bd..6ac679b 100644 (file)
@@ -27,7 +27,7 @@ namespace route_domain_cmds {
 /**
  * A command class that creates the IP table
  */
-class create_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Ip_table_add_del>
+class create_cmd : public rpc_cmd<HW::item<bool>, vapi::Ip_table_add_del>
 {
 public:
   /**
@@ -65,7 +65,7 @@ private:
 /**
  * A cmd class that Deletes the IP Table
  */
-class delete_cmd : public rpc_cmd<HW::item<bool>, rc_t, vapi::Ip_table_add_del>
+class delete_cmd : public rpc_cmd<HW::item<bool>, vapi::Ip_table_add_del>
 {
 public:
   /**
index 84b6717..1996f4b 100644 (file)
@@ -34,7 +34,7 @@ namespace VOM {
  * The command is templatised on the type of the HW::item to be set by
  * the command, and the data returned in the promise,
  */
-template <typename HWITEM, typename DATA, typename MSG>
+template <typename HWITEM, typename MSG>
 class rpc_cmd : public cmd
 {
 public:
@@ -71,34 +71,27 @@ public:
   /**
    * Fulfill the commands promise. Called from the RX thread
    */
-  void fulfill(const DATA& d)
-  {
-    m_promise.set_value(d);
-
-    /*
-     * we reset the promise after setting the value to reuse it
-     * when we run the retire command from the same cmd object
-     */
-    //    m_promise = std::promise<DATA>();
-  }
+  void fulfill(const HWITEM& d) { m_promise.set_value(d); }
 
   /**
    * Wait on the commands promise. i.e. block on the completion
    * of the command.
    */
-  DATA wait()
+  rc_t wait()
   {
     std::future_status status;
-    std::future<DATA> result;
+    std::future<HWITEM> result;
 
     result = m_promise.get_future();
     status = result.wait_for(std::chrono::seconds(5));
 
     if (status != std::future_status::ready) {
-      return (DATA(rc_t::TIMEOUT));
+      m_hw_item.set(rc_t::TIMEOUT);
+    } else {
+      m_hw_item = result.get();
     }
 
-    return (result.get());
+    return (m_hw_item.rc());
   }
 
   /**
@@ -116,9 +109,13 @@ public:
    */
   virtual vapi_error_e operator()(MSG& reply)
   {
+    HWITEM hi = m_hw_item;
     int retval = reply.get_response().get_payload().retval;
     VOM_LOG(log_level_t::DEBUG) << to_string() << " " << retval;
-    fulfill(rc_t::from_vpp_retval(retval));
+
+    /* set a temporary value in this callback thread */
+    hi.set(rc_t::from_vpp_retval(retval));
+    fulfill(hi);
 
     return (VAPI_OK);
   }
@@ -137,7 +134,7 @@ protected:
   /**
    * The promise that implements the synchronous issue
    */
-  std::promise<DATA> m_promise;
+  std::promise<HWITEM> m_promise;
 };
 };
 
index 47af692..853a9b6 100644 (file)
@@ -49,7 +49,7 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
 
   if (m_hw_item.rc() == rc_t::OK) {
     insert_interface();
index 763ded5..4ebd2be 100644 (file)
@@ -61,12 +61,12 @@ tap_create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
   if (m_hw_item.rc() == rc_t::OK) {
     insert_interface();
   }
 
-  return rc_t::OK;
+  return (m_hw_item.rc());
 }
 
 std::string
index 53654c5..7b08d83 100644 (file)
@@ -53,15 +53,9 @@ enum class dependency_t
   INTERFACE,
 
   /**
-   * bond group binding is after interfaces but before
-   * anything else
+   * virtual interfaces - those that depend on some real interface
    */
-  BOND_BINDING,
-
-  /**
-   * Tunnel or virtual interfaces next
-   */
-  TUNNEL,
+  VIRTUAL_INTERFACE,
 
   /**
    * Tables in which entries are added, e.g bridge/route-domains
@@ -89,8 +83,6 @@ enum class dependency_t
  */
 struct rc_t : public enum_base<rc_t>
 {
-  rc_t(const rc_t& rc) = default;
-
   /**
    * Destructor
    */
index 3d5ed64..9e7c01d 100644 (file)
@@ -246,7 +246,7 @@ vxlan_tunnel::event_handler::handle_replay()
 dependency_t
 vxlan_tunnel::event_handler::order() const
 {
-  return (dependency_t::TUNNEL);
+  return (dependency_t::VIRTUAL_INTERFACE);
 }
 
 void
index ca4ccf3..dcc06e7 100644 (file)
@@ -51,9 +51,9 @@ create_cmd::issue(connection& con)
 
   VAPI_CALL(req.execute());
 
-  m_hw_item = wait();
+  wait();
 
-  if (m_hw_item) {
+  if (rc_t::OK == m_hw_item.rc()) {
     insert_interface();
   }
 
index d3dfd16..55b93fd 100644 (file)
@@ -38,28 +38,28 @@ define pipe_create
 /** \brief Reply for pipe create reply
     @param context - returned sender context, to match reply w/ request
     @param retval - return code
-    @param parent_sw_if_index - software index allocated for the new pipe parent interface
-                                Use the parent interface for link up/down and to delete
+    @param sw_if_index - software index allocated for the new pipe parent interface
+                         Use the parent interface for link up/down and to delete
     @param pipe_sw_if_index - the two SW indicies that form the ends of the pipe.
 */
 define pipe_create_reply
 {
   u32 context;
   i32 retval;
-  u32 parent_sw_if_index;
+  u32 sw_if_index;
   u32 pipe_sw_if_index[2];
 };
 
 /** \brief Delete pipe interface
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
-    @param parnet_sw_if_index - interface index of existing pipe interface
+    @param sw_if_index - interface index of existing pipe interface
 */
 autoreply define pipe_delete
 {
   u32 client_index;
   u32 context;
-  u32 parent_sw_if_index;
+  u32 sw_if_index;
 };
 
 /** \brief Dump pipe interfaces request */
@@ -71,14 +71,14 @@ define pipe_dump
 
 /** \brief Reply for pipe dump request
     @param sw_if_index - software index of pipe interface
-    @param parent_sw_if_index - software index allocated for the pipe parent interface
+    @param sw_if_index - software index allocated for the pipe parent interface
     @param pipe_sw_if_index - the two SW indicies that form the ends of the pipe.
     @param instance - instance allocated
 */
 define pipe_details
 {
   u32 context;
-  u32 parent_sw_if_index;
+  u32 sw_if_index;
   u32 pipe_sw_if_index[2];
   u32 instance;
 };
index 46bbea5..cb67d1f 100644 (file)
@@ -59,7 +59,7 @@ vl_api_pipe_create_t_handler (vl_api_pipe_create_t * mp)
   /* *INDENT-OFF* */
   REPLY_MACRO2(VL_API_PIPE_CREATE_REPLY,
   ({
-    rmp->parent_sw_if_index = ntohl (parent_sw_if_index);
+    rmp->sw_if_index = ntohl (parent_sw_if_index);
     rmp->pipe_sw_if_index[0] = ntohl (pipe_sw_if_index[0]);
     rmp->pipe_sw_if_index[1] = ntohl (pipe_sw_if_index[1]);
   }));
@@ -72,7 +72,7 @@ vl_api_pipe_delete_t_handler (vl_api_pipe_delete_t * mp)
   vl_api_pipe_delete_reply_t *rmp;
   int rv;
 
-  rv = vnet_delete_pipe_interface (ntohl (mp->parent_sw_if_index));
+  rv = vnet_delete_pipe_interface (ntohl (mp->sw_if_index));
 
   REPLY_MACRO (VL_API_PIPE_DELETE_REPLY);
 }
@@ -98,7 +98,7 @@ pipe_send_details (u32 parent_sw_if_index,
   mp->context = ctx->context;
 
   mp->instance = ntohl (instance);
-  mp->parent_sw_if_index = ntohl (parent_sw_if_index);
+  mp->sw_if_index = ntohl (parent_sw_if_index);
   mp->pipe_sw_if_index[0] = ntohl (pipe_sw_if_index[0]);
   mp->pipe_sw_if_index[1] = ntohl (pipe_sw_if_index[1]);
 
index 0213c42..5ccdf55 100644 (file)
@@ -67,6 +67,8 @@
 #include "vom/nat_static_cmds.hpp"
 #include "vom/nat_binding.hpp"
 #include "vom/nat_binding_cmds.hpp"
+#include "vom/pipe.hpp"
+#include "vom/pipe_cmds.hpp"
 
 using namespace boost;
 using namespace VOM;
@@ -427,6 +429,14 @@ public:
                     {
                         rc = handle_derived<interface_cmds::events_cmd>(f_exp, f_act);
                     }
+                    else if (typeid(*f_exp) == typeid(pipe_cmds::create_cmd))
+                    {
+                        rc = handle_derived<pipe_cmds::create_cmd>(f_exp, f_act);
+                    }
+                    else if (typeid(*f_exp) == typeid(pipe_cmds::delete_cmd))
+                    {
+                        rc = handle_derived<pipe_cmds::delete_cmd>(f_exp, f_act);
+                    }
                     else
                     {
                         throw ExpException(2);
@@ -1860,4 +1870,72 @@ BOOST_AUTO_TEST_CASE(test_prefixes) {
 
 }
 
+BOOST_AUTO_TEST_CASE(test_pipes) {
+    VppInit vi;
+    const std::string gk = "GKChesterton";
+
+    const std::string pipe_name_1 = "pipe1";
+    VOM::pipe pipe1(1, interface::admin_state_t::UP);
+    HW::item<handle_t> hw_hdl(4, rc_t::OK);
+    HW::item<pipe::handle_pair_t> hw_hdl_pair(std::make_pair(5,6), rc_t::OK);
+
+    HW::item<interface::admin_state_t> hw_as_up(interface::admin_state_t::UP,
+                                                rc_t::OK);
+    HW::item<interface::admin_state_t> hw_as_down(interface::admin_state_t::DOWN,
+                                                  rc_t::OK);
+    ADD_EXPECT(pipe_cmds::create_cmd(hw_hdl, pipe_name_1, 1, hw_hdl_pair));
+    ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_hdl));
+    TRY_CHECK_RC(OM::write(gk, pipe1));
+
+    pipe1.set_ends(hw_hdl_pair.data());
+
+    // put each end of the pipe in a BD
+    bridge_domain bd1(33, bridge_domain::learning_mode_t::OFF,
+                      bridge_domain::arp_term_mode_t::OFF,
+                      bridge_domain::flood_mode_t::OFF,
+                      bridge_domain::mac_age_mode_t::ON);
+
+    HW::item<uint32_t> hw_bd(33, rc_t::OK);
+    ADD_EXPECT(bridge_domain_cmds::create_cmd(hw_bd,
+                                              bridge_domain::learning_mode_t::OFF,
+                                              bridge_domain::arp_term_mode_t::OFF,
+                                              bridge_domain::flood_mode_t::OFF,
+                                              bridge_domain::mac_age_mode_t::ON));
+
+    TRY_CHECK_RC(OM::write(gk, bd1));
+
+    l2_binding *l2_1 = new l2_binding(*pipe1.east(), bd1);
+    HW::item<bool> hw_l2_1_bind(true, rc_t::OK);
+
+    ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_1_bind,
+                                         pipe1.east()->handle(),
+                                         hw_bd.data(), false));
+    TRY_CHECK_RC(OM::write(gk, *l2_1));
+
+    l2_binding *l2_2 = new l2_binding(*pipe1.west(), bd1);
+    HW::item<bool> hw_l2_2_bind(true, rc_t::OK);
+
+    ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_2_bind,
+                                         pipe1.west()->handle(),
+                                         hw_bd.data(), false));
+    TRY_CHECK_RC(OM::write(gk, *l2_2));
+
+    STRICT_ORDER_OFF();
+
+    delete l2_1;
+    delete l2_2;
+    ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_1_bind,
+                                           pipe1.east()->handle(),
+                                           hw_bd.data(),
+                                           false));
+    ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_1_bind,
+                                           pipe1.west()->handle(),
+                                           hw_bd.data(),
+                                           false));
+    ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_hdl));
+    ADD_EXPECT(pipe_cmds::delete_cmd(hw_hdl, hw_hdl_pair));
+    ADD_EXPECT(bridge_domain_cmds::delete_cmd(hw_bd));
+    TRY_CHECK(OM::remove(gk));
+}
+
 BOOST_AUTO_TEST_SUITE_END()
index a89c1e9..a2b630f 100644 (file)
@@ -32,11 +32,11 @@ class VppPipe(VppInterface):
         self.result = self._test.vapi.pipe_create(
             0 if self.instance == 0xffffffff else 1,
             self.instance)
-        self.set_sw_if_index(self.result.parent_sw_if_index)
+        self.set_sw_if_index(self.result.sw_if_index)
 
     def remove_vpp_config(self):
         self._test.vapi.pipe_delete(
-            self.result.parent_sw_if_index)
+            self.result.sw_if_index)
 
     def __str__(self):
         return self.object_id()
@@ -47,7 +47,7 @@ class VppPipe(VppInterface):
     def query_vpp_config(self):
         pipes = self._test.vapi.pipe_dump()
         for p in pipes:
-            if p.parent_sw_if_index == self.result.parent_sw_if_index:
+            if p.sw_if_index == self.result.sw_if_index:
                 return True
         return False
 
@@ -78,9 +78,7 @@ class TestPipe(VppTestCase):
     def test_pipe(self):
         """ Pipes """
 
-        pipes = []
-        pipes.append(VppPipe(self))
-        pipes.append(VppPipe(self, 10))
+        pipes = [VppPipe(self), VppPipe(self, 10)]
 
         for p in pipes:
             p.add_vpp_config()