From 8c1afb56b6a479d6595444238815c4ced0e754ea Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Fri, 16 Oct 2020 15:28:47 +0200 Subject: misc: deprecate VOM Type: make Change-Id: Ifb3e52af93d24fcc2f2e6a0c408e16902a2fe553 Signed-off-by: Damjan Marion --- extras/deprecated/vom/CMakeLists.txt | 46 + extras/deprecated/vom/cmake/CMakeLists.txt | 22 + extras/deprecated/vom/cmake/FindCheck.cmake | 71 + extras/deprecated/vom/cmake/FindSubunit.cmake | 47 + extras/deprecated/vom/cmake/VOMConfig.cmake | 26 + extras/deprecated/vom/test/test_vom.py | 53 + extras/deprecated/vom/test/vom_test.cpp | 2287 ++++++++++++++++++++ extras/deprecated/vom/vom.mk | 45 + extras/deprecated/vom/vom/.clang-format | 4 + extras/deprecated/vom/vom/CMakeLists.txt | 323 +++ extras/deprecated/vom/vom/acl_binding.cpp | 216 ++ extras/deprecated/vom/vom/acl_binding.hpp | 245 +++ extras/deprecated/vom/vom/acl_binding_cmds.cpp | 189 ++ extras/deprecated/vom/vom/acl_binding_cmds.hpp | 195 ++ extras/deprecated/vom/vom/acl_ethertype.cpp | 253 +++ extras/deprecated/vom/vom/acl_ethertype.hpp | 247 +++ extras/deprecated/vom/vom/acl_ethertype_cmds.cpp | 167 ++ extras/deprecated/vom/vom/acl_ethertype_cmds.hpp | 144 ++ extras/deprecated/vom/vom/acl_l2_list.cpp | 281 +++ extras/deprecated/vom/vom/acl_l2_list.hpp | 224 ++ extras/deprecated/vom/vom/acl_l2_rule.cpp | 99 + extras/deprecated/vom/vom/acl_l2_rule.hpp | 115 + extras/deprecated/vom/vom/acl_l3_list.cpp | 292 +++ extras/deprecated/vom/vom/acl_l3_list.hpp | 224 ++ extras/deprecated/vom/vom/acl_l3_rule.cpp | 213 ++ extras/deprecated/vom/vom/acl_l3_rule.hpp | 196 ++ extras/deprecated/vom/vom/acl_list_cmds.cpp | 197 ++ extras/deprecated/vom/vom/acl_list_cmds.hpp | 223 ++ extras/deprecated/vom/vom/acl_types.cpp | 59 + extras/deprecated/vom/vom/acl_types.hpp | 68 + extras/deprecated/vom/vom/api_types.cpp | 278 +++ extras/deprecated/vom/vom/api_types.hpp | 75 + extras/deprecated/vom/vom/arp_proxy_binding.cpp | 160 ++ extras/deprecated/vom/vom/arp_proxy_binding.hpp | 159 ++ .../deprecated/vom/vom/arp_proxy_binding_cmds.cpp | 127 ++ .../deprecated/vom/vom/arp_proxy_binding_cmds.hpp | 135 ++ extras/deprecated/vom/vom/arp_proxy_config.cpp | 163 ++ extras/deprecated/vom/vom/arp_proxy_config.hpp | 165 ++ .../deprecated/vom/vom/arp_proxy_config_cmds.cpp | 142 ++ .../deprecated/vom/vom/arp_proxy_config_cmds.hpp | 140 ++ extras/deprecated/vom/vom/bond_group_binding.cpp | 179 ++ extras/deprecated/vom/vom/bond_group_binding.hpp | 186 ++ .../deprecated/vom/vom/bond_group_binding_cmds.cpp | 145 ++ .../deprecated/vom/vom/bond_group_binding_cmds.hpp | 138 ++ extras/deprecated/vom/vom/bond_interface.cpp | 197 ++ extras/deprecated/vom/vom/bond_interface.hpp | 197 ++ extras/deprecated/vom/vom/bond_interface_cmds.cpp | 139 ++ extras/deprecated/vom/vom/bond_interface_cmds.hpp | 111 + extras/deprecated/vom/vom/bond_member.cpp | 130 ++ extras/deprecated/vom/vom/bond_member.hpp | 147 ++ extras/deprecated/vom/vom/bridge_domain.cpp | 308 +++ extras/deprecated/vom/vom/bridge_domain.hpp | 306 +++ .../deprecated/vom/vom/bridge_domain_arp_entry.cpp | 220 ++ .../deprecated/vom/vom/bridge_domain_arp_entry.hpp | 195 ++ .../vom/vom/bridge_domain_arp_entry_cmds.cpp | 161 ++ .../vom/vom/bridge_domain_arp_entry_cmds.hpp | 146 ++ extras/deprecated/vom/vom/bridge_domain_cmds.cpp | 151 ++ extras/deprecated/vom/vom/bridge_domain_cmds.hpp | 156 ++ extras/deprecated/vom/vom/bridge_domain_entry.cpp | 224 ++ extras/deprecated/vom/vom/bridge_domain_entry.hpp | 192 ++ .../vom/vom/bridge_domain_entry_cmds.cpp | 155 ++ .../vom/vom/bridge_domain_entry_cmds.hpp | 143 ++ extras/deprecated/vom/vom/client_db.cpp | 59 + extras/deprecated/vom/vom/client_db.hpp | 89 + extras/deprecated/vom/vom/cmd.cpp | 37 + extras/deprecated/vom/vom/cmd.hpp | 80 + extras/deprecated/vom/vom/connection.cpp | 61 + extras/deprecated/vom/vom/connection.hpp | 82 + extras/deprecated/vom/vom/dhcp_client.cpp | 355 +++ extras/deprecated/vom/vom/dhcp_client.hpp | 317 +++ extras/deprecated/vom/vom/dhcp_client_cmds.cpp | 242 +++ extras/deprecated/vom/vom/dhcp_client_cmds.hpp | 213 ++ extras/deprecated/vom/vom/dump_cmd.hpp | 155 ++ extras/deprecated/vom/vom/enum_base.hpp | 126 ++ extras/deprecated/vom/vom/event_cmd.hpp | 117 + extras/deprecated/vom/vom/gbp_bridge_domain.cpp | 355 +++ extras/deprecated/vom/vom/gbp_bridge_domain.hpp | 221 ++ .../deprecated/vom/vom/gbp_bridge_domain_cmds.cpp | 159 ++ .../deprecated/vom/vom/gbp_bridge_domain_cmds.hpp | 137 ++ extras/deprecated/vom/vom/gbp_contract.cpp | 254 +++ extras/deprecated/vom/vom/gbp_contract.hpp | 217 ++ extras/deprecated/vom/vom/gbp_contract_cmds.cpp | 200 ++ extras/deprecated/vom/vom/gbp_contract_cmds.hpp | 147 ++ extras/deprecated/vom/vom/gbp_endpoint.cpp | 224 ++ extras/deprecated/vom/vom/gbp_endpoint.hpp | 218 ++ extras/deprecated/vom/vom/gbp_endpoint_cmds.cpp | 192 ++ extras/deprecated/vom/vom/gbp_endpoint_cmds.hpp | 141 ++ extras/deprecated/vom/vom/gbp_endpoint_group.cpp | 291 +++ extras/deprecated/vom/vom/gbp_endpoint_group.hpp | 245 +++ .../deprecated/vom/vom/gbp_endpoint_group_cmds.cpp | 147 ++ .../deprecated/vom/vom/gbp_endpoint_group_cmds.hpp | 141 ++ extras/deprecated/vom/vom/gbp_ext_itf.cpp | 197 ++ extras/deprecated/vom/vom/gbp_ext_itf.hpp | 186 ++ extras/deprecated/vom/vom/gbp_ext_itf_cmds.cpp | 135 ++ extras/deprecated/vom/vom/gbp_ext_itf_cmds.hpp | 134 ++ extras/deprecated/vom/vom/gbp_recirc.cpp | 200 ++ extras/deprecated/vom/vom/gbp_recirc.hpp | 209 ++ extras/deprecated/vom/vom/gbp_recirc_cmds.cpp | 138 ++ extras/deprecated/vom/vom/gbp_recirc_cmds.hpp | 135 ++ extras/deprecated/vom/vom/gbp_route_domain.cpp | 279 +++ extras/deprecated/vom/vom/gbp_route_domain.hpp | 197 ++ .../deprecated/vom/vom/gbp_route_domain_cmds.cpp | 140 ++ .../deprecated/vom/vom/gbp_route_domain_cmds.hpp | 133 ++ extras/deprecated/vom/vom/gbp_rule.cpp | 228 ++ extras/deprecated/vom/vom/gbp_rule.hpp | 282 +++ extras/deprecated/vom/vom/gbp_subnet.cpp | 299 +++ extras/deprecated/vom/vom/gbp_subnet.hpp | 252 +++ extras/deprecated/vom/vom/gbp_subnet_cmds.cpp | 166 ++ extras/deprecated/vom/vom/gbp_subnet_cmds.hpp | 142 ++ extras/deprecated/vom/vom/gbp_types.hpp | 40 + extras/deprecated/vom/vom/gbp_vxlan.cpp | 241 +++ extras/deprecated/vom/vom/gbp_vxlan.hpp | 191 ++ extras/deprecated/vom/vom/gbp_vxlan_cmds.cpp | 139 ++ extras/deprecated/vom/vom/gbp_vxlan_cmds.hpp | 137 ++ extras/deprecated/vom/vom/hw.cpp | 306 +++ extras/deprecated/vom/vom/hw.hpp | 396 ++++ extras/deprecated/vom/vom/hw_cmds.cpp | 54 + extras/deprecated/vom/vom/hw_cmds.hpp | 64 + extras/deprecated/vom/vom/igmp_binding.cpp | 162 ++ extras/deprecated/vom/vom/igmp_binding.hpp | 183 ++ extras/deprecated/vom/vom/igmp_binding_cmds.cpp | 105 + extras/deprecated/vom/vom/igmp_binding_cmds.hpp | 101 + extras/deprecated/vom/vom/igmp_listen.cpp | 188 ++ extras/deprecated/vom/vom/igmp_listen.hpp | 201 ++ extras/deprecated/vom/vom/igmp_listen_cmds.cpp | 177 ++ extras/deprecated/vom/vom/igmp_listen_cmds.hpp | 162 ++ extras/deprecated/vom/vom/inspect.cpp | 107 + extras/deprecated/vom/vom/inspect.hpp | 96 + extras/deprecated/vom/vom/interface.cpp | 776 +++++++ extras/deprecated/vom/vom/interface.hpp | 758 +++++++ extras/deprecated/vom/vom/interface_cmds.cpp | 668 ++++++ extras/deprecated/vom/vom/interface_cmds.hpp | 539 +++++ extras/deprecated/vom/vom/interface_factory.cpp | 253 +++ extras/deprecated/vom/vom/interface_factory.hpp | 72 + extras/deprecated/vom/vom/interface_ip6_nd.hpp | 382 ++++ .../deprecated/vom/vom/interface_ip6_nd_cmds.cpp | 98 + extras/deprecated/vom/vom/interface_span.cpp | 219 ++ extras/deprecated/vom/vom/interface_span.hpp | 222 ++ extras/deprecated/vom/vom/interface_span_cmds.cpp | 149 ++ extras/deprecated/vom/vom/interface_span_cmds.hpp | 154 ++ extras/deprecated/vom/vom/interface_types.cpp | 119 + extras/deprecated/vom/vom/ip_punt_redirect.cpp | 197 ++ extras/deprecated/vom/vom/ip_punt_redirect.hpp | 196 ++ .../deprecated/vom/vom/ip_punt_redirect_cmds.cpp | 150 ++ .../deprecated/vom/vom/ip_punt_redirect_cmds.hpp | 159 ++ extras/deprecated/vom/vom/ip_unnumbered.cpp | 162 ++ extras/deprecated/vom/vom/ip_unnumbered.hpp | 175 ++ extras/deprecated/vom/vom/ip_unnumbered_cmds.cpp | 142 ++ extras/deprecated/vom/vom/ip_unnumbered_cmds.hpp | 147 ++ extras/deprecated/vom/vom/l2_binding.cpp | 240 ++ extras/deprecated/vom/vom/l2_binding.hpp | 224 ++ extras/deprecated/vom/vom/l2_binding_cmds.cpp | 133 ++ extras/deprecated/vom/vom/l2_binding_cmds.hpp | 131 ++ extras/deprecated/vom/vom/l2_emulation.cpp | 168 ++ extras/deprecated/vom/vom/l2_emulation.hpp | 180 ++ extras/deprecated/vom/vom/l2_emulation_cmds.cpp | 105 + extras/deprecated/vom/vom/l2_emulation_cmds.hpp | 102 + extras/deprecated/vom/vom/l2_vtr.cpp | 48 + extras/deprecated/vom/vom/l2_vtr.hpp | 52 + extras/deprecated/vom/vom/l2_vtr_cmds.cpp | 73 + extras/deprecated/vom/vom/l2_vtr_cmds.hpp | 76 + extras/deprecated/vom/vom/l2_xconnect.cpp | 237 ++ extras/deprecated/vom/vom/l2_xconnect.hpp | 210 ++ extras/deprecated/vom/vom/l2_xconnect_cmds.cpp | 144 ++ extras/deprecated/vom/vom/l2_xconnect_cmds.hpp | 147 ++ extras/deprecated/vom/vom/l3_binding.cpp | 200 ++ extras/deprecated/vom/vom/l3_binding.hpp | 209 ++ extras/deprecated/vom/vom/l3_binding_cmds.cpp | 160 ++ extras/deprecated/vom/vom/l3_binding_cmds.hpp | 158 ++ extras/deprecated/vom/vom/lldp_binding.cpp | 163 ++ extras/deprecated/vom/vom/lldp_binding.hpp | 182 ++ extras/deprecated/vom/vom/lldp_binding_cmds.cpp | 110 + extras/deprecated/vom/vom/lldp_binding_cmds.hpp | 110 + extras/deprecated/vom/vom/lldp_global.cpp | 162 ++ extras/deprecated/vom/vom/lldp_global.hpp | 183 ++ extras/deprecated/vom/vom/lldp_global_cmds.cpp | 74 + extras/deprecated/vom/vom/lldp_global_cmds.hpp | 80 + extras/deprecated/vom/vom/logger.cpp | 170 ++ extras/deprecated/vom/vom/logger.hpp | 194 ++ extras/deprecated/vom/vom/mroute_cmds.cpp | 174 ++ extras/deprecated/vom/vom/mroute_cmds.hpp | 149 ++ extras/deprecated/vom/vom/nat_binding.cpp | 296 +++ extras/deprecated/vom/vom/nat_binding.hpp | 232 ++ extras/deprecated/vom/vom/nat_binding_cmds.cpp | 375 ++++ extras/deprecated/vom/vom/nat_binding_cmds.hpp | 380 ++++ extras/deprecated/vom/vom/nat_static.cpp | 236 ++ extras/deprecated/vom/vom/nat_static.hpp | 195 ++ extras/deprecated/vom/vom/nat_static_cmds.cpp | 271 +++ extras/deprecated/vom/vom/nat_static_cmds.hpp | 249 +++ extras/deprecated/vom/vom/neighbour.cpp | 232 ++ extras/deprecated/vom/vom/neighbour.hpp | 223 ++ extras/deprecated/vom/vom/neighbour_cmds.cpp | 172 ++ extras/deprecated/vom/vom/neighbour_cmds.hpp | 148 ++ extras/deprecated/vom/vom/object_base.cpp | 70 + extras/deprecated/vom/vom/object_base.hpp | 146 ++ extras/deprecated/vom/vom/om.cpp | 156 ++ extras/deprecated/vom/vom/om.hpp | 356 +++ extras/deprecated/vom/vom/pipe.cpp | 211 ++ extras/deprecated/vom/vom/pipe.hpp | 171 ++ extras/deprecated/vom/vom/pipe_cmds.cpp | 152 ++ extras/deprecated/vom/vom/pipe_cmds.hpp | 131 ++ extras/deprecated/vom/vom/prefix.cpp | 592 +++++ extras/deprecated/vom/vom/prefix.hpp | 414 ++++ extras/deprecated/vom/vom/qos_map.cpp | 190 ++ extras/deprecated/vom/vom/qos_map.hpp | 182 ++ extras/deprecated/vom/vom/qos_map_cmds.cpp | 142 ++ extras/deprecated/vom/vom/qos_map_cmds.hpp | 133 ++ extras/deprecated/vom/vom/qos_mark.cpp | 187 ++ extras/deprecated/vom/vom/qos_mark.hpp | 179 ++ extras/deprecated/vom/vom/qos_mark_cmds.cpp | 143 ++ extras/deprecated/vom/vom/qos_mark_cmds.hpp | 138 ++ extras/deprecated/vom/vom/qos_record.cpp | 190 ++ extras/deprecated/vom/vom/qos_record.hpp | 173 ++ extras/deprecated/vom/vom/qos_record_cmds.cpp | 139 ++ extras/deprecated/vom/vom/qos_record_cmds.hpp | 136 ++ extras/deprecated/vom/vom/qos_store.cpp | 186 ++ extras/deprecated/vom/vom/qos_store.hpp | 178 ++ extras/deprecated/vom/vom/qos_store_cmds.cpp | 143 ++ extras/deprecated/vom/vom/qos_store_cmds.hpp | 140 ++ extras/deprecated/vom/vom/qos_types.cpp | 39 + extras/deprecated/vom/vom/qos_types.hpp | 60 + extras/deprecated/vom/vom/qos_types_api.cpp | 56 + extras/deprecated/vom/vom/qos_types_api.hpp | 35 + extras/deprecated/vom/vom/ra_config.cpp | 89 + extras/deprecated/vom/vom/ra_config.hpp | 145 ++ extras/deprecated/vom/vom/ra_prefix.cpp | 87 + extras/deprecated/vom/vom/ra_prefix.hpp | 134 ++ extras/deprecated/vom/vom/route.cpp | 703 ++++++ extras/deprecated/vom/vom/route.hpp | 595 +++++ extras/deprecated/vom/vom/route_api_types.cpp | 190 ++ extras/deprecated/vom/vom/route_api_types.hpp | 40 + extras/deprecated/vom/vom/route_cmds.cpp | 171 ++ extras/deprecated/vom/vom/route_cmds.hpp | 142 ++ extras/deprecated/vom/vom/route_domain.cpp | 228 ++ extras/deprecated/vom/vom/route_domain.hpp | 200 ++ extras/deprecated/vom/vom/route_domain_cmds.cpp | 140 ++ extras/deprecated/vom/vom/route_domain_cmds.hpp | 148 ++ extras/deprecated/vom/vom/rpc_cmd.hpp | 151 ++ extras/deprecated/vom/vom/singular_db.hpp | 148 ++ extras/deprecated/vom/vom/singular_db_funcs.hpp | 52 + extras/deprecated/vom/vom/srpc_cmd.hpp | 74 + extras/deprecated/vom/vom/stat_client.cpp | 247 +++ extras/deprecated/vom/vom/stat_client.hpp | 209 ++ extras/deprecated/vom/vom/stat_reader.cpp | 139 ++ extras/deprecated/vom/vom/stat_reader.hpp | 103 + extras/deprecated/vom/vom/sub_interface.cpp | 114 + extras/deprecated/vom/vom/sub_interface.hpp | 110 + extras/deprecated/vom/vom/sub_interface_cmds.cpp | 115 + extras/deprecated/vom/vom/sub_interface_cmds.hpp | 108 + extras/deprecated/vom/vom/tap_interface.cpp | 126 ++ extras/deprecated/vom/vom/tap_interface.hpp | 118 + extras/deprecated/vom/vom/tap_interface_cmds.cpp | 158 ++ extras/deprecated/vom/vom/tap_interface_cmds.hpp | 102 + extras/deprecated/vom/vom/test_stats.cpp | 92 + extras/deprecated/vom/vom/types.cpp | 342 +++ extras/deprecated/vom/vom/types.hpp | 426 ++++ .../deprecated/vom/vom/vxlan_gbp_tunnel_cmds.cpp | 166 ++ .../deprecated/vom/vom/vxlan_gbp_tunnel_cmds.hpp | 138 ++ extras/deprecated/vom/vom/vxlan_tunnel.cpp | 359 +++ extras/deprecated/vom/vom/vxlan_tunnel.hpp | 269 +++ extras/deprecated/vom/vom/vxlan_tunnel_cmds.cpp | 162 ++ extras/deprecated/vom/vom/vxlan_tunnel_cmds.hpp | 137 ++ extras/rpm/vpp.spec | 2 +- extras/vom/CMakeLists.txt | 46 - extras/vom/cmake/CMakeLists.txt | 22 - extras/vom/cmake/FindCheck.cmake | 71 - extras/vom/cmake/FindSubunit.cmake | 47 - extras/vom/cmake/VOMConfig.cmake | 26 - extras/vom/vom/.clang-format | 4 - extras/vom/vom/CMakeLists.txt | 323 --- extras/vom/vom/acl_binding.cpp | 216 -- extras/vom/vom/acl_binding.hpp | 245 --- extras/vom/vom/acl_binding_cmds.cpp | 189 -- extras/vom/vom/acl_binding_cmds.hpp | 195 -- extras/vom/vom/acl_ethertype.cpp | 253 --- extras/vom/vom/acl_ethertype.hpp | 247 --- extras/vom/vom/acl_ethertype_cmds.cpp | 167 -- extras/vom/vom/acl_ethertype_cmds.hpp | 144 -- extras/vom/vom/acl_l2_list.cpp | 281 --- extras/vom/vom/acl_l2_list.hpp | 224 -- extras/vom/vom/acl_l2_rule.cpp | 99 - extras/vom/vom/acl_l2_rule.hpp | 115 - extras/vom/vom/acl_l3_list.cpp | 292 --- extras/vom/vom/acl_l3_list.hpp | 224 -- extras/vom/vom/acl_l3_rule.cpp | 213 -- extras/vom/vom/acl_l3_rule.hpp | 196 -- extras/vom/vom/acl_list_cmds.cpp | 197 -- extras/vom/vom/acl_list_cmds.hpp | 223 -- extras/vom/vom/acl_types.cpp | 59 - extras/vom/vom/acl_types.hpp | 68 - extras/vom/vom/api_types.cpp | 278 --- extras/vom/vom/api_types.hpp | 75 - extras/vom/vom/arp_proxy_binding.cpp | 160 -- extras/vom/vom/arp_proxy_binding.hpp | 159 -- extras/vom/vom/arp_proxy_binding_cmds.cpp | 127 -- extras/vom/vom/arp_proxy_binding_cmds.hpp | 135 -- extras/vom/vom/arp_proxy_config.cpp | 163 -- extras/vom/vom/arp_proxy_config.hpp | 165 -- extras/vom/vom/arp_proxy_config_cmds.cpp | 142 -- extras/vom/vom/arp_proxy_config_cmds.hpp | 140 -- extras/vom/vom/bond_group_binding.cpp | 179 -- extras/vom/vom/bond_group_binding.hpp | 186 -- extras/vom/vom/bond_group_binding_cmds.cpp | 145 -- extras/vom/vom/bond_group_binding_cmds.hpp | 138 -- extras/vom/vom/bond_interface.cpp | 197 -- extras/vom/vom/bond_interface.hpp | 197 -- extras/vom/vom/bond_interface_cmds.cpp | 139 -- extras/vom/vom/bond_interface_cmds.hpp | 111 - extras/vom/vom/bond_member.cpp | 130 -- extras/vom/vom/bond_member.hpp | 147 -- extras/vom/vom/bridge_domain.cpp | 308 --- extras/vom/vom/bridge_domain.hpp | 306 --- extras/vom/vom/bridge_domain_arp_entry.cpp | 220 -- extras/vom/vom/bridge_domain_arp_entry.hpp | 195 -- extras/vom/vom/bridge_domain_arp_entry_cmds.cpp | 161 -- extras/vom/vom/bridge_domain_arp_entry_cmds.hpp | 146 -- extras/vom/vom/bridge_domain_cmds.cpp | 151 -- extras/vom/vom/bridge_domain_cmds.hpp | 156 -- extras/vom/vom/bridge_domain_entry.cpp | 224 -- extras/vom/vom/bridge_domain_entry.hpp | 192 -- extras/vom/vom/bridge_domain_entry_cmds.cpp | 155 -- extras/vom/vom/bridge_domain_entry_cmds.hpp | 143 -- extras/vom/vom/client_db.cpp | 59 - extras/vom/vom/client_db.hpp | 89 - extras/vom/vom/cmd.cpp | 37 - extras/vom/vom/cmd.hpp | 80 - extras/vom/vom/connection.cpp | 61 - extras/vom/vom/connection.hpp | 82 - extras/vom/vom/dhcp_client.cpp | 355 --- extras/vom/vom/dhcp_client.hpp | 317 --- extras/vom/vom/dhcp_client_cmds.cpp | 242 --- extras/vom/vom/dhcp_client_cmds.hpp | 213 -- extras/vom/vom/dump_cmd.hpp | 155 -- extras/vom/vom/enum_base.hpp | 126 -- extras/vom/vom/event_cmd.hpp | 117 - extras/vom/vom/gbp_bridge_domain.cpp | 355 --- extras/vom/vom/gbp_bridge_domain.hpp | 221 -- extras/vom/vom/gbp_bridge_domain_cmds.cpp | 159 -- extras/vom/vom/gbp_bridge_domain_cmds.hpp | 137 -- extras/vom/vom/gbp_contract.cpp | 254 --- extras/vom/vom/gbp_contract.hpp | 217 -- extras/vom/vom/gbp_contract_cmds.cpp | 200 -- extras/vom/vom/gbp_contract_cmds.hpp | 147 -- extras/vom/vom/gbp_endpoint.cpp | 224 -- extras/vom/vom/gbp_endpoint.hpp | 218 -- extras/vom/vom/gbp_endpoint_cmds.cpp | 192 -- extras/vom/vom/gbp_endpoint_cmds.hpp | 141 -- extras/vom/vom/gbp_endpoint_group.cpp | 291 --- extras/vom/vom/gbp_endpoint_group.hpp | 245 --- extras/vom/vom/gbp_endpoint_group_cmds.cpp | 147 -- extras/vom/vom/gbp_endpoint_group_cmds.hpp | 141 -- extras/vom/vom/gbp_ext_itf.cpp | 197 -- extras/vom/vom/gbp_ext_itf.hpp | 186 -- extras/vom/vom/gbp_ext_itf_cmds.cpp | 135 -- extras/vom/vom/gbp_ext_itf_cmds.hpp | 134 -- extras/vom/vom/gbp_recirc.cpp | 200 -- extras/vom/vom/gbp_recirc.hpp | 209 -- extras/vom/vom/gbp_recirc_cmds.cpp | 138 -- extras/vom/vom/gbp_recirc_cmds.hpp | 135 -- extras/vom/vom/gbp_route_domain.cpp | 279 --- extras/vom/vom/gbp_route_domain.hpp | 197 -- extras/vom/vom/gbp_route_domain_cmds.cpp | 140 -- extras/vom/vom/gbp_route_domain_cmds.hpp | 133 -- extras/vom/vom/gbp_rule.cpp | 228 -- extras/vom/vom/gbp_rule.hpp | 282 --- extras/vom/vom/gbp_subnet.cpp | 299 --- extras/vom/vom/gbp_subnet.hpp | 252 --- extras/vom/vom/gbp_subnet_cmds.cpp | 166 -- extras/vom/vom/gbp_subnet_cmds.hpp | 142 -- extras/vom/vom/gbp_types.hpp | 40 - extras/vom/vom/gbp_vxlan.cpp | 241 --- extras/vom/vom/gbp_vxlan.hpp | 191 -- extras/vom/vom/gbp_vxlan_cmds.cpp | 139 -- extras/vom/vom/gbp_vxlan_cmds.hpp | 137 -- extras/vom/vom/hw.cpp | 306 --- extras/vom/vom/hw.hpp | 396 ---- extras/vom/vom/hw_cmds.cpp | 54 - extras/vom/vom/hw_cmds.hpp | 64 - extras/vom/vom/igmp_binding.cpp | 162 -- extras/vom/vom/igmp_binding.hpp | 183 -- extras/vom/vom/igmp_binding_cmds.cpp | 105 - extras/vom/vom/igmp_binding_cmds.hpp | 101 - extras/vom/vom/igmp_listen.cpp | 188 -- extras/vom/vom/igmp_listen.hpp | 201 -- extras/vom/vom/igmp_listen_cmds.cpp | 177 -- extras/vom/vom/igmp_listen_cmds.hpp | 162 -- extras/vom/vom/inspect.cpp | 107 - extras/vom/vom/inspect.hpp | 96 - extras/vom/vom/interface.cpp | 776 ------- extras/vom/vom/interface.hpp | 758 ------- extras/vom/vom/interface_cmds.cpp | 668 ------ extras/vom/vom/interface_cmds.hpp | 539 ----- extras/vom/vom/interface_factory.cpp | 253 --- extras/vom/vom/interface_factory.hpp | 72 - extras/vom/vom/interface_ip6_nd.hpp | 382 ---- extras/vom/vom/interface_ip6_nd_cmds.cpp | 98 - extras/vom/vom/interface_span.cpp | 219 -- extras/vom/vom/interface_span.hpp | 222 -- extras/vom/vom/interface_span_cmds.cpp | 149 -- extras/vom/vom/interface_span_cmds.hpp | 154 -- extras/vom/vom/interface_types.cpp | 119 - extras/vom/vom/ip_punt_redirect.cpp | 197 -- extras/vom/vom/ip_punt_redirect.hpp | 196 -- extras/vom/vom/ip_punt_redirect_cmds.cpp | 150 -- extras/vom/vom/ip_punt_redirect_cmds.hpp | 159 -- extras/vom/vom/ip_unnumbered.cpp | 162 -- extras/vom/vom/ip_unnumbered.hpp | 175 -- extras/vom/vom/ip_unnumbered_cmds.cpp | 142 -- extras/vom/vom/ip_unnumbered_cmds.hpp | 147 -- extras/vom/vom/l2_binding.cpp | 240 -- extras/vom/vom/l2_binding.hpp | 224 -- extras/vom/vom/l2_binding_cmds.cpp | 133 -- extras/vom/vom/l2_binding_cmds.hpp | 131 -- extras/vom/vom/l2_emulation.cpp | 168 -- extras/vom/vom/l2_emulation.hpp | 180 -- extras/vom/vom/l2_emulation_cmds.cpp | 105 - extras/vom/vom/l2_emulation_cmds.hpp | 102 - extras/vom/vom/l2_vtr.cpp | 48 - extras/vom/vom/l2_vtr.hpp | 52 - extras/vom/vom/l2_vtr_cmds.cpp | 73 - extras/vom/vom/l2_vtr_cmds.hpp | 76 - extras/vom/vom/l2_xconnect.cpp | 237 -- extras/vom/vom/l2_xconnect.hpp | 210 -- extras/vom/vom/l2_xconnect_cmds.cpp | 144 -- extras/vom/vom/l2_xconnect_cmds.hpp | 147 -- extras/vom/vom/l3_binding.cpp | 200 -- extras/vom/vom/l3_binding.hpp | 209 -- extras/vom/vom/l3_binding_cmds.cpp | 160 -- extras/vom/vom/l3_binding_cmds.hpp | 158 -- extras/vom/vom/lldp_binding.cpp | 163 -- extras/vom/vom/lldp_binding.hpp | 182 -- extras/vom/vom/lldp_binding_cmds.cpp | 110 - extras/vom/vom/lldp_binding_cmds.hpp | 110 - extras/vom/vom/lldp_global.cpp | 162 -- extras/vom/vom/lldp_global.hpp | 183 -- extras/vom/vom/lldp_global_cmds.cpp | 74 - extras/vom/vom/lldp_global_cmds.hpp | 80 - extras/vom/vom/logger.cpp | 170 -- extras/vom/vom/logger.hpp | 194 -- extras/vom/vom/mroute_cmds.cpp | 174 -- extras/vom/vom/mroute_cmds.hpp | 149 -- extras/vom/vom/nat_binding.cpp | 296 --- extras/vom/vom/nat_binding.hpp | 232 -- extras/vom/vom/nat_binding_cmds.cpp | 375 ---- extras/vom/vom/nat_binding_cmds.hpp | 380 ---- extras/vom/vom/nat_static.cpp | 236 -- extras/vom/vom/nat_static.hpp | 195 -- extras/vom/vom/nat_static_cmds.cpp | 271 --- extras/vom/vom/nat_static_cmds.hpp | 249 --- extras/vom/vom/neighbour.cpp | 232 -- extras/vom/vom/neighbour.hpp | 223 -- extras/vom/vom/neighbour_cmds.cpp | 172 -- extras/vom/vom/neighbour_cmds.hpp | 148 -- extras/vom/vom/object_base.cpp | 70 - extras/vom/vom/object_base.hpp | 146 -- extras/vom/vom/om.cpp | 156 -- extras/vom/vom/om.hpp | 356 --- extras/vom/vom/pipe.cpp | 211 -- extras/vom/vom/pipe.hpp | 171 -- extras/vom/vom/pipe_cmds.cpp | 152 -- extras/vom/vom/pipe_cmds.hpp | 131 -- extras/vom/vom/prefix.cpp | 592 ----- extras/vom/vom/prefix.hpp | 414 ---- extras/vom/vom/qos_map.cpp | 190 -- extras/vom/vom/qos_map.hpp | 182 -- extras/vom/vom/qos_map_cmds.cpp | 142 -- extras/vom/vom/qos_map_cmds.hpp | 133 -- extras/vom/vom/qos_mark.cpp | 187 -- extras/vom/vom/qos_mark.hpp | 179 -- extras/vom/vom/qos_mark_cmds.cpp | 143 -- extras/vom/vom/qos_mark_cmds.hpp | 138 -- extras/vom/vom/qos_record.cpp | 190 -- extras/vom/vom/qos_record.hpp | 173 -- extras/vom/vom/qos_record_cmds.cpp | 139 -- extras/vom/vom/qos_record_cmds.hpp | 136 -- extras/vom/vom/qos_store.cpp | 186 -- extras/vom/vom/qos_store.hpp | 178 -- extras/vom/vom/qos_store_cmds.cpp | 143 -- extras/vom/vom/qos_store_cmds.hpp | 140 -- extras/vom/vom/qos_types.cpp | 39 - extras/vom/vom/qos_types.hpp | 60 - extras/vom/vom/qos_types_api.cpp | 56 - extras/vom/vom/qos_types_api.hpp | 35 - extras/vom/vom/ra_config.cpp | 89 - extras/vom/vom/ra_config.hpp | 145 -- extras/vom/vom/ra_prefix.cpp | 87 - extras/vom/vom/ra_prefix.hpp | 134 -- extras/vom/vom/route.cpp | 703 ------ extras/vom/vom/route.hpp | 595 ----- extras/vom/vom/route_api_types.cpp | 190 -- extras/vom/vom/route_api_types.hpp | 40 - extras/vom/vom/route_cmds.cpp | 171 -- extras/vom/vom/route_cmds.hpp | 142 -- extras/vom/vom/route_domain.cpp | 228 -- extras/vom/vom/route_domain.hpp | 200 -- extras/vom/vom/route_domain_cmds.cpp | 140 -- extras/vom/vom/route_domain_cmds.hpp | 148 -- extras/vom/vom/rpc_cmd.hpp | 151 -- extras/vom/vom/singular_db.hpp | 148 -- extras/vom/vom/singular_db_funcs.hpp | 52 - extras/vom/vom/srpc_cmd.hpp | 74 - extras/vom/vom/stat_client.cpp | 247 --- extras/vom/vom/stat_client.hpp | 209 -- extras/vom/vom/stat_reader.cpp | 139 -- extras/vom/vom/stat_reader.hpp | 103 - extras/vom/vom/sub_interface.cpp | 114 - extras/vom/vom/sub_interface.hpp | 110 - extras/vom/vom/sub_interface_cmds.cpp | 115 - extras/vom/vom/sub_interface_cmds.hpp | 108 - extras/vom/vom/tap_interface.cpp | 126 -- extras/vom/vom/tap_interface.hpp | 118 - extras/vom/vom/tap_interface_cmds.cpp | 158 -- extras/vom/vom/tap_interface_cmds.hpp | 102 - extras/vom/vom/test_stats.cpp | 92 - extras/vom/vom/types.cpp | 342 --- extras/vom/vom/types.hpp | 426 ---- extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp | 166 -- extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp | 138 -- extras/vom/vom/vxlan_tunnel.cpp | 359 --- extras/vom/vom/vxlan_tunnel.hpp | 269 --- extras/vom/vom/vxlan_tunnel_cmds.cpp | 162 -- extras/vom/vom/vxlan_tunnel_cmds.hpp | 137 -- 522 files changed, 49805 insertions(+), 47420 deletions(-) create mode 100644 extras/deprecated/vom/CMakeLists.txt create mode 100644 extras/deprecated/vom/cmake/CMakeLists.txt create mode 100644 extras/deprecated/vom/cmake/FindCheck.cmake create mode 100644 extras/deprecated/vom/cmake/FindSubunit.cmake create mode 100644 extras/deprecated/vom/cmake/VOMConfig.cmake create mode 100644 extras/deprecated/vom/test/test_vom.py create mode 100644 extras/deprecated/vom/test/vom_test.cpp create mode 100644 extras/deprecated/vom/vom.mk create mode 100644 extras/deprecated/vom/vom/.clang-format create mode 100644 extras/deprecated/vom/vom/CMakeLists.txt create mode 100644 extras/deprecated/vom/vom/acl_binding.cpp create mode 100644 extras/deprecated/vom/vom/acl_binding.hpp create mode 100644 extras/deprecated/vom/vom/acl_binding_cmds.cpp create mode 100644 extras/deprecated/vom/vom/acl_binding_cmds.hpp create mode 100644 extras/deprecated/vom/vom/acl_ethertype.cpp create mode 100644 extras/deprecated/vom/vom/acl_ethertype.hpp create mode 100644 extras/deprecated/vom/vom/acl_ethertype_cmds.cpp create mode 100644 extras/deprecated/vom/vom/acl_ethertype_cmds.hpp create mode 100644 extras/deprecated/vom/vom/acl_l2_list.cpp create mode 100644 extras/deprecated/vom/vom/acl_l2_list.hpp create mode 100644 extras/deprecated/vom/vom/acl_l2_rule.cpp create mode 100644 extras/deprecated/vom/vom/acl_l2_rule.hpp create mode 100644 extras/deprecated/vom/vom/acl_l3_list.cpp create mode 100644 extras/deprecated/vom/vom/acl_l3_list.hpp create mode 100644 extras/deprecated/vom/vom/acl_l3_rule.cpp create mode 100644 extras/deprecated/vom/vom/acl_l3_rule.hpp create mode 100644 extras/deprecated/vom/vom/acl_list_cmds.cpp create mode 100644 extras/deprecated/vom/vom/acl_list_cmds.hpp create mode 100644 extras/deprecated/vom/vom/acl_types.cpp create mode 100644 extras/deprecated/vom/vom/acl_types.hpp create mode 100644 extras/deprecated/vom/vom/api_types.cpp create mode 100644 extras/deprecated/vom/vom/api_types.hpp create mode 100644 extras/deprecated/vom/vom/arp_proxy_binding.cpp create mode 100644 extras/deprecated/vom/vom/arp_proxy_binding.hpp create mode 100644 extras/deprecated/vom/vom/arp_proxy_binding_cmds.cpp create mode 100644 extras/deprecated/vom/vom/arp_proxy_binding_cmds.hpp create mode 100644 extras/deprecated/vom/vom/arp_proxy_config.cpp create mode 100644 extras/deprecated/vom/vom/arp_proxy_config.hpp create mode 100644 extras/deprecated/vom/vom/arp_proxy_config_cmds.cpp create mode 100644 extras/deprecated/vom/vom/arp_proxy_config_cmds.hpp create mode 100644 extras/deprecated/vom/vom/bond_group_binding.cpp create mode 100644 extras/deprecated/vom/vom/bond_group_binding.hpp create mode 100644 extras/deprecated/vom/vom/bond_group_binding_cmds.cpp create mode 100644 extras/deprecated/vom/vom/bond_group_binding_cmds.hpp create mode 100644 extras/deprecated/vom/vom/bond_interface.cpp create mode 100644 extras/deprecated/vom/vom/bond_interface.hpp create mode 100644 extras/deprecated/vom/vom/bond_interface_cmds.cpp create mode 100644 extras/deprecated/vom/vom/bond_interface_cmds.hpp create mode 100644 extras/deprecated/vom/vom/bond_member.cpp create mode 100644 extras/deprecated/vom/vom/bond_member.hpp create mode 100644 extras/deprecated/vom/vom/bridge_domain.cpp create mode 100644 extras/deprecated/vom/vom/bridge_domain.hpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_arp_entry.cpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_arp_entry.hpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_arp_entry_cmds.cpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_arp_entry_cmds.hpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_cmds.cpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_cmds.hpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_entry.cpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_entry.hpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_entry_cmds.cpp create mode 100644 extras/deprecated/vom/vom/bridge_domain_entry_cmds.hpp create mode 100644 extras/deprecated/vom/vom/client_db.cpp create mode 100644 extras/deprecated/vom/vom/client_db.hpp create mode 100644 extras/deprecated/vom/vom/cmd.cpp create mode 100644 extras/deprecated/vom/vom/cmd.hpp create mode 100644 extras/deprecated/vom/vom/connection.cpp create mode 100644 extras/deprecated/vom/vom/connection.hpp create mode 100644 extras/deprecated/vom/vom/dhcp_client.cpp create mode 100644 extras/deprecated/vom/vom/dhcp_client.hpp create mode 100644 extras/deprecated/vom/vom/dhcp_client_cmds.cpp create mode 100644 extras/deprecated/vom/vom/dhcp_client_cmds.hpp create mode 100644 extras/deprecated/vom/vom/dump_cmd.hpp create mode 100644 extras/deprecated/vom/vom/enum_base.hpp create mode 100644 extras/deprecated/vom/vom/event_cmd.hpp create mode 100644 extras/deprecated/vom/vom/gbp_bridge_domain.cpp create mode 100644 extras/deprecated/vom/vom/gbp_bridge_domain.hpp create mode 100644 extras/deprecated/vom/vom/gbp_bridge_domain_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_bridge_domain_cmds.hpp create mode 100644 extras/deprecated/vom/vom/gbp_contract.cpp create mode 100644 extras/deprecated/vom/vom/gbp_contract.hpp create mode 100644 extras/deprecated/vom/vom/gbp_contract_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_contract_cmds.hpp create mode 100644 extras/deprecated/vom/vom/gbp_endpoint.cpp create mode 100644 extras/deprecated/vom/vom/gbp_endpoint.hpp create mode 100644 extras/deprecated/vom/vom/gbp_endpoint_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_endpoint_cmds.hpp create mode 100644 extras/deprecated/vom/vom/gbp_endpoint_group.cpp create mode 100644 extras/deprecated/vom/vom/gbp_endpoint_group.hpp create mode 100644 extras/deprecated/vom/vom/gbp_endpoint_group_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_endpoint_group_cmds.hpp create mode 100644 extras/deprecated/vom/vom/gbp_ext_itf.cpp create mode 100644 extras/deprecated/vom/vom/gbp_ext_itf.hpp create mode 100644 extras/deprecated/vom/vom/gbp_ext_itf_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_ext_itf_cmds.hpp create mode 100644 extras/deprecated/vom/vom/gbp_recirc.cpp create mode 100644 extras/deprecated/vom/vom/gbp_recirc.hpp create mode 100644 extras/deprecated/vom/vom/gbp_recirc_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_recirc_cmds.hpp create mode 100644 extras/deprecated/vom/vom/gbp_route_domain.cpp create mode 100644 extras/deprecated/vom/vom/gbp_route_domain.hpp create mode 100644 extras/deprecated/vom/vom/gbp_route_domain_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_route_domain_cmds.hpp create mode 100644 extras/deprecated/vom/vom/gbp_rule.cpp create mode 100644 extras/deprecated/vom/vom/gbp_rule.hpp create mode 100644 extras/deprecated/vom/vom/gbp_subnet.cpp create mode 100644 extras/deprecated/vom/vom/gbp_subnet.hpp create mode 100644 extras/deprecated/vom/vom/gbp_subnet_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_subnet_cmds.hpp create mode 100644 extras/deprecated/vom/vom/gbp_types.hpp create mode 100644 extras/deprecated/vom/vom/gbp_vxlan.cpp create mode 100644 extras/deprecated/vom/vom/gbp_vxlan.hpp create mode 100644 extras/deprecated/vom/vom/gbp_vxlan_cmds.cpp create mode 100644 extras/deprecated/vom/vom/gbp_vxlan_cmds.hpp create mode 100644 extras/deprecated/vom/vom/hw.cpp create mode 100644 extras/deprecated/vom/vom/hw.hpp create mode 100644 extras/deprecated/vom/vom/hw_cmds.cpp create mode 100644 extras/deprecated/vom/vom/hw_cmds.hpp create mode 100644 extras/deprecated/vom/vom/igmp_binding.cpp create mode 100644 extras/deprecated/vom/vom/igmp_binding.hpp create mode 100644 extras/deprecated/vom/vom/igmp_binding_cmds.cpp create mode 100644 extras/deprecated/vom/vom/igmp_binding_cmds.hpp create mode 100644 extras/deprecated/vom/vom/igmp_listen.cpp create mode 100644 extras/deprecated/vom/vom/igmp_listen.hpp create mode 100644 extras/deprecated/vom/vom/igmp_listen_cmds.cpp create mode 100644 extras/deprecated/vom/vom/igmp_listen_cmds.hpp create mode 100644 extras/deprecated/vom/vom/inspect.cpp create mode 100644 extras/deprecated/vom/vom/inspect.hpp create mode 100644 extras/deprecated/vom/vom/interface.cpp create mode 100644 extras/deprecated/vom/vom/interface.hpp create mode 100644 extras/deprecated/vom/vom/interface_cmds.cpp create mode 100644 extras/deprecated/vom/vom/interface_cmds.hpp create mode 100644 extras/deprecated/vom/vom/interface_factory.cpp create mode 100644 extras/deprecated/vom/vom/interface_factory.hpp create mode 100644 extras/deprecated/vom/vom/interface_ip6_nd.hpp create mode 100644 extras/deprecated/vom/vom/interface_ip6_nd_cmds.cpp create mode 100644 extras/deprecated/vom/vom/interface_span.cpp create mode 100644 extras/deprecated/vom/vom/interface_span.hpp create mode 100644 extras/deprecated/vom/vom/interface_span_cmds.cpp create mode 100644 extras/deprecated/vom/vom/interface_span_cmds.hpp create mode 100644 extras/deprecated/vom/vom/interface_types.cpp create mode 100644 extras/deprecated/vom/vom/ip_punt_redirect.cpp create mode 100644 extras/deprecated/vom/vom/ip_punt_redirect.hpp create mode 100644 extras/deprecated/vom/vom/ip_punt_redirect_cmds.cpp create mode 100644 extras/deprecated/vom/vom/ip_punt_redirect_cmds.hpp create mode 100644 extras/deprecated/vom/vom/ip_unnumbered.cpp create mode 100644 extras/deprecated/vom/vom/ip_unnumbered.hpp create mode 100644 extras/deprecated/vom/vom/ip_unnumbered_cmds.cpp create mode 100644 extras/deprecated/vom/vom/ip_unnumbered_cmds.hpp create mode 100644 extras/deprecated/vom/vom/l2_binding.cpp create mode 100644 extras/deprecated/vom/vom/l2_binding.hpp create mode 100644 extras/deprecated/vom/vom/l2_binding_cmds.cpp create mode 100644 extras/deprecated/vom/vom/l2_binding_cmds.hpp create mode 100644 extras/deprecated/vom/vom/l2_emulation.cpp create mode 100644 extras/deprecated/vom/vom/l2_emulation.hpp create mode 100644 extras/deprecated/vom/vom/l2_emulation_cmds.cpp create mode 100644 extras/deprecated/vom/vom/l2_emulation_cmds.hpp create mode 100644 extras/deprecated/vom/vom/l2_vtr.cpp create mode 100644 extras/deprecated/vom/vom/l2_vtr.hpp create mode 100644 extras/deprecated/vom/vom/l2_vtr_cmds.cpp create mode 100644 extras/deprecated/vom/vom/l2_vtr_cmds.hpp create mode 100644 extras/deprecated/vom/vom/l2_xconnect.cpp create mode 100644 extras/deprecated/vom/vom/l2_xconnect.hpp create mode 100644 extras/deprecated/vom/vom/l2_xconnect_cmds.cpp create mode 100644 extras/deprecated/vom/vom/l2_xconnect_cmds.hpp create mode 100644 extras/deprecated/vom/vom/l3_binding.cpp create mode 100644 extras/deprecated/vom/vom/l3_binding.hpp create mode 100644 extras/deprecated/vom/vom/l3_binding_cmds.cpp create mode 100644 extras/deprecated/vom/vom/l3_binding_cmds.hpp create mode 100644 extras/deprecated/vom/vom/lldp_binding.cpp create mode 100644 extras/deprecated/vom/vom/lldp_binding.hpp create mode 100644 extras/deprecated/vom/vom/lldp_binding_cmds.cpp create mode 100644 extras/deprecated/vom/vom/lldp_binding_cmds.hpp create mode 100644 extras/deprecated/vom/vom/lldp_global.cpp create mode 100644 extras/deprecated/vom/vom/lldp_global.hpp create mode 100644 extras/deprecated/vom/vom/lldp_global_cmds.cpp create mode 100644 extras/deprecated/vom/vom/lldp_global_cmds.hpp create mode 100644 extras/deprecated/vom/vom/logger.cpp create mode 100644 extras/deprecated/vom/vom/logger.hpp create mode 100644 extras/deprecated/vom/vom/mroute_cmds.cpp create mode 100644 extras/deprecated/vom/vom/mroute_cmds.hpp create mode 100644 extras/deprecated/vom/vom/nat_binding.cpp create mode 100644 extras/deprecated/vom/vom/nat_binding.hpp create mode 100644 extras/deprecated/vom/vom/nat_binding_cmds.cpp create mode 100644 extras/deprecated/vom/vom/nat_binding_cmds.hpp create mode 100644 extras/deprecated/vom/vom/nat_static.cpp create mode 100644 extras/deprecated/vom/vom/nat_static.hpp create mode 100644 extras/deprecated/vom/vom/nat_static_cmds.cpp create mode 100644 extras/deprecated/vom/vom/nat_static_cmds.hpp create mode 100644 extras/deprecated/vom/vom/neighbour.cpp create mode 100644 extras/deprecated/vom/vom/neighbour.hpp create mode 100644 extras/deprecated/vom/vom/neighbour_cmds.cpp create mode 100644 extras/deprecated/vom/vom/neighbour_cmds.hpp create mode 100644 extras/deprecated/vom/vom/object_base.cpp create mode 100644 extras/deprecated/vom/vom/object_base.hpp create mode 100644 extras/deprecated/vom/vom/om.cpp create mode 100644 extras/deprecated/vom/vom/om.hpp create mode 100644 extras/deprecated/vom/vom/pipe.cpp create mode 100644 extras/deprecated/vom/vom/pipe.hpp create mode 100644 extras/deprecated/vom/vom/pipe_cmds.cpp create mode 100644 extras/deprecated/vom/vom/pipe_cmds.hpp create mode 100644 extras/deprecated/vom/vom/prefix.cpp create mode 100644 extras/deprecated/vom/vom/prefix.hpp create mode 100644 extras/deprecated/vom/vom/qos_map.cpp create mode 100644 extras/deprecated/vom/vom/qos_map.hpp create mode 100644 extras/deprecated/vom/vom/qos_map_cmds.cpp create mode 100644 extras/deprecated/vom/vom/qos_map_cmds.hpp create mode 100644 extras/deprecated/vom/vom/qos_mark.cpp create mode 100644 extras/deprecated/vom/vom/qos_mark.hpp create mode 100644 extras/deprecated/vom/vom/qos_mark_cmds.cpp create mode 100644 extras/deprecated/vom/vom/qos_mark_cmds.hpp create mode 100644 extras/deprecated/vom/vom/qos_record.cpp create mode 100644 extras/deprecated/vom/vom/qos_record.hpp create mode 100644 extras/deprecated/vom/vom/qos_record_cmds.cpp create mode 100644 extras/deprecated/vom/vom/qos_record_cmds.hpp create mode 100644 extras/deprecated/vom/vom/qos_store.cpp create mode 100644 extras/deprecated/vom/vom/qos_store.hpp create mode 100644 extras/deprecated/vom/vom/qos_store_cmds.cpp create mode 100644 extras/deprecated/vom/vom/qos_store_cmds.hpp create mode 100644 extras/deprecated/vom/vom/qos_types.cpp create mode 100644 extras/deprecated/vom/vom/qos_types.hpp create mode 100644 extras/deprecated/vom/vom/qos_types_api.cpp create mode 100644 extras/deprecated/vom/vom/qos_types_api.hpp create mode 100644 extras/deprecated/vom/vom/ra_config.cpp create mode 100644 extras/deprecated/vom/vom/ra_config.hpp create mode 100644 extras/deprecated/vom/vom/ra_prefix.cpp create mode 100644 extras/deprecated/vom/vom/ra_prefix.hpp create mode 100644 extras/deprecated/vom/vom/route.cpp create mode 100644 extras/deprecated/vom/vom/route.hpp create mode 100644 extras/deprecated/vom/vom/route_api_types.cpp create mode 100644 extras/deprecated/vom/vom/route_api_types.hpp create mode 100644 extras/deprecated/vom/vom/route_cmds.cpp create mode 100644 extras/deprecated/vom/vom/route_cmds.hpp create mode 100644 extras/deprecated/vom/vom/route_domain.cpp create mode 100644 extras/deprecated/vom/vom/route_domain.hpp create mode 100644 extras/deprecated/vom/vom/route_domain_cmds.cpp create mode 100644 extras/deprecated/vom/vom/route_domain_cmds.hpp create mode 100644 extras/deprecated/vom/vom/rpc_cmd.hpp create mode 100644 extras/deprecated/vom/vom/singular_db.hpp create mode 100644 extras/deprecated/vom/vom/singular_db_funcs.hpp create mode 100644 extras/deprecated/vom/vom/srpc_cmd.hpp create mode 100644 extras/deprecated/vom/vom/stat_client.cpp create mode 100644 extras/deprecated/vom/vom/stat_client.hpp create mode 100644 extras/deprecated/vom/vom/stat_reader.cpp create mode 100644 extras/deprecated/vom/vom/stat_reader.hpp create mode 100644 extras/deprecated/vom/vom/sub_interface.cpp create mode 100644 extras/deprecated/vom/vom/sub_interface.hpp create mode 100644 extras/deprecated/vom/vom/sub_interface_cmds.cpp create mode 100644 extras/deprecated/vom/vom/sub_interface_cmds.hpp create mode 100644 extras/deprecated/vom/vom/tap_interface.cpp create mode 100644 extras/deprecated/vom/vom/tap_interface.hpp create mode 100644 extras/deprecated/vom/vom/tap_interface_cmds.cpp create mode 100644 extras/deprecated/vom/vom/tap_interface_cmds.hpp create mode 100644 extras/deprecated/vom/vom/test_stats.cpp create mode 100644 extras/deprecated/vom/vom/types.cpp create mode 100644 extras/deprecated/vom/vom/types.hpp create mode 100644 extras/deprecated/vom/vom/vxlan_gbp_tunnel_cmds.cpp create mode 100644 extras/deprecated/vom/vom/vxlan_gbp_tunnel_cmds.hpp create mode 100644 extras/deprecated/vom/vom/vxlan_tunnel.cpp create mode 100644 extras/deprecated/vom/vom/vxlan_tunnel.hpp create mode 100644 extras/deprecated/vom/vom/vxlan_tunnel_cmds.cpp create mode 100644 extras/deprecated/vom/vom/vxlan_tunnel_cmds.hpp delete mode 100644 extras/vom/CMakeLists.txt delete mode 100644 extras/vom/cmake/CMakeLists.txt delete mode 100644 extras/vom/cmake/FindCheck.cmake delete mode 100644 extras/vom/cmake/FindSubunit.cmake delete mode 100644 extras/vom/cmake/VOMConfig.cmake delete mode 100644 extras/vom/vom/.clang-format delete mode 100644 extras/vom/vom/CMakeLists.txt delete mode 100644 extras/vom/vom/acl_binding.cpp delete mode 100644 extras/vom/vom/acl_binding.hpp delete mode 100644 extras/vom/vom/acl_binding_cmds.cpp delete mode 100644 extras/vom/vom/acl_binding_cmds.hpp delete mode 100644 extras/vom/vom/acl_ethertype.cpp delete mode 100644 extras/vom/vom/acl_ethertype.hpp delete mode 100644 extras/vom/vom/acl_ethertype_cmds.cpp delete mode 100644 extras/vom/vom/acl_ethertype_cmds.hpp delete mode 100644 extras/vom/vom/acl_l2_list.cpp delete mode 100644 extras/vom/vom/acl_l2_list.hpp delete mode 100644 extras/vom/vom/acl_l2_rule.cpp delete mode 100644 extras/vom/vom/acl_l2_rule.hpp delete mode 100644 extras/vom/vom/acl_l3_list.cpp delete mode 100644 extras/vom/vom/acl_l3_list.hpp delete mode 100644 extras/vom/vom/acl_l3_rule.cpp delete mode 100644 extras/vom/vom/acl_l3_rule.hpp delete mode 100644 extras/vom/vom/acl_list_cmds.cpp delete mode 100644 extras/vom/vom/acl_list_cmds.hpp delete mode 100644 extras/vom/vom/acl_types.cpp delete mode 100644 extras/vom/vom/acl_types.hpp delete mode 100644 extras/vom/vom/api_types.cpp delete mode 100644 extras/vom/vom/api_types.hpp delete mode 100644 extras/vom/vom/arp_proxy_binding.cpp delete mode 100644 extras/vom/vom/arp_proxy_binding.hpp delete mode 100644 extras/vom/vom/arp_proxy_binding_cmds.cpp delete mode 100644 extras/vom/vom/arp_proxy_binding_cmds.hpp delete mode 100644 extras/vom/vom/arp_proxy_config.cpp delete mode 100644 extras/vom/vom/arp_proxy_config.hpp delete mode 100644 extras/vom/vom/arp_proxy_config_cmds.cpp delete mode 100644 extras/vom/vom/arp_proxy_config_cmds.hpp delete mode 100644 extras/vom/vom/bond_group_binding.cpp delete mode 100644 extras/vom/vom/bond_group_binding.hpp delete mode 100644 extras/vom/vom/bond_group_binding_cmds.cpp delete mode 100644 extras/vom/vom/bond_group_binding_cmds.hpp delete mode 100644 extras/vom/vom/bond_interface.cpp delete mode 100644 extras/vom/vom/bond_interface.hpp delete mode 100644 extras/vom/vom/bond_interface_cmds.cpp delete mode 100644 extras/vom/vom/bond_interface_cmds.hpp delete mode 100644 extras/vom/vom/bond_member.cpp delete mode 100644 extras/vom/vom/bond_member.hpp delete mode 100644 extras/vom/vom/bridge_domain.cpp delete mode 100644 extras/vom/vom/bridge_domain.hpp delete mode 100644 extras/vom/vom/bridge_domain_arp_entry.cpp delete mode 100644 extras/vom/vom/bridge_domain_arp_entry.hpp delete mode 100644 extras/vom/vom/bridge_domain_arp_entry_cmds.cpp delete mode 100644 extras/vom/vom/bridge_domain_arp_entry_cmds.hpp delete mode 100644 extras/vom/vom/bridge_domain_cmds.cpp delete mode 100644 extras/vom/vom/bridge_domain_cmds.hpp delete mode 100644 extras/vom/vom/bridge_domain_entry.cpp delete mode 100644 extras/vom/vom/bridge_domain_entry.hpp delete mode 100644 extras/vom/vom/bridge_domain_entry_cmds.cpp delete mode 100644 extras/vom/vom/bridge_domain_entry_cmds.hpp delete mode 100644 extras/vom/vom/client_db.cpp delete mode 100644 extras/vom/vom/client_db.hpp delete mode 100644 extras/vom/vom/cmd.cpp delete mode 100644 extras/vom/vom/cmd.hpp delete mode 100644 extras/vom/vom/connection.cpp delete mode 100644 extras/vom/vom/connection.hpp delete mode 100644 extras/vom/vom/dhcp_client.cpp delete mode 100644 extras/vom/vom/dhcp_client.hpp delete mode 100644 extras/vom/vom/dhcp_client_cmds.cpp delete mode 100644 extras/vom/vom/dhcp_client_cmds.hpp delete mode 100644 extras/vom/vom/dump_cmd.hpp delete mode 100644 extras/vom/vom/enum_base.hpp delete mode 100644 extras/vom/vom/event_cmd.hpp delete mode 100644 extras/vom/vom/gbp_bridge_domain.cpp delete mode 100644 extras/vom/vom/gbp_bridge_domain.hpp delete mode 100644 extras/vom/vom/gbp_bridge_domain_cmds.cpp delete mode 100644 extras/vom/vom/gbp_bridge_domain_cmds.hpp delete mode 100644 extras/vom/vom/gbp_contract.cpp delete mode 100644 extras/vom/vom/gbp_contract.hpp delete mode 100644 extras/vom/vom/gbp_contract_cmds.cpp delete mode 100644 extras/vom/vom/gbp_contract_cmds.hpp delete mode 100644 extras/vom/vom/gbp_endpoint.cpp delete mode 100644 extras/vom/vom/gbp_endpoint.hpp delete mode 100644 extras/vom/vom/gbp_endpoint_cmds.cpp delete mode 100644 extras/vom/vom/gbp_endpoint_cmds.hpp delete mode 100644 extras/vom/vom/gbp_endpoint_group.cpp delete mode 100644 extras/vom/vom/gbp_endpoint_group.hpp delete mode 100644 extras/vom/vom/gbp_endpoint_group_cmds.cpp delete mode 100644 extras/vom/vom/gbp_endpoint_group_cmds.hpp delete mode 100644 extras/vom/vom/gbp_ext_itf.cpp delete mode 100644 extras/vom/vom/gbp_ext_itf.hpp delete mode 100644 extras/vom/vom/gbp_ext_itf_cmds.cpp delete mode 100644 extras/vom/vom/gbp_ext_itf_cmds.hpp delete mode 100644 extras/vom/vom/gbp_recirc.cpp delete mode 100644 extras/vom/vom/gbp_recirc.hpp delete mode 100644 extras/vom/vom/gbp_recirc_cmds.cpp delete mode 100644 extras/vom/vom/gbp_recirc_cmds.hpp delete mode 100644 extras/vom/vom/gbp_route_domain.cpp delete mode 100644 extras/vom/vom/gbp_route_domain.hpp delete mode 100644 extras/vom/vom/gbp_route_domain_cmds.cpp delete mode 100644 extras/vom/vom/gbp_route_domain_cmds.hpp delete mode 100644 extras/vom/vom/gbp_rule.cpp delete mode 100644 extras/vom/vom/gbp_rule.hpp delete mode 100644 extras/vom/vom/gbp_subnet.cpp delete mode 100644 extras/vom/vom/gbp_subnet.hpp delete mode 100644 extras/vom/vom/gbp_subnet_cmds.cpp delete mode 100644 extras/vom/vom/gbp_subnet_cmds.hpp delete mode 100644 extras/vom/vom/gbp_types.hpp delete mode 100644 extras/vom/vom/gbp_vxlan.cpp delete mode 100644 extras/vom/vom/gbp_vxlan.hpp delete mode 100644 extras/vom/vom/gbp_vxlan_cmds.cpp delete mode 100644 extras/vom/vom/gbp_vxlan_cmds.hpp delete mode 100644 extras/vom/vom/hw.cpp delete mode 100644 extras/vom/vom/hw.hpp delete mode 100644 extras/vom/vom/hw_cmds.cpp delete mode 100644 extras/vom/vom/hw_cmds.hpp delete mode 100644 extras/vom/vom/igmp_binding.cpp delete mode 100644 extras/vom/vom/igmp_binding.hpp delete mode 100644 extras/vom/vom/igmp_binding_cmds.cpp delete mode 100644 extras/vom/vom/igmp_binding_cmds.hpp delete mode 100644 extras/vom/vom/igmp_listen.cpp delete mode 100644 extras/vom/vom/igmp_listen.hpp delete mode 100644 extras/vom/vom/igmp_listen_cmds.cpp delete mode 100644 extras/vom/vom/igmp_listen_cmds.hpp delete mode 100644 extras/vom/vom/inspect.cpp delete mode 100644 extras/vom/vom/inspect.hpp delete mode 100644 extras/vom/vom/interface.cpp delete mode 100644 extras/vom/vom/interface.hpp delete mode 100644 extras/vom/vom/interface_cmds.cpp delete mode 100644 extras/vom/vom/interface_cmds.hpp delete mode 100644 extras/vom/vom/interface_factory.cpp delete mode 100644 extras/vom/vom/interface_factory.hpp delete mode 100644 extras/vom/vom/interface_ip6_nd.hpp delete mode 100644 extras/vom/vom/interface_ip6_nd_cmds.cpp delete mode 100644 extras/vom/vom/interface_span.cpp delete mode 100644 extras/vom/vom/interface_span.hpp delete mode 100644 extras/vom/vom/interface_span_cmds.cpp delete mode 100644 extras/vom/vom/interface_span_cmds.hpp delete mode 100644 extras/vom/vom/interface_types.cpp delete mode 100644 extras/vom/vom/ip_punt_redirect.cpp delete mode 100644 extras/vom/vom/ip_punt_redirect.hpp delete mode 100644 extras/vom/vom/ip_punt_redirect_cmds.cpp delete mode 100644 extras/vom/vom/ip_punt_redirect_cmds.hpp delete mode 100644 extras/vom/vom/ip_unnumbered.cpp delete mode 100644 extras/vom/vom/ip_unnumbered.hpp delete mode 100644 extras/vom/vom/ip_unnumbered_cmds.cpp delete mode 100644 extras/vom/vom/ip_unnumbered_cmds.hpp delete mode 100644 extras/vom/vom/l2_binding.cpp delete mode 100644 extras/vom/vom/l2_binding.hpp delete mode 100644 extras/vom/vom/l2_binding_cmds.cpp delete mode 100644 extras/vom/vom/l2_binding_cmds.hpp delete mode 100644 extras/vom/vom/l2_emulation.cpp delete mode 100644 extras/vom/vom/l2_emulation.hpp delete mode 100644 extras/vom/vom/l2_emulation_cmds.cpp delete mode 100644 extras/vom/vom/l2_emulation_cmds.hpp delete mode 100644 extras/vom/vom/l2_vtr.cpp delete mode 100644 extras/vom/vom/l2_vtr.hpp delete mode 100644 extras/vom/vom/l2_vtr_cmds.cpp delete mode 100644 extras/vom/vom/l2_vtr_cmds.hpp delete mode 100644 extras/vom/vom/l2_xconnect.cpp delete mode 100644 extras/vom/vom/l2_xconnect.hpp delete mode 100644 extras/vom/vom/l2_xconnect_cmds.cpp delete mode 100644 extras/vom/vom/l2_xconnect_cmds.hpp delete mode 100644 extras/vom/vom/l3_binding.cpp delete mode 100644 extras/vom/vom/l3_binding.hpp delete mode 100644 extras/vom/vom/l3_binding_cmds.cpp delete mode 100644 extras/vom/vom/l3_binding_cmds.hpp delete mode 100644 extras/vom/vom/lldp_binding.cpp delete mode 100644 extras/vom/vom/lldp_binding.hpp delete mode 100644 extras/vom/vom/lldp_binding_cmds.cpp delete mode 100644 extras/vom/vom/lldp_binding_cmds.hpp delete mode 100644 extras/vom/vom/lldp_global.cpp delete mode 100644 extras/vom/vom/lldp_global.hpp delete mode 100644 extras/vom/vom/lldp_global_cmds.cpp delete mode 100644 extras/vom/vom/lldp_global_cmds.hpp delete mode 100644 extras/vom/vom/logger.cpp delete mode 100644 extras/vom/vom/logger.hpp delete mode 100644 extras/vom/vom/mroute_cmds.cpp delete mode 100644 extras/vom/vom/mroute_cmds.hpp delete mode 100644 extras/vom/vom/nat_binding.cpp delete mode 100644 extras/vom/vom/nat_binding.hpp delete mode 100644 extras/vom/vom/nat_binding_cmds.cpp delete mode 100644 extras/vom/vom/nat_binding_cmds.hpp delete mode 100644 extras/vom/vom/nat_static.cpp delete mode 100644 extras/vom/vom/nat_static.hpp delete mode 100644 extras/vom/vom/nat_static_cmds.cpp delete mode 100644 extras/vom/vom/nat_static_cmds.hpp delete mode 100644 extras/vom/vom/neighbour.cpp delete mode 100644 extras/vom/vom/neighbour.hpp delete mode 100644 extras/vom/vom/neighbour_cmds.cpp delete mode 100644 extras/vom/vom/neighbour_cmds.hpp delete mode 100644 extras/vom/vom/object_base.cpp delete mode 100644 extras/vom/vom/object_base.hpp delete mode 100644 extras/vom/vom/om.cpp delete mode 100644 extras/vom/vom/om.hpp delete mode 100644 extras/vom/vom/pipe.cpp delete mode 100644 extras/vom/vom/pipe.hpp delete mode 100644 extras/vom/vom/pipe_cmds.cpp delete mode 100644 extras/vom/vom/pipe_cmds.hpp delete mode 100644 extras/vom/vom/prefix.cpp delete mode 100644 extras/vom/vom/prefix.hpp delete mode 100644 extras/vom/vom/qos_map.cpp delete mode 100644 extras/vom/vom/qos_map.hpp delete mode 100644 extras/vom/vom/qos_map_cmds.cpp delete mode 100644 extras/vom/vom/qos_map_cmds.hpp delete mode 100644 extras/vom/vom/qos_mark.cpp delete mode 100644 extras/vom/vom/qos_mark.hpp delete mode 100644 extras/vom/vom/qos_mark_cmds.cpp delete mode 100644 extras/vom/vom/qos_mark_cmds.hpp delete mode 100644 extras/vom/vom/qos_record.cpp delete mode 100644 extras/vom/vom/qos_record.hpp delete mode 100644 extras/vom/vom/qos_record_cmds.cpp delete mode 100644 extras/vom/vom/qos_record_cmds.hpp delete mode 100644 extras/vom/vom/qos_store.cpp delete mode 100644 extras/vom/vom/qos_store.hpp delete mode 100644 extras/vom/vom/qos_store_cmds.cpp delete mode 100644 extras/vom/vom/qos_store_cmds.hpp delete mode 100644 extras/vom/vom/qos_types.cpp delete mode 100644 extras/vom/vom/qos_types.hpp delete mode 100644 extras/vom/vom/qos_types_api.cpp delete mode 100644 extras/vom/vom/qos_types_api.hpp delete mode 100644 extras/vom/vom/ra_config.cpp delete mode 100644 extras/vom/vom/ra_config.hpp delete mode 100644 extras/vom/vom/ra_prefix.cpp delete mode 100644 extras/vom/vom/ra_prefix.hpp delete mode 100644 extras/vom/vom/route.cpp delete mode 100644 extras/vom/vom/route.hpp delete mode 100644 extras/vom/vom/route_api_types.cpp delete mode 100644 extras/vom/vom/route_api_types.hpp delete mode 100644 extras/vom/vom/route_cmds.cpp delete mode 100644 extras/vom/vom/route_cmds.hpp delete mode 100644 extras/vom/vom/route_domain.cpp delete mode 100644 extras/vom/vom/route_domain.hpp delete mode 100644 extras/vom/vom/route_domain_cmds.cpp delete mode 100644 extras/vom/vom/route_domain_cmds.hpp delete mode 100644 extras/vom/vom/rpc_cmd.hpp delete mode 100644 extras/vom/vom/singular_db.hpp delete mode 100644 extras/vom/vom/singular_db_funcs.hpp delete mode 100644 extras/vom/vom/srpc_cmd.hpp delete mode 100644 extras/vom/vom/stat_client.cpp delete mode 100644 extras/vom/vom/stat_client.hpp delete mode 100644 extras/vom/vom/stat_reader.cpp delete mode 100644 extras/vom/vom/stat_reader.hpp delete mode 100644 extras/vom/vom/sub_interface.cpp delete mode 100644 extras/vom/vom/sub_interface.hpp delete mode 100644 extras/vom/vom/sub_interface_cmds.cpp delete mode 100644 extras/vom/vom/sub_interface_cmds.hpp delete mode 100644 extras/vom/vom/tap_interface.cpp delete mode 100644 extras/vom/vom/tap_interface.hpp delete mode 100644 extras/vom/vom/tap_interface_cmds.cpp delete mode 100644 extras/vom/vom/tap_interface_cmds.hpp delete mode 100644 extras/vom/vom/test_stats.cpp delete mode 100644 extras/vom/vom/types.cpp delete mode 100644 extras/vom/vom/types.hpp delete mode 100644 extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp delete mode 100644 extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp delete mode 100644 extras/vom/vom/vxlan_tunnel.cpp delete mode 100644 extras/vom/vom/vxlan_tunnel.hpp delete mode 100644 extras/vom/vom/vxlan_tunnel_cmds.cpp delete mode 100644 extras/vom/vom/vxlan_tunnel_cmds.hpp (limited to 'extras') diff --git a/extras/deprecated/vom/CMakeLists.txt b/extras/deprecated/vom/CMakeLists.txt new file mode 100644 index 00000000000..4947235717e --- /dev/null +++ b/extras/deprecated/vom/CMakeLists.txt @@ -0,0 +1,46 @@ +# 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. + +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) + +project(vom) + +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) + +unset (VOM_LIB_VERSION) +execute_process( + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND bash -c "git describe | cut -f1 -d- | cut -dv -f2" + OUTPUT_VARIABLE VOM_LIB_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) +set(CMAKE_INSTALL_MESSAGE NEVER) + +find_package(VPP) +find_package(Threads REQUIRED) +find_package(Boost OPTIONAL_COMPONENTS system filesystem) + +add_subdirectory(vom) +add_subdirectory(cmake) + +add_vpp_packaging( + NAME "vom" + VENDOR "fd.io" + DESCRIPTION "VPP Object Model" +) diff --git a/extras/deprecated/vom/cmake/CMakeLists.txt b/extras/deprecated/vom/cmake/CMakeLists.txt new file mode 100644 index 00000000000..dff24a99180 --- /dev/null +++ b/extras/deprecated/vom/cmake/CMakeLists.txt @@ -0,0 +1,22 @@ +# 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. + +install( + FILES + VOMConfig.cmake + + DESTINATION + lib/cmake/vom + + COMPONENT vom +) diff --git a/extras/deprecated/vom/cmake/FindCheck.cmake b/extras/deprecated/vom/cmake/FindCheck.cmake new file mode 100644 index 00000000000..e5f399c5449 --- /dev/null +++ b/extras/deprecated/vom/cmake/FindCheck.cmake @@ -0,0 +1,71 @@ +# 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. + +######################################## +# +# Find the Libcheck library and includes +# This module sets: +# CHECK_FOUND: True if Libcheck was found +# CHECK_LIBRARY: The Libcheck library +# CHECK_INCLUDE_DIR: The Libcheck include dir +# + +set(CHECK_SEARCH_PATH_LIST + ${CHECK_HOME} + $ENV{CHECK_HOME} + /usr/local + /opt + /usr +) + +find_path(CHECK_INCLUDE_DIR check.h + HINTS ${CHECK_SEARCH_PATH_LIST} + PATH_SUFFIXES include + DOC "Find the check includes" +) + +find_library(CHECK_LIBRARY NAMES check + HINTS ${CHECK_SEARCH_PATH_LIST} + PATH_SUFFIXES lib + DOC "Find the check libraries" +) + +execute_process( + COMMAND grep "CHECK_MICRO_VERSION" ${CHECK_INCLUDE_DIR}/check.h + COMMAND grep -Eo [0-9]+ + OUTPUT_VARIABLE CHECK_MICRO_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +execute_process( + COMMAND grep "CHECK_MINOR_VERSION" ${CHECK_INCLUDE_DIR}/check.h + COMMAND grep -Eo [0-9]+ + OUTPUT_VARIABLE CHECK_MINOR_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +execute_process( + COMMAND grep "CHECK_MAJOR_VERSION" ${CHECK_INCLUDE_DIR}/check.h + COMMAND grep -Eo [0-9]+ + OUTPUT_VARIABLE CHECK_MAJOR_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +set(CHECK_VERSION "${CHECK_MAJOR_VERSION}.${CHECK_MINOR_VERSION}.${CHECK_MICRO_VERSION}") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + Check + REQUIRED_VARS CHECK_LIBRARY CHECK_INCLUDE_DIR + VERSION_VAR CHECK_VERSION +) \ No newline at end of file diff --git a/extras/deprecated/vom/cmake/FindSubunit.cmake b/extras/deprecated/vom/cmake/FindSubunit.cmake new file mode 100644 index 00000000000..121cb5f10e2 --- /dev/null +++ b/extras/deprecated/vom/cmake/FindSubunit.cmake @@ -0,0 +1,47 @@ +# 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. + +######################################## +# +# Find the Libsubunit library and includes +# This module sets: +# SUBUNIT_FOUND: True if Libsubunit was found +# SUBUNIT_LIBRARY: The Libsubunit library +# SUBUNIT_INCLUDE_DIR: The Libsubunit include dir +# + +set(SUBUNIT_SEARCH_PATH_LIST + ${SUBUNIT_HOME} + $ENV{SUBUNIT_HOME} + /usr/local + /opt + /usr +) + +find_path(SUBUNIT_INCLUDE_DIR + NAMES child.h + HINTS ${SUBUNIT_SEARCH_PATH_LIST} + PATH_SUFFIXES include subunit +) + +find_library(SUBUNIT_LIBRARY + NAMES subunit + PATH_SUFFIXES lib + HINTS ${SUBUNIT_SEARCH_PATH_LIST} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + Subunit + REQUIRED_VARS SUBUNIT_LIBRARY SUBUNIT_INCLUDE_DIR +) \ No newline at end of file diff --git a/extras/deprecated/vom/cmake/VOMConfig.cmake b/extras/deprecated/vom/cmake/VOMConfig.cmake new file mode 100644 index 00000000000..a2ea6b60491 --- /dev/null +++ b/extras/deprecated/vom/cmake/VOMConfig.cmake @@ -0,0 +1,26 @@ +# 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. + +get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) + +find_path(VOM_INCLUDE_DIR PATH_SUFFIXES NAMES vom/om.hpp) + +if(VOM_INCLUDE_DIR) + include_directories (${VOM_INCLUDE_DIR}) +else() + message(FATAL_ERROR "VOM headers, libraries and/or tools not found") +endif() + +set(VPP_EXTERNAL_PROJECT 1) + +include(CheckCCompilerFlag) diff --git a/extras/deprecated/vom/test/test_vom.py b/extras/deprecated/vom/test/test_vom.py new file mode 100644 index 00000000000..7dea7697f8c --- /dev/null +++ b/extras/deprecated/vom/test/test_vom.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +""" VAPI test """ + +import unittest +import os +import signal +from framework import VppTestCase, running_extended_tests, \ + VppTestRunner, Worker + + +@unittest.skipUnless(running_extended_tests, "part of extended tests") +class VOMTestCase(VppTestCase): + """ VPP Object Model Test """ + + @classmethod + def setUpClass(cls): + super(VOMTestCase, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(VOMTestCase, cls).tearDownClass() + + def test_vom_cpp(self): + """ run C++ VOM tests """ + var = "TEST_BR" + built_root = os.getenv(var, None) + self.assertIsNotNone(built_root, + "Environment variable `%s' not set" % var) + executable = "%s/vom_test/vom_test" % built_root + worker = Worker( + [executable, "vpp object model", self.shm_prefix], self.logger) + worker.start() + timeout = 120 + worker.join(timeout) + self.logger.info("Worker result is `%s'" % worker.result) + error = False + if worker.result is None: + try: + error = True + self.logger.error( + "Timeout! Worker did not finish in %ss" % timeout) + os.killpg(os.getpgid(worker.process.pid), signal.SIGTERM) + worker.join() + except: + raise Exception("Couldn't kill worker-spawned process") + if error: + raise Exception( + "Timeout! Worker did not finish in %ss" % timeout) + self.assert_equal(worker.result, 0, "Binary test return code") + + +if __name__ == '__main__': + unittest.main(testRunner=VppTestRunner) diff --git a/extras/deprecated/vom/test/vom_test.cpp b/extras/deprecated/vom/test/vom_test.cpp new file mode 100644 index 00000000000..fa9ecdafe80 --- /dev/null +++ b/extras/deprecated/vom/test/vom_test.cpp @@ -0,0 +1,2287 @@ +/* + * Test suite for class VppOM + * + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +#define BOOST_TEST_MODULE "VPP OBJECT MODEL" +#define BOOST_TEST_DYN_LINK + +#include +#include + + +#include +#include + +#include "vom/om.hpp" +#include "vom/interface.hpp" +#include "vom/interface_cmds.hpp" +#include "vom/bond_interface_cmds.hpp" +#include "vom/bond_group_binding.hpp" +#include "vom/bond_group_binding_cmds.hpp" +#include "vom/l2_binding.hpp" +#include "vom/l2_binding_cmds.hpp" +#include "vom/l2_vtr_cmds.hpp" +#include "vom/l2_xconnect.hpp" +#include "vom/l2_xconnect_cmds.hpp" +#include "vom/l3_binding.hpp" +#include "vom/l3_binding_cmds.hpp" +#include "vom/bridge_domain.hpp" +#include "vom/bridge_domain_entry.hpp" +#include "vom/bridge_domain_arp_entry.hpp" +#include "vom/bridge_domain_cmds.hpp" +#include "vom/bridge_domain_entry_cmds.hpp" +#include "vom/bridge_domain_arp_entry_cmds.hpp" +#include "vom/prefix.hpp" +#include "vom/route.hpp" +#include "vom/route_cmds.hpp" +#include "vom/mroute_cmds.hpp" +#include "vom/route_domain.hpp" +#include "vom/route_domain_cmds.hpp" +#include "vom/vxlan_tunnel.hpp" +#include "vom/vxlan_tunnel_cmds.hpp" +#include "vom/sub_interface.hpp" +#include "vom/sub_interface_cmds.hpp" +#include "vom/acl_ethertype.hpp" +#include "vom/acl_ethertype_cmds.hpp" +#include "vom/acl_l2_list.hpp" +#include "vom/acl_l3_list.hpp" +#include "vom/acl_binding.hpp" +#include "vom/acl_list_cmds.hpp" +#include "vom/acl_binding_cmds.hpp" +#include "vom/acl_l3_rule.hpp" +#include "vom/acl_l2_rule.hpp" +#include "vom/arp_proxy_config.hpp" +#include "vom/arp_proxy_binding.hpp" +#include "vom/arp_proxy_config_cmds.hpp" +#include "vom/arp_proxy_binding_cmds.hpp" +#include "vom/igmp_binding.hpp" +#include "vom/igmp_binding_cmds.hpp" +#include "vom/igmp_listen.hpp" +#include "vom/igmp_listen_cmds.hpp" +#include "vom/ip_punt_redirect.hpp" +#include "vom/ip_punt_redirect_cmds.hpp" +#include "vom/ip_unnumbered.hpp" +#include "vom/ip_unnumbered_cmds.hpp" +#include "vom/interface_ip6_nd.hpp" +#include "vom/interface_span.hpp" +#include "vom/interface_span_cmds.hpp" +#include "vom/neighbour.hpp" +#include "vom/neighbour_cmds.hpp" +#include "vom/nat_static.hpp" +#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" +#include "vom/qos_mark.hpp" +#include "vom/qos_mark_cmds.hpp" +#include "vom/qos_map.hpp" +#include "vom/qos_map_cmds.hpp" +#include "vom/qos_record.hpp" +#include "vom/qos_record_cmds.hpp" +#include "vom/qos_store.hpp" +#include "vom/qos_store_cmds.hpp" + +using namespace boost; +using namespace VOM; + +/** + * An expectation exception + */ +class ExpException +{ +public: + ExpException(unsigned int number) + { + // a neat place to add a break point + // std::cout << " ExpException here: " << number << std::endl; + } +}; + +class MockListener : public interface::event_listener, + public interface::stat_listener +{ + void handle_interface_stat(const interface& itf) + { + } + void handle_interface_event(std::vector events) + { + } +}; + +class MockCmdQ : public HW::cmd_q +{ +public: + MockCmdQ(): + m_strict_order(true) + { + } + virtual ~MockCmdQ() + { + } + void expect(cmd *f) + { + m_exp_queue.push_back(f); + } + void enqueue(cmd *f) + { + m_act_queue.push_back(f); + } + void enqueue(std::queue &cmds) + { + while (cmds.size()) + { + m_act_queue.push_back(cmds.front()); + cmds.pop(); + } + } + void enqueue(std::shared_ptr f) + { + m_act_queue.push_back(f.get()); + } + + void dequeue(cmd *f) + { + } + + void dequeue(std::shared_ptr cmd) + { + } + + void strict_order(bool on) + { + m_strict_order = on; + } + + bool is_empty() + { + return ((0 == m_exp_queue.size()) && + (0 == m_act_queue.size())); + } + + rc_t write() + { + cmd *f_exp, *f_act; + rc_t rc = rc_t::OK; + + while (m_act_queue.size()) + { + bool matched = false; + auto it_exp = m_exp_queue.begin(); + auto it_act = m_act_queue.begin(); + + f_act = *it_act; + + std::cout << " Act: " << f_act->to_string() << std::endl; + while (it_exp != m_exp_queue.end()) + { + f_exp = *it_exp; + try + { + std::cout << " Exp: " << f_exp->to_string() << std::endl; + + if (typeid(*f_exp) != typeid(*f_act)) + { + throw ExpException(1); + } + + if (typeid(*f_exp) == typeid(interface_cmds::af_packet_create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::loopback_create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::bvi_create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::vhost_create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bond_interface_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::loopback_delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::bvi_delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::af_packet_delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::vhost_delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bond_interface_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::state_change_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::set_table_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::set_mac_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::set_tag)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bond_group_binding_cmds::bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bond_group_binding_cmds::unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(route_domain_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(route_domain_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(route::ip_route_cmds::update_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(route::ip_route_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(route::ip_mroute_cmds::update_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(route::ip_mroute_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(neighbour_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(neighbour_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(l3_binding_cmds::bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(l3_binding_cmds::unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bridge_domain_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bridge_domain_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bridge_domain_entry_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bridge_domain_entry_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bridge_domain_arp_entry_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(bridge_domain_arp_entry_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(l2_binding_cmds::bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(l2_binding_cmds::unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(l2_vtr_cmds::set_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(l2_xconnect_cmds::bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(l2_xconnect_cmds::unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(vxlan_tunnel_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(vxlan_tunnel_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(sub_interface_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(sub_interface_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::acl_ethertype_cmds::bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::acl_ethertype_cmds::unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::list_cmds::l3_update_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::list_cmds::l3_delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::binding_cmds::l3_bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::binding_cmds::l3_unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::list_cmds::l2_update_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::list_cmds::l2_delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::binding_cmds::l2_bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ACL::binding_cmds::l2_unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(arp_proxy_binding_cmds::bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(arp_proxy_binding_cmds::unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(arp_proxy_config_cmds::config_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(arp_proxy_config_cmds::unconfig_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(igmp_binding_cmds::bind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(igmp_binding_cmds::unbind_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(igmp_listen_cmds::listen_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(igmp_listen_cmds::unlisten_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ip_punt_redirect_cmds::config_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ip_punt_redirect_cmds::unconfig_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ip_unnumbered_cmds::config_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ip_unnumbered_cmds::unconfig_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ip6nd_ra_config::config_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ip6nd_ra_config::unconfig_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ip6nd_ra_prefix::config_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(ip6nd_ra_prefix::unconfig_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_span_cmds::config_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_span_cmds::unconfig_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(nat_static_cmds::create_44_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(nat_static_cmds::delete_44_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(nat_binding_cmds::bind_44_input_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(nat_binding_cmds::unbind_44_input_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(interface_cmds::events_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(pipe_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(pipe_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(QoS::mark_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(QoS::mark_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(QoS::record_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(QoS::record_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(QoS::store_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(QoS::store_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(QoS::map_cmds::create_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else if (typeid(*f_exp) == typeid(QoS::map_cmds::delete_cmd)) + { + rc = handle_derived(f_exp, f_act); + } + else + { + throw ExpException(2); + } + + // if we get here then we found the match. + m_exp_queue.erase(it_exp); + m_act_queue.erase(it_act); + delete f_exp; + delete f_act; + + // return any injected failures to the agent + if (rc_t::OK != rc && rc_t::NOOP != rc) + { + return (rc); + } + + matched = true; + break; + } + catch (ExpException &e) + { + // The expected and actual do not match + if (m_strict_order) + { + // in strict ordering mode this is fatal, so rethrow + throw e; + } + else + { + // move the iterator onto the next in the expected list and + // check for a match + ++it_exp; + } + } + } + + if (!matched) + throw ExpException(3); + } + + return (rc); + } +private: + + template + rc_t handle_derived(const cmd *f_exp, cmd *f_act) + { + const T *i_exp; + T *i_act; + + i_exp = dynamic_cast(f_exp); + i_act = dynamic_cast(f_act); + if (!(*i_exp == *i_act)) + { + throw ExpException(4); + } + // pass the data and return code to the agent + i_act->item() = i_exp->item(); + + return (i_act->item().rc()); + } + + // The Q to push the expectations on + std::deque m_exp_queue; + + // the queue to push the actual events on + std::deque m_act_queue; + + // control whether the expected queue is strictly ordered. + bool m_strict_order; +}; + +class VppInit { +public: + std::string name; + MockCmdQ *f; + + VppInit() + : name("vpp-ut"), + f(new MockCmdQ()) + { + HW::init(f); + OM::init(); + logger().set(log_level_t::DEBUG); + } + + ~VppInit() { + delete f; + } +}; + +BOOST_AUTO_TEST_SUITE(vom) + +#define TRY_CHECK_RC(stmt) \ +{ \ + try { \ + BOOST_CHECK(rc_t::OK == stmt); \ + } \ + catch (ExpException &e) \ + { \ + BOOST_CHECK(false); \ + } \ + BOOST_CHECK(vi.f->is_empty()); \ +} + +#define TRY_CHECK(stmt) \ +{ \ + try { \ + stmt; \ + } \ + catch (ExpException &e) \ + { \ + BOOST_CHECK(false); \ + } \ + BOOST_CHECK(vi.f->is_empty()); \ +} + +#define ADD_EXPECT(stmt) \ + vi.f->expect(new stmt) + +#define STRICT_ORDER_OFF() \ + vi.f->strict_order(false) + +BOOST_AUTO_TEST_CASE(test_interface) { + VppInit vi; + const std::string go = "GeorgeOrwell"; + const std::string js = "JohnSteinbeck"; + rc_t rc = rc_t::OK; + + /* + * George creates and deletes the interface + */ + std::string itf1_name = "afpacket1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + /* + * set the expectation for a afpacket interface create. + * 2 is the interface handle VPP [mock] assigns + */ + HW::item hw_ifh(2, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + + TRY_CHECK_RC(OM::write(go, itf1)); + + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + + TRY_CHECK(OM::remove(go)); + + /* + * George creates the interface, then John brings it down. + * George's remove is a no-op, sice John also owns the interface + */ + interface itf1b(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::DOWN); + + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(go, itf1)); + + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + TRY_CHECK_RC(OM::write(js, itf1b)); + + TRY_CHECK(OM::remove(go)); + + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + TRY_CHECK(OM::remove(js)); + + /* + * George adds an interface, then we flush all of Geroge's state + */ + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(go, itf1)); + + TRY_CHECK(OM::mark(go)); + + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + TRY_CHECK(OM::sweep(go)); + + /* + * George adds an interface. mark stale. update the same interface. sweep + * and expect no delete + */ + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + TRY_CHECK_RC(OM::write(go, itf1b)); + + TRY_CHECK(OM::mark(go)); + + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(go, itf1)); + + TRY_CHECK(OM::sweep(go)); + + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + TRY_CHECK(OM::remove(go)); + + /* + * George adds an insterface, then we mark that state. Add a second interface + * an flush the first that is now stale. + */ + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(go, itf1)); + + TRY_CHECK(OM::mark(go)); + + std::string itf2_name = "afpacket2"; + std::string itf2_tag = "uuid-of-afpacket2-interface"; + interface itf2(itf2_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP, + itf2_tag); + HW::item hw_ifh2(3, rc_t::OK); + + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::set_tag(hw_ifh2, itf2_tag)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2)); + TRY_CHECK_RC(OM::write(go, itf2)); + + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + TRY_CHECK(OM::sweep(go)); + + TRY_CHECK(OM::mark(go)); + + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name)); + TRY_CHECK(OM::sweep(go)); + + + std::string itf3_name = "/PATH/TO/vhost_user1.sock"; + std::string itf3_tag = "uuid-of-vhost_user1-interface"; + interface itf3(itf3_name, + interface::type_t::VHOST, + interface::admin_state_t::UP, + itf3_tag); + HW::item hw_ifh3(4, rc_t::OK); + + ADD_EXPECT(interface_cmds::vhost_create_cmd(hw_ifh3, itf3_name, itf3_tag)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh3)); + TRY_CHECK_RC(OM::write(go, itf3)); + + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh3)); + ADD_EXPECT(interface_cmds::vhost_delete_cmd(hw_ifh3, itf3_name)); + TRY_CHECK(OM::remove(go)); +} + +BOOST_AUTO_TEST_CASE(test_bvi) { + VppInit vi; + const std::string ernest = "ErnestHemmingway"; + const std::string graham = "GrahamGreene"; + rc_t rc = rc_t::OK; + l3_binding *l3; + + HW::item hw_as_up(interface::admin_state_t::UP, + rc_t::OK); + HW::item hw_as_down(interface::admin_state_t::DOWN, + rc_t::OK); + + /* + * Enrest creates a BVI with address 10.10.10.10/24 + */ + route::prefix_t pfx_10("10.10.10.10", 24); + + const std::string bvi_name = "bvi1"; + interface itf(bvi_name, + interface::type_t::BVI, + interface::admin_state_t::UP); + HW::item hw_ifh(4, rc_t::OK); + HW::item hw_pfx_10(pfx_10, rc_t::OK); + + ADD_EXPECT(interface_cmds::bvi_create_cmd(hw_ifh, bvi_name)); + ADD_EXPECT(interface_cmds::set_tag(hw_ifh, bvi_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(ernest, itf)); + + l3 = new l3_binding(itf, pfx_10); + HW::item hw_l3_bind(true, rc_t::OK); + HW::item hw_l3_unbind(false, rc_t::OK); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind, hw_ifh.data(), pfx_10)); + TRY_CHECK_RC(OM::write(ernest, *l3)); + + // change the MAC address on the BVI + interface itf_new_mac(bvi_name, + interface::type_t::BVI, + interface::admin_state_t::UP); + l2_address_t l2_addr({0,1,2,3,4,5}); + HW::item hw_mac(l2_addr, rc_t::OK); + itf_new_mac.set(l2_addr); + ADD_EXPECT(interface_cmds::set_mac_cmd(hw_mac, hw_ifh)); + TRY_CHECK_RC(OM::write(ernest, itf_new_mac)); + + // create/write the interface to the OM again but with an unset MAC + // this should not generate a MAC address update + TRY_CHECK_RC(OM::write(ernest, itf)); + + // change the MAC address on the BVI - again + interface itf_new_mac2(bvi_name, + interface::type_t::BVI, + interface::admin_state_t::UP); + l2_address_t l2_addr2({0,1,2,3,4,6}); + HW::item hw_mac2(l2_addr2, rc_t::OK); + itf_new_mac2.set(l2_addr2); + ADD_EXPECT(interface_cmds::set_mac_cmd(hw_mac2, hw_ifh)); + TRY_CHECK_RC(OM::write(ernest, itf_new_mac2)); + + delete l3; + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind, hw_ifh.data(), pfx_10)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::bvi_delete_cmd(hw_ifh)); + TRY_CHECK(OM::remove(ernest)); + + /* + * Graham creates a BVI with address 10.10.10.10/24 in Routing Domain + */ + route_domain rd(1); + HW::item hw_rd4_create(true, rc_t::OK); + HW::item hw_rd4_delete(false, rc_t::OK); + HW::item hw_rd6_create(true, rc_t::OK); + HW::item hw_rd6_delete(false, rc_t::OK); + HW::item hw_rd4_bind(1, rc_t::OK); + HW::item hw_rd4_unbind(route::DEFAULT_TABLE, rc_t::OK); + HW::item hw_rd6_bind(1, rc_t::OK); + HW::item hw_rd6_unbind(route::DEFAULT_TABLE, rc_t::OK); + ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd4_create, l3_proto_t::IPV4, 1)); + ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd6_create, l3_proto_t::IPV6, 1)); + TRY_CHECK_RC(OM::write(graham, rd)); + + const std::string bvi2_name = "bvi2"; + interface *itf2 = new interface(bvi2_name, + interface::type_t::BVI, + interface::admin_state_t::UP, + rd); + HW::item hw_ifh2(5, rc_t::OK); + + ADD_EXPECT(interface_cmds::bvi_create_cmd(hw_ifh2, bvi2_name)); + ADD_EXPECT(interface_cmds::set_tag(hw_ifh2, bvi2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_bind, l3_proto_t::IPV4, hw_ifh2)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd6_bind, l3_proto_t::IPV6, hw_ifh2)); + + TRY_CHECK_RC(OM::write(graham, *itf2)); + + l3 = new l3_binding(*itf2, pfx_10); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind, hw_ifh2.data(), pfx_10)); + TRY_CHECK_RC(OM::write(graham, *l3)); + + delete l3; + delete itf2; + + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind, hw_ifh2.data(), pfx_10)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_unbind, l3_proto_t::IPV4, hw_ifh2)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd6_unbind, l3_proto_t::IPV6, hw_ifh2)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2)); + ADD_EXPECT(interface_cmds::bvi_delete_cmd(hw_ifh2)); + ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd4_delete, l3_proto_t::IPV4, 1)); + ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd6_delete, l3_proto_t::IPV6, 1)); + TRY_CHECK(OM::remove(graham)); +} + +BOOST_AUTO_TEST_CASE(test_bond) { + VppInit vi; + const std::string cb = "CarolBerg"; + rc_t rc = rc_t::OK; + + /* + * creates the interfaces + */ + std::string itf1_name = "afpacket1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh(2, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + + TRY_CHECK_RC(OM::write(cb, itf1)); + + std::string itf2_name = "afpacket2"; + interface itf2(itf2_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + + HW::item hw_ifh2(4, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2)); + + TRY_CHECK_RC(OM::write(cb, itf2)); + + std::string bond_name = "bond"; + bond_interface bond_itf(bond_name, interface::admin_state_t::UP, + bond_interface::mode_t::LACP); + + HW::item hw_ifh3(6, rc_t::OK); + ADD_EXPECT(bond_interface_cmds::create_cmd(hw_ifh3, bond_name, + bond_interface::mode_t::LACP, bond_interface::lb_t::L2, l2_address_t::ZERO)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh3)); + + TRY_CHECK_RC(OM::write(cb, bond_itf)); + + bond_member *bm1 = new bond_member(itf1, bond_member::mode_t::ACTIVE, + bond_member::rate_t::SLOW); + bond_member *bm2 = new bond_member(itf2, bond_member::mode_t::ACTIVE, + bond_member::rate_t::SLOW); + bond_group_binding *bgb = new bond_group_binding(bond_itf, {*bm1, *bm2}); + + HW::item bond_hw_bind(true, rc_t::OK); + ADD_EXPECT(bond_group_binding_cmds::bind_cmd(bond_hw_bind, hw_ifh3.data(), *bm1)); + ADD_EXPECT(bond_group_binding_cmds::bind_cmd(bond_hw_bind, hw_ifh3.data(), *bm2)); + + TRY_CHECK_RC(OM::write(cb, *bgb)); + + delete bgb; + delete bm2; + delete bm1; + + STRICT_ORDER_OFF(); + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + ADD_EXPECT(bond_group_binding_cmds::unbind_cmd(bond_hw_bind, hw_ifh.data())); + ADD_EXPECT(bond_group_binding_cmds::unbind_cmd(bond_hw_bind, hw_ifh2.data())); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh3)); + ADD_EXPECT(bond_interface_cmds::delete_cmd(hw_ifh3)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + + TRY_CHECK(OM::remove(cb)); +} + +BOOST_AUTO_TEST_CASE(test_bridge) { + VppInit vi; + const std::string franz = "FranzKafka"; + const std::string dante = "Dante"; + const std::string jkr = "jkrowling"; + rc_t rc = rc_t::OK; + + /* + * Franz creates an interface, Bridge-domain, then binds the two + */ + + // interface create + std::string itf1_name = "afpacket1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh(3, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, + rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + + TRY_CHECK_RC(OM::write(franz, itf1)); + + // bridge-domain create + bridge_domain bd1(33); + + HW::item hw_bd(33, rc_t::OK); + ADD_EXPECT(bridge_domain_cmds::create_cmd(hw_bd, + bridge_domain::learning_mode_t::ON, + bridge_domain::arp_term_mode_t::ON, + bridge_domain::arp_ufwd_mode_t::ON, + bridge_domain::flood_mode_t::ON, + bridge_domain::uu_flood_mode_t::ON, + bridge_domain::mac_age_mode_t::OFF)); + + TRY_CHECK_RC(OM::write(franz, bd1)); + + // L2-interface create and bind + // this needs to be delete'd before the flush below, since it too maintains + // references to the BD and Interface + l2_binding *l2itf = new l2_binding(itf1, bd1); + HW::item hw_l2_bind(true, rc_t::OK); + + ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_bind, + hw_ifh.data(), + hw_bd.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + TRY_CHECK_RC(OM::write(franz, *l2itf)); + + /* + * Dante adds an interface to the same BD + */ + std::string itf2_name = "afpacket2"; + interface itf2(itf2_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh2(4, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2)); + TRY_CHECK_RC(OM::write(dante, itf2)); + + // BD add is a no-op since it exists + TRY_CHECK_RC(OM::write(dante, bd1)); + + l2_binding *l2itf2 = new l2_binding(itf2, bd1); + HW::item hw_set_vtr(l2_vtr::option_t::POP_1, rc_t::OK); + l2itf2->set(l2_vtr::option_t::POP_1, 68); + + ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_bind, + hw_ifh2.data(), + hw_bd.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + ADD_EXPECT(l2_vtr_cmds::set_cmd(hw_set_vtr, hw_ifh2.data(), 68)); + TRY_CHECK_RC(OM::write(dante, *l2itf2)); + + // Add some static entries to the bridge-domain + HW::item hw_be1(true, rc_t::OK); + mac_address_t mac1({0,1,2,3,4,5}); + bridge_domain_entry *be1 = new bridge_domain_entry(bd1, mac1, itf2); + ADD_EXPECT(bridge_domain_entry_cmds::create_cmd(hw_be1, mac1, bd1.id(), hw_ifh2.data(), + false)); + TRY_CHECK_RC(OM::write(dante, *be1)); + + // Add some entries to the bridge-domain ARP termination table + HW::item hw_bea1(true, rc_t::OK); + boost::asio::ip::address ip1 = boost::asio::ip::address::from_string("10.10.10.10"); + + bridge_domain_arp_entry *bea1 = new bridge_domain_arp_entry(bd1, ip1, mac1); + ADD_EXPECT(bridge_domain_arp_entry_cmds::create_cmd(hw_be1, bd1.id(), mac1, ip1)); + TRY_CHECK_RC(OM::write(dante, *bea1)); + + // flush Franz's state + delete l2itf; + HW::item hw_as_down(interface::admin_state_t::DOWN, + rc_t::OK); + ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_bind, + hw_ifh.data(), + hw_bd.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + TRY_CHECK(OM::remove(franz)); + + // flush Dante's state - the order the interface and BD are deleted + // is an uncontrollable artifact of the C++ object destruction. + delete l2itf2; + delete be1; + delete bea1; + STRICT_ORDER_OFF(); + ADD_EXPECT(bridge_domain_arp_entry_cmds::delete_cmd(hw_be1, bd1.id(), mac1, ip1)); + ADD_EXPECT(bridge_domain_entry_cmds::delete_cmd(hw_be1, mac1, bd1.id(), false)); + ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_bind, + hw_ifh2.data(), + hw_bd.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + + ADD_EXPECT(bridge_domain_cmds::delete_cmd(hw_bd)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name)); + TRY_CHECK(OM::remove(dante)); + + // test the BVI entry in l2fib + bridge_domain bd2(99); + + HW::item hw_bd2(99, rc_t::OK); + ADD_EXPECT(bridge_domain_cmds::create_cmd(hw_bd2, + bridge_domain::learning_mode_t::ON, + bridge_domain::arp_term_mode_t::ON, + bridge_domain::arp_ufwd_mode_t::ON, + bridge_domain::flood_mode_t::ON, + bridge_domain::uu_flood_mode_t::ON, + bridge_domain::mac_age_mode_t::OFF)); + + TRY_CHECK_RC(OM::write(jkr, bd2)); + + std::string itf3_name = "bvi"; + interface itf3(itf3_name, + interface::type_t::BVI, + interface::admin_state_t::UP); + + HW::item hw_ifh3(5, rc_t::OK); + ADD_EXPECT(interface_cmds::bvi_create_cmd(hw_ifh3, itf3_name)); + ADD_EXPECT(interface_cmds::set_tag(hw_ifh3, itf3_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh3)); + TRY_CHECK_RC(OM::write(jkr, itf3)); + + l2_binding *l2itf3 = new l2_binding(itf3, bd2); + ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_bind, + hw_ifh3.data(), + hw_bd2.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI)); + TRY_CHECK_RC(OM::write(jkr, *l2itf3)); + + HW::item hw_be2(true, rc_t::OK); + mac_address_t mac2({0,1,2,3,4,5}); + bridge_domain_entry *be2 = new bridge_domain_entry(bd2, mac2, itf3); + ADD_EXPECT(bridge_domain_entry_cmds::create_cmd(hw_be2, mac2, bd2.id(), hw_ifh3.data(), true)); + TRY_CHECK_RC(OM::write(jkr, *be2)); + + delete l2itf3; + delete be2; + STRICT_ORDER_OFF(); + ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_bind, + hw_ifh3.data(), + hw_bd2.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI)); + ADD_EXPECT(bridge_domain_entry_cmds::delete_cmd(hw_be2, mac2, bd2.id(), true)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh3)); + ADD_EXPECT(interface_cmds::bvi_delete_cmd(hw_ifh3)); + ADD_EXPECT(bridge_domain_cmds::delete_cmd(hw_bd2)); + TRY_CHECK(OM::remove(jkr)); +} + +BOOST_AUTO_TEST_CASE(test_l2_xconnect) { + VppInit vi; + const std::string nicholas = "NicholasAbercrombie"; + rc_t rc = rc_t::OK; + + /* + * Interface 1 + */ + std::string itf1_name = "host1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(nicholas, itf1)); + + /* + * Interface 2 + */ + std::string itf2_name = "host2"; + interface itf2(itf2_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh2(4, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2)); + TRY_CHECK_RC(OM::write(nicholas, itf2)); + + l2_xconnect *l2_xconn = new l2_xconnect(itf1, itf2); + HW::item xconnect_east(true, rc_t::OK); + HW::item xconnect_west(true, rc_t::OK); + HW::item xconnect_east_unbind(false, rc_t::OK); + HW::item xconnect_west_unbind(false, rc_t::OK); + ADD_EXPECT(l2_xconnect_cmds::bind_cmd(xconnect_east, hw_ifh.data(), hw_ifh2.data())); + ADD_EXPECT(l2_xconnect_cmds::bind_cmd(xconnect_west, hw_ifh2.data(), hw_ifh.data())); + TRY_CHECK_RC(OM::write(nicholas, *l2_xconn)); + + delete l2_xconn; + + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + STRICT_ORDER_OFF(); + ADD_EXPECT(l2_xconnect_cmds::unbind_cmd(xconnect_east_unbind, hw_ifh.data(), hw_ifh2.data())); + ADD_EXPECT(l2_xconnect_cmds::unbind_cmd(xconnect_west_unbind, hw_ifh2.data(), hw_ifh.data())); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + + TRY_CHECK(OM::remove(nicholas)); +} + +BOOST_AUTO_TEST_CASE(test_vxlan) { + VppInit vi; + const std::string franz = "FranzKafka"; + rc_t rc = rc_t::OK; + + /* + * Franz creates an interface, Bridge-domain, then binds the two + */ + + // VXLAN create + vxlan_tunnel::endpoint_t ep(boost::asio::ip::address::from_string("10.10.10.10"), + boost::asio::ip::address::from_string("10.10.10.11"), + 322); + + vxlan_tunnel vxt(ep.src, ep.dst, ep.vni); + + HW::item hw_vxt(3, rc_t::OK); + ADD_EXPECT(vxlan_tunnel_cmds::create_cmd(hw_vxt, "don't-care", ep, + handle_t::INVALID)); + + TRY_CHECK_RC(OM::write(franz, vxt)); + + // bridge-domain create + bridge_domain bd1(33, bridge_domain::learning_mode_t::OFF, + bridge_domain::arp_term_mode_t::OFF, + bridge_domain::arp_ufwd_mode_t::OFF, + bridge_domain::flood_mode_t::OFF, + bridge_domain::uu_flood_mode_t::OFF, + bridge_domain::mac_age_mode_t::ON); + + HW::item 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::arp_ufwd_mode_t::OFF, + bridge_domain::flood_mode_t::OFF, + bridge_domain::uu_flood_mode_t::OFF, + bridge_domain::mac_age_mode_t::ON)); + + TRY_CHECK_RC(OM::write(franz, bd1)); + + // L2-interface create and bind + // this needs to be delete'd before the flush below, since it too maintains + // references to the BD and Interface + l2_binding *l2itf = new l2_binding(vxt, bd1); + HW::item hw_l2_bind(true, rc_t::OK); + + ADD_EXPECT(l2_binding_cmds::bind_cmd(hw_l2_bind, + hw_vxt.data(), + hw_bd.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + TRY_CHECK_RC(OM::write(franz, *l2itf)); + + // flush Franz's state + delete l2itf; + HW::item hw_vxtdel(3, rc_t::NOOP); + STRICT_ORDER_OFF(); + ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_bind, + hw_vxt.data(), + hw_bd.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + ADD_EXPECT(bridge_domain_cmds::delete_cmd(hw_bd)); + ADD_EXPECT(vxlan_tunnel_cmds::delete_cmd(hw_vxtdel, ep)); + TRY_CHECK(OM::remove(franz)); +} + +BOOST_AUTO_TEST_CASE(test_vlan) { + VppInit vi; + const std::string noam = "NoamChomsky"; + rc_t rc = rc_t::OK; + + std::string itf1_name = "host1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh(2, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + + TRY_CHECK_RC(OM::write(noam, itf1)); + + sub_interface *vl33 = new sub_interface(itf1, + interface::admin_state_t::UP, + 33); + + HW::item hw_vl33(3, rc_t::OK); + ADD_EXPECT(sub_interface_cmds::create_cmd(hw_vl33, itf1_name+".33", hw_ifh.data(), 33)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_vl33)); + + TRY_CHECK_RC(OM::write(noam, *vl33)); + + delete vl33; + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + HW::item hw_vl33_down(3, rc_t::NOOP); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_vl33)); + ADD_EXPECT(sub_interface_cmds::delete_cmd(hw_vl33_down)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + + TRY_CHECK(OM::remove(noam)); +} + +BOOST_AUTO_TEST_CASE(test_acl) { + VppInit vi; + const std::string fyodor = "FyodorDostoyevsky"; + const std::string leo = "LeoTolstoy"; + rc_t rc = rc_t::OK; + + /* + * Fyodor adds an ACL in the input direction + */ + std::string itf1_name = "host1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(fyodor, itf1)); + + ACL::ethertype_rule_t e1(ethertype_t::ARP, direction_t::INPUT); + ACL::ethertype_rule_t e2(ethertype_t::ARP, direction_t::OUTPUT); + ACL::ethertype_rule_t e3(ethertype_t::IPV4, direction_t::INPUT); + ACL::acl_ethertype::ethertype_rules_t l_e = {e1, e2, e3}; + ACL::acl_ethertype *a_e = new ACL::acl_ethertype(itf1, l_e); + HW::item ae_binding(true, rc_t::OK); + ADD_EXPECT(ACL::acl_ethertype_cmds::bind_cmd(ae_binding, hw_ifh.data(), l_e)); + TRY_CHECK_RC(OM::write(fyodor, *a_e)); + + route::prefix_t src("10.10.10.10", 32); + ACL::l3_rule r1(10, ACL::action_t::PERMIT, src, route::prefix_t::ZERO); + ACL::l3_rule r2(20, ACL::action_t::DENY, route::prefix_t::ZERO, route::prefix_t::ZERO); + + std::string acl_name = "acl1"; + ACL::l3_list acl1(acl_name); + acl1.insert(r2); + acl1.insert(r1); + ACL::l3_list::rules_t rules = {r1, r2}; + + HW::item hw_acl(2, rc_t::OK); + ADD_EXPECT(ACL::list_cmds::l3_update_cmd(hw_acl, acl_name, rules)); + TRY_CHECK_RC(OM::write(fyodor, acl1)); + + ACL::l3_rule r3(30, ACL::action_t::PERMIT, route::prefix_t::ZERO, route::prefix_t::ZERO); + ACL::l3_list acl2(acl_name); + acl2.insert(r3); + ACL::l3_list::rules_t rules2 = {r3}; + ADD_EXPECT(ACL::list_cmds::l3_update_cmd(hw_acl, acl_name, rules2)); + TRY_CHECK_RC(OM::write(fyodor, acl2)); + + ACL::l3_binding *l3b = new ACL::l3_binding(direction_t::INPUT, itf1, acl1); + HW::item hw_binding(true, rc_t::OK); + ADD_EXPECT(ACL::binding_cmds::l3_bind_cmd(hw_binding, direction_t::INPUT, + hw_ifh.data(), hw_acl.data())); + TRY_CHECK_RC(OM::write(fyodor, *l3b)); + + /** + * Leo adds an L2 ACL in the output direction + */ + TRY_CHECK_RC(OM::write(leo, itf1)); + + std::string l2_acl_name = "l2_acl1"; + mac_address_t mac({0x0, 0x0, 0x1, 0x2, 0x3, 0x4}); + mac_address_t mac_mask({0xff, 0xff, 0xff, 0x0, 0x0, 0x0}); + ACL::l2_rule l2_r1(10, ACL::action_t::PERMIT, src, mac, mac_mask); + ACL::l2_rule l2_r2(20, ACL::action_t::DENY, src, {}, {}); + + ACL::l2_list l2_acl(l2_acl_name); + l2_acl.insert(l2_r2); + l2_acl.insert(l2_r1); + + ACL::l2_list::rules_t l2_rules = {l2_r1, l2_r2}; + + HW::item l2_hw_acl(3, rc_t::OK); + ADD_EXPECT(ACL::list_cmds::l2_update_cmd(l2_hw_acl, l2_acl_name, l2_rules)); + TRY_CHECK_RC(OM::write(leo, l2_acl)); + + ACL::l2_binding *l2b = new ACL::l2_binding(direction_t::OUTPUT, itf1, l2_acl); + HW::item l2_hw_binding(true, rc_t::OK); + ADD_EXPECT(ACL::binding_cmds::l2_bind_cmd(l2_hw_binding, direction_t::OUTPUT, + hw_ifh.data(), l2_hw_acl.data())); + TRY_CHECK_RC(OM::write(leo, *l2b)); + + delete l2b; + ADD_EXPECT(ACL::binding_cmds::l2_unbind_cmd(l2_hw_binding, direction_t::OUTPUT, + hw_ifh.data(), l2_hw_acl.data())); + ADD_EXPECT(ACL::list_cmds::l2_delete_cmd(l2_hw_acl)); + TRY_CHECK(OM::remove(leo)); + + delete l3b; + delete a_e; + HW::item hw_as_down(interface::admin_state_t::DOWN, + rc_t::OK); + STRICT_ORDER_OFF(); + ADD_EXPECT(ACL::binding_cmds::l3_unbind_cmd(hw_binding, direction_t::INPUT, + hw_ifh.data(), hw_acl.data())); + ADD_EXPECT(ACL::list_cmds::l3_delete_cmd(hw_acl)); + ADD_EXPECT(ACL::acl_ethertype_cmds::unbind_cmd(ae_binding, hw_ifh.data())); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + + TRY_CHECK(OM::remove(fyodor)); +} + +BOOST_AUTO_TEST_CASE(test_igmp) { + VppInit vi; + const std::string Isaiah = "IsaiahBerlin"; + rc_t rc = rc_t::OK; + + boost::asio::ip::address_v4 gaddr = boost::asio::ip::address_v4::from_string("232.0.0.1"); + boost::asio::ip::address_v4 saddr1 = boost::asio::ip::address_v4::from_string("192.168.0.20"); + boost::asio::ip::address_v4 saddr2 = boost::asio::ip::address_v4::from_string("192.168.0.30"); + + std::string itf3_name = "host3"; + interface itf3(itf3_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf3_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(Isaiah, itf3)); + + igmp_binding *ib = new igmp_binding(itf3); + HW::item hw_binding(true, rc_t::OK); + ADD_EXPECT(igmp_binding_cmds::bind_cmd(hw_binding, hw_ifh.data())); + TRY_CHECK_RC(OM::write(Isaiah, *ib)); + + igmp_listen::src_addrs_t saddrs = {saddr1, saddr2}; + + igmp_listen *il = new igmp_listen(*ib, gaddr, saddrs); + HW::item hw_as_listen(true, rc_t::OK); + ADD_EXPECT(igmp_listen_cmds::listen_cmd(hw_as_listen, hw_ifh.data(), gaddr, saddrs)); + TRY_CHECK_RC(OM::write(Isaiah, *il)); + + delete il; + delete ib; + + HW::item hw_as_down(interface::admin_state_t::DOWN, + rc_t::OK); + STRICT_ORDER_OFF(); + ADD_EXPECT(igmp_listen_cmds::unlisten_cmd(hw_as_listen, hw_ifh.data(), gaddr)); + ADD_EXPECT(igmp_binding_cmds::unbind_cmd(hw_binding, hw_ifh.data())); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf3_name)); + + TRY_CHECK(OM::remove(Isaiah)); +} + +BOOST_AUTO_TEST_CASE(test_arp_proxy) { + VppInit vi; + const std::string kurt = "KurtVonnegut"; + rc_t rc = rc_t::OK; + + asio::ip::address_v4 low = asio::ip::address_v4::from_string("10.0.0.0"); + asio::ip::address_v4 high = asio::ip::address_v4::from_string("10.0.0.255"); + + arp_proxy_config ap(low, high); + HW::item hw_ap_cfg(true, rc_t::OK); + ADD_EXPECT(arp_proxy_config_cmds::config_cmd(hw_ap_cfg, low, high)); + TRY_CHECK_RC(OM::write(kurt, ap)); + + std::string itf3_name = "host3"; + interface itf3(itf3_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf3_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(kurt, itf3)); + + arp_proxy_binding *apb = new arp_proxy_binding(itf3); + HW::item hw_binding(true, rc_t::OK); + ADD_EXPECT(arp_proxy_binding_cmds::bind_cmd(hw_binding, hw_ifh.data())); + TRY_CHECK_RC(OM::write(kurt, *apb)); + + delete apb; + + HW::item hw_as_down(interface::admin_state_t::DOWN, + rc_t::OK); + STRICT_ORDER_OFF(); + ADD_EXPECT(arp_proxy_binding_cmds::unbind_cmd(hw_binding, hw_ifh.data())); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf3_name)); + ADD_EXPECT(arp_proxy_config_cmds::unconfig_cmd(hw_ap_cfg, low, high)); + + TRY_CHECK(OM::remove(kurt)); +} + +BOOST_AUTO_TEST_CASE(test_ip_punt_redirect) { + VppInit vi; + const std::string eliot = "EliotReed"; + rc_t rc = rc_t::OK; + + /* + * Interface 1 is the tx interface + */ + std::string itf1_name = "tx-itf"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(eliot, itf1)); + + boost::asio::ip::address addr = boost::asio::ip::address::from_string("192.168.0.20"); + + /* + * Interface 2 is the rx interface + */ + std::string itf2_name = "rx-itf"; + interface itf2(itf2_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh2(4, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2)); + TRY_CHECK_RC(OM::write(eliot, itf2)); + + ip_punt_redirect *ip_punt = new ip_punt_redirect(itf2, itf1, addr); + HW::item hw_ip_cfg(true, rc_t::OK); + HW::item hw_ip_uncfg(false, rc_t::OK); + ADD_EXPECT(ip_punt_redirect_cmds::config_cmd(hw_ip_cfg, hw_ifh2.data(), hw_ifh.data(), addr)); + TRY_CHECK_RC(OM::write(eliot, *ip_punt)); + + delete ip_punt; + + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + STRICT_ORDER_OFF(); + ADD_EXPECT(ip_punt_redirect_cmds::unconfig_cmd(hw_ip_uncfg, hw_ifh2.data(), hw_ifh.data(), addr)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name)); + + TRY_CHECK(OM::remove(eliot)); +} + +BOOST_AUTO_TEST_CASE(test_ip_unnumbered) { + VppInit vi; + const std::string eric = "EricAmbler"; + rc_t rc = rc_t::OK; + + /* + * Interface 1 has the L3 address + */ + std::string itf1_name = "host1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(eric, itf1)); + + route::prefix_t pfx_10("10.10.10.10", 24); + l3_binding *l3 = new l3_binding(itf1, pfx_10); + HW::item hw_l3_bind(true, rc_t::OK); + HW::item hw_l3_unbind(false, rc_t::OK); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind, hw_ifh.data(), pfx_10)); + TRY_CHECK_RC(OM::write(eric, *l3)); + + /* + * Interface 2 is unnumbered + */ + std::string itf2_name = "host2"; + interface itf2(itf2_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh2(4, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh2)); + TRY_CHECK_RC(OM::write(eric, itf2)); + + ip_unnumbered *ipun = new ip_unnumbered(itf2, itf1); + HW::item hw_ip_cfg(true, rc_t::OK); + HW::item hw_ip_uncfg(false, rc_t::OK); + ADD_EXPECT(ip_unnumbered_cmds::config_cmd(hw_ip_cfg, hw_ifh2.data(), hw_ifh.data())); + TRY_CHECK_RC(OM::write(eric, *ipun)); + + delete l3; + delete ipun; + + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + STRICT_ORDER_OFF(); + ADD_EXPECT(ip_unnumbered_cmds::unconfig_cmd(hw_ip_uncfg, hw_ifh2.data(), hw_ifh.data())); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind, hw_ifh.data(), pfx_10)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + + TRY_CHECK(OM::remove(eric)); +} + +BOOST_AUTO_TEST_CASE(test_ip6nd) { + VppInit vi; + const std::string paulo = "PauloCoelho"; + rc_t rc = rc_t::OK; + + /* + * ra config + */ + std::string itf_name = "host_ip6nd"; + interface itf(itf_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(3, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(paulo, itf)); + + route::prefix_t pfx_10("fd8f:69d8:c12c:ca62::3", 128); + l3_binding *l3 = new l3_binding(itf, pfx_10); + HW::item hw_l3_bind(true, rc_t::OK); + HW::item hw_l3_unbind(false, rc_t::OK); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind, hw_ifh.data(), pfx_10)); + TRY_CHECK_RC(OM::write(paulo, *l3)); + + ra_config ra(0, 1, 0, 4); + ip6nd_ra_config *ip6ra = new ip6nd_ra_config(itf, ra); + HW::item hw_ip6nd_ra_config_config(true, rc_t::OK); + HW::item hw_ip6nd_ra_config_unconfig(false, rc_t::OK); + ADD_EXPECT(ip6nd_ra_config::config_cmd(hw_ip6nd_ra_config_config, hw_ifh.data(), ra)); + TRY_CHECK_RC(OM::write(paulo, *ip6ra)); + + /* + * ra prefix + */ + ra_prefix ra_pfx(pfx_10, 0, 0, 2592000, 604800); + ip6nd_ra_prefix *ip6pfx = new ip6nd_ra_prefix(itf, ra_pfx); + HW::item hw_ip6nd_ra_prefix_config(true, rc_t::OK); + HW::item hw_ip6nd_ra_prefix_unconfig(false, rc_t::OK); + ADD_EXPECT(ip6nd_ra_prefix::config_cmd(hw_ip6nd_ra_prefix_config, hw_ifh.data(), ra_pfx)); + TRY_CHECK_RC(OM::write(paulo, *ip6pfx)); + + delete ip6pfx; + + ADD_EXPECT(ip6nd_ra_prefix::unconfig_cmd(hw_ip6nd_ra_prefix_unconfig, hw_ifh.data(), ra_pfx)); + + delete ip6ra; + delete l3; + + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + + STRICT_ORDER_OFF(); + ADD_EXPECT(ip6nd_ra_config::unconfig_cmd(hw_ip6nd_ra_config_unconfig, hw_ifh.data(), ra)); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind, hw_ifh.data(), pfx_10)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf_name)); + + TRY_CHECK(OM::remove(paulo)); +} + +BOOST_AUTO_TEST_CASE(test_interface_span) { + VppInit vi; + const std::string elif = "ElifShafak"; + rc_t rc = rc_t::OK; + + /* + * Interface 1 to be mirrored + */ + std::string itf1_name = "port-from"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(elif, itf1)); + + /* + * Interface 2 where traffic is mirrored + */ + std::string itf2_name = "port-to"; + interface itf2(itf2_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh2(4, rc_t::OK); + HW::item hw_as_up2(interface::admin_state_t::UP, rc_t::OK); + + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up2, hw_ifh2)); + TRY_CHECK_RC(OM::write(elif, itf2)); + + interface_span *itf_span = new interface_span(itf1, itf2, interface_span::state_t::TX_RX_ENABLED); + HW::item hw_is_cfg(true, rc_t::OK); + HW::item hw_is_uncfg(true, rc_t::OK); + ADD_EXPECT(interface_span_cmds::config_cmd(hw_is_cfg, hw_ifh.data(), hw_ifh2.data(), interface_span::state_t::TX_RX_ENABLED)); + TRY_CHECK_RC(OM::write(elif, *itf_span)); + + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + HW::item hw_as_down2(interface::admin_state_t::DOWN, rc_t::OK); + + delete itf_span; + STRICT_ORDER_OFF(); + ADD_EXPECT(interface_span_cmds::unconfig_cmd(hw_is_uncfg, hw_ifh.data(), hw_ifh2.data())); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down2, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name)); + + TRY_CHECK(OM::remove(elif)); +} + +BOOST_AUTO_TEST_CASE(test_routing) { + VppInit vi; + const std::string ian = "IanFleming"; + rc_t rc = rc_t::OK; + + /* + * non-default route domain + */ + route_domain rd4(1); + HW::item hw_rd4_create(true, rc_t::OK); + HW::item hw_rd4_delete(false, rc_t::OK); + HW::item hw_rd6_create(true, rc_t::OK); + HW::item hw_rd6_delete(false, rc_t::OK); + HW::item hw_rd4_bind(1, rc_t::OK); + HW::item hw_rd4_unbind(route::DEFAULT_TABLE, rc_t::OK); + HW::item hw_rd6_bind(1, rc_t::OK); + HW::item hw_rd7_unbind(route::DEFAULT_TABLE, rc_t::OK); + ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd4_create, l3_proto_t::IPV4, 1)); + ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd6_create, l3_proto_t::IPV6, 1)); + TRY_CHECK_RC(OM::write(ian, rd4)); + + /* + * a couple of interfaces + */ + std::string itf1_name = "af1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(ian, itf1)); + + std::string itf2_name = "af2"; + interface *itf2 = new interface(itf2_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP, + rd4); + + HW::item hw_ifh2(4, rc_t::OK); + HW::item hw_as_up2(interface::admin_state_t::UP, rc_t::OK); + HW::item hw_as_down2(interface::admin_state_t::DOWN, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up2, hw_ifh2)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_bind, l3_proto_t::IPV4, hw_ifh2)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd6_bind, l3_proto_t::IPV6, hw_ifh2)); + TRY_CHECK_RC(OM::write(ian, *itf2)); + + /* + * prefix on each interface + */ + route::prefix_t pfx_10("10.10.10.10", 24); + l3_binding *l3_10 = new l3_binding(itf1, pfx_10); + HW::item hw_l3_10_bind(true, rc_t::OK); + HW::item hw_l3_10_unbind(false, rc_t::OK); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_10_bind, hw_ifh.data(), pfx_10)); + TRY_CHECK_RC(OM::write(ian, *l3_10)); + route::prefix_t pfx_11("11.11.11.11", 24); + l3_binding *l3_11 = new l3_binding(*itf2, pfx_11); + HW::item hw_l3_11_bind(true, rc_t::OK); + HW::item hw_l3_11_unbind(false, rc_t::OK); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_11_bind, hw_ifh2.data(), pfx_11)); + TRY_CHECK_RC(OM::write(ian, *l3_11)); + + /* + * A route via interface 1 in the default table + */ + route::prefix_t pfx_5("5.5.5.5", 32); + boost::asio::ip::address nh_9 = boost::asio::ip::address::from_string("10.10.10.9"); + route::path *path_9 = new route::path(nh_9, itf1); + boost::asio::ip::address nh_10 = boost::asio::ip::address::from_string("10.10.10.11"); + route::path *path_10 = new route::path(nh_10, itf1); + route::ip_route *route_5 = new route::ip_route(pfx_5); + route_5->add(*path_10); + route_5->add(*path_9); + route::path_list_t pl_9_10 = {*path_9, *path_10}; + HW::item hw_route_5(0, rc_t::OK); + ADD_EXPECT(route::ip_route_cmds::update_cmd(hw_route_5, 0, pfx_5, pl_9_10)); + TRY_CHECK_RC(OM::write(ian, *route_5)); + + route_5->remove(*path_9); + route::path_list_t pl_10 = {*path_10}; + ADD_EXPECT(route::ip_route_cmds::update_cmd(hw_route_5, 0, pfx_5, pl_10)); + TRY_CHECK_RC(OM::write(ian, *route_5)); + + delete path_9; + + /* + * A route via interface 2 in the non-default table + */ + boost::asio::ip::address nh_11 = boost::asio::ip::address::from_string("11.11.11.10"); + route::path *path_11 = new route::path(nh_11, *itf2); + boost::asio::ip::address nh_12 = boost::asio::ip::address::from_string("11.11.11.12"); + route::path *path_12 = new route::path(nh_12, *itf2); + route::ip_route *route_5_2 = new route::ip_route(rd4, pfx_5); + route::path_list_t pl_11 = {*path_11}; + route_5_2->add(*path_11); + HW::item hw_route_5_2(1, rc_t::OK); + ADD_EXPECT(route::ip_route_cmds::update_cmd(hw_route_5_2, 1, pfx_5, pl_11)); + TRY_CHECK_RC(OM::write(ian, *route_5_2)); + + route::path_list_t pl_11_12 = {*path_11, *path_12}; + route_5_2->add(*path_12); + ADD_EXPECT(route::ip_route_cmds::update_cmd(hw_route_5_2, 1, pfx_5, pl_11_12)); + TRY_CHECK_RC(OM::write(ian, *route_5_2)); + + /* + * An ARP entry for the neighbour on itf1 + */ + HW::item hw_neighbour(0, rc_t::OK); + mac_address_t mac_n({0,1,2,4,5,6}); + neighbour *ne = new neighbour(itf1, nh_10, mac_n); + ADD_EXPECT(neighbour_cmds::create_cmd(hw_neighbour, hw_ifh.data(), + mac_n, nh_10, + neighbour::flags_t::STATIC)); + TRY_CHECK_RC(OM::write(ian, *ne)); + + /* + * A DVR route + */ + route::prefix_t pfx_6("6.6.6.6", 32); + route::path *path_13 = new route::path(*itf2, nh_proto_t::ETHERNET); + route::ip_route *route_dvr = new route::ip_route(pfx_6); + route_dvr->add(*path_13); + route::path_list_t pl_13 = {*path_13}; + HW::item hw_route_dvr(2, rc_t::OK); + ADD_EXPECT(route::ip_route_cmds::update_cmd(hw_route_dvr, 0, pfx_6, pl_13)); + TRY_CHECK_RC(OM::write(ian, *route_dvr)); + + /* + * a multicast route + */ + route::mprefix_t mpfx_4(boost::asio::ip::address::from_string("232.1.1.1"), 32); + route::ip_mroute *mroute_4 = new route::ip_mroute(mpfx_4); + + route::path *mp1 = new route::path(itf1, nh_proto_t::IPV4); + route::path *mp2 = new route::path(*itf2, nh_proto_t::IPV4); + mroute_4->add(*mp1, route::itf_flags_t::FORWARD); + mroute_4->add(*mp1, route::itf_flags_t::ACCEPT); + mroute_4->add(*mp2, route::itf_flags_t::FORWARD); + HW::item hw_mroute_4(true, rc_t::OK); + ADD_EXPECT(route::ip_mroute_cmds::update_cmd(hw_mroute_4, 0, mpfx_4, + *mp1, route::itf_flags_t::FORWARD)); + ADD_EXPECT(route::ip_mroute_cmds::update_cmd(hw_mroute_4, 0, mpfx_4, + *mp2, route::itf_flags_t::FORWARD)); + ADD_EXPECT(route::ip_mroute_cmds::update_cmd(hw_mroute_4, 0, mpfx_4, + *mp1, route::itf_flags_t::ACCEPT)); + TRY_CHECK_RC(OM::write(ian, *mroute_4)); + + STRICT_ORDER_OFF(); + // delete the stack objects that hold references to others + // so the OM::remove is the call that removes the last reference + delete l3_11; + delete l3_10; + delete itf2; + delete route_5; + delete route_5_2; + delete route_dvr; + delete ne; + delete mroute_4; + + ADD_EXPECT(route::ip_mroute_cmds::delete_cmd(hw_mroute_4, 0, mpfx_4, + *mp1, route::itf_flags_t::FORWARD)); + ADD_EXPECT(route::ip_mroute_cmds::delete_cmd(hw_mroute_4, 0, mpfx_4, + *mp2, route::itf_flags_t::FORWARD)); + ADD_EXPECT(route::ip_mroute_cmds::delete_cmd(hw_mroute_4, 0, mpfx_4, + *mp1, route::itf_flags_t::ACCEPT)); + + delete mp1; + delete mp2; + + ADD_EXPECT(neighbour_cmds::delete_cmd(hw_neighbour, hw_ifh.data(), + mac_n, nh_10, + neighbour::flags_t::STATIC)); + ADD_EXPECT(route::ip_route_cmds::delete_cmd(hw_route_dvr, 0, pfx_6)); + ADD_EXPECT(route::ip_route_cmds::delete_cmd(hw_route_5_2, 1, pfx_5)); + ADD_EXPECT(route::ip_route_cmds::delete_cmd(hw_route_5, 0, pfx_5)); + + delete path_10; + delete path_11; + delete path_12; + delete path_13; + pl_9_10.clear(); + pl_10.clear(); + pl_13.clear(); + pl_11_12.clear(); + pl_11.clear(); + + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_10_unbind, hw_ifh.data(), pfx_10)); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_11_unbind, hw_ifh2.data(), pfx_11)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf1_name)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_unbind, l3_proto_t::IPV4, hw_ifh2)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd4_unbind, l3_proto_t::IPV6, hw_ifh2)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down2, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf2_name)); + ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd4_delete, l3_proto_t::IPV4, 1)); + ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd6_delete, l3_proto_t::IPV6, 1)); + + TRY_CHECK(OM::remove(ian)); +} + +BOOST_AUTO_TEST_CASE(test_nat) { + VppInit vi; + const std::string gs = "GeorgeSimenon"; + rc_t rc = rc_t::OK; + + /* + * Inside Interface + */ + std::string itf_in_name = "inside"; + interface itf_in(itf_in_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf_in_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(gs, itf_in)); + + /* + * outside + */ + std::string itf_out_name = "port-to"; + interface itf_out(itf_out_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + + HW::item hw_ifh2(4, rc_t::OK); + HW::item hw_as_up2(interface::admin_state_t::UP, rc_t::OK); + HW::item hw_as_down2(interface::admin_state_t::DOWN, rc_t::OK); + + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh2, itf_out_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up2, hw_ifh2)); + TRY_CHECK_RC(OM::write(gs, itf_out)); + + /* + * A NAT static mapping + */ + boost::asio::ip::address in_addr = boost::asio::ip::address::from_string("10.0.0.1"); + boost::asio::ip::address_v4 out_addr = boost::asio::ip::address_v4::from_string("1.1.1.1"); + + nat_static ns(in_addr, out_addr); + HW::item hw_ns(true, rc_t::OK); + + ADD_EXPECT(nat_static_cmds::create_44_cmd(hw_ns, 0, in_addr.to_v4(), out_addr)); + TRY_CHECK_RC(OM::write(gs, ns)); + + /* + * bind nat inside and out + */ + nat_binding *nb_in = new nat_binding(itf_in, + direction_t::INPUT, + l3_proto_t::IPV4, + nat_binding::zone_t::INSIDE); + HW::item hw_nb_in(true, rc_t::OK); + + ADD_EXPECT(nat_binding_cmds::bind_44_input_cmd(hw_nb_in, + hw_ifh.data().value(), + nat_binding::zone_t::INSIDE)); + TRY_CHECK_RC(OM::write(gs, *nb_in)); + + nat_binding *nb_out = new nat_binding(itf_out, + direction_t::INPUT, + l3_proto_t::IPV4, + nat_binding::zone_t::OUTSIDE); + HW::item hw_nb_out(true, rc_t::OK); + + ADD_EXPECT(nat_binding_cmds::bind_44_input_cmd(hw_nb_out, + hw_ifh2.data().value(), + nat_binding::zone_t::OUTSIDE)); + TRY_CHECK_RC(OM::write(gs, *nb_out)); + + + STRICT_ORDER_OFF(); + delete nb_in; + delete nb_out; + ADD_EXPECT(nat_binding_cmds::unbind_44_input_cmd(hw_nb_in, + hw_ifh.data().value(), + nat_binding::zone_t::INSIDE)); + ADD_EXPECT(nat_binding_cmds::unbind_44_input_cmd(hw_nb_out, + hw_ifh2.data().value(), + nat_binding::zone_t::OUTSIDE)); + ADD_EXPECT(nat_static_cmds::delete_44_cmd(hw_ns, 0, in_addr.to_v4(), out_addr)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf_in_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down2, hw_ifh2)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh2, itf_out_name)); + + TRY_CHECK(OM::remove(gs)); +} + +BOOST_AUTO_TEST_CASE(test_interface_events) { + VppInit vi; + MockListener ml; + + HW::item hw_want(true, rc_t::OK); + + ADD_EXPECT(interface_cmds::events_cmd(ml)); + cmd* itf = new interface_cmds::events_cmd(ml); + + HW::enqueue(itf); + HW::write(); +} + +BOOST_AUTO_TEST_CASE(test_interface_route_domain_change) { + VppInit vi; + const std::string rene = "ReneGoscinny"; + rc_t rc = rc_t::OK; + + /* + * Create an interface with two IP addresses + */ + std::string itf1_name = "host1"; + interface itf1(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh1(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh1, itf1_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh1)); + TRY_CHECK_RC(OM::write(rene, itf1)); + + route::prefix_t pfx_10("10.10.10.10", 24); + l3_binding *l3_1 = new l3_binding(itf1, pfx_10); + HW::item hw_l3_bind1(true, rc_t::OK); + HW::item hw_l3_unbind1(false, rc_t::OK); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind1, hw_ifh1.data(), pfx_10)); + TRY_CHECK_RC(OM::write(rene, *l3_1)); + + route::prefix_t pfx_11("10.10.11.11", 24); + l3_binding *l3_2 = new l3_binding(itf1, pfx_11); + HW::item hw_l3_bind2(true, rc_t::OK); + HW::item hw_l3_unbind2(false, rc_t::OK); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind2, hw_ifh1.data(), pfx_11)); + TRY_CHECK_RC(OM::write(rene, *l3_2)); + + route_domain rd(1); + HW::item hw_rd_create(true, rc_t::OK); + HW::item hw_rd_delete(false, rc_t::OK); + HW::item hw_rd_bind(1, rc_t::OK); + HW::item hw_rd_unbind(route::DEFAULT_TABLE, rc_t::OK); + ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd_create, l3_proto_t::IPV4, 1)); + ADD_EXPECT(route_domain_cmds::create_cmd(hw_rd_create, l3_proto_t::IPV6, 1)); + TRY_CHECK_RC(OM::write(rene, rd)); + + /* + * update the interface to change to a new route-domain + * expect that the l3-bindings are removed and readded. + */ + interface *itf2 = new interface(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP, + rd); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind1, hw_ifh1.data(), pfx_10)); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind2, hw_ifh1.data(), pfx_11)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd_bind, l3_proto_t::IPV4, hw_ifh1)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd_bind, l3_proto_t::IPV6, hw_ifh1)); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind1, hw_ifh1.data(), pfx_10)); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind2, hw_ifh1.data(), pfx_11)); + TRY_CHECK_RC(OM::write(rene, *itf2)); + + /* + * mve the interface back to the default route-domain + */ + interface itf3(itf1_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind1, hw_ifh1.data(), pfx_10)); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind2, hw_ifh1.data(), pfx_11)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd_unbind, l3_proto_t::IPV4, hw_ifh1)); + ADD_EXPECT(interface_cmds::set_table_cmd(hw_rd_unbind, l3_proto_t::IPV6, hw_ifh1)); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind1, hw_ifh1.data(), pfx_10)); + ADD_EXPECT(l3_binding_cmds::bind_cmd(hw_l3_bind2, hw_ifh1.data(), pfx_11)); + TRY_CHECK_RC(OM::write(rene, itf3)); + + delete l3_1; + delete l3_2; + delete itf2; + + STRICT_ORDER_OFF(); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind1, hw_ifh1.data(), pfx_10)); + ADD_EXPECT(l3_binding_cmds::unbind_cmd(hw_l3_unbind2, hw_ifh1.data(), pfx_11)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh1)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh1, itf1_name)); + ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd_delete, l3_proto_t::IPV4, 1)); + ADD_EXPECT(route_domain_cmds::delete_cmd(hw_rd_delete, l3_proto_t::IPV6, 1)); + + TRY_CHECK(OM::remove(rene)); +} + +BOOST_AUTO_TEST_CASE(test_prefixes) { + route::prefix_t p6_s_16(boost::asio::ip::address::from_string("2001::"), 16); + + BOOST_CHECK(p6_s_16.mask() == boost::asio::ip::address::from_string("ffff::")); + + route::prefix_t p6_s_17(boost::asio::ip::address::from_string("2001:ff00::"), 17); + + BOOST_CHECK(p6_s_17.mask() == boost::asio::ip::address::from_string("ffff:8000::")); + BOOST_CHECK(p6_s_17.low().address() == boost::asio::ip::address::from_string("2001:8000::")); + + route::prefix_t p6_s_15(boost::asio::ip::address::from_string("2001:ff00::"), 15); + BOOST_CHECK(p6_s_15.mask() == boost::asio::ip::address::from_string("fffe::")); + BOOST_CHECK(p6_s_15.low().address() == boost::asio::ip::address::from_string("2000::")); + + route::prefix_t p4_s_16(boost::asio::ip::address::from_string("192.168.0.0"), 16); + + BOOST_CHECK(p4_s_16.mask() == boost::asio::ip::address::from_string("255.255.0.0")); + + route::prefix_t p4_s_17(boost::asio::ip::address::from_string("192.168.127.0"), 17); + + BOOST_CHECK(p4_s_17.mask() == boost::asio::ip::address::from_string("255.255.128.0")); + BOOST_CHECK(p4_s_17.low().address() == boost::asio::ip::address::from_string("192.168.0.0")); + BOOST_CHECK(p4_s_17.high().address() == boost::asio::ip::address::from_string("192.168.127.255")); + + route::prefix_t p4_s_15(boost::asio::ip::address::from_string("192.168.255.255"), 15); + + BOOST_CHECK(p4_s_15.mask() == boost::asio::ip::address::from_string("255.254.0.0")); + BOOST_CHECK(p4_s_15.low().address() == boost::asio::ip::address::from_string("192.168.0.0")); + BOOST_CHECK(p4_s_15.high().address() == boost::asio::ip::address::from_string("192.169.255.255")); + + route::prefix_t p4_s_32(boost::asio::ip::address::from_string("192.168.1.1"), 32); + + BOOST_CHECK(p4_s_32.mask() == boost::asio::ip::address::from_string("255.255.255.255")); + BOOST_CHECK(p4_s_32.low().address() == boost::asio::ip::address::from_string("192.168.1.1")); + BOOST_CHECK(p4_s_32.high().address() == boost::asio::ip::address::from_string("192.168.1.1")); + +} + +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 hw_hdl(4, rc_t::OK); + HW::item hw_hdl_pair(std::make_pair(5,6), rc_t::OK); + + HW::item hw_as_up(interface::admin_state_t::UP, + rc_t::OK); + HW::item 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::arp_ufwd_mode_t::ON, + bridge_domain::flood_mode_t::OFF, + bridge_domain::uu_flood_mode_t::ON, + bridge_domain::mac_age_mode_t::ON); + + HW::item 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::arp_ufwd_mode_t::ON, + bridge_domain::flood_mode_t::OFF, + bridge_domain::uu_flood_mode_t::ON, + 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 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(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + TRY_CHECK_RC(OM::write(gk, *l2_1)); + + l2_binding *l2_2 = new l2_binding(*pipe1.west(), bd1); + HW::item 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(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + 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(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + ADD_EXPECT(l2_binding_cmds::unbind_cmd(hw_l2_1_bind, + pipe1.west()->handle(), + hw_bd.data(), + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL)); + 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_CASE(test_qos) { + VppInit vi; + const std::string albert = "AlbertCamus"; + rc_t rc = rc_t::OK; + + /* + * Create an interface on which to enable QoS + */ + std::string itf_name = "host1"; + interface itf(itf_name, + interface::type_t::AFPACKET, + interface::admin_state_t::UP); + HW::item hw_ifh(2, rc_t::OK); + HW::item hw_as_up(interface::admin_state_t::UP, rc_t::OK); + HW::item hw_as_down(interface::admin_state_t::DOWN, rc_t::OK); + ADD_EXPECT(interface_cmds::af_packet_create_cmd(hw_ifh, itf_name)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_up, hw_ifh)); + TRY_CHECK_RC(OM::write(albert, itf)); + + QoS::map::outputs_t out; + out[0][5] = 5; + out[3][6] = 6; + + QoS::map qem(1, out); + + HW::item hw_qem(true, rc_t::OK); + ADD_EXPECT(QoS::map_cmds::create_cmd(hw_qem, 1, out)); + TRY_CHECK_RC(OM::write(albert, qem)); + + QoS::record *qr = new QoS::record(itf, QoS::source_t::IP); + HW::item hw_qr(true, rc_t::OK); + ADD_EXPECT(QoS::record_cmds::create_cmd(hw_qr, hw_ifh.data(), QoS::source_t::IP)); + TRY_CHECK_RC(OM::write(albert, *qr)); + + QoS::store *qs = new QoS::store(itf, QoS::source_t::IP, 55); + HW::item hw_qs(true, rc_t::OK); + ADD_EXPECT(QoS::store_cmds::create_cmd(hw_qs, hw_ifh.data(), QoS::source_t::IP, 55)); + TRY_CHECK_RC(OM::write(albert, *qs)); + + QoS::mark *qm = new QoS::mark(itf, qem, QoS::source_t::IP); + HW::item hw_qm(true, rc_t::OK); + ADD_EXPECT(QoS::mark_cmds::create_cmd(hw_qm, hw_ifh.data(), 1, QoS::source_t::IP)); + TRY_CHECK_RC(OM::write(albert, *qm)); + + STRICT_ORDER_OFF(); + delete qr; + delete qm; + delete qs; + ADD_EXPECT(QoS::mark_cmds::delete_cmd(hw_qm, hw_ifh.data(), QoS::source_t::IP)); + ADD_EXPECT(QoS::map_cmds::delete_cmd(hw_qem, 1)); + ADD_EXPECT(QoS::record_cmds::delete_cmd(hw_qr, hw_ifh.data(), QoS::source_t::IP)); + ADD_EXPECT(QoS::store_cmds::delete_cmd(hw_qs, hw_ifh.data(), QoS::source_t::IP)); + ADD_EXPECT(interface_cmds::state_change_cmd(hw_as_down, hw_ifh)); + ADD_EXPECT(interface_cmds::af_packet_delete_cmd(hw_ifh, itf_name)); + TRY_CHECK(OM::remove(albert)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/extras/deprecated/vom/vom.mk b/extras/deprecated/vom/vom.mk new file mode 100644 index 00000000000..f284473beb5 --- /dev/null +++ b/extras/deprecated/vom/vom.mk @@ -0,0 +1,45 @@ +# Copyright (c) 2017-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. + +vom_configure_depend = vpp-install +vom_source = extras +vom_configure_subdir = vom + +ifneq ($(shell which cmake3),) +CMAKE?=cmake3 +else +CMAKE?=cmake +endif + +vom_cmake_args ?= +vom_cmake_args += -DCMAKE_INSTALL_PREFIX:PATH=$(PACKAGE_INSTALL_DIR) +vom_cmake_args += -DCMAKE_CXX_FLAGS="$($(TAG)_TAG_CPPFLAGS)" +vom_cmake_args += -DCMAKE_SHARED_LINKER_FLAGS="$($(TAG)_TAG_LDFLAGS)" +vom_cmake_args += -DCMAKE_PREFIX_PATH:PATH="$(PACKAGE_INSTALL_DIR)/../vpp" + +# Use devtoolset on centos 7 +ifneq ($(wildcard /opt/rh/devtoolset-9/enable),) +vom_cmake_args += -DCMAKE_PROGRAM_PATH:PATH="/opt/rh/devtoolset-9/root/bin" +endif + +vom_configure = \ + cd $(PACKAGE_BUILD_DIR) && \ + $(CMAKE) -G Ninja $(vom_cmake_args) $(call find_source_fn,$(PACKAGE_SOURCE))$(PACKAGE_SUBDIR) + +vom_build = $(CMAKE) --build $(PACKAGE_BUILD_DIR) -- $(MAKE_PARALLEL_FLAGS) + +vom_install = $(CMAKE) --build $(PACKAGE_BUILD_DIR) -- install + +vom-package-deb: vom-install + @$(CMAKE) --build $(PACKAGE_BUILD_DIR)/vom -- package + @find $(PACKAGE_BUILD_DIR)/vom -name '*.deb' -exec mv {} $(CURDIR) \; diff --git a/extras/deprecated/vom/vom/.clang-format b/extras/deprecated/vom/vom/.clang-format new file mode 100644 index 00000000000..b83102010d0 --- /dev/null +++ b/extras/deprecated/vom/vom/.clang-format @@ -0,0 +1,4 @@ + +BasedOnStyle: mozilla +AlwaysBreakAfterReturnType: TopLevelDefinitions +BinPackParameters: false diff --git a/extras/deprecated/vom/vom/CMakeLists.txt b/extras/deprecated/vom/vom/CMakeLists.txt new file mode 100644 index 00000000000..92a4348dba4 --- /dev/null +++ b/extras/deprecated/vom/vom/CMakeLists.txt @@ -0,0 +1,323 @@ +# 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. + +unset (VPPAPICLIENT_LIB) +unset (VAPICLIENT_LIB) +unset (ACL_FILE) +unset (NAT_FILE) +unset (L2E_FILE) +unset (GBP_FILE) +unset (IGMP_FILE) +unset (VOM_SOURCES) +unset (VOM_HEADERS) + +find_library(VPPAPICLIENT_LIB NAMES vppapiclient REQUIRED) +find_path(VPPAPICLIENT_INCLUDE_DIR NAMES vpp-api/client/vppapiclient.h) +find_library(VAPICLIENT_LIB NAMES vapiclient REQUIRED) +find_path(VAPICLIENT_INCLUDE_DIR NAMES vapi/vapi.hpp) + + +if(NOT VPPAPICLIENT_INCLUDE_DIR OR NOT VPPAPICLIENT_LIB) + message(FATAL_ERROR "Cannot find vppapiclient library and/or headers") +endif() +if(NOT VAPICLIENT_INCLUDE_DIR OR NOT VAPICLIENT_LIB) + message(FATAL_ERROR "Cannot find vapiclient library and/or headers") +endif() + +include_directories(${VPPAPICLIENT_INCLUDE_DIR}) +include_directories(${VAPICLIENT_INCLUDE_DIR}) +include_directories(${CMAKE_SOURCE_DIR}) + +find_file(ACL_FILE NAMES acl.api.vapi.hpp PATH_SUFFIXES vapi) +find_file(NAT_FILE NAMES nat.api.vapi.hpp PATH_SUFFIXES vapi) +find_file(L2E_FILE NAMES l2e.api.vapi.hpp PATH_SUFFIXES vapi) +find_file(GBP_FILE NAMES gbp.api.vapi.hpp PATH_SUFFIXES vapi) +find_file(IGMP_FILE NAMES igmp.api.vapi.hpp PATH_SUFFIXES vapi) + +if(ACL_FILE) + list(APPEND VOM_SOURCES + acl_binding_cmds.cpp + acl_binding.cpp + acl_ethertype_cmds.cpp + acl_ethertype.cpp + acl_l2_list.cpp + acl_l2_rule.cpp + acl_l3_list.cpp + acl_l3_rule.cpp + acl_list_cmds.cpp + acl_types.cpp + ) +endif() + +if(NAT_FILE) + list(APPEND VOM_SOURCES + nat_static.cpp + nat_static_cmds.cpp + nat_binding.cpp + nat_binding_cmds.cpp + ) +endif() + +if (L2E_FILE) + list(APPEND VOM_SOURCES + l2_emulation_cmds.cpp + l2_emulation.cpp + ) +endif() + +if(GBP_FILE) + list(APPEND VOM_SOURCES + gbp_contract_cmds.cpp + gbp_contract.cpp + gbp_bridge_domain_cmds.cpp + gbp_bridge_domain.cpp + gbp_endpoint_cmds.cpp + gbp_endpoint.cpp + gbp_endpoint_group_cmds.cpp + gbp_endpoint_group.cpp + gbp_ext_itf.cpp + gbp_ext_itf_cmds.cpp + gbp_recirc_cmds.cpp + gbp_recirc.cpp + gbp_route_domain_cmds.cpp + gbp_route_domain.cpp + gbp_rule.cpp + gbp_subnet_cmds.cpp + gbp_subnet.cpp + gbp_types.hpp + gbp_vxlan.cpp + gbp_vxlan_cmds.cpp + ) +endif() + +if (IGMP_FILE) + list(APPEND VOM_SOURCES + igmp_binding_cmds.cpp + igmp_binding.cpp + igmp_listen_cmds.cpp + igmp_listen.cpp + ) +endif() + +list(APPEND VOM_SOURCES + types.cpp + api_types.cpp + arp_proxy_binding_cmds.cpp + arp_proxy_binding.cpp + arp_proxy_config_cmds.cpp + arp_proxy_config.cpp + bond_group_binding_cmds.cpp + bond_group_binding.cpp + bond_interface_cmds.cpp + bond_interface.cpp + bond_member.cpp + bridge_domain_cmds.cpp + bridge_domain.cpp + bridge_domain_arp_entry.cpp + bridge_domain_arp_entry_cmds.cpp + bridge_domain_entry_cmds.cpp + bridge_domain_entry.cpp + client_db.cpp + cmd.cpp + connection.cpp + dhcp_client_cmds.cpp + dhcp_client.cpp + hw_cmds.cpp + hw.cpp + inspect.cpp + interface_cmds.cpp + interface.cpp + interface_factory.cpp + interface_ip6_nd_cmds.cpp + interface_span_cmds.cpp + interface_span.cpp + interface_types.cpp + ip_punt_redirect_cmds.cpp + ip_punt_redirect.cpp + ip_unnumbered_cmds.cpp + ip_unnumbered.cpp + l2_binding_cmds.cpp + l2_binding.cpp + l2_vtr.cpp + l2_vtr_cmds.cpp + l2_xconnect_cmds.cpp + l2_xconnect.cpp + l3_binding_cmds.cpp + l3_binding.cpp + lldp_binding_cmds.cpp + lldp_binding.cpp + lldp_global_cmds.cpp + lldp_global.cpp + logger.cpp + neighbour.cpp + neighbour_cmds.cpp + object_base.cpp + mroute_cmds.cpp + om.cpp + pipe.cpp + pipe_cmds.cpp + prefix.cpp + qos_map.cpp + qos_map_cmds.cpp + qos_mark.cpp + qos_mark_cmds.cpp + qos_record.cpp + qos_record_cmds.cpp + qos_store.cpp + qos_store_cmds.cpp + qos_types.cpp + qos_types_api.cpp + ra_config.cpp + ra_prefix.cpp + route.cpp + route_api_types.cpp + route_cmds.cpp + route_domain.cpp + route_domain_cmds.cpp + stat_client.cpp + stat_reader.cpp + sub_interface_cmds.cpp + sub_interface.cpp + tap_interface.cpp + tap_interface_cmds.cpp + vxlan_gbp_tunnel_cmds.cpp + vxlan_tunnel_cmds.cpp + vxlan_tunnel.cpp +) + +if(ACL_FILE) + list(APPEND VOM_HEADERS + acl_binding.hpp + acl_ethertype.hpp + acl_l2_rule.hpp + acl_l3_rule.hpp + acl_l3_list.hpp + acl_l2_list.hpp + acl_types.hpp + ) +endif() + +if(NAT_FILE) + list(APPEND VOM_HEADERS + nat_static.hpp + nat_binding.hpp + ) +endif() + +if(L2E_FILE) + list(APPEND VOM_HEADERS + l2_emulation.hpp + ) +endif() + +if(GBP_FILE) + list(APPEND VOM_HEADERS + gbp_contract.hpp + gbp_bridge_domain.hpp + gbp_endpoint.hpp + gbp_endpoint_group.hpp + gbp_ext_itf.hpp + gbp_recirc.hpp + gbp_route_domain.hpp + gbp_rule.hpp + gbp_subnet.hpp + gbp_types.hpp + gbp_vxlan.hpp + ) +endif() + +if(IGMP_FILE) + list(APPEND VOM_HEADERS + igmp_binding.hpp + igmp_listen.hpp + ) +endif() + +list(APPEND VOM_HEADERS + arp_proxy_binding.hpp + arp_proxy_config.hpp + bond_group_binding.hpp + bond_interface.hpp + bond_member.hpp + bridge_domain.hpp + bridge_domain_arp_entry.hpp + bridge_domain_entry.hpp + client_db.hpp + cmd.hpp + connection.hpp + dhcp_client.hpp + dump_cmd.hpp + enum_base.hpp + event_cmd.hpp + hw.hpp + inspect.hpp + interface.hpp + interface_cmds.hpp + interface_ip6_nd.hpp + interface_span.hpp + ip_punt_redirect.hpp + ip_unnumbered.hpp + l2_binding.hpp + l2_vtr.hpp + l2_xconnect.hpp + l3_binding.hpp + lldp_binding.hpp + lldp_global.hpp + logger.hpp + neighbour.hpp + object_base.hpp + om.hpp + pipe.hpp + prefix.hpp + qos_map.hpp + qos_mark.hpp + qos_record.hpp + qos_store.hpp + qos_types.hpp + ra_config.hpp + ra_prefix.hpp + route.hpp + route_domain.hpp + rpc_cmd.hpp + singular_db.hpp + singular_db_funcs.hpp + stat_client.hpp + stat_reader.hpp + sub_interface.hpp + tap_interface.hpp + types.hpp + api_types.hpp + vxlan_tunnel.hpp +) + +add_definitions(-Wall -Werror -std=gnu++11 -g) +add_library(vom SHARED ${VOM_SOURCES}) +if (VOM_LIB_VERSION) + set_target_properties(vom PROPERTIES SOVERSION ${VOM_LIB_VERSION}) +endif() +target_link_libraries(vom ${VPPAPICLIENT_LIB} ${VAPICLIENT_LIB} Threads::Threads + ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} m rt) +install(TARGETS vom DESTINATION lib COMPONENT vom) +install(FILES ${VOM_HEADERS} DESTINATION include/vom COMPONENT vom) + +if (Boost_FOUND) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + add_definitions(-stdlib=libstdc++) + endif() + add_executable(vom_stats_test test_stats.cpp) + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + target_link_libraries(vom_stats_test vom stdc++) + else() + target_link_libraries(vom_stats_test vom) + endif() +endif() diff --git a/extras/deprecated/vom/vom/acl_binding.cpp b/extras/deprecated/vom/vom/acl_binding.cpp new file mode 100644 index 00000000000..5cdbf89abd6 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_binding.cpp @@ -0,0 +1,216 @@ +/* + * 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/acl_binding.hpp" +#include "vom/acl_binding_cmds.hpp" + +namespace VOM { +namespace ACL { +template <> +dependency_t +l2_binding::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +template <> +l2_binding::event_handler::event_handler() +{ + /* hack to get this function instantiated */ + order(); + + OM::register_listener(this); + inspect::register_handler({ "l2-acl-binding" }, "L2 ACL bindings", this); +} + +template <> +void +l2_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + /* hack to get this function instantiated */ + order(); + + /* + * dump VPP Bridge domains + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = interface::find(payload.sw_if_index); + + if (itf) { + for (int ii = 0; ii < payload.count; ii++) { + std::shared_ptr acl = l2_list::find(payload.acls[ii]); + + if (acl) { + l2_binding binding(direction_t::INPUT, *itf, *acl); + OM::commit(key, binding); + } else { + VOM_LOG(log_level_t::ERROR) << "no ACL id:" << payload.acls[ii]; + } + } + } else { + VOM_LOG(log_level_t::ERROR) << "no interface:" << payload.sw_if_index; + } + } +} + +template <> +dependency_t +l3_binding::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +template <> +l3_binding::event_handler::event_handler() +{ + /* hack to get this function instantiated */ + order(); + + OM::register_listener(this); + inspect::register_handler({ "l3-acl-binding" }, "L3 ACL bindings", this); +} + +template <> +void +l3_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + /* hack to get this function instantiated */ + order(); + + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = interface::find(payload.sw_if_index); + uint8_t n_input = payload.n_input; + + if (itf) { + for (int ii = 0; ii < payload.count; ii++) { + std::shared_ptr acl = l3_list::find(payload.acls[ii]); + + if (acl) { + if (n_input) { + l3_binding binding(direction_t::INPUT, *itf, *acl); + n_input--; + OM::commit(key, binding); + } else { + l3_binding binding(direction_t::OUTPUT, *itf, *acl); + OM::commit(key, binding); + } + } else { + VOM_LOG(log_level_t::ERROR) << "no ACL id:" << payload.acls[ii]; + } + } + } else { + VOM_LOG(log_level_t::ERROR) << "no interface:" << payload.sw_if_index; + } + } +} + +template <> +void +l3_binding::update(const binding& obj) +{ + if (!m_binding) { + HW::enqueue(new binding_cmds::l3_bind_cmd( + m_binding, m_direction, m_itf->handle(), m_acl->handle())); + } + HW::write(); +} + +template <> +void +l3_binding::sweep(void) +{ + if (m_binding) { + HW::enqueue(new binding_cmds::l3_unbind_cmd( + m_binding, m_direction, m_itf->handle(), m_acl->handle())); + } + HW::write(); +} + +template <> +void +l3_binding::replay(void) +{ + if (m_binding) { + HW::enqueue(new binding_cmds::l3_bind_cmd( + m_binding, m_direction, m_itf->handle(), m_acl->handle())); + } +} + +template <> +void +l2_binding::update(const binding& obj) +{ + if (!m_binding) { + HW::enqueue(new binding_cmds::l2_bind_cmd( + m_binding, m_direction, m_itf->handle(), m_acl->handle())); + } + HW::write(); +} + +template <> +void +l2_binding::sweep(void) +{ + if (m_binding) { + HW::enqueue(new binding_cmds::l2_unbind_cmd( + m_binding, m_direction, m_itf->handle(), m_acl->handle())); + } + HW::write(); +} + +template <> +void +l2_binding::replay(void) +{ + if (m_binding) { + HW::enqueue(new binding_cmds::l2_bind_cmd( + m_binding, m_direction, m_itf->handle(), m_acl->handle())); + } +} +}; + +std::ostream& +operator<<(std::ostream& os, + const std::pair& key) +{ + os << "[" << key.first.to_string() << " " << key.second << "]"; + + return (os); +} +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_binding.hpp b/extras/deprecated/vom/vom/acl_binding.hpp new file mode 100644 index 00000000000..e2130fb3389 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_binding.hpp @@ -0,0 +1,245 @@ +/* + * 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_ACL_BINDING_H__ +#define __VOM_ACL_BINDING_H__ + +#include + +#include "vom/acl_l2_list.hpp" +#include "vom/acl_l3_list.hpp" +#include "vom/acl_types.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace ACL { +/** + * A binding between an ACL and an interface. + * A representation of the application of the ACL to the interface. + */ +template +class binding : public object_base +{ +public: + /** + * The key for a binding is the direction and the interface + */ + typedef std::pair key_t; + + /** + * Construct a new object matching the desried state + */ + binding(const direction_t& direction, const interface& itf, const LIST& acl) + : m_direction(direction) + , m_itf(itf.singular()) + , m_acl(acl.singular()) + , m_binding(false) + { + m_evh.order(); + } + + /** + * Copy Constructor + */ + binding(const binding& o) + : m_direction(o.m_direction) + , m_itf(o.m_itf) + , m_acl(o.m_acl) + , m_binding(o.m_binding) + { + } + + /** + * Destructor + */ + ~binding() + { + sweep(); + m_db.release(std::make_pair(m_direction, m_itf->key()), this); + } + + /** + * Return the 'singular instance' of the L2 config that matches this + * object + */ + std::shared_ptr singular() const { return find_or_add(*this); } + + /** + * convert to string format for debug purposes + */ + std::string to_string() const + { + std::ostringstream s; + s << "acl-binding:[" << m_direction.to_string() << " " << m_itf->to_string() + << " " << m_acl->to_string() << " " << m_binding.to_string() << "]"; + + return (s.str()); + } + + /** + * Dump all bindings into the stream provided + */ + static void dump(std::ostream& os) { m_db.dump(os); } + + static dependency_t order() { return m_evh.order(); } + +private: + /** + * 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() { m_db.replay(); } + + /** + * Show the object in the Singular DB + */ + void show(std::ostream& os) { db_dump(m_db, os); } + + /** + * Get the sortable Id of the listener + */ + dependency_t order() const; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const binding& obj); + + /** + * Find or Add the instance in the DB + */ + static std::shared_ptr find_or_add(const binding& temp) + { + return (m_db.find_or_add( + std::make_pair(temp.m_direction, temp.m_itf->key()), temp)); + } + + /* + * It's the OM class that calls singular() + */ + friend class VOM::OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * Replay the objects state to HW + */ + void replay(void); + + /** + * The direction the of the packets on which to apply the ACL + * input or output + */ + const direction_t m_direction; + + /** + * A reference counting pointer the interface that this L3 layer + * represents. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * A reference counting pointer the ACL that this + * interface is bound to. By holding the reference here, we can + * guarantee that this object will outlive the BD. + */ + const std::shared_ptr m_acl; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A map of all L2 interfaces key against the interface's handle_t + */ + static singular_db m_db; +}; + +/** + * Typedef the L3 binding type + */ +typedef binding l3_binding; + +/** + * Typedef the L2 binding type + */ +typedef binding l2_binding; + +/** + * Definition of the static Singular DB for ACL bindings + */ +template +singular_db::key_t, ACL::binding> + binding::m_db; + +template +typename ACL::binding::event_handler binding::m_evh; + +namespace { +const static dependency_t __attribute__((unused)) l2o = l2_binding::order(); +const static dependency_t __attribute__((unused)) l3o = l3_binding::order(); +}; +}; + +std::ostream& operator<<(std::ostream& os, + const std::pair& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_binding_cmds.cpp b/extras/deprecated/vom/vom/acl_binding_cmds.cpp new file mode 100644 index 00000000000..57a6e420ca8 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_binding_cmds.cpp @@ -0,0 +1,189 @@ +/* + * 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/acl_binding_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_ACL_API_JSON; + +namespace VOM { +namespace ACL { +namespace binding_cmds { +template <> +rc_t +l3_bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.is_add = 1; + payload.is_input = (m_direction == direction_t::INPUT ? 1 : 0); + payload.acl_index = m_acl.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +template <> +std::string +l3_bind_cmd::to_string() const +{ + std::ostringstream s; + s << "l3-acl-bind:[" << m_direction.to_string() + << " itf:" << m_itf.to_string() << " acl:" << m_acl.to_string() << "]"; + + return (s.str()); +} + +template <> +rc_t +l3_unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.is_add = 0; + payload.is_input = (m_direction == direction_t::INPUT ? 1 : 0); + payload.acl_index = m_acl.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +template <> +std::string +l3_unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "l3-acl-unbind:[" << m_direction.to_string() + << " itf:" << m_itf.to_string() << " acl:" << m_acl.to_string() << "]"; + + return (s.str()); +} + +template <> +rc_t +l3_dump_cmd::issue(connection& con) +{ + m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +template <> +std::string +l3_dump_cmd::to_string() const +{ + return ("l3-acl-bind-dump"); +} + +template <> +rc_t +l2_bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.is_add = 1; + payload.acl_index = m_acl.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +template <> +std::string +l2_bind_cmd::to_string() const +{ + std::ostringstream s; + s << "l2-acl-bind:[" << m_direction.to_string() + << " itf:" << m_itf.to_string() << " acl:" << m_acl.to_string() << "]"; + + return (s.str()); +} + +template <> +rc_t +l2_unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.is_add = 0; + payload.acl_index = m_acl.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +template <> +std::string +l2_unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "l2-acl-unbind:[" << m_direction.to_string() + << " itf:" << m_itf.to_string() << " acl:" << m_acl.to_string() << "]"; + + return (s.str()); +} + +template <> +rc_t +l2_dump_cmd::issue(connection& con) +{ + m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +template <> +std::string +l2_dump_cmd::to_string() const +{ + return ("l2-acl-bind-dump"); +} + +}; // namespace binding_cmds +}; // namespace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_binding_cmds.hpp b/extras/deprecated/vom/vom/acl_binding_cmds.hpp new file mode 100644 index 00000000000..0e301df6100 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_binding_cmds.hpp @@ -0,0 +1,195 @@ +/* + * 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_ACL_BINDING_CMDS_H__ +#define __VOM_ACL_BINDING_CMDS_H__ + +#include "vom/acl_binding.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace ACL { +namespace binding_cmds { +/** + * A command class that binds the ACL to the interface + */ +template +class bind_cmd : public rpc_cmd, BIND> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, + const direction_t& direction, + const handle_t& itf, + const handle_t& acl) + : rpc_cmd, BIND>(item) + , m_direction(direction) + , m_itf(itf) + , m_acl(acl) + { + } + + /** + * 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 bind_cmd& other) const + { + return ((m_itf == other.m_itf) && (m_acl == m_acl)); + } + +private: + /** + * The direction of the binding + */ + const direction_t m_direction; + + /** + * The interface to bind to + */ + const handle_t m_itf; + + /** + * The ACL to bind + */ + const handle_t m_acl; +}; + +/** + * A command class that binds the ACL to the interface + */ +template +class unbind_cmd : public rpc_cmd, BIND> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, + const direction_t& direction, + const handle_t& itf, + const handle_t& acl) + : rpc_cmd, BIND>(item) + , m_direction(direction) + , m_itf(itf) + , m_acl(acl) + { + } + + /** + * 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 unbind_cmd& other) const + { + return ((m_itf == other.m_itf) && (m_acl == m_acl)); + } + +private: + /** + * The direction of the binding + */ + const direction_t m_direction; + + /** + * The interface to bind to + */ + const handle_t m_itf; + + /** + * The ACL to bind + */ + const handle_t m_acl; +}; + +/** + * A cmd class that Dumps all the ACLs + */ +template +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +/** + * Typedef the L3 ACL binding commands + */ +typedef bind_cmd l3_bind_cmd; +typedef unbind_cmd l3_unbind_cmd; +typedef dump_cmd l3_dump_cmd; + +/** + * Typedef the L2 binding type + */ +typedef bind_cmd l2_bind_cmd; +typedef unbind_cmd l2_unbind_cmd; +typedef dump_cmd l2_dump_cmd; + +}; // namespace binding_cmds +}; // namespace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_ethertype.cpp b/extras/deprecated/vom/vom/acl_ethertype.cpp new file mode 100644 index 00000000000..a72471ac8dc --- /dev/null +++ b/extras/deprecated/vom/vom/acl_ethertype.cpp @@ -0,0 +1,253 @@ +/* + * 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/acl_ethertype.hpp" +#include "vom/acl_ethertype_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace ACL { + +ethertype_rule_t::ethertype_rule_t(const ethertype_t& eth, + const direction_t& dir) + : m_eth(eth) + , m_dir(dir) +{ +} + +std::string +ethertype_rule_t::to_string() const +{ + std::ostringstream s; + + s << "[" + << "ethertype:" << m_eth.to_string() << " dir:" << m_dir.to_string() + << "],"; + + return (s.str()); +} + +bool +ethertype_rule_t::operator<(const ethertype_rule_t& other) const +{ + return (m_dir > other.m_dir); +} + +bool +ethertype_rule_t::operator==(const ethertype_rule_t& other) const +{ + return (m_dir == other.m_dir && m_eth == other.m_eth); +} + +uint16_t +ethertype_rule_t::getEthertype() const +{ + return m_eth.value(); +} + +const direction_t& +ethertype_rule_t::getDirection() const +{ + return m_dir; +} + +/** + * A DB of all acl ethertype bindings configs + */ +singular_db acl_ethertype::m_db; + +acl_ethertype::event_handler acl_ethertype::m_evh; + +acl_ethertype::acl_ethertype(const interface& itf, + const acl_ethertype::ethertype_rules_t& le) + : m_itf(itf.singular()) + , m_le(le) + , m_binding(true) +{ +} + +acl_ethertype::acl_ethertype(const acl_ethertype& o) + : m_itf(o.m_itf) + , m_le(o.m_le) + , m_binding(o.m_binding) +{ +} + +acl_ethertype::~acl_ethertype() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_itf->key(), this); +} + +void +acl_ethertype::sweep() +{ + if (m_binding) { + HW::enqueue(new acl_ethertype_cmds::unbind_cmd(m_binding, m_itf->handle())); + } + HW::write(); +} + +const acl_ethertype::key_t& +acl_ethertype::key() const +{ + return (m_itf->key()); +} + +bool +acl_ethertype::operator==(const acl_ethertype& other) const +{ + return (m_itf->key() == other.m_itf->key() && m_le == other.m_le); +} + +std::shared_ptr +acl_ethertype::find(const key_t& key) +{ + return (m_db.find(key)); +} + +void +acl_ethertype::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +acl_ethertype::replay() +{ + if (m_binding) { + HW::enqueue( + new acl_ethertype_cmds::bind_cmd(m_binding, m_itf->handle(), m_le)); + } +} + +std::string +acl_ethertype::to_string() const +{ + std::ostringstream s; + s << "Acl-Ethertype:" << m_itf->to_string() << " ethertype-rules:"; + auto it = m_le.cbegin(); + while (it != m_le.cend()) { + s << it->to_string(); + ++it; + } + s << " rules-size:" << m_le.size(); + + return (s.str()); +} + +void +acl_ethertype::update(const acl_ethertype& desired) +{ + /* + * always update the instance with the latest rules + */ + if (!m_binding || desired.m_le != m_le) { + HW::enqueue( + new acl_ethertype_cmds::bind_cmd(m_binding, m_itf->handle(), m_le)); + } + + m_le = desired.m_le; +} + +std::shared_ptr +acl_ethertype::find_or_add(const acl_ethertype& temp) +{ + return (m_db.find_or_add(temp.m_itf->key(), temp)); +} + +std::shared_ptr +acl_ethertype::singular() const +{ + return find_or_add(*this); +} + +acl_ethertype::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "acl-ethertype" }, "ACL Ethertype bindings", + this); +} + +void +acl_ethertype::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +acl_ethertype::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump VPP acl ethertypes + */ + std::shared_ptr cmd = + std::make_shared(~0); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + handle_t hdl(payload.sw_if_index); + std::shared_ptr itf = interface::find(hdl); + uint8_t n_input = payload.n_input; + uint8_t count = payload.count; + ethertype_rules_t ler; + if (itf) { + for (int i = 0; i < count; i++) { + ethertype_t e = ethertype_t::from_numeric_val(payload.whitelist[i]); + if (n_input) { + ethertype_rule_t er(e, direction_t::INPUT); + ler.insert(er); + n_input--; + } else { + ethertype_rule_t er(e, direction_t::OUTPUT); + ler.insert(er); + } + } + if (!ler.empty()) { + acl_ethertype a_e(*itf, ler); + VOM_LOG(log_level_t::DEBUG) << "ethertype dump: " << a_e.to_string(); + OM::commit(key, a_e); + } + } else { + VOM_LOG(log_level_t::ERROR) << "no interface:" << payload.sw_if_index; + } + } +} + +dependency_t +acl_ethertype::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +acl_ethertype::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +}; +}; +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_ethertype.hpp b/extras/deprecated/vom/vom/acl_ethertype.hpp new file mode 100644 index 00000000000..740a2061e77 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_ethertype.hpp @@ -0,0 +1,247 @@ +/* + * 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_ACL_ETHERTYPE_H__ +#define __VOM_ACL_ETHERTYPE_H__ + +#include + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +namespace ACL { +/** + * An ACL ethertype list comprises a set of inbound ether types and out bound + * ether types + * to be applied to packets. + * A list is bound to a given interface. + */ + +struct ethertype_rule_t +{ +public: + /** + * Constructor + */ + ethertype_rule_t(const ethertype_t& eth, const direction_t& dir); + + /** + * Destructor + */ + ~ethertype_rule_t() = default; + + /** + * convert to string + */ + std::string to_string() const; + + /** + * comparision operator + */ + bool operator<(const ethertype_rule_t& other) const; + + /** + * comparision operator (for testing) + */ + bool operator==(const ethertype_rule_t& other) const; + + /** + * get the ether value + */ + uint16_t getEthertype(void) const; + + /** + * get the direction + */ + const direction_t& getDirection(void) const; + +private: + /** + * ethertype for this rule + */ + const ethertype_t m_eth; + + /** + * direction in which ethertype will be applied w.r.t. intf + */ + const direction_t m_dir; +}; + +class acl_ethertype : public object_base +{ +public: + /** + * The KEY can be used to uniquely identify the ACL ethertype. + * (other choices for keys, like the summation of the properties + * of the rules, are rather too cumbersome to use + */ + typedef std::string key_t; + + /** + * The ethertype container + */ + typedef std::multiset ethertype_rules_t; + + /** + * Construct a new object matching the desried state + */ + acl_ethertype(const interface& itf, const ethertype_rules_t& le); + + /** + * Copy Constructor + */ + acl_ethertype(const acl_ethertype& o); + + /** + * Destructor + */ + ~acl_ethertype(); + + /** + * Return the binding's key + */ + const key_t& key() const; + + /** + * comparision operator (for testing) + */ + bool operator==(const acl_ethertype& o) const; + + /** + * Return the 'singular' of the acl ethertype that matches this object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all acl ethertype into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Static function to find the acl_ethertype in the model + */ + static std::shared_ptr find(const key_t& key); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enque commands to the VPP command Q for the update + */ + void update(const acl_ethertype& obj); + + /** + * Find or add acl ethertype to the OM + */ + static std::shared_ptr find_or_add(const acl_ethertype& temp); + + /* + * It's the OM class that calls singular() + */ + friend class VOM::OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer to the interface on which acl ethertype + * resides. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * Inbound and outbound ethers list applied on given interface + */ + ethertype_rules_t m_le; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A map of all acl ethertype keyed against the interface. + */ + static singular_db m_db; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_ethertype_cmds.cpp b/extras/deprecated/vom/vom/acl_ethertype_cmds.cpp new file mode 100644 index 00000000000..7bad2b7ebdb --- /dev/null +++ b/extras/deprecated/vom/vom/acl_ethertype_cmds.cpp @@ -0,0 +1,167 @@ +/* + * 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/acl_ethertype_cmds.hpp" + +namespace VOM { +namespace ACL { +namespace acl_ethertype_cmds { + +bind_cmd::bind_cmd(HW::item& item, + const handle_t& itf, + const acl_ethertype::ethertype_rules_t& le) + : rpc_cmd(item) + , m_itf(itf) + , m_le(le) +{ +} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return (m_itf == other.m_itf && m_le == other.m_le); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), m_le.size(), std::ref(*this)); + uint32_t i = 0; + uint8_t n_input = 0; + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.count = m_le.size(); + + auto it = m_le.cbegin(); + while (it != m_le.cend()) { + payload.whitelist[i] = it->getEthertype(); + if (it->getDirection() == direction_t::INPUT) + n_input++; + ++it; + ++i; + } + + payload.n_input = n_input; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "ACL-Ethertype: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string() << " ethertype-rules:"; + auto it = m_le.cbegin(); + while (it != m_le.cend()) { + s << it->to_string(); + ++it; + } + + s << " rules-size:" << m_le.size(); + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{ +} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), 0, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.count = 0; + + payload.n_input = 0; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "ACL-Ethertype-Unbind: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string(); + return (s.str()); +} + +dump_cmd::dump_cmd(const handle_t& hdl) + : m_itf(hdl) +{ +} + +dump_cmd::dump_cmd(const dump_cmd& d) + : m_itf(d.m_itf) +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("acl-ethertype-dump"); +} +}; // namespace acl_ethertype_cmds +}; // namespace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_ethertype_cmds.hpp b/extras/deprecated/vom/vom/acl_ethertype_cmds.hpp new file mode 100644 index 00000000000..3ac9d87bc51 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_ethertype_cmds.hpp @@ -0,0 +1,144 @@ +/* + * 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_ACL_ETHERTYPE_CMDS_H__ +#define __VOM_ACL_ETHERTYPE_CMDS_H__ + +#include "vom/acl_ethertype.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace ACL { +namespace acl_ethertype_cmds { +/** + * A command class that binds the ethertype list to the interface + */ +class bind_cmd + : public rpc_cmd, vapi::Acl_interface_set_etype_whitelist> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, + const handle_t& itf, + const acl_ethertype::ethertype_rules_t& le); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to bind + */ + const handle_t& m_itf; + + /** + * Ethertype list applied to interface + */ + const acl_ethertype::ethertype_rules_t& m_le; +}; + +/** + * A command class that unbinds the ethertype list to the interface + */ +class unbind_cmd + : public rpc_cmd, vapi::Acl_interface_set_etype_whitelist> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to bind + */ + const handle_t m_itf; +}; + +/** + * A cmd class that Dumps all the acl ethertypes on given interface + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(const handle_t& itf); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * The interface to get the addresses for + */ + const handle_t m_itf; +}; +}; +}; +}; +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_l2_list.cpp b/extras/deprecated/vom/vom/acl_l2_list.cpp new file mode 100644 index 00000000000..fb18ace4b4b --- /dev/null +++ b/extras/deprecated/vom/vom/acl_l2_list.cpp @@ -0,0 +1,281 @@ +/* + * 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/acl_l2_list.hpp" +#include "vom/acl_list_cmds.hpp" +#include "vom/api_types.hpp" +#include "vom/logger.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace ACL { + +/** + * Definition of the static singular_db for ACL Lists + */ +singular_db l2_list::m_db; + +/** + * Definition of the static per-handle DB for ACL Lists + */ +std::map> l2_list::m_hdl_db; + +l2_list::event_handler l2_list::m_evh; + +l2_list::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "l2-acl-list" }, "L2 ACL lists", this); +} + +l2_list::l2_list(const key_t& key) + : m_hdl(handle_t::INVALID) + , m_key(key) +{} + +l2_list::l2_list(const handle_t& hdl, const key_t& key) + : m_hdl(hdl) + , m_key(key) +{} + +l2_list::l2_list(const key_t& key, const rules_t& rules) + : m_hdl(handle_t::INVALID) + , m_key(key) + , m_rules(rules) +{} + +l2_list::l2_list(const l2_list& o) + : m_hdl(o.m_hdl) + , m_key(o.m_key) + , m_rules(o.m_rules) +{} + +l2_list::~l2_list() +{ + sweep(); + m_db.release(m_key, this); +} + +std::shared_ptr +l2_list::singular() const +{ + return find_or_add(*this); +} + +/** + * Dump all ACLs into the stream provided + */ +void +l2_list::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +/** + * convert to string format for debug purposes + */ +std::string +l2_list::to_string() const +{ + std::ostringstream s; + s << "acl-list:[" << m_key << " " << m_hdl.to_string() << " rules:["; + + for (auto rule : m_rules) { + s << rule.to_string() << " "; + } + + s << "]]"; + + return (s.str()); +} + +void +l2_list::insert(const l2_rule& rule) +{ + m_rules.insert(rule); +} + +void +l2_list::remove(const l2_rule& rule) +{ + m_rules.erase(rule); +} + +const handle_t& +l2_list::handle() const +{ + return (singular()->handle_i()); +} + +std::shared_ptr +l2_list::find(const handle_t& handle) +{ + return (m_hdl_db[handle].lock()); +} + +std::shared_ptr +l2_list::find(const key_t& key) +{ + return (m_db.find(key)); +} + +std::shared_ptr +l2_list::find_or_add(const l2_list& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +const handle_t& +l2_list::handle_i() const +{ + return (m_hdl.data()); +} + +void +l2_list::add(const key_t& key, const HW::item& item) +{ + std::shared_ptr sp = find(key); + + if (sp && item) { + m_hdl_db[item.data()] = sp; + } +} + +void +l2_list::remove(const HW::item& item) +{ + m_hdl_db.erase(item.data()); +} + +const l2_list::key_t& +l2_list::key() const +{ + return m_key; +} + +const l2_list::rules_t& +l2_list::rules() const +{ + return m_rules; +} + +bool +l2_list::operator==(const l2_list& l) const +{ + return (key() == l.key() && rules() == l.rules()); +} + +void +l2_list::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump L2 ACLs + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + const handle_t hdl(payload.acl_index); + l2_list acl(hdl, std::string(reinterpret_cast(payload.tag))); + + for (unsigned int ii = 0; ii < payload.count; ii++) { + const route::prefix_t pfx = from_api(payload.r[ii].src_prefix); + l2_rule rule(ii, + action_t::from_int(payload.r[ii].is_permit), + pfx, + { payload.r[ii].src_mac }, + { payload.r[ii].src_mac_mask }); + + acl.insert(rule); + } + VOM_LOG(log_level_t::DEBUG) << "dump: " << acl.to_string(); + + /* + * Write each of the discovered ACLs into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, acl); + } +} + +void +l2_list::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +dependency_t +l2_list::event_handler::order() const +{ + return (dependency_t::ACL); +} + +void +l2_list::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +l2_list::update(const l2_list& obj) +{ + /* + * always update the instance with the latest rule set + */ + if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) { + HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules)); + } + /* + * We don't, can't, read the priority from VPP, + * so the is equals check above does not include the priorty. + * but we save it now. + */ + m_rules = obj.m_rules; +} + +void +l2_list::sweep(void) +{ + if (m_hdl) { + HW::enqueue(new list_cmds::l2_delete_cmd(m_hdl)); + } + HW::write(); +} + +void +l2_list::replay(void) +{ + if (m_hdl) { + m_hdl.data().reset(); + HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules)); + } +} + +}; // namespace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_l2_list.hpp b/extras/deprecated/vom/vom/acl_l2_list.hpp new file mode 100644 index 00000000000..dd7e00a6d4d --- /dev/null +++ b/extras/deprecated/vom/vom/acl_l2_list.hpp @@ -0,0 +1,224 @@ +/* + * 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_ACL_L2_LIST_H__ +#define __VOM_ACL_L2_LIST_H__ + +#include + +#include "vom/acl_l2_rule.hpp" +#include "vom/acl_types.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +namespace ACL { +/** + * An L2 ACL list comprises a set of match actions rules to be applied to + * packets. + * A list is bound to a given interface. + */ +class l2_list : public object_base +{ +public: + /** + * The KEY can be used to uniquely identify the ACL. + * (other choices for keys, like the summation of the properties + * of the rules, are rather too cumbersome to use + */ + typedef std::string key_t; + + /** + * The rule container type + */ + typedef std::multiset rules_t; + + /** + * Construct a new object matching the desried state + */ + l2_list(const key_t& key); + + l2_list(const handle_t& hdl, const key_t& key); + + l2_list(const key_t& key, const rules_t& rules); + + /** + * Copy Constructor + */ + l2_list(const l2_list& o); + + /** + * Destructor + */ + ~l2_list(); + + /** + * Return the 'sigular instance' of the ACL that matches this object + */ + std::shared_ptr singular() const; + + /** + * Dump all ACLs into the stream provided + */ + static void dump(std::ostream& os); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Insert priority sorted a rule into the list + */ + void insert(const l2_rule& rule); + + /** + * Remove a rule from the list + */ + void remove(const l2_rule& rule); + + /** + * Return the VPP assign handle + */ + const handle_t& handle() const; + + static std::shared_ptr find(const handle_t& handle); + + static std::shared_ptr find(const key_t& key); + static void add(const key_t& key, const HW::item& item); + + static void remove(const HW::item& item); + + const key_t& key() const; + + const rules_t& rules() const; + + /** + * Comparison operator - for UT + */ + bool operator==(const l2_list& l) const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enqueue commands to the VPP command Q for the update + */ + void update(const l2_list& obj); + + /** + * HW assigned handle + */ + HW::item m_hdl; + + /** + * Find or add the sigular instance in the DB + */ + static std::shared_ptr find_or_add(const l2_list& temp); + + /** + * return the acl-list's handle in the singular instance + */ + const handle_t& handle_i() const; + + /* + * It's the VOM::OM class that updates call update + */ + friend class VOM::OM; + + /** + * It's the VOM::singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * Replay the objects state to HW + */ + void replay(void); + + /** + * A map of all ACL's against the client's key + */ + static singular_db m_db; + + /** + * A map of all ACLs keyed against VPP's handle + */ + static std::map> m_hdl_db; + + /** + * The Key is a user defined identifer for this ACL + */ + const key_t m_key; + + /** + * A sorted list of the rules + */ + rules_t m_rules; +}; + +}; // namesace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_l2_rule.cpp b/extras/deprecated/vom/vom/acl_l2_rule.cpp new file mode 100644 index 00000000000..fdbe62f6f0e --- /dev/null +++ b/extras/deprecated/vom/vom/acl_l2_rule.cpp @@ -0,0 +1,99 @@ +/* + * 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 + +#include "vom/acl_l2_rule.hpp" + +namespace VOM { +namespace ACL { + +l2_rule::l2_rule(uint32_t priority, + const action_t& action, + const route::prefix_t& ip, + const mac_address_t& mac, + const mac_address_t& mac_mask) + : m_priority(priority) + , m_action(action) + , m_src_ip(ip) + , m_mac(mac) + , m_mac_mask(mac_mask) +{ +} + +bool +l2_rule::operator<(const l2_rule& other) const +{ + return (other.m_priority < m_priority); +} + +bool +l2_rule::operator==(const l2_rule& rule) const +{ + return ((m_action == rule.m_action) && (m_src_ip == rule.m_src_ip) && + (m_mac == rule.m_mac) && (m_mac_mask == rule.m_mac_mask)); +} + +std::string +l2_rule::to_string() const +{ + std::ostringstream s; + + s << "L2-rule:[" + << "priority:" << m_priority << " action:" << m_action.to_string() + << " ip:" << m_src_ip.to_string() << " mac:" << m_mac + << " mac-mask:" << m_mac_mask << "]"; + + return (s.str()); +} + +uint32_t +l2_rule::priority() const +{ + return m_priority; +} + +const action_t& +l2_rule::action() const +{ + return m_action; +} + +const route::prefix_t& +l2_rule::src_ip() const +{ + return m_src_ip; +} + +const mac_address_t& +l2_rule::mac() const +{ + return m_mac; +} + +const mac_address_t& +l2_rule::mac_mask() const +{ + return m_mac_mask; +} +} +} +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_l2_rule.hpp b/extras/deprecated/vom/vom/acl_l2_rule.hpp new file mode 100644 index 00000000000..806d8b08867 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_l2_rule.hpp @@ -0,0 +1,115 @@ +/* + * 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_L2_ACL_RULE_H__ +#define __VOM_L2_ACL_RULE_H__ + +#include "vom/acl_types.hpp" +#include "vom/prefix.hpp" + +namespace VOM { +namespace ACL { +/** + * An ACL rule is the building block of an ACL. An ACL, which is + * the object applied to an interface, is comprised of an ordersed + * sequence of ACL rules. + * This class is a wrapper around the VAPI generated struct and exports + * an API with better types. + */ +class l2_rule +{ +public: + /** + * Construct a new object matching the desried state + */ + l2_rule(uint32_t priority, + const action_t& action, + const route::prefix_t& ip, + const mac_address_t& mac, + const mac_address_t& mac_mask); + + /** + * Copy Constructor + */ + l2_rule(const l2_rule& o) = default; + + /** + * Destructor + */ + ~l2_rule() = default; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * less-than operator + */ + bool operator<(const l2_rule& rule) const; + + /** + * comparison operator (for testing) + */ + bool operator==(const l2_rule& rule) const; + + /** + * Getters + */ + uint32_t priority() const; + const action_t& action() const; + const route::prefix_t& src_ip() const; + const mac_address_t& mac() const; + const mac_address_t& mac_mask() const; + +private: + /** + * Priority. Used to sort the rules in a list in the order + * in which they are applied + */ + uint32_t m_priority; + + /** + * Action on match + */ + action_t m_action; + + /** + * Source Prefix + */ + route::prefix_t m_src_ip; + + /** + * Source Mac + */ + mac_address_t m_mac; + + /** + * Source MAC mask + */ + mac_address_t m_mac_mask; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_l3_list.cpp b/extras/deprecated/vom/vom/acl_l3_list.cpp new file mode 100644 index 00000000000..1afe8cb8863 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_l3_list.cpp @@ -0,0 +1,292 @@ +/* + * 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/acl_l3_list.hpp" +#include "vom/acl_list_cmds.hpp" +#include "vom/api_types.hpp" +#include "vom/logger.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace ACL { + +/** + * Definition of the static singular_db for ACL Lists + */ +singular_db l3_list::m_db; + +/** + * Definition of the static per-handle DB for ACL Lists + */ +std::map> l3_list::m_hdl_db; + +l3_list::event_handler l3_list::m_evh; + +l3_list::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "l3-acl-list" }, "L3 ACL lists", this); +} + +l3_list::l3_list(const key_t& key) + : m_hdl(handle_t::INVALID) + , m_key(key) +{} + +l3_list::l3_list(const handle_t& hdl, const key_t& key) + : m_hdl(hdl) + , m_key(key) +{} + +l3_list::l3_list(const key_t& key, const rules_t& rules) + : m_hdl(handle_t::INVALID) + , m_key(key) + , m_rules(rules) +{} + +l3_list::l3_list(const l3_list& o) + : m_hdl(o.m_hdl) + , m_key(o.m_key) + , m_rules(o.m_rules) +{} + +l3_list::~l3_list() +{ + sweep(); + m_db.release(m_key, this); +} + +std::shared_ptr +l3_list::singular() const +{ + return find_or_add(*this); +} + +/** + * Dump all ACLs into the stream provided + */ +void +l3_list::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +/** + * convert to string format for debug purposes + */ +std::string +l3_list::to_string() const +{ + std::ostringstream s; + s << "acl-list:[" << m_key << " " << m_hdl.to_string() << " rules:["; + + for (auto rule : m_rules) { + s << rule.to_string() << " "; + } + + s << "]]"; + + return (s.str()); +} + +void +l3_list::insert(const l3_rule& rule) +{ + m_rules.insert(rule); +} + +void +l3_list::remove(const l3_rule& rule) +{ + m_rules.erase(rule); +} + +const handle_t& +l3_list::handle() const +{ + return (singular()->handle_i()); +} + +std::shared_ptr +l3_list::find(const handle_t& handle) +{ + return (m_hdl_db[handle].lock()); +} + +std::shared_ptr +l3_list::find(const key_t& key) +{ + return (m_db.find(key)); +} + +std::shared_ptr +l3_list::find_or_add(const l3_list& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +const handle_t& +l3_list::handle_i() const +{ + return (m_hdl.data()); +} + +void +l3_list::add(const key_t& key, const HW::item& item) +{ + std::shared_ptr sp = find(key); + + if (sp && item) { + m_hdl_db[item.data()] = sp; + } +} + +void +l3_list::remove(const HW::item& item) +{ + m_hdl_db.erase(item.data()); +} + +const l3_list::key_t& +l3_list::key() const +{ + return m_key; +} + +const l3_list::rules_t& +l3_list::rules() const +{ + return m_rules; +} + +bool +l3_list::operator==(const l3_list& l) const +{ + return (key() == l.key() && rules() == l.rules()); +} + +void +l3_list::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump L3 ACLs Bridge domains + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + const handle_t hdl(payload.acl_index); + l3_list acl(hdl, std::string(reinterpret_cast(payload.tag))); + + for (unsigned int ii = 0; ii < payload.count; ii++) { + const route::prefix_t src = from_api(payload.r[ii].src_prefix); + const route::prefix_t dst = from_api(payload.r[ii].dst_prefix); + l3_rule rule(ii, action_t::from_int(payload.r[ii].is_permit), src, dst); + + rule.set_proto(payload.r[ii].proto); + rule.set_src_from_port(payload.r[ii].srcport_or_icmptype_first); + rule.set_src_to_port(payload.r[ii].srcport_or_icmptype_last); + rule.set_dst_from_port(payload.r[ii].dstport_or_icmpcode_first); + rule.set_dst_to_port(payload.r[ii].dstport_or_icmpcode_last); + rule.set_tcp_flags_mask(payload.r[ii].tcp_flags_mask); + rule.set_tcp_flags_value(payload.r[ii].tcp_flags_value); + + acl.insert(rule); + } + VOM_LOG(log_level_t::DEBUG) << "dump: " << acl.to_string(); + + /* + * Write each of the discovered ACLs into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, acl); + } +} + +void +l3_list::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +dependency_t +l3_list::event_handler::order() const +{ + return (dependency_t::ACL); +} + +void +l3_list::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +l3_list::update(const l3_list& obj) +{ + /* + * always update the instance with the latest rule set + */ + if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) { + HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules)); + } + /* + * We don't, can't, read the priority from VPP, + * so the is equals check above does not include the priorty. + * but we save it now. + */ + m_rules = obj.m_rules; +} + +/** + * Sweep/reap the object if still stale + */ +void +l3_list::sweep(void) +{ + if (m_hdl) { + HW::enqueue(new list_cmds::l3_delete_cmd(m_hdl)); + } + HW::write(); +} + +/** + * Replay the objects state to HW + */ +void +l3_list::replay(void) +{ + if (m_hdl) { + m_hdl.data().reset(); + HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules)); + } +} + +}; // namespace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_l3_list.hpp b/extras/deprecated/vom/vom/acl_l3_list.hpp new file mode 100644 index 00000000000..ecbb19ae6a4 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_l3_list.hpp @@ -0,0 +1,224 @@ +/* + * 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_ACL_L3_LIST_H__ +#define __VOM_ACL_L3_LIST_H__ + +#include + +#include "vom/acl_l3_rule.hpp" +#include "vom/acl_types.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +namespace ACL { +/** + * An L3 ACL list comprises a set of match actions rules to be applied to + * packets. + * A list is bound to a given interface. + */ +class l3_list : public object_base +{ +public: + /** + * The KEY can be used to uniquely identify the ACL. + * (other choices for keys, like the summation of the properties + * of the rules, are rather too cumbersome to use + */ + typedef std::string key_t; + + /** + * The rule container type + */ + typedef std::multiset rules_t; + + /** + * Construct a new object matching the desried state + */ + l3_list(const key_t& key); + + l3_list(const handle_t& hdl, const key_t& key); + + l3_list(const key_t& key, const rules_t& rules); + + /** + * Copy Constructor + */ + l3_list(const l3_list& o); + + /** + * Destructor + */ + ~l3_list(); + + /** + * Return the 'sigular instance' of the ACL that matches this object + */ + std::shared_ptr singular() const; + + /** + * Dump all ACLs into the stream provided + */ + static void dump(std::ostream& os); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Insert priority sorted a rule into the list + */ + void insert(const l3_rule& rule); + + /** + * Remove a rule from the list + */ + void remove(const l3_rule& rule); + + /** + * Return the VPP assign handle + */ + const handle_t& handle() const; + + static std::shared_ptr find(const handle_t& handle); + + static std::shared_ptr find(const key_t& key); + static void add(const key_t& key, const HW::item& item); + + static void remove(const HW::item& item); + + const key_t& key() const; + + const rules_t& rules() const; + + /** + * Comparison operator - for UT + */ + bool operator==(const l3_list& l) const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enqueue commands to the VPP command Q for the update + */ + void update(const l3_list& obj); + + /** + * HW assigned handle + */ + HW::item m_hdl; + + /** + * Find or add the sigular instance in the DB + */ + static std::shared_ptr find_or_add(const l3_list& temp); + + /** + * return the acl-list's handle in the singular instance + */ + const handle_t& handle_i() const; + + /* + * It's the VOM::OM class that updates call update + */ + friend class VOM::OM; + + /** + * It's the VOM::singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * Replay the objects state to HW + */ + void replay(void); + + /** + * A map of all ACL's against the client's key + */ + static singular_db m_db; + + /** + * A map of all ACLs keyed against VPP's handle + */ + static std::map> m_hdl_db; + + /** + * The Key is a user defined identifer for this ACL + */ + const key_t m_key; + + /** + * A sorted list of the rules + */ + rules_t m_rules; +}; + +}; // namesace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_l3_rule.cpp b/extras/deprecated/vom/vom/acl_l3_rule.cpp new file mode 100644 index 00000000000..07e1b3b4940 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_l3_rule.cpp @@ -0,0 +1,213 @@ +/* + * 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 + +#include "vom/acl_l3_rule.hpp" + +namespace VOM { +namespace ACL { +l3_rule::l3_rule(uint32_t priority, + const action_t& action, + const route::prefix_t& src, + const route::prefix_t& dst, + uint8_t proto, + uint16_t srcport_or_icmptype_first, + uint16_t srcport_or_icmptype_last, + uint16_t dstport_or_icmpcode_first, + uint16_t dstport_or_icmpcode_last, + uint8_t tcp_flags_mask, + uint8_t tcp_flags_value) + : m_priority(priority) + , m_action(action) + , m_src(src) + , m_dst(dst) + , m_proto(proto) + , m_srcport_or_icmptype_first(srcport_or_icmptype_first) + , m_srcport_or_icmptype_last(srcport_or_icmptype_last) + , m_dstport_or_icmpcode_first(dstport_or_icmpcode_first) + , m_dstport_or_icmpcode_last(dstport_or_icmpcode_last) + , m_tcp_flags_mask(tcp_flags_mask) + , m_tcp_flags_value(tcp_flags_value) +{ +} + +bool +l3_rule::operator<(const l3_rule& other) const +{ + return (other.m_priority < m_priority); +} + +bool +l3_rule::operator==(const l3_rule& rule) const +{ + return ((m_action == rule.m_action) && (m_src == rule.m_src) && + (m_dst == rule.m_dst) && (m_proto == rule.m_proto) && + (m_srcport_or_icmptype_first == rule.m_srcport_or_icmptype_first) && + (m_srcport_or_icmptype_last == rule.m_srcport_or_icmptype_last) && + (m_dstport_or_icmpcode_first == rule.m_dstport_or_icmpcode_first) && + (m_dstport_or_icmpcode_last == rule.m_dstport_or_icmpcode_last) && + (m_tcp_flags_mask == rule.m_tcp_flags_mask) && + (m_tcp_flags_value == rule.m_tcp_flags_value)); +} + +std::string +l3_rule::to_string() const +{ + std::ostringstream s; + + s << "L3-rule:[" + << "priority:" << m_priority << " action:" << m_action.to_string() + << " src:" << m_src.to_string() << " dst:" << m_dst.to_string() + << " proto:" << std::to_string(m_proto) + << " srcportfrom:" << m_srcport_or_icmptype_first + << " srcportto: " << m_srcport_or_icmptype_last + << " dstportfrom:" << m_dstport_or_icmpcode_first + << " dstportto:" << m_dstport_or_icmpcode_last + << " tcpflagmask:" << std::to_string(m_tcp_flags_mask) + << " tcpflagvalue:" << std::to_string(m_tcp_flags_value) << "]"; + + return (s.str()); +} + +void +l3_rule::set_src_ip(route::prefix_t src) +{ + m_src = src; +} + +void +l3_rule::set_dst_ip(route::prefix_t dst) +{ + m_dst = dst; +} + +void +l3_rule::set_proto(uint8_t proto) +{ + m_proto = proto; +} +void +l3_rule::set_src_from_port(uint16_t srcport_or_icmptype_first) +{ + m_srcport_or_icmptype_first = srcport_or_icmptype_first; +} + +void +l3_rule::set_src_to_port(uint16_t srcport_or_icmptype_last) +{ + m_srcport_or_icmptype_last = srcport_or_icmptype_last; +} + +void +l3_rule::set_dst_from_port(uint16_t dstport_or_icmpcode_first) +{ + m_dstport_or_icmpcode_first = dstport_or_icmpcode_first; +} + +void +l3_rule::set_dst_to_port(uint16_t dstport_or_icmpcode_last) +{ + m_dstport_or_icmpcode_last = dstport_or_icmpcode_last; +} + +void +l3_rule::set_tcp_flags_mask(uint8_t tcp_flags_mask) +{ + m_tcp_flags_mask = tcp_flags_mask; +} + +void +l3_rule::set_tcp_flags_value(uint8_t tcp_flags_value) +{ + m_tcp_flags_value = tcp_flags_value; +} + +const route::prefix_t& +l3_rule::src() const +{ + return m_src; +} + +uint32_t +l3_rule::priority() const +{ + return m_priority; +} + +const action_t& +l3_rule::action() const +{ + return m_action; +} + +const route::prefix_t& +l3_rule::dst() const +{ + return m_dst; +} + +uint8_t +l3_rule::proto() const +{ + return m_proto; +} + +uint16_t +l3_rule::srcport_or_icmptype_first() const +{ + return m_srcport_or_icmptype_first; +} + +uint16_t +l3_rule::srcport_or_icmptype_last() const +{ + return m_srcport_or_icmptype_last; +} + +uint16_t +l3_rule::dstport_or_icmpcode_first() const +{ + return m_dstport_or_icmpcode_first; +} + +uint16_t +l3_rule::dstport_or_icmpcode_last() const +{ + return m_dstport_or_icmpcode_last; +} + +uint8_t +l3_rule::tcp_flags_mask() const +{ + return m_tcp_flags_mask; +} + +uint8_t +l3_rule::tcp_flags_value() const +{ + return m_tcp_flags_value; +} + +}; // namespace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_l3_rule.hpp b/extras/deprecated/vom/vom/acl_l3_rule.hpp new file mode 100644 index 00000000000..dad38f1918c --- /dev/null +++ b/extras/deprecated/vom/vom/acl_l3_rule.hpp @@ -0,0 +1,196 @@ +/* + * 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_L3_ACL_RULE_H__ +#define __VOM_L3_ACL_RULE_H__ + +#include "vom/acl_types.hpp" +#include "vom/prefix.hpp" + +namespace VOM { +namespace ACL { +/** + * An ACL rule is the building block of an ACL. An ACL, which is + * the object applied to an interface, is comprised of an ordersed + * sequence of ACL rules. + * This class is a wrapper around the VAPI generated struct and exports + * an API with better types. + */ +class l3_rule +{ +public: + /** + * Construct a new object matching the desried state + */ + l3_rule(uint32_t priority, + const action_t& action, + const route::prefix_t& src, + const route::prefix_t& dst, + uint8_t proto = 0, + uint16_t srcport_or_icmptype_first = 0, + uint16_t srcport_or_icmptype_last = 0, + uint16_t dstport_or_icmpcode_first = 0, + uint16_t dstport_or_icmpcode_last = 0, + uint8_t tcp_flags_mask = 0, + uint8_t tcp_flags_value = 0); + + /** + * Copy Constructor + */ + l3_rule(const l3_rule& o) = default; + + /** + * Destructor + */ + ~l3_rule() = default; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * less-than operator + */ + bool operator<(const l3_rule& rule) const; + + /** + * comparison operator (for testing) + */ + bool operator==(const l3_rule& rule) const; + + /** + * Set Src Ip Address + */ + void set_src_ip(route::prefix_t src); + + /** + * Set Dst Ip Address + */ + void set_dst_ip(route::prefix_t dst); + + /** + *Set proto + */ + void set_proto(uint8_t proto); + + /** + * Set Src port or ICMP Type first + */ + void set_src_from_port(uint16_t srcport_or_icmptype_first); + + /** + * Set Src port or ICMP Type last + */ + void set_src_to_port(uint16_t srcport_or_icmptype_last); + + /** + * Set Dst port or ICMP code first + */ + void set_dst_from_port(uint16_t dstport_or_icmpcode_first); + + /** + * Set Dst port or ICMP code last + */ + void set_dst_to_port(uint16_t dstport_or_icmpcode_last); + + /** + * Set TCP flags mask + */ + void set_tcp_flags_mask(uint8_t tcp_flags_mask); + + /** + * Set TCP flags value + */ + void set_tcp_flags_value(uint8_t tcp_flags_value); + + /** + * Getters + */ + const route::prefix_t& src() const; + uint32_t priority() const; + const action_t& action() const; + const route::prefix_t& dst() const; + uint8_t proto() const; + uint16_t srcport_or_icmptype_first() const; + uint16_t srcport_or_icmptype_last() const; + uint16_t dstport_or_icmpcode_first() const; + uint16_t dstport_or_icmpcode_last() const; + uint8_t tcp_flags_mask() const; + uint8_t tcp_flags_value() const; + +private: + /** + * Priority. Used to sort the rules in a list in the order + * in which they are applied + */ + uint32_t m_priority; + + /** + * Action on match + */ + action_t m_action; + + /** + * Source Prefix + */ + route::prefix_t m_src; + + /** + * Destination Prefix + */ + route::prefix_t m_dst; + + /** + * L4 protocol. IANA number. 1 = ICMP, 58 = ICMPv6, 6 = TCP, 17 = + * UDP. + * 0 => ignore L4 and ignore the ports/tcpflags when matching. + */ + uint8_t m_proto; + + /** + * If the L4 protocol is TCP or UDP, the below + * hold ranges of ports, else if the L4 is ICMP/ICMPv6 + * they hold ranges of ICMP(v6) types/codes. + * + * Ranges are inclusive, i.e. to match "any" TCP/UDP port, + * use first=0,last=65535. For ICMP(v6), + * use first=0,last=255. + */ + uint16_t m_srcport_or_icmptype_first; + uint16_t m_srcport_or_icmptype_last; + uint16_t m_dstport_or_icmpcode_first; + uint16_t m_dstport_or_icmpcode_last; + + /* + * for proto = 6, this matches if the + * TCP flags in the packet, ANDed with tcp_flags_mask, + * is equal to tcp_flags_value. + */ + uint8_t m_tcp_flags_mask; + uint8_t m_tcp_flags_value; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_list_cmds.cpp b/extras/deprecated/vom/vom/acl_list_cmds.cpp new file mode 100644 index 00000000000..44686a7cf35 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_list_cmds.cpp @@ -0,0 +1,197 @@ +/* + * 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/acl_list_cmds.hpp" +#include "vom/api_types.hpp" + +namespace VOM { +namespace ACL { +namespace list_cmds { +/* + * Jumping through hoops to not expose the VAPI types publically + */ +static void +to_vpp(const l2_rule& rule, vapi_type_macip_acl_rule& payload) +{ + payload.is_permit = (vapi_enum_acl_action)rule.action().value(); + rule.src_ip().to_vpp((uint8_t*)&payload.src_prefix.address.af, + (uint8_t*)&payload.src_prefix.address.un, + &payload.src_prefix.len); + rule.mac().to_bytes(payload.src_mac, 6); + rule.mac_mask().to_bytes(payload.src_mac_mask, 6); +} + +static void +to_vpp(const l3_rule& rule, vapi_type_acl_rule& payload) +{ + payload.is_permit = (vapi_enum_acl_action)rule.action().value(); + payload.src_prefix = to_api(rule.src()); + payload.dst_prefix = to_api(rule.dst()); + + payload.proto = (vapi_enum_ip_proto)rule.proto(); + payload.srcport_or_icmptype_first = rule.srcport_or_icmptype_first(); + payload.srcport_or_icmptype_last = rule.srcport_or_icmptype_last(); + payload.dstport_or_icmpcode_first = rule.dstport_or_icmpcode_first(); + payload.dstport_or_icmpcode_last = rule.dstport_or_icmpcode_last(); + + payload.tcp_flags_mask = rule.tcp_flags_mask(); + payload.tcp_flags_value = rule.tcp_flags_value(); +} + +template<> +rc_t +l3_update_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), m_rules.size(), std::ref(*this)); + uint32_t ii = 0; + + auto& payload = req.get_request().get_payload(); + payload.acl_index = m_hw_item.data().value(); + payload.count = m_rules.size(); + memset(payload.tag, 0, sizeof(payload.tag)); + memcpy( + payload.tag, m_key.c_str(), std::min(m_key.length(), sizeof(payload.tag))); + + auto it = m_rules.cbegin(); + + while (it != m_rules.cend()) { + to_vpp(*it, payload.r[ii]); + ++it; + ++ii; + } + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) + insert_acl(); + + return rc_t::OK; +} + +template<> +rc_t +l3_delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.acl_index = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_acl(); + + return rc_t::OK; +} + +template<> +rc_t +l3_dump_cmd::issue(connection& con) +{ + m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); + + auto& payload = m_dump->get_request().get_payload(); + payload.acl_index = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +template<> +rc_t +l2_update_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), m_rules.size(), std::ref(*this)); + uint32_t ii = 0; + + auto& payload = req.get_request().get_payload(); + // payload.acl_index = m_hw_item.data().value(); + payload.count = m_rules.size(); + memset(payload.tag, 0, sizeof(payload.tag)); + memcpy( + payload.tag, m_key.c_str(), std::min(m_key.length(), sizeof(payload.tag))); + + auto it = m_rules.cbegin(); + + while (it != m_rules.cend()) { + to_vpp(*it, payload.r[ii]); + ++it; + ++ii; + } + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) + insert_acl(); + + return rc_t::OK; +} + +template<> +rc_t +l2_delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.acl_index = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_acl(); + + return rc_t::OK; +} + +template<> +rc_t +l2_dump_cmd::issue(connection& con) +{ + m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); + + auto& payload = m_dump->get_request().get_payload(); + payload.acl_index = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +}; // namespace list_cmds +}; // namespace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_list_cmds.hpp b/extras/deprecated/vom/vom/acl_list_cmds.hpp new file mode 100644 index 00000000000..2fc20287e91 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_list_cmds.hpp @@ -0,0 +1,223 @@ +/* + * 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_ACL_LIST_CMDS_H__ +#define __VOM_ACL_LIST_CMDS_H__ + +#include "vom/acl_l2_list.hpp" +#include "vom/acl_l3_list.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace ACL { +namespace list_cmds { +/** + * A command class that Create the list + */ +template +class update_cmd : public rpc_cmd, UPDATE> +{ +public: + typedef typename LIST::rules_t cmd_rules_t; + typedef typename LIST::key_t cmd_key_t; + + /** + * Constructor + */ + update_cmd(HW::item& item, + const cmd_key_t& key, + const cmd_rules_t& rules) + : rpc_cmd, UPDATE>(item) + , m_key(key) + , m_rules(rules) + { + } + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const + { + std::ostringstream s; + s << "ACL-list-update:[ " << this->item().to_string() << " rule-list:["; + for (auto rule : m_rules) { + s << " " << rule.to_string(); + } + s << "]]"; + + return (s.str()); + } + + /** + * Comparison operator - only used for UT + */ + bool operator==(const update_cmd& other) const + { + return ((m_key == other.m_key) && (m_rules == other.m_rules)); + } + + void succeeded() + { + rpc_cmd, UPDATE>::succeeded(); + LIST::add(m_key, this->item()); + } + + /** + * A callback function for handling ACL creates + */ + virtual vapi_error_e operator()(UPDATE& reply) + { + int acl_index = reply.get_response().get_payload().acl_index; + int retval = reply.get_response().get_payload().retval; + + VOM_LOG(log_level_t::DEBUG) << this->to_string() << " retval:" << retval + << " acl_index:" << acl_index; + + rc_t rc = rc_t::from_vpp_retval(retval); + handle_t handle(acl_index); + + HW::item res(handle, rc); + + this->fulfill(res); + + return (VAPI_OK); + } + +private: + /** + * add the created acl to the DB + */ + void insert_acl() { LIST::add(m_key, this->item()); } + + /** + * The key. + */ + const cmd_key_t& m_key; + + /** + * The rules + */ + const cmd_rules_t& m_rules; +}; + +/** + * A cmd class that Deletes an ACL + */ +template +class delete_cmd : public rpc_cmd, DELETE> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item) + : rpc_cmd, DELETE>(item) + { + } + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con) { return (rc_t::INVALID); } + + /** + * convert to string format for debug purposes + */ + std::string to_string() const + { + std::ostringstream s; + s << "ACL-list-delete: " << this->item().to_string(); + + return (s.str()); + } + + /** + * Comparison operator - only used for UT + */ + bool operator==(const delete_cmd& other) const + { + return (this->item().data() == other.item().data()); + } + +private: + /** + * remove the acl from the DB + */ + void remove_acl() { LIST::remove(this->item()); } +}; + +/** + * A cmd class that Dumps all the ACLs + */ +template +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * 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 { return ("acl-list-dump"); } + + /** + * Comparison operator - only used for UT + */ + bool operator==(const dump_cmd& i) const { return true; } +}; + +/** + * Typedef the L3 ACL commands + */ +typedef update_cmd l3_update_cmd; +typedef delete_cmd l3_delete_cmd; +typedef dump_cmd l3_dump_cmd; + +/** + * Typedef the L2 ACL commands + */ +typedef update_cmd l2_update_cmd; +typedef delete_cmd l2_delete_cmd; +typedef dump_cmd l2_dump_cmd; + +}; // namespace list_cmds +}; // namespace ACL +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/acl_types.cpp b/extras/deprecated/vom/vom/acl_types.cpp new file mode 100644 index 00000000000..840bf736bd5 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_types.cpp @@ -0,0 +1,59 @@ +/* + * 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/acl_types.hpp" + +namespace VOM { +namespace ACL { +const action_t action_t::PERMITANDREFLEX(2, "permitandreflex"); +const action_t action_t::PERMIT(1, "permit"); +const action_t action_t::DENY(0, "deny"); + +action_t::action_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +const action_t& +action_t::from_int(uint8_t i) +{ + if (i == 2) + return action_t::PERMITANDREFLEX; + else if (i) + return action_t::PERMIT; + + return action_t::DENY; +} + +const action_t& +action_t::from_bool(bool b, uint8_t c) +{ + if (b) { + if (c) + return action_t::PERMITANDREFLEX; + return action_t::PERMIT; + } + return action_t::DENY; +} +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/acl_types.hpp b/extras/deprecated/vom/vom/acl_types.hpp new file mode 100644 index 00000000000..a473818ad55 --- /dev/null +++ b/extras/deprecated/vom/vom/acl_types.hpp @@ -0,0 +1,68 @@ +/* + * 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_ACL_TYPES_H__ +#define __VOM_ACL_TYPES_H__ + +#include "vom/types.hpp" + +namespace VOM { +namespace ACL { +/** + * ACL Actions + */ +struct action_t : public enum_base +{ + /** + * Permit and Reflexive + */ + const static action_t PERMITANDREFLEX; + + /** + * Permit Action + */ + const static action_t PERMIT; + + /** + * Deny Action + */ + const static action_t DENY; + + /** + * Get the enum type from a VPP integer value + */ + static const action_t& from_int(uint8_t i); + + /** + *Get the enum type from a bool value and optional uint8_t value + *which implements the connection tracking .... + */ + static const action_t& from_bool(bool b, uint8_t c); + +private: + action_t(int v, const std::string s); +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/api_types.cpp b/extras/deprecated/vom/vom/api_types.cpp new file mode 100644 index 00000000000..cd66699bb3e --- /dev/null +++ b/extras/deprecated/vom/vom/api_types.cpp @@ -0,0 +1,278 @@ +/* + * 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 + +namespace VOM { + +vapi_enum_ip_neighbor_flags +to_api(const neighbour::flags_t& f) +{ + vapi_enum_ip_neighbor_flags out = IP_API_NEIGHBOR_FLAG_NONE; + + if (f & neighbour::flags_t::STATIC) + out = static_cast(out | + IP_API_NEIGHBOR_FLAG_STATIC); + if (f & neighbour::flags_t::NO_FIB_ENTRY) + out = static_cast( + out | IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY); + + return (out); +} + +const neighbour::flags_t +from_api(vapi_enum_ip_neighbor_flags f) +{ + neighbour::flags_t out = neighbour::flags_t::NONE; + + if (f & IP_API_NEIGHBOR_FLAG_STATIC) + out |= neighbour::flags_t::STATIC; + if (f & IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY) + out |= neighbour::flags_t::NO_FIB_ENTRY; + + return out; +} + +invalid_decode::invalid_decode(const std::string reason) + : reason(reason) +{} + +void +to_api(const boost::asio::ip::address_v4& a, vapi_type_ip4_address& v) +{ + std::copy_n(std::begin(a.to_bytes()), a.to_bytes().size(), v); +} +void +to_api(const boost::asio::ip::address_v6& a, vapi_type_ip6_address& v) +{ + std::copy_n(std::begin(a.to_bytes()), a.to_bytes().size(), v); +} + +void +to_api(const ip_address_t& a, vapi_type_address& v) +{ + if (a.is_v4()) { + v.af = ADDRESS_IP4; + memcpy(v.un.ip4, a.to_v4().to_bytes().data(), 4); + } else { + v.af = ADDRESS_IP6; + memcpy(v.un.ip6, a.to_v6().to_bytes().data(), 16); + } +} + +void +to_api(const ip_address_t& a, + vapi_union_address_union& u, + vapi_enum_address_family& af) +{ + if (a.is_v4()) { + af = ADDRESS_IP4; + memcpy(u.ip4, a.to_v4().to_bytes().data(), 4); + } else { + af = ADDRESS_IP6; + memcpy(u.ip6, a.to_v6().to_bytes().data(), 16); + } +} + +void +to_api(const ip_address_t& a, vapi_union_address_union& u) +{ + if (a.is_v4()) { + memcpy(u.ip4, a.to_v4().to_bytes().data(), 4); + } else { + memcpy(u.ip6, a.to_v6().to_bytes().data(), 16); + } +} + +boost::asio::ip::address_v6 +from_api(const vapi_type_ip6_address& v) +{ + std::array a; + std::copy(v, v + 16, std::begin(a)); + boost::asio::ip::address_v6 v6(a); + + return v6; +} + +boost::asio::ip::address_v4 +from_api(const vapi_type_ip4_address& v) +{ + std::array a; + std::copy(v, v + 4, std::begin(a)); + boost::asio::ip::address_v4 v4(a); + + return v4; +} + +ip_address_t +from_api(const vapi_type_address& v) +{ + boost::asio::ip::address addr; + + if (ADDRESS_IP6 == v.af) { + std::array a; + std::copy(v.un.ip6, v.un.ip6 + 16, std::begin(a)); + boost::asio::ip::address_v6 v6(a); + addr = v6; + } else { + std::array a; + std::copy(v.un.ip6, v.un.ip6 + 4, std::begin(a)); + boost::asio::ip::address_v4 v4(a); + addr = v4; + } + + return addr; +} + +ip_address_t +from_api(const vapi_union_address_union& u, vapi_enum_fib_path_nh_proto proto) +{ + boost::asio::ip::address addr; + + if (FIB_API_PATH_NH_PROTO_IP6 == proto) { + std::array a; + std::copy(u.ip6, u.ip6 + 16, std::begin(a)); + boost::asio::ip::address_v6 v6(a); + addr = v6; + } else if (FIB_API_PATH_NH_PROTO_IP4 == proto) { + std::array a; + std::copy(u.ip6, u.ip6 + 4, std::begin(a)); + boost::asio::ip::address_v4 v4(a); + addr = v4; + } + + return addr; +} + +ip_address_t +from_api(const vapi_union_address_union& u, vapi_enum_address_family af) +{ + boost::asio::ip::address addr; + + if (ADDRESS_IP6 == af) { + std::array a; + std::copy(u.ip6, u.ip6 + 16, std::begin(a)); + boost::asio::ip::address_v6 v6(a); + addr = v6; + } else { + std::array a; + std::copy(u.ip6, u.ip6 + 4, std::begin(a)); + boost::asio::ip::address_v4 v4(a); + addr = v4; + } + + return addr; +} + +void +to_api(const mac_address_t& a, vapi_type_mac_address& v) +{ + std::copy(std::begin(a.bytes), std::end(a.bytes), v); +} + +mac_address_t +from_api(const vapi_type_mac_address& v) +{ + return mac_address_t(v); +} + +route::prefix_t +from_api(const vapi_type_prefix& v) +{ + return route::prefix_t(from_api(v.address), v.len); +} + +vapi_type_prefix +to_api(const route::prefix_t& p) +{ + vapi_type_prefix v; + to_api(p.address(), v.address); + v.len = p.mask_width(); + return v; +} + +route::mprefix_t +from_api(const vapi_type_mprefix& v) +{ + return route::mprefix_t(from_api(v.src_address, v.af), + from_api(v.grp_address, v.af), + v.grp_address_length); +} + +vapi_type_mprefix +to_api(const route::mprefix_t& p) +{ + vapi_enum_address_family af; + vapi_type_mprefix v; + to_api(p.grp_address(), v.grp_address, af); + to_api(p.src_address(), v.src_address, af); + v.grp_address_length = p.mask_width(); + v.af = af; + return v; +} + +vapi_enum_fib_path_nh_proto +to_api(const nh_proto_t& p) +{ + if (p == nh_proto_t::IPV4) { + return FIB_API_PATH_NH_PROTO_IP4; + } else if (p == nh_proto_t::IPV6) { + return FIB_API_PATH_NH_PROTO_IP6; + } else if (p == nh_proto_t::ETHERNET) { + return FIB_API_PATH_NH_PROTO_ETHERNET; + } else if (p == nh_proto_t::MPLS) { + return FIB_API_PATH_NH_PROTO_MPLS; + } + + return FIB_API_PATH_NH_PROTO_IP4; +} + +vapi_enum_address_family +to_api(const l3_proto_t p) +{ + if (p == l3_proto_t::IPV6) { + return ADDRESS_IP6; + } + return ADDRESS_IP4; +} + +const nh_proto_t& +from_api(vapi_enum_fib_path_nh_proto p) +{ + switch (p) { + case FIB_API_PATH_NH_PROTO_IP4: + return nh_proto_t::IPV4; + case FIB_API_PATH_NH_PROTO_IP6: + return nh_proto_t::IPV6; + case FIB_API_PATH_NH_PROTO_ETHERNET: + return nh_proto_t::ETHERNET; + case FIB_API_PATH_NH_PROTO_MPLS: + return nh_proto_t::MPLS; + case FIB_API_PATH_NH_PROTO_BIER: + break; + } + + return nh_proto_t::IPV4; +} + +}; // VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/api_types.hpp b/extras/deprecated/vom/vom/api_types.hpp new file mode 100644 index 00000000000..dd6f2085810 --- /dev/null +++ b/extras/deprecated/vom/vom/api_types.hpp @@ -0,0 +1,75 @@ +/* + * 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 +#include +#include +#include + +#include +#include + +namespace VOM { + +struct invalid_decode +{ + invalid_decode(const std::string reason); + const std::string reason; +}; + +typedef boost::asio::ip::address ip_address_t; + +vapi_enum_ip_neighbor_flags to_api(const neighbour::flags_t& f); +const neighbour::flags_t from_api(vapi_enum_ip_neighbor_flags f); + +void to_api(const ip_address_t& a, vapi_type_address& v); +void to_api(const boost::asio::ip::address_v4& a, vapi_type_ip4_address& v); +void to_api(const boost::asio::ip::address_v6& a, vapi_type_ip6_address& v); +void to_api(const boost::asio::ip::address& a, + vapi_union_address_union& u, + vapi_enum_address_family& af); +void to_api(const boost::asio::ip::address& a, vapi_union_address_union& u); +vapi_enum_address_family to_api(const l3_proto_t p); + +boost::asio::ip::address_v4 from_api(const vapi_type_ip4_address& v); +boost::asio::ip::address_v6 from_api(const vapi_type_ip6_address& v); +ip_address_t from_api(const vapi_type_address& v); +ip_address_t from_api(const vapi_union_address_union& u, + vapi_enum_address_family af); +ip_address_t from_api(const vapi_union_address_union& u, + vapi_enum_fib_path_nh_proto proto); + +void to_api(const mac_address_t& a, vapi_type_mac_address& m); + +mac_address_t from_api(const vapi_type_mac_address& v); + +route::prefix_t from_api(const vapi_type_prefix&); +route::mprefix_t from_api(const vapi_type_mprefix&); + +vapi_type_prefix to_api(const route::prefix_t&); +vapi_type_mprefix to_api(const route::mprefix_t&); + +vapi_enum_fib_path_nh_proto to_api(const nh_proto_t&); +const nh_proto_t& from_api(vapi_enum_fib_path_nh_proto); + +}; // VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/arp_proxy_binding.cpp b/extras/deprecated/vom/vom/arp_proxy_binding.cpp new file mode 100644 index 00000000000..8c8ee099b21 --- /dev/null +++ b/extras/deprecated/vom/vom/arp_proxy_binding.cpp @@ -0,0 +1,160 @@ +/* + * 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/arp_proxy_binding.hpp" +#include "vom/arp_proxy_binding_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +/** + * A DB of all ARP proxy bindings configs + */ +singular_db arp_proxy_binding::m_db; + +arp_proxy_binding::event_handler arp_proxy_binding::m_evh; + +arp_proxy_binding::arp_proxy_binding(const interface& itf) + : m_itf(itf.singular()) + , m_binding(true) +{ +} + +arp_proxy_binding::arp_proxy_binding(const arp_proxy_binding& o) + : m_itf(o.m_itf) + , m_binding(o.m_binding) +{ +} + +arp_proxy_binding::~arp_proxy_binding() +{ + sweep(); + m_db.release(m_itf->key(), this); +} + +void +arp_proxy_binding::sweep() +{ + if (m_binding) { + HW::enqueue( + new arp_proxy_binding_cmds::unbind_cmd(m_binding, m_itf->handle())); + } + HW::write(); +} + +void +arp_proxy_binding::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +arp_proxy_binding::replay() +{ + if (m_binding) { + HW::enqueue( + new arp_proxy_binding_cmds::bind_cmd(m_binding, m_itf->handle())); + } +} + +std::string +arp_proxy_binding::to_string() const +{ + std::ostringstream s; + s << "ArpProxy-binding: " << m_itf->to_string(); + + return (s.str()); +} + +void +arp_proxy_binding::update(const arp_proxy_binding& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (!m_binding) { + HW::enqueue( + new arp_proxy_binding_cmds::bind_cmd(m_binding, m_itf->handle())); + } +} + +std::shared_ptr +arp_proxy_binding::find_or_add(const arp_proxy_binding& temp) +{ + return (m_db.find_or_add(temp.m_itf->key(), temp)); +} + +std::shared_ptr +arp_proxy_binding::singular() const +{ + return find_or_add(*this); +} + +arp_proxy_binding::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "arp-proxy-binding" }, "ARP proxy bindings", + this); +} + +void +arp_proxy_binding::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +arp_proxy_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = interface::find(payload.sw_if_index); + + if (itf) { + arp_proxy_binding ab(*itf); + OM::commit(key, ab); + } else { + VOM_LOG(log_level_t::ERROR) << "arp-proxy-binding dump:" + << " itf:" << payload.sw_if_index; + } + } +} + +dependency_t +arp_proxy_binding::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +arp_proxy_binding::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/arp_proxy_binding.hpp b/extras/deprecated/vom/vom/arp_proxy_binding.hpp new file mode 100644 index 00000000000..b11c5ba4414 --- /dev/null +++ b/extras/deprecated/vom/vom/arp_proxy_binding.hpp @@ -0,0 +1,159 @@ +/* + * 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_ARP_PROXY_BINDING_H__ +#define __VOM_ARP_PROXY_BINDING_H__ + +#include "vom/arp_proxy_config.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of LLDP client configuration on an interface + */ +class arp_proxy_binding : public object_base +{ +public: + /** + * Construct a new object matching the desried state + */ + arp_proxy_binding(const interface& itf); + + /** + * Copy Constructor + */ + arp_proxy_binding(const arp_proxy_binding& o); + + /** + * Destructor + */ + ~arp_proxy_binding(); + + /** + * Return the 'singular' of the LLDP binding that matches this object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all LLDP bindings into the stream provided + */ + static void dump(std::ostream& os); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const arp_proxy_binding& obj); + + /** + * Find or add LLDP binding to the OM + */ + static std::shared_ptr find_or_add( + const arp_proxy_binding& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer to the interface on which LLDP config + * resides. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A map of all ArpProxy bindings keyed against the interface. + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/arp_proxy_binding_cmds.cpp b/extras/deprecated/vom/vom/arp_proxy_binding_cmds.cpp new file mode 100644 index 00000000000..eb832fa455e --- /dev/null +++ b/extras/deprecated/vom/vom/arp_proxy_binding_cmds.cpp @@ -0,0 +1,127 @@ +/* + * 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/arp_proxy_binding_cmds.hpp" + +namespace VOM { +namespace arp_proxy_binding_cmds { + +bind_cmd::bind_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.enable = 1; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "ARP-proxy-bind: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string(); + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.enable = 0; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "ARP-proxy-unbind: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string(); + + return (s.str()); +} + +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 ("ARP-proxy-binding-dump"); +} + +}; // namespace arp_proxy_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/arp_proxy_binding_cmds.hpp b/extras/deprecated/vom/vom/arp_proxy_binding_cmds.hpp new file mode 100644 index 00000000000..a3139373e61 --- /dev/null +++ b/extras/deprecated/vom/vom/arp_proxy_binding_cmds.hpp @@ -0,0 +1,135 @@ +/* + * 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_ARP_PROXY_BINDING_CMDS_H__ +#define __VOM_ARP_PROXY_BINDING_CMDS_H__ + +#include "vom/arp_proxy_binding.hpp" +#include "vom/dump_cmd.hpp" + +#include + +namespace VOM { +namespace arp_proxy_binding_cmds { +/** + * A command class that binds the LLDP config to the interface + */ +class bind_cmd + : public rpc_cmd, vapi::Proxy_arp_intfc_enable_disable> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to bind + */ + const handle_t& m_itf; +}; + +/** + * A cmd class that Unbinds ArpProxy Config from an interface + */ +class unbind_cmd + : public rpc_cmd, vapi::Proxy_arp_intfc_enable_disable> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to unbind + */ + const handle_t& m_itf; +}; + +/** + * A cmd class that Dumps all the Proxy ARP configs + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // namespace cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/arp_proxy_config.cpp b/extras/deprecated/vom/vom/arp_proxy_config.cpp new file mode 100644 index 00000000000..3d502a2b437 --- /dev/null +++ b/extras/deprecated/vom/vom/arp_proxy_config.cpp @@ -0,0 +1,163 @@ +/* + * 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/arp_proxy_config.hpp" +#include "vom/api_types.hpp" +#include "vom/arp_proxy_config_cmds.hpp" +#include "vom/prefix.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +singular_db arp_proxy_config::m_db; + +arp_proxy_config::event_handler arp_proxy_config::m_evh; + +arp_proxy_config::arp_proxy_config(const boost::asio::ip::address_v4& low, + const boost::asio::ip::address_v4& high) + : m_low(low) + , m_high(high) + , m_config(true) +{ +} + +arp_proxy_config::arp_proxy_config(const arp_proxy_config& o) + : m_low(o.m_low) + , m_high(o.m_high) + , m_config(o.m_config) +{ +} + +arp_proxy_config::~arp_proxy_config() +{ + sweep(); + + // not in the DB anymore. + m_db.release(std::make_pair(m_low, m_high), this); +} + +void +arp_proxy_config::sweep() +{ + if (m_config) { + HW::enqueue( + new arp_proxy_config_cmds::unconfig_cmd(m_config, m_low, m_high)); + } + HW::write(); +} + +void +arp_proxy_config::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +arp_proxy_config::replay() +{ + if (m_config) { + HW::enqueue(new arp_proxy_config_cmds::config_cmd(m_config, m_low, m_high)); + } +} + +std::string +arp_proxy_config::to_string() const +{ + std::ostringstream s; + s << "ARP-proxy:" + << " low:" << m_low.to_string() << " high:" << m_high.to_string(); + + return (s.str()); +} + +void +arp_proxy_config::update(const arp_proxy_config& desired) +{ + if (!m_config) { + HW::enqueue(new arp_proxy_config_cmds::config_cmd(m_config, m_low, m_high)); + } +} + +std::shared_ptr +arp_proxy_config::find_or_add(const arp_proxy_config& temp) +{ + return (m_db.find_or_add(std::make_pair(temp.m_low, temp.m_high), temp)); +} + +std::shared_ptr +arp_proxy_config::singular() const +{ + return find_or_add(*this); +} + +arp_proxy_config::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "arp-proxy-config" }, "ARP Proxy configurations", + this); +} + +void +arp_proxy_config::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +arp_proxy_config::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + boost::asio::ip::address lo = from_api(payload.proxy.low); + boost::asio::ip::address hi = from_api(payload.proxy.hi); + + arp_proxy_config ap(lo.to_v4(), hi.to_v4()); + OM::commit(key, ap); + } +} + +dependency_t +arp_proxy_config::event_handler::order() const +{ + return (dependency_t::GLOBAL); +} + +void +arp_proxy_config::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const arp_proxy_config::key_t& key) +{ + os << "[" << key.first << ", " << key.second << "]"; + + return (os); +} +} +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/arp_proxy_config.hpp b/extras/deprecated/vom/vom/arp_proxy_config.hpp new file mode 100644 index 00000000000..129f7bd7e9e --- /dev/null +++ b/extras/deprecated/vom/vom/arp_proxy_config.hpp @@ -0,0 +1,165 @@ +/* + * 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_ARP_PROXY_CONFIG_H__ +#define __VOM_ARP_PROXY_CONFIG_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of LLDP client configuration on an interface + */ +class arp_proxy_config : public object_base +{ +public: + /** + * Key type + */ + typedef std::pair + key_t; + + /** + * Construct a new object matching the desried state + */ + arp_proxy_config(const boost::asio::ip::address_v4& low, + const boost::asio::ip::address_v4& high); + + /** + * Copy Constructor + */ + arp_proxy_config(const arp_proxy_config& o); + + /** + * Destructor + */ + ~arp_proxy_config(); + + /** + * Return the 'singular' of the LLDP config that matches this object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all LLDP configs into the stream provided + */ + static void dump(std::ostream& os); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const arp_proxy_config& obj); + + /** + * Find or add LLDP config to the OM + */ + static std::shared_ptr find_or_add( + const arp_proxy_config& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Address range + */ + const boost::asio::ip::address_v4 m_low; + const boost::asio::ip::address_v4 m_high; + + /** + * A map of all ArpProxy configs keyed against the interface. + */ + static singular_db m_db; + + /** + * HW configuration for the config. The bool representing the + * do/don't configured/unconfigured. + */ + HW::item m_config; +}; + +std::ostream& operator<<(std::ostream& os, const arp_proxy_config::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/arp_proxy_config_cmds.cpp b/extras/deprecated/vom/vom/arp_proxy_config_cmds.cpp new file mode 100644 index 00000000000..c9eb606e623 --- /dev/null +++ b/extras/deprecated/vom/vom/arp_proxy_config_cmds.cpp @@ -0,0 +1,142 @@ +/* + * 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/arp_proxy_config_cmds.hpp" +#include "vom/api_types.hpp" + +DEFINE_VAPI_MSG_IDS_ARP_API_JSON; + +namespace VOM { +namespace arp_proxy_config_cmds { + +config_cmd::config_cmd(HW::item& item, + const boost::asio::ip::address_v4& low, + const boost::asio::ip::address_v4& high) + : rpc_cmd(item) + , m_low(low) + , m_high(high) +{} + +bool +config_cmd::operator==(const config_cmd& o) const +{ + return ((m_low == o.m_low) && (m_high == o.m_high)); +} + +rc_t +config_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + + to_api(m_low, payload.proxy.low); + to_api(m_high, payload.proxy.hi); + + VAPI_CALL(req.execute()); + + wait(); + + return (rc_t::OK); +} + +std::string +config_cmd::to_string() const +{ + std::ostringstream s; + s << "ARP-proxy-config: " << m_hw_item.to_string() + << " low:" << m_low.to_string() << " high:" << m_high.to_string(); + + return (s.str()); +} + +unconfig_cmd::unconfig_cmd(HW::item& item, + const boost::asio::ip::address_v4& low, + const boost::asio::ip::address_v4& high) + : rpc_cmd(item) + , m_low(low) + , m_high(high) +{} + +bool +unconfig_cmd::operator==(const unconfig_cmd& o) const +{ + return ((m_low == o.m_low) && (m_high == o.m_high)); +} + +rc_t +unconfig_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + + to_api(m_low, payload.proxy.low); + to_api(m_high, payload.proxy.hi); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return (rc_t::OK); +} + +std::string +unconfig_cmd::to_string() const +{ + std::ostringstream s; + s << "ARP-proxy-unconfig: " << m_hw_item.to_string() + << " low:" << m_low.to_string() << " high:" << m_high.to_string(); + + return (s.str()); +} + +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 ("ARP-proxy-dump"); +} + +}; // namesapce cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/arp_proxy_config_cmds.hpp b/extras/deprecated/vom/vom/arp_proxy_config_cmds.hpp new file mode 100644 index 00000000000..194acd6eff6 --- /dev/null +++ b/extras/deprecated/vom/vom/arp_proxy_config_cmds.hpp @@ -0,0 +1,140 @@ +/* + * 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_ARP_PROXY_CONFIG_CMDS_H__ +#define __VOM_ARP_PROXY_CONFIG_CMDS_H__ + +#include "vom/arp_proxy_config.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace arp_proxy_config_cmds { +/** + * A command class that adds the ARP Proxy config + */ +class config_cmd : public rpc_cmd, vapi::Proxy_arp_add_del> +{ +public: + /** + * Constructor + */ + config_cmd(HW::item& item, + const boost::asio::ip::address_v4& lo, + const boost::asio::ip::address_v4& high); + + /** + * 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 config_cmd& i) const; + +private: + /** + * Address range + */ + const boost::asio::ip::address_v4 m_low; + const boost::asio::ip::address_v4 m_high; +}; + +/** + * A cmd class that Unconfigs ArpProxy Config from an interface + */ +class unconfig_cmd : public rpc_cmd, vapi::Proxy_arp_add_del> +{ +public: + /** + * Constructor + */ + unconfig_cmd(HW::item& item, + const boost::asio::ip::address_v4& lo, + const boost::asio::ip::address_v4& hig); + + /** + * 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 unconfig_cmd& i) const; + +private: + /** + * Address range + */ + const boost::asio::ip::address_v4 m_low; + const boost::asio::ip::address_v4 m_high; +}; + +/** + * A cmd class that Dumps all the Proxy ARP configs + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // namespace cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bond_group_binding.cpp b/extras/deprecated/vom/vom/bond_group_binding.cpp new file mode 100644 index 00000000000..f36641b7911 --- /dev/null +++ b/extras/deprecated/vom/vom/bond_group_binding.cpp @@ -0,0 +1,179 @@ +/* + * 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/bond_group_binding.hpp" +#include "vom/bond_group_binding_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +/** + * A DB of all bond interface binding + */ +singular_db + bond_group_binding::m_db; + +bond_group_binding::event_handler bond_group_binding::m_evh; + +bond_group_binding::bond_group_binding(const bond_interface& itf, + const enslaved_itf_t& itfs) + : m_itf(itf.singular()) + , m_mem_itfs(itfs) + , m_binding(false) +{ +} + +bond_group_binding::bond_group_binding(const bond_group_binding& o) + : m_itf(o.m_itf) + , m_mem_itfs(o.m_mem_itfs) + , m_binding(o.m_binding) +{ +} + +bond_group_binding::~bond_group_binding() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +const bond_group_binding::key_t +bond_group_binding::key() const +{ + return (m_itf->key() + "-binding"); +} + +void +bond_group_binding::sweep() +{ + + auto it = m_mem_itfs.cbegin(); + while (it != m_mem_itfs.cend()) { + if (m_binding) { + HW::enqueue( + new bond_group_binding_cmds::unbind_cmd(m_binding, it->hdl())); + } + HW::write(); + ++it; + } +} + +void +bond_group_binding::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +bond_group_binding::replay() +{ + auto it = m_mem_itfs.cbegin(); + while (it != m_mem_itfs.cend()) { + if (m_binding) { + HW::enqueue( + new bond_group_binding_cmds::bind_cmd(m_binding, m_itf->handle(), *it)); + } + HW::write(); + ++it; + } +} + +std::string +bond_group_binding::to_string() const +{ + auto it = m_mem_itfs.cbegin(); + std::ostringstream s; + s << "bond-interface-binding: " << m_itf->to_string() << " slave-itfs: ["; + while (it != m_mem_itfs.cend()) { + s << " " << it->to_string(); + ++it; + } + s << "]"; + return (s.str()); +} + +void +bond_group_binding::update(const bond_group_binding& desired) +{ + /* + * the desired state is always that the interface should be created + */ + auto it = m_mem_itfs.cbegin(); + while (it != m_mem_itfs.cend()) { + if (!m_binding) { + HW::enqueue( + new bond_group_binding_cmds::bind_cmd(m_binding, m_itf->handle(), *it)); + } + ++it; + } +} + +std::shared_ptr +bond_group_binding::find_or_add(const bond_group_binding& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +bond_group_binding::singular() const +{ + return find_or_add(*this); +} + +bond_group_binding::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "bond-intf-binding" }, "Bond interface binding", + this); +} + +void +bond_group_binding::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +bond_group_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * handle it in interface class + */ +} + +dependency_t +bond_group_binding::event_handler::order() const +{ + /* + * We want enslaved interfaces bind to bond after interface + * but before anything else. + */ + return (dependency_t::VIRTUAL_INTERFACE); +} + +void +bond_group_binding::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bond_group_binding.hpp b/extras/deprecated/vom/vom/bond_group_binding.hpp new file mode 100644 index 00000000000..04befb52939 --- /dev/null +++ b/extras/deprecated/vom/vom/bond_group_binding.hpp @@ -0,0 +1,186 @@ +/* + * 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_BOND_GROUP_BINDING_H__ +#define __VOM_BOND_GROUP_BINDING_H__ + +#include + +#include "vom/bond_interface.hpp" +#include "vom/bond_member.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of bond interface binding + */ +class bond_group_binding : public object_base +{ +public: + /** + * The KEY can be used to uniquely identify the Bond Binding. + * (other choices for keys, like the summation of the properties + * of the rules, are rather too cumbersome to use + */ + typedef std::string key_t; + + /** + * The container type for enslaved itfs + */ + typedef std::set enslaved_itf_t; + + /** + * Construct a new object matching the desried state + */ + bond_group_binding(const bond_interface& itf, const enslaved_itf_t& mem); + + /** + * Copy Constructor + */ + bond_group_binding(const bond_group_binding& o); + + /** + * Destructor + */ + ~bond_group_binding(); + + /** + * Return the 'singular' of the bond interface binding that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * get the key to this object + */ + const key_t key() const; + + /** + * Dump all bond interface bindings into the stream provided + */ + static void dump(std::ostream& os); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enqueue command to the VPP command Q for the update + */ + void update(const bond_group_binding& obj); + + /** + * Find or add bond interface binding to the OM + */ + static std::shared_ptr find_or_add( + const bond_group_binding& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer to the bond interface. + * By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + std::shared_ptr m_itf; + + /** + * A list of member interfaces. + */ + const enslaved_itf_t m_mem_itfs; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A map of all bond interface bindings keyed against the interface + + * "binding". + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bond_group_binding_cmds.cpp b/extras/deprecated/vom/vom/bond_group_binding_cmds.cpp new file mode 100644 index 00000000000..ffda355358d --- /dev/null +++ b/extras/deprecated/vom/vom/bond_group_binding_cmds.cpp @@ -0,0 +1,145 @@ +/* + * 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/bond_group_binding_cmds.hpp" + +namespace VOM { +namespace bond_group_binding_cmds { + +bind_cmd::bind_cmd(HW::item& item, + const handle_t& bond_itf, + const bond_member& itf) + : rpc_cmd(item) + , m_bond_itf(bond_itf) + , m_itf(itf) +{ +} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return ((m_bond_itf == other.m_bond_itf) && (m_itf == other.m_itf)); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + m_itf.to_vpp(payload); + payload.bond_sw_if_index = m_bond_itf.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "bond-itf-bind: " << m_hw_item.to_string() + << " bond-itf:" << m_bond_itf.to_string() + << " slave-itf:" << m_itf.hdl().to_string(); + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{ +} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "bond-itf-unbind: " << m_hw_item.to_string() + << " slave-itf:" << m_itf.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd(const handle_t& hdl) + : m_itf(hdl) +{ +} + +dump_cmd::dump_cmd(const dump_cmd& d) + : m_itf(d.m_itf) +{ +} + +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))); + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("bond-slave-itfs-dump"); +} + +}; // namespace bond_group_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bond_group_binding_cmds.hpp b/extras/deprecated/vom/vom/bond_group_binding_cmds.hpp new file mode 100644 index 00000000000..3f511304516 --- /dev/null +++ b/extras/deprecated/vom/vom/bond_group_binding_cmds.hpp @@ -0,0 +1,138 @@ +/* + * 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_BOND_GROUP_BINDING_CMDS_H__ +#define __VOM_BOND_GROUP_BINDING_CMDS_H__ + +#include "vom/bond_group_binding.hpp" +#include "vom/dump_cmd.hpp" + +#include + +namespace VOM { +namespace bond_group_binding_cmds { +/** + * A command class that binds the slave interface to the bond interface + */ +class bind_cmd : public rpc_cmd, vapi::Bond_enslave> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, + const handle_t& bond_itf, + const bond_member& itf); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * sw_if_index of bond interface + */ + const handle_t m_bond_itf; + + /** + * member interface of bond group + */ + const bond_member m_itf; +}; + +/** + * A cmd class that detach slave from a bond interface + */ +class unbind_cmd : public rpc_cmd, vapi::Bond_detach_slave> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * slave interface of bond group + */ + const handle_t m_itf; +}; + +/** + * A cmd class that Dumps slave itfs + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + dump_cmd(const handle_t& itf); + dump_cmd(const dump_cmd& d); + /** + * 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; + +private: + /** + * The interface to get the addresses for + */ + const handle_t m_itf; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bond_interface.cpp b/extras/deprecated/vom/vom/bond_interface.cpp new file mode 100644 index 00000000000..33a001b0209 --- /dev/null +++ b/extras/deprecated/vom/vom/bond_interface.cpp @@ -0,0 +1,197 @@ +/* + * 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/bond_interface.hpp" +#include "vom/bond_group_binding.hpp" +#include "vom/bond_group_binding_cmds.hpp" +#include "vom/bond_interface_cmds.hpp" + +namespace VOM { +/** + * Construct a new object matching the desried state + */ +bond_interface::bond_interface(const std::string& name, + admin_state_t state, + mode_t mode, + lb_t lb) + : interface(name, type_t::BOND, state) + , m_l2_address(l2_address_t::ZERO) + , m_mode(mode) + , m_lb(lb) +{ +} + +bond_interface::bond_interface(const std::string& name, + admin_state_t state, + const l2_address_t& l2_address, + mode_t mode, + lb_t lb) + : interface(name, type_t::BOND, state) + , m_l2_address(l2_address) + , m_mode(mode) + , m_lb(lb) +{ +} + +bond_interface::~bond_interface() +{ + sweep(); + release(); +} + +bond_interface::bond_interface(const bond_interface& o) + : interface(o) + , m_l2_address(o.m_l2_address) + , m_mode(o.m_mode) + , m_lb(o.m_lb) +{ +} + +std::shared_ptr +bond_interface::find(const handle_t& hdl) +{ + return std::dynamic_pointer_cast(interface::find(hdl)); +} + +void +bond_interface::set(bond_interface::mode_t mode) +{ + m_mode = mode; +} + +void +bond_interface::set(bond_interface::lb_t lb) +{ + m_lb = lb; +} + +std::string +bond_interface::to_string() const +{ + std::ostringstream s; + + s << this->interface::to_string() << " mode:" << m_mode.to_string() + << " lb:" << m_lb.to_string(); + + return (s.str()); +} + +std::queue& +bond_interface::mk_create_cmd(std::queue& q) +{ + q.push(new bond_interface_cmds::create_cmd(m_hdl, name(), m_mode, m_lb, + m_l2_address)); + + return (q); +} + +std::queue& +bond_interface::mk_delete_cmd(std::queue& q) +{ + q.push(new bond_interface_cmds::delete_cmd(m_hdl)); + + return (q); +} + +std::shared_ptr +bond_interface::singular() const +{ + return std::dynamic_pointer_cast(singular_i()); +} + +std::shared_ptr +bond_interface::singular_i() const +{ + return m_db.find_or_add(name(), *this); +} + +void +bond_interface::set(handle_t& handle) +{ + this->interface::set(handle); +} + +const bond_interface::mode_t bond_interface::mode_t::ROUND_ROBIN(1, + "round-robin"); +const bond_interface::mode_t bond_interface::mode_t::ACTIVE_BACKUP( + 2, + "active-backup"); +const bond_interface::mode_t bond_interface::mode_t::XOR(3, "xor"); +const bond_interface::mode_t bond_interface::mode_t::BROADCAST(4, "broadcast"); +const bond_interface::mode_t bond_interface::mode_t::LACP(5, "lacp"); +const bond_interface::mode_t bond_interface::mode_t::UNSPECIFIED(0, + "unspecified"); + +const bond_interface::mode_t +bond_interface::mode_t::from_numeric_val(uint8_t numeric) +{ + if (1 == numeric) { + return (bond_interface::mode_t::ROUND_ROBIN); + } + if (2 == numeric) { + return (bond_interface::mode_t::ACTIVE_BACKUP); + } + if (3 == numeric) { + return (bond_interface::mode_t::XOR); + } + if (4 == numeric) { + return (bond_interface::mode_t::BROADCAST); + } + if (5 == numeric) { + return (bond_interface::mode_t::LACP); + } + + return (bond_interface::mode_t::UNSPECIFIED); +} + +bond_interface::mode_t::mode_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const bond_interface::lb_t bond_interface::lb_t::L2(0, "l2"); +const bond_interface::lb_t bond_interface::lb_t::L34(1, "l34"); +const bond_interface::lb_t bond_interface::lb_t::L23(2, "l23"); +const bond_interface::lb_t bond_interface::lb_t::UNSPECIFIED(~0, "unspecified"); + +const bond_interface::lb_t +bond_interface::lb_t::from_numeric_val(uint8_t numeric) +{ + if (0 == numeric) { + return (bond_interface::lb_t::L2); + } + if (1 == numeric) { + return (bond_interface::lb_t::L34); + } + if (2 == numeric) { + return (bond_interface::lb_t::L23); + } + + return (bond_interface::lb_t::UNSPECIFIED); +} + +bond_interface::lb_t::lb_t(int v, const std::string& s) + : enum_base(v, s) +{ +} +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bond_interface.hpp b/extras/deprecated/vom/vom/bond_interface.hpp new file mode 100644 index 00000000000..e52b519d6ba --- /dev/null +++ b/extras/deprecated/vom/vom/bond_interface.hpp @@ -0,0 +1,197 @@ +/* + * 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_BOND_INTERFACE_H__ +#define __VOM_BOND_INTERFACE_H__ + +#include "vom/interface.hpp" + +namespace VOM { +/** + * A bond-interface. e.g. a bond interface + */ +class bond_interface : public interface +{ +public: + /** + * A bond interface mode + */ + struct mode_t : enum_base + { + /** + * Round-Robin bond interface mode + */ + const static mode_t ROUND_ROBIN; + /** + * Active-backup bond interface mode + */ + const static mode_t ACTIVE_BACKUP; + /** + * XOR bond interface mode + */ + const static mode_t XOR; + /** + * Broadcast bond interface mode + */ + const static mode_t BROADCAST; + /** + * LACP bond interface mode + */ + const static mode_t LACP; + /** + * Unspecified bond interface mode + */ + const static mode_t UNSPECIFIED; + + /** + * Convert VPP's value of the bond to a mode + */ + static const mode_t from_numeric_val(uint8_t v); + + private: + /** + * Private constructor taking the value and the string name + */ + mode_t(int v, const std::string& s); + }; + + /** + * A bond interface load balance + */ + struct lb_t : enum_base + { + /** + * L2 bond interface lb + */ + const static lb_t L2; + /** + * L34 bond interface lb + */ + const static lb_t L34; + /** + * L23 bond interface lb + */ + const static lb_t L23; + /** + * Unspecified bond interface lb + */ + const static lb_t UNSPECIFIED; + + /** + * Convert VPP's value of the bond to a lb + */ + static const lb_t from_numeric_val(uint8_t v); + + private: + /** + * Private constructor taking the value and the string name + */ + lb_t(int v, const std::string& s); + }; + + bond_interface(const std::string& name, + admin_state_t state, + mode_t mode, + lb_t lb = lb_t::UNSPECIFIED); + + bond_interface(const std::string& name, + admin_state_t state, + const l2_address_t& l2_address, + mode_t mode, + lb_t lb = lb_t::UNSPECIFIED); + + ~bond_interface(); + bond_interface(const bond_interface& o); + + /** + * The the singular instance of the bond interface in the DB by handle + */ + static std::shared_ptr find(const handle_t& hdl); + + /** + * Return the matching 'singular instance' of the BOND interface + */ + std::shared_ptr singular() const; + + /** + * set the mode + */ + void set(mode_t mode); + + /** + * set the lb + */ + void set(lb_t lb); + + /** + * convert to string + */ + virtual std::string to_string() const; + +protected: + /** + * set the handle + */ + void set(handle_t& handle); + friend class interface_factory; + +private: + /** + * l2 address on bond interface + */ + l2_address_t m_l2_address; + + /** + * mode on bond interface + */ + mode_t m_mode; + + /** + * lb mode on bond interface + */ + lb_t m_lb; + + /** + * Return the matching 'instance' of the sub-interface + * over-ride from the base class + */ + std::shared_ptr singular_i() const; + + /** + * Virtual functions to construct an interface create commands. + */ + virtual std::queue& mk_create_cmd(std::queue& cmds); + + /** + * Virtual functions to construct an interface delete commands. + */ + virtual std::queue& mk_delete_cmd(std::queue& cmds); + + /* + * It's the OM class that call singular() + */ + friend class OM; +}; +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bond_interface_cmds.cpp b/extras/deprecated/vom/vom/bond_interface_cmds.cpp new file mode 100644 index 00000000000..3e49d2f85e2 --- /dev/null +++ b/extras/deprecated/vom/vom/bond_interface_cmds.cpp @@ -0,0 +1,139 @@ +/* + * 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/bond_interface_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_BOND_API_JSON; + +namespace VOM { +namespace bond_interface_cmds { +create_cmd::create_cmd(HW::item& item, + const std::string& name, + const bond_interface::mode_t& mode, + const bond_interface::lb_t& lb, + const l2_address_t& l2_address) + : interface::create_cmd(item, name) + , m_mode(mode) + , m_lb(lb) + , m_l2_address(l2_address) +{ +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + if (m_l2_address != l2_address_t::ZERO) { + m_l2_address.to_bytes(payload.mac_address, 6); + payload.use_custom_mac = 1; + } + + payload.mode = (vapi_enum_bond_mode)m_mode.value(); + if ((m_mode == bond_interface::mode_t::XOR || + m_mode == bond_interface::mode_t::LACP) && + m_lb != bond_interface::lb_t::UNSPECIFIED) + payload.lb = (vapi_enum_bond_lb_algo)m_lb.value(); + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) { + insert_interface(); + } + + return rc_t::OK; +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "bond-intf-create: " << m_hw_item.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item) + : interface::delete_cmd(item) +{ +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + remove_interface(); + + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "bond-itf-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("bond-itf-dump"); +} +} // namespace bond_interface_cmds +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bond_interface_cmds.hpp b/extras/deprecated/vom/vom/bond_interface_cmds.hpp new file mode 100644 index 00000000000..5b1e0fcc98d --- /dev/null +++ b/extras/deprecated/vom/vom/bond_interface_cmds.hpp @@ -0,0 +1,111 @@ +/* + * 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_BOND_INTERFACE_CMDS_H__ +#define __VOM_BOND_INTERFACE_CMDS_H__ + +#include "vom/bond_interface.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/interface.hpp" +#include "vom/rpc_cmd.hpp" + +#include +#include + +namespace VOM { +namespace bond_interface_cmds { + +/** + * A functor class that creates an interface + */ +class create_cmd : public interface::create_cmd +{ +public: + create_cmd(HW::item& item, + const std::string& name, + const bond_interface::mode_t& mode, + const bond_interface::lb_t& lb, + const l2_address_t& l2_address); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + +private: + const bond_interface::mode_t m_mode; + const bond_interface::lb_t m_lb; + const l2_address_t m_l2_address; +}; + +/** + * A functor class that deletes a Tap interface + */ +class delete_cmd : public interface::delete_cmd +{ +public: + delete_cmd(HW::item& item); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; +}; + +/** + * A cmd class that Dumps all the Vpp Interfaces + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + dump_cmd(); + + /** + * 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 bond_interface_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ +#endif diff --git a/extras/deprecated/vom/vom/bond_member.cpp b/extras/deprecated/vom/vom/bond_member.cpp new file mode 100644 index 00000000000..d8edb1b6a20 --- /dev/null +++ b/extras/deprecated/vom/vom/bond_member.cpp @@ -0,0 +1,130 @@ +/* + * 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/bond_member.hpp" + +namespace VOM { +/** + * Construct a new object matching the desried state + */ +bond_member::bond_member(const interface& itf, mode_t mode, rate_t rate) + : m_itf(itf.singular()) + , m_mode(mode) + , m_rate(rate) +{ +} + +bond_member::~bond_member() +{ +} + +bond_member::bond_member(const bond_member& o) + : m_itf(o.m_itf) + , m_mode(o.m_mode) + , m_rate(o.m_rate) +{ +} + +void +bond_member::to_vpp(vapi_payload_bond_enslave& bond_enslave) const +{ + bond_enslave.sw_if_index = m_itf->handle().value(); + bond_enslave.is_passive = (m_mode == mode_t::PASSIVE) ? 1 : 0; + bond_enslave.is_long_timeout = (m_rate == rate_t::SLOW) ? 1 : 0; +} + +std::string +bond_member::to_string() const +{ + std::ostringstream s; + + s << m_itf->to_string() << " mode:" << m_mode.to_string() + << " rate:" << m_rate.to_string(); + + return (s.str()); +} + +bool +bond_member::operator<(const bond_member& itf) const +{ + return (m_itf->handle() < itf.m_itf->handle()); +} + +void +bond_member::set(mode_t mode) +{ + m_mode = mode; +} + +void +bond_member::set(rate_t rate) +{ + m_rate = rate; +} + +const handle_t +bond_member::hdl(void) const +{ + return m_itf->handle(); +} + +bool +bond_member::operator==(const bond_member& b) const +{ + return ((m_itf == b.m_itf) && (m_mode == b.m_mode) && (m_rate == b.m_rate)); +} + +const bond_member::mode_t bond_member::mode_t::ACTIVE(0, "active"); +const bond_member::mode_t bond_member::mode_t::PASSIVE(1, "passive"); + +const bond_member::mode_t +bond_member::mode_t::from_numeric_val(uint8_t numeric) +{ + if (0 == numeric) + return (bond_member::mode_t::ACTIVE); + + return (bond_member::mode_t::PASSIVE); +} + +bond_member::mode_t::mode_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const bond_member::rate_t bond_member::rate_t::FAST(0, "fast"); +const bond_member::rate_t bond_member::rate_t::SLOW(1, "slow"); + +const bond_member::rate_t +bond_member::rate_t::from_numeric_val(uint8_t numeric) +{ + if (0 == numeric) + return (bond_member::rate_t::FAST); + + return (bond_member::rate_t::SLOW); +} + +bond_member::rate_t::rate_t(int v, const std::string& s) + : enum_base(v, s) +{ +} +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bond_member.hpp b/extras/deprecated/vom/vom/bond_member.hpp new file mode 100644 index 00000000000..0d65d77028c --- /dev/null +++ b/extras/deprecated/vom/vom/bond_member.hpp @@ -0,0 +1,147 @@ +/* + * 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_BOND_MEMBER_H__ +#define __VOM_BOND_MEMBER_H__ + +#include "vom/interface.hpp" +#include + +namespace VOM { +/** + * A bond-member. e.g. a bond_member interface + */ +class bond_member +{ +public: + /** + * A member interface mode + */ + struct mode_t : enum_base + { + /** + * Active member interface mode + */ + const static mode_t ACTIVE; + /** + * Passive member interface mode + */ + const static mode_t PASSIVE; + + /** + * Convert VPP's value of the bond to a mode + */ + static const mode_t from_numeric_val(uint8_t v); + + private: + /** + * Private constructor taking the value and the string name + */ + mode_t(int v, const std::string& s); + }; + + /** + * A member interface rate + */ + struct rate_t : enum_base + { + /** + * Fast member interface rate + */ + const static rate_t FAST; + /** + * SLOW member interface rate + */ + const static rate_t SLOW; + + /** + * Convert VPP's value of the bond to a mode + */ + static const rate_t from_numeric_val(uint8_t v); + + private: + /** + * Private constructor taking the value and the string name + */ + rate_t(int v, const std::string& s); + }; + + bond_member(const interface& itf, mode_t mode, rate_t rate); + + ~bond_member(); + bond_member(const bond_member& o); + + /** + * convert to VPP + */ + void to_vpp(vapi_payload_bond_enslave& bond_enslave) const; + + /** + * set the mode + */ + void set(mode_t mode); + + /** + * set the rate + */ + void set(rate_t rate); + + /** + * convert to string + */ + std::string to_string(void) const; + + /** + * less-than operator + */ + bool operator<(const bond_member& mem_itf) const; + + /** + * Get the interface handle + */ + const handle_t hdl(void) const; + + /** + * equality operator + */ + bool operator==(const bond_member& i) const; + +private: + /** + * Refernece conter lock on the parent + */ + const std::shared_ptr m_itf; + + /** + * passive vs active member + */ + mode_t m_mode; + + /** + * slow 90sec. vs. fast 3sec timeout + */ + rate_t m_rate; +}; +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bridge_domain.cpp b/extras/deprecated/vom/vom/bridge_domain.cpp new file mode 100644 index 00000000000..b9105e015f4 --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain.cpp @@ -0,0 +1,308 @@ +/* + * 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/bridge_domain.hpp" +#include "vom/bridge_domain_cmds.hpp" +#include "vom/interface.hpp" +#include "vom/l2_binding.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +const bridge_domain::learning_mode_t bridge_domain::learning_mode_t::ON(1, + "on"); +const bridge_domain::learning_mode_t bridge_domain::learning_mode_t::OFF(0, + "off"); + +bridge_domain::learning_mode_t::learning_mode_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const bridge_domain::flood_mode_t bridge_domain::flood_mode_t::ON(1, "on"); +const bridge_domain::flood_mode_t bridge_domain::flood_mode_t::OFF(0, "off"); + +bridge_domain::flood_mode_t::flood_mode_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const bridge_domain::uu_flood_mode_t bridge_domain::uu_flood_mode_t::ON(1, + "on"); +const bridge_domain::uu_flood_mode_t bridge_domain::uu_flood_mode_t::OFF(0, + "off"); + +bridge_domain::uu_flood_mode_t::uu_flood_mode_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const bridge_domain::mac_age_mode_t bridge_domain::mac_age_mode_t::ON(1, "on"); +const bridge_domain::mac_age_mode_t bridge_domain::mac_age_mode_t::OFF(0, + "off"); + +bridge_domain::mac_age_mode_t::mac_age_mode_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const bridge_domain::arp_term_mode_t bridge_domain::arp_term_mode_t::ON(1, + "on"); +const bridge_domain::arp_term_mode_t bridge_domain::arp_term_mode_t::OFF(0, + "off"); + +bridge_domain::arp_term_mode_t::arp_term_mode_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const bridge_domain::arp_ufwd_mode_t bridge_domain::arp_ufwd_mode_t::ON(1, + "on"); +const bridge_domain::arp_ufwd_mode_t bridge_domain::arp_ufwd_mode_t::OFF(0, + "off"); + +bridge_domain::arp_ufwd_mode_t::arp_ufwd_mode_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +/** + * A DB of al the interfaces, key on the name + */ +singular_db bridge_domain::m_db; + +bridge_domain::event_handler bridge_domain::m_evh; + +/** + * Construct a new object matching the desried state + */ +bridge_domain::bridge_domain(uint32_t id, + const learning_mode_t& lmode, + const arp_term_mode_t& amode, + const arp_ufwd_mode_t& aumode, + const flood_mode_t& fmode, + const uu_flood_mode_t& uufmode, + const mac_age_mode_t& mmode) + : m_id(id) + , m_learning_mode(lmode) + , m_arp_term_mode(amode) + , m_arp_ufwd_mode(aumode) + , m_flood_mode(fmode) + , m_uu_flood_mode(uufmode) + , m_mac_age_mode(mmode) +{ +} + +bridge_domain::bridge_domain(const bridge_domain& o) + : m_id(o.m_id) + , m_learning_mode(o.m_learning_mode) + , m_arp_term_mode(o.m_arp_term_mode) + , m_arp_ufwd_mode(o.m_arp_ufwd_mode) + , m_flood_mode(o.m_flood_mode) + , m_uu_flood_mode(o.m_uu_flood_mode) + , m_mac_age_mode(o.m_mac_age_mode) +{ +} + +const bridge_domain::key_t& +bridge_domain::key() const +{ + return (m_id.data()); +} + +uint32_t +bridge_domain::id() const +{ + return (m_id.data()); +} + +bool +bridge_domain::operator==(const bridge_domain& b) const +{ + return ((m_learning_mode == b.m_learning_mode) && + (m_flood_mode == b.m_flood_mode) && + (m_uu_flood_mode == b.m_uu_flood_mode) && + (m_mac_age_mode == b.m_mac_age_mode) && + (m_arp_term_mode == b.m_arp_term_mode) && + (m_arp_ufwd_mode == b.m_arp_ufwd_mode) && id() == b.id()); +} + +void +bridge_domain::sweep() +{ + if (rc_t::OK == m_id.rc()) { + HW::enqueue(new bridge_domain_cmds::delete_cmd(m_id)); + } + HW::write(); +} + +void +bridge_domain::replay() +{ + if (rc_t::OK == m_id.rc()) { + HW::enqueue(new bridge_domain_cmds::create_cmd( + m_id, m_learning_mode, m_arp_term_mode, m_arp_ufwd_mode, m_flood_mode, + m_uu_flood_mode, m_mac_age_mode)); + } +} + +bridge_domain::~bridge_domain() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_id.data(), this); +} + +std::string +bridge_domain::to_string() const +{ + std::ostringstream s; + s << "bridge-domain:[" << m_id.to_string() + << " learning-mode:" << m_learning_mode.to_string() << "]"; + + return (s.str()); +} + +std::shared_ptr +bridge_domain::find(const key_t& key) +{ + return (m_db.find(key)); +} + +void +bridge_domain::update(const bridge_domain& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (rc_t::OK != m_id.rc()) { + HW::enqueue(new bridge_domain_cmds::create_cmd( + m_id, m_learning_mode, m_arp_term_mode, m_arp_ufwd_mode, m_flood_mode, + m_uu_flood_mode, m_mac_age_mode)); + } +} + +std::shared_ptr +bridge_domain::find_or_add(const bridge_domain& temp) +{ + return (m_db.find_or_add(temp.m_id.data(), temp)); +} + +std::shared_ptr +bridge_domain::singular() const +{ + return find_or_add(*this); +} + +void +bridge_domain::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +bridge_domain::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump VPP Bridge domains + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + bridge_domain bd( + payload.bd_id, + (payload.learn ? learning_mode_t::ON : learning_mode_t::OFF), + (payload.arp_term ? arp_term_mode_t::ON : arp_term_mode_t::OFF), + (payload.arp_ufwd ? arp_ufwd_mode_t::ON : arp_ufwd_mode_t::OFF), + (payload.flood ? flood_mode_t::ON : flood_mode_t::OFF), + (payload.uu_flood ? uu_flood_mode_t::ON : uu_flood_mode_t::OFF), + (payload.mac_age ? mac_age_mode_t::ON : mac_age_mode_t::OFF)); + + VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); + + /* + * Write each of the discovered bridge-domains into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, bd); + + std::shared_ptr uu_fwd_itf = + interface::find(payload.uu_fwd_sw_if_index); + if (uu_fwd_itf) { + l2_binding l2(*uu_fwd_itf, bd, + l2_binding::l2_port_type_t::L2_PORT_TYPE_UU_FWD); + OM::commit(key, l2); + } else { + VOM_LOG(log_level_t::ERROR) << "no uu-fwd interface:" + << payload.uu_fwd_sw_if_index; + } + + /** + * For each interface in the BD construct an l2_binding + */ + for (unsigned int ii = 0; ii < payload.n_sw_ifs; ii++) { + std::shared_ptr itf = + interface::find(payload.sw_if_details[ii].sw_if_index); + if (itf) { + l2_binding l2(*itf, bd); + OM::commit(key, l2); + } else { + VOM_LOG(log_level_t::ERROR) << "no interface:" + << payload.sw_if_details[ii].sw_if_index; + } + } + } +} + +bridge_domain::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "bd", "bridge" }, "Bridge Domains", this); +} + +void +bridge_domain::event_handler::handle_replay() +{ + m_db.replay(); +} + +dependency_t +bridge_domain::event_handler::order() const +{ + return (dependency_t::TABLE); +} + +void +bridge_domain::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bridge_domain.hpp b/extras/deprecated/vom/vom/bridge_domain.hpp new file mode 100644 index 00000000000..633ed15b0d4 --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain.hpp @@ -0,0 +1,306 @@ +/* + * 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_BRIDGE_DOMAIN_H__ +#define __VOM_BRIDGE_DOMAIN_H__ + +#include "vom/enum_base.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A base class for all object_base in the VPP object_base-Model. + * provides the abstract interface. + */ +class bridge_domain : public object_base +{ +public: + /** + * Key Type for Bridge Domains in the sigular DB + */ + typedef uint32_t key_t; + + /** + * Bridge Domain Learning mode + */ + struct learning_mode_t : enum_base + { + const static learning_mode_t ON; + const static learning_mode_t OFF; + + private: + /** + * Private constructor taking the value and the string name + */ + learning_mode_t(int v, const std::string& s); + }; + + /** + * Bridge Domain ARP termination mode + */ + struct arp_term_mode_t : enum_base + { + const static arp_term_mode_t ON; + const static arp_term_mode_t OFF; + + private: + /** + * Private constructor taking the value and the string name + */ + arp_term_mode_t(int v, const std::string& s); + }; + + /** + * Bridge Domain ARP Unicast Forward mode + */ + struct arp_ufwd_mode_t : enum_base + { + const static arp_ufwd_mode_t ON; + const static arp_ufwd_mode_t OFF; + + private: + /** + * Private constructor taking the value and the string name + */ + arp_ufwd_mode_t(int v, const std::string& s); + }; + + /** + * Bridge Domain MAC aging mode + */ + struct mac_age_mode_t : enum_base + { + const static mac_age_mode_t ON; + const static mac_age_mode_t OFF; + + private: + /** + * Private constructor taking the value and the string name + */ + mac_age_mode_t(int v, const std::string& s); + }; + + /** + * Bridge Domain flood mode + */ + struct flood_mode_t : enum_base + { + const static flood_mode_t ON; + const static flood_mode_t OFF; + + private: + /** + * Private constructor taking the value and the string name + */ + flood_mode_t(int v, const std::string& s); + }; + + /** + * Bridge Domain Unknown Unicast Flood mode + */ + struct uu_flood_mode_t : enum_base + { + const static uu_flood_mode_t ON; + const static uu_flood_mode_t OFF; + + private: + /** + * Private constructor taking the value and the string name + */ + uu_flood_mode_t(int v, const std::string& s); + }; + + /** + * The value of the defaultbridge domain + */ + const static uint32_t DEFAULT_TABLE = 0; + + /** + * Construct a new object matching the desried state + */ + bridge_domain(uint32_t id, + const learning_mode_t& lmode = learning_mode_t::ON, + const arp_term_mode_t& amode = arp_term_mode_t::ON, + const arp_ufwd_mode_t& aumode = arp_ufwd_mode_t::OFF, + const flood_mode_t& fmode = flood_mode_t::ON, + const uu_flood_mode_t& uufmode = uu_flood_mode_t::ON, + const mac_age_mode_t& mmode = mac_age_mode_t::OFF); + + /** + * Copy Constructor + */ + bridge_domain(const bridge_domain& o); + + /** + * Destructor + */ + ~bridge_domain(); + + /** + * Comparison operator - for UT + */ + bool operator==(const bridge_domain& b) const; + + /** + * Return the bridge domain's VPP ID + */ + uint32_t id() const; + + /** + * Return the bridge domain's key + */ + const key_t& key() const; + + /** + * Return the matchin 'singular' instance of the bridge-domain + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string(void) const; + + /** + * Static function to find the bridge_domain in the model + */ + static std::shared_ptr find(const key_t& key); + + /** + * Dump all bridge-doamin into the stream provided + */ + static void dump(std::ostream& os); + +private: + /** + * 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; + }; + + /** + * Instance of the event handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const bridge_domain& obj); + + /** + * Find or add an singular of a Bridge-Domain in the object_base Model + */ + static std::shared_ptr find_or_add(const bridge_domain& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * The ID we assign to this BD and the HW result in VPP + */ + HW::item m_id; + + /** + * The learning mode of the bridge + */ + learning_mode_t m_learning_mode; + + /** + * The ARP termination mode of the bridge + */ + arp_term_mode_t m_arp_term_mode; + + /** + * The ARP Unicast Forward mode of the bridge + */ + arp_ufwd_mode_t m_arp_ufwd_mode; + + /** + * The flood mode of the bridge + */ + flood_mode_t m_flood_mode; + + /** + * The unknown unicast flood mode of the bridge + */ + uu_flood_mode_t m_uu_flood_mode; + + /** + * The MAC aging mode of the bridge + */ + mac_age_mode_t m_mac_age_mode; + + /** + * A map of all interfaces key against the interface's name + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bridge_domain_arp_entry.cpp b/extras/deprecated/vom/vom/bridge_domain_arp_entry.cpp new file mode 100644 index 00000000000..699d35bfc3c --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_arp_entry.cpp @@ -0,0 +1,220 @@ +/* + * 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/bridge_domain_arp_entry.hpp" +#include "vom/api_types.hpp" +#include "vom/bridge_domain_arp_entry_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +singular_db + bridge_domain_arp_entry::m_db; + +bridge_domain_arp_entry::event_handler bridge_domain_arp_entry::m_evh; + +bridge_domain_arp_entry::bridge_domain_arp_entry( + const bridge_domain& bd, + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac) + : m_hw(false) + , m_bd(bd.singular()) + , m_ip_addr(ip_addr) + , m_mac(mac) +{ +} + +bridge_domain_arp_entry::bridge_domain_arp_entry( + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac) + : m_hw(false) + , m_bd(nullptr) + , m_ip_addr(ip_addr) + , m_mac(mac) +{ + /* + * the route goes in the default table + */ + bridge_domain bd(bridge_domain::DEFAULT_TABLE); + + m_bd = bd.singular(); +} + +bridge_domain_arp_entry::bridge_domain_arp_entry( + const bridge_domain_arp_entry& bde) + : m_hw(bde.m_hw) + , m_bd(bde.m_bd) + , m_ip_addr(bde.m_ip_addr) + , m_mac(bde.m_mac) +{ +} + +bridge_domain_arp_entry::~bridge_domain_arp_entry() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +const bridge_domain_arp_entry::key_t +bridge_domain_arp_entry::key() const +{ + return (std::make_pair(m_bd->key(), m_ip_addr)); +} + +bool +bridge_domain_arp_entry::operator==(const bridge_domain_arp_entry& bdae) const +{ + return ((key() == bdae.key()) && (m_mac == bdae.m_mac)); +} + +void +bridge_domain_arp_entry::sweep() +{ + if (m_hw) { + HW::enqueue(new bridge_domain_arp_entry_cmds::delete_cmd(m_hw, m_bd->id(), + m_mac, m_ip_addr)); + } + HW::write(); +} + +void +bridge_domain_arp_entry::replay() +{ + if (m_hw) { + HW::enqueue(new bridge_domain_arp_entry_cmds::create_cmd(m_hw, m_bd->id(), + m_mac, m_ip_addr)); + } +} + +std::string +bridge_domain_arp_entry::to_string() const +{ + std::ostringstream s; + s << "bridge-domain-arp-entry:[" << m_bd->to_string() << ", " + << m_mac.to_string() << ", " << m_ip_addr.to_string() << "]"; + + return (s.str()); +} + +void +bridge_domain_arp_entry::update(const bridge_domain_arp_entry& r) +{ + /* + * create the table if it is not yet created + */ + if (rc_t::OK != m_hw.rc()) { + HW::enqueue(new bridge_domain_arp_entry_cmds::create_cmd(m_hw, m_bd->id(), + m_mac, m_ip_addr)); + } +} + +std::shared_ptr +bridge_domain_arp_entry::find_or_add(const bridge_domain_arp_entry& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +bridge_domain_arp_entry::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +bridge_domain_arp_entry::singular() const +{ + return find_or_add(*this); +} + +void +bridge_domain_arp_entry::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +bridge_domain_arp_entry::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "bd-arp" }, + "bridge domain ARP termination entries", this); +} + +void +bridge_domain_arp_entry::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +bridge_domain_arp_entry::event_handler::handle_populate( + const client_db::key_t& key) +{ + /* + * dump VPP Bridge domains + */ + std::shared_ptr cmd = + std::make_shared(~0); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr bd = + bridge_domain::find(payload.entry.bd_id); + bridge_domain_arp_entry bd_ae(*bd, from_api(payload.entry.ip), + from_api(payload.entry.mac)); + + VOM_LOG(log_level_t::DEBUG) << "dump: " << bd_ae.to_string(); + + /* + * Write each of the discovered bridge-domain arp entry into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, bd_ae); + } +} + +dependency_t +bridge_domain_arp_entry::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +bridge_domain_arp_entry::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const bridge_domain_arp_entry::key_t& key) +{ + os << "[" << key.first << ", " << key.second << "]"; + + return (os); +} +} +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bridge_domain_arp_entry.hpp b/extras/deprecated/vom/vom/bridge_domain_arp_entry.hpp new file mode 100644 index 00000000000..ac1bcdb5668 --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_arp_entry.hpp @@ -0,0 +1,195 @@ +/* + * 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_BRIDGE_DOMAIN_ARP_ENTRY_H__ +#define __VOM_BRIDGE_DOMAIN_ARP_ENTRY_H__ + +#include "vom/bridge_domain.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" +#include "vom/types.hpp" + +namespace VOM { +/** + * A entry in the ARP termination table of a Bridge Domain + */ +class bridge_domain_arp_entry : public object_base +{ +public: + /** + * The key for a bridge_domain ARP entry; + * the BD, IP address and MAC address + */ + typedef std::pair key_t; + + /** + * Construct a bridge domain ARP Entry in the given bridge domain + */ + bridge_domain_arp_entry(const bridge_domain& bd, + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac); + + /** + * Construct a bridge domain ARP entry in the default table + */ + bridge_domain_arp_entry(const boost::asio::ip::address& ip_addr, + const mac_address_t& mac); + + /** + * Copy Construct + */ + bridge_domain_arp_entry(const bridge_domain_arp_entry& r); + + /** + * Destructor + */ + ~bridge_domain_arp_entry(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const bridge_domain_arp_entry& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const bridge_domain_arp_entry& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add( + const bridge_domain_arp_entry& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the bridge_domain + */ + HW::item m_hw; + + /** + * The bridge_domain domain the bridge_domain is in. + */ + std::shared_ptr m_bd; + + /** + * The IP address + */ + boost::asio::ip::address m_ip_addr; + + /** + * The mac to return + */ + mac_address_t m_mac; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, + const bridge_domain_arp_entry::key_t& key); +}; // namespace + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bridge_domain_arp_entry_cmds.cpp b/extras/deprecated/vom/vom/bridge_domain_arp_entry_cmds.cpp new file mode 100644 index 00000000000..fdfc45b7d9a --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_arp_entry_cmds.cpp @@ -0,0 +1,161 @@ +/* + * 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/bridge_domain_arp_entry_cmds.hpp" +#include "vom/api_types.hpp" + +namespace VOM { +namespace bridge_domain_arp_entry_cmds { + +create_cmd::create_cmd(HW::item& item, + uint32_t bd, + const mac_address_t& mac, + const boost::asio::ip::address& ip_addr) + : rpc_cmd(item) + , m_bd(bd) + , m_mac(mac) + , m_ip_addr(ip_addr) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_mac == other.m_mac) && (m_ip_addr == other.m_ip_addr) && + (m_bd == other.m_bd)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.entry.bd_id = m_bd; + payload.is_add = 1; + to_api(m_mac, payload.entry.mac); + to_api(m_ip_addr, payload.entry.ip); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "bridge-domain-arp-entry-create: " << m_hw_item.to_string() + << " bd:" << m_bd << " mac:" << m_mac.to_string() + << " ip:" << m_ip_addr.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + uint32_t bd, + const mac_address_t& mac, + const boost::asio::ip::address& ip_addr) + : rpc_cmd(item) + , m_bd(bd) + , m_mac(mac) + , m_ip_addr(ip_addr) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return ((m_mac == other.m_mac) && (m_ip_addr == other.m_ip_addr) && + (m_bd == other.m_bd)); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.entry.bd_id = m_bd; + payload.is_add = 0; + to_api(m_mac, payload.entry.mac); + to_api(m_ip_addr, payload.entry.ip); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "bridge-domain-arp-entry-delete: " << m_hw_item.to_string() + << " bd:" << m_bd << " mac:" << m_mac.to_string() + << " ip:" << m_ip_addr.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd(uint32_t bd_id) + : m_bd(bd_id) +{ +} + +dump_cmd::dump_cmd(const dump_cmd& d) + : m_bd(d.m_bd) +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.bd_id = m_bd; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("bridge-domain-arp-entry-dump"); +} + +}; // namespace bridge_domain_arp_entry +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bridge_domain_arp_entry_cmds.hpp b/extras/deprecated/vom/vom/bridge_domain_arp_entry_cmds.hpp new file mode 100644 index 00000000000..2c7b5e27043 --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_arp_entry_cmds.hpp @@ -0,0 +1,146 @@ +/* + * 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_BRIDGE_DOMAIN_ARP_ENTRY_CMDS_H__ +#define __VOM_BRIDGE_DOMAIN_ARP_ENTRY_CMDS_H__ + +#include "vom/bridge_domain_arp_entry.hpp" +#include "vom/dump_cmd.hpp" + +#include +#include + +namespace VOM { +namespace bridge_domain_arp_entry_cmds { + +/** +* A command class that creates or updates the bridge domain ARP Entry +*/ +class create_cmd : public rpc_cmd, vapi::Bd_ip_mac_add_del> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + uint32_t id, + const mac_address_t& mac, + const boost::asio::ip::address& ip_addr); + + /** + * 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; + +private: + uint32_t m_bd; + mac_address_t m_mac; + boost::asio::ip::address m_ip_addr; +}; + +/** + * A cmd class that deletes a bridge domain ARP entry + */ +class delete_cmd : public rpc_cmd, vapi::Bd_ip_mac_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, + uint32_t id, + const mac_address_t& mac, + const boost::asio::ip::address& ip_addr); + + /** + * 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: + uint32_t m_bd; + mac_address_t m_mac; + boost::asio::ip::address m_ip_addr; +}; + +/** + * A cmd class that Dumps all arp termination tables + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(uint32_t bd_id); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; + + /** + * The bd_id to get the arp termination table for + */ + uint32_t m_bd; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bridge_domain_cmds.cpp b/extras/deprecated/vom/vom/bridge_domain_cmds.cpp new file mode 100644 index 00000000000..00c554205bd --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_cmds.cpp @@ -0,0 +1,151 @@ +/* + * 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/bridge_domain_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_L2_API_JSON; + +namespace VOM { +namespace bridge_domain_cmds { +create_cmd::create_cmd(HW::item& item, + const bridge_domain::learning_mode_t& lmode, + const bridge_domain::arp_term_mode_t& amode, + const bridge_domain::arp_ufwd_mode_t& aumode, + const bridge_domain::flood_mode_t& fmode, + const bridge_domain::uu_flood_mode_t& uufmode, + const bridge_domain::mac_age_mode_t& mmode) + : rpc_cmd(item) + , m_learning_mode(lmode) + , m_arp_term_mode(amode) + , m_arp_ufwd_mode(aumode) + , m_flood_mode(fmode) + , m_uu_flood_mode(uufmode) + , m_mac_age_mode(mmode) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return (m_hw_item.data() == other.m_hw_item.data()); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.bd_id = m_hw_item.data(); + payload.flood = m_flood_mode.value(); + payload.uu_flood = m_uu_flood_mode.value(); + payload.forward = 1; + payload.learn = m_learning_mode.value(); + payload.arp_term = m_arp_term_mode.value(); + payload.arp_ufwd = m_arp_ufwd_mode.value(); + payload.mac_age = m_mac_age_mode.value(); + payload.is_add = 1; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "bridge-domain-create: " << m_hw_item.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item) + : rpc_cmd(item) +{ +} + +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)); + + auto& payload = req.get_request().get_payload(); + payload.bd_id = m_hw_item.data(); + payload.is_add = 0; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return (rc_t::OK); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "bridge-domain-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.bd_id = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("bridge-domain-dump"); +} +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bridge_domain_cmds.hpp b/extras/deprecated/vom/vom/bridge_domain_cmds.hpp new file mode 100644 index 00000000000..2cb3bc8fe7f --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_cmds.hpp @@ -0,0 +1,156 @@ +/* + * 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_BRIDGE_DOMAIN_CMDS_H__ +#define __VOM_BRIDGE_DOMAIN_CMDS_H__ + +#include "vom/bridge_domain.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace bridge_domain_cmds { +/** + * A command class that creates an Bridge-Domain + */ +class create_cmd + : public rpc_cmd, vapi::Bridge_domain_add_del> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + const bridge_domain::learning_mode_t& lmode, + const bridge_domain::arp_term_mode_t& amode, + const bridge_domain::arp_ufwd_mode_t& aumode, + const bridge_domain::flood_mode_t& fmode, + const bridge_domain::uu_flood_mode_t& uufmode, + const bridge_domain::mac_age_mode_t& mmode); + + /** + * 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; + +private: + /** + * the learning mode for the bridge + */ + bridge_domain::learning_mode_t m_learning_mode; + /** + * the learning mode for the bridge + */ + bridge_domain::arp_term_mode_t m_arp_term_mode; + /** + * the learning mode for the bridge + */ + bridge_domain::arp_ufwd_mode_t m_arp_ufwd_mode; + /** + * the flood mode for the bridge + */ + bridge_domain::flood_mode_t m_flood_mode; + /** + * the unknown unicast flood mode for the bridge + */ + bridge_domain::uu_flood_mode_t m_uu_flood_mode; + /** + * the flood mode for the bridge + */ + bridge_domain::mac_age_mode_t m_mac_age_mode; +}; + +/** + * A cmd class that Delete an Bridge-Domain + */ +class delete_cmd + : public rpc_cmd, vapi::Bridge_domain_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item); + + /** + * 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; +}; + +/** + * A cmd class that Dumps all the bridge domains + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bridge_domain_entry.cpp b/extras/deprecated/vom/vom/bridge_domain_entry.cpp new file mode 100644 index 00000000000..6c837f5dc9f --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_entry.cpp @@ -0,0 +1,224 @@ +/* + * 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/bridge_domain_entry.hpp" +#include "vom/bridge_domain_entry_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +singular_db + bridge_domain_entry::m_db; + +bridge_domain_entry::event_handler bridge_domain_entry::m_evh; + +bridge_domain_entry::bridge_domain_entry(const bridge_domain& bd, + const mac_address_t& mac, + const interface& tx_itf) + : m_hw(false) + , m_mac(mac) + , m_bd(bd.singular()) + , m_tx_itf(tx_itf.singular()) +{ +} + +bridge_domain_entry::bridge_domain_entry(const mac_address_t& mac, + const interface& tx_itf) + : m_hw(false) + , m_mac(mac) + , m_bd(nullptr) + , m_tx_itf(tx_itf.singular()) +{ + /* + * the entry goes in the default bridge-domain + */ + bridge_domain bd(bridge_domain::DEFAULT_TABLE); + + m_bd = bd.singular(); +} + +bridge_domain_entry::bridge_domain_entry(const bridge_domain_entry& bde) + : m_hw(bde.m_hw) + , m_mac(bde.m_mac) + , m_bd(bde.m_bd) + , m_tx_itf(bde.m_tx_itf) +{ +} + +const bridge_domain_entry::key_t +bridge_domain_entry::key() const +{ + return (std::make_pair(m_bd->key(), m_mac)); +} + +bool +bridge_domain_entry::operator==(const bridge_domain_entry& bde) const +{ + return ((key() == bde.key()) && (m_tx_itf == bde.m_tx_itf)); +} + +bridge_domain_entry::~bridge_domain_entry() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +void +bridge_domain_entry::sweep() +{ + if (m_hw) { + HW::enqueue(new bridge_domain_entry_cmds::delete_cmd( + m_hw, m_mac, m_bd->id(), interface::type_t::BVI == m_tx_itf->type())); + } + HW::write(); +} + +void +bridge_domain_entry::replay() +{ + if (m_hw) { + HW::enqueue(new bridge_domain_entry_cmds::create_cmd( + m_hw, m_mac, m_bd->id(), m_tx_itf->handle(), + interface::type_t::BVI == m_tx_itf->type())); + } +} +std::string +bridge_domain_entry::to_string() const +{ + std::ostringstream s; + s << "bridge-domain-entry:[" << m_bd->to_string() << ", " << m_mac.to_string() + << ", tx:" << m_tx_itf->name() << "]"; + + return (s.str()); +} + +void +bridge_domain_entry::update(const bridge_domain_entry& r) +{ + /* + * create the table if it is not yet created + */ + if (rc_t::OK != m_hw.rc()) { + HW::enqueue(new bridge_domain_entry_cmds::create_cmd( + m_hw, m_mac, m_bd->id(), m_tx_itf->handle(), + interface::type_t::BVI == m_tx_itf->type())); + } +} + +std::shared_ptr +bridge_domain_entry::find_or_add(const bridge_domain_entry& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +bridge_domain_entry::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +bridge_domain_entry::singular() const +{ + return find_or_add(*this); +} + +void +bridge_domain_entry::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +bridge_domain_entry::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "bd-entry" }, + "bridge domain entry configurations", this); +} + +void +bridge_domain_entry::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +bridge_domain_entry::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = interface::find(payload.sw_if_index); + std::shared_ptr bd = bridge_domain::find(payload.bd_id); + + if (!bd || !itf) { + VOM_LOG(log_level_t::ERROR) << "bridge-domain-entry dump:" + << " itf:" << payload.sw_if_index + << " bd:" << payload.bd_id; + continue; + } + + mac_address_t mac(payload.mac); + bridge_domain_entry bd_e(*bd, mac, *itf); + + VOM_LOG(log_level_t::DEBUG) << "bridge-domain-entry dump:" + << " " << bd->to_string() << " " + << itf->to_string() << " mac:[" + << mac.to_string() << "]"; + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, bd_e); + } +} + +dependency_t +bridge_domain_entry::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +bridge_domain_entry::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const bridge_domain_entry::key_t& key) +{ + os << "[" << key.first << ", " << key.second.to_string() << "]"; + + return (os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bridge_domain_entry.hpp b/extras/deprecated/vom/vom/bridge_domain_entry.hpp new file mode 100644 index 00000000000..68a3459c824 --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_entry.hpp @@ -0,0 +1,192 @@ +/* + * 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_BRIDGE_DOMAIN_ENTRY_H__ +#define __VOM_BRIDGE_DOMAIN_ENTRY_H__ + +#include "vom/bridge_domain.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A MAC forwarding entry in the bridge-domain/L2-FIB + */ +class bridge_domain_entry : public object_base +{ +public: + /** + * The key for a bridge_domain + */ + typedef std::pair key_t; + + /** + * Construct a bridge_domain in the given bridge domain + */ + bridge_domain_entry(const bridge_domain& bd, + const mac_address_t& mac, + const interface& tx_itf); + + /** + * Construct a bridge_domain in the default table + */ + bridge_domain_entry(const mac_address_t& mac, const interface& tx_itf); + + /** + * Copy Construct + */ + bridge_domain_entry(const bridge_domain_entry& r); + + /** + * Destructor + */ + ~bridge_domain_entry(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const bridge_domain_entry& be) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const bridge_domain_entry& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add( + const bridge_domain_entry& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the bridge_domain + */ + HW::item m_hw; + + /** + * The mac to match + */ + mac_address_t m_mac; + + /** + * The bridge_domain domain the bridge_domain is in. + */ + std::shared_ptr m_bd; + + /** + * The set of paths + */ + std::shared_ptr m_tx_itf; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, + const bridge_domain_entry::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/bridge_domain_entry_cmds.cpp b/extras/deprecated/vom/vom/bridge_domain_entry_cmds.cpp new file mode 100644 index 00000000000..885a5578f12 --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_entry_cmds.cpp @@ -0,0 +1,155 @@ +/* + * 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/bridge_domain_entry_cmds.hpp" + +namespace VOM { +namespace bridge_domain_entry_cmds { +create_cmd::create_cmd(HW::item& item, + const mac_address_t& mac, + uint32_t bd, + handle_t tx_itf, + bool is_bvi) + : rpc_cmd(item) + , m_mac(mac) + , m_bd(bd) + , m_tx_itf(tx_itf) + , m_is_bvi(is_bvi) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_mac == other.m_mac) && (m_tx_itf == other.m_tx_itf) && + (m_bd == other.m_bd) && (m_is_bvi == other.m_is_bvi)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.bd_id = m_bd; + payload.is_add = 1; + m_mac.to_bytes(payload.mac, 6); + payload.sw_if_index = m_tx_itf.value(); + payload.bvi_mac = m_is_bvi; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "bridge-domain-entry-create: " << m_hw_item.to_string() << " bd:" << m_bd + << " mac:" << m_mac.to_string() << " tx:" << m_tx_itf + << " bvi:" << m_is_bvi; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + const mac_address_t& mac, + uint32_t bd, + bool is_bvi) + : rpc_cmd(item) + , m_mac(mac) + , m_bd(bd) + , m_is_bvi(is_bvi) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return ((m_mac == other.m_mac) && (m_bd == other.m_bd) && + (m_is_bvi == other.m_is_bvi)); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.bd_id = m_bd; + payload.is_add = 0; + m_mac.to_bytes(payload.mac, 6); + payload.sw_if_index = ~0; + payload.bvi_mac = m_is_bvi; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "bridge-domain-entry-delete: " << m_hw_item.to_string() << " bd:" << m_bd + << " mac:" << m_mac.to_string() << " bvi:" << m_is_bvi; + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.bd_id = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("bridge-domain-entry-dump"); +} +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/bridge_domain_entry_cmds.hpp b/extras/deprecated/vom/vom/bridge_domain_entry_cmds.hpp new file mode 100644 index 00000000000..88bb4e1ec49 --- /dev/null +++ b/extras/deprecated/vom/vom/bridge_domain_entry_cmds.hpp @@ -0,0 +1,143 @@ +/* + * 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_BRIDGE_DOMAIN_ENTRY_CMDS_H__ +#define __VOM_BRIDGE_DOMAIN_ENTRY_CMDS_H__ + +#include "vom/bridge_domain_entry.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace bridge_domain_entry_cmds { + +/** +* A command class that creates or updates the bridge_domain +*/ +class create_cmd : public rpc_cmd, vapi::L2fib_add_del> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + const mac_address_t& mac, + uint32_t id, + handle_t tx_intf, + bool is_bvi); + + /** + * 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; + +private: + mac_address_t m_mac; + uint32_t m_bd; + handle_t m_tx_itf; + bool m_is_bvi; +}; + +/** + * A cmd class that deletes a bridge_domain + */ +class delete_cmd : public rpc_cmd, vapi::L2fib_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, + const mac_address_t& mac, + uint32_t id, + bool is_bvi); + + /** + * 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: + mac_address_t m_mac; + uint32_t m_bd; + bool m_is_bvi; +}; + +/** + * A cmd class that Dumps all the interface spans + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/client_db.cpp b/extras/deprecated/vom/vom/client_db.cpp new file mode 100644 index 00000000000..b7dcd0114a4 --- /dev/null +++ b/extras/deprecated/vom/vom/client_db.cpp @@ -0,0 +1,59 @@ +/* + * 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/client_db.hpp" + +namespace VOM { +object_ref_list& +client_db::find(const client_db::key_t& k) +{ + return (m_objs[k]); +} + +void +client_db::flush(const client_db::key_t& k) +{ + auto found = m_objs.find(k); + + if (found != m_objs.end()) + m_objs.erase(found); +} + +void +client_db::dump(const key_t& key, std::ostream& os) +{ + object_ref_list& orlist = find(key); + + for (auto entry : orlist) { + os << " " << entry.obj()->to_string() << std::endl; + } +} + +void +client_db::dump(std::ostream& os) +{ + for (auto entry : m_objs) { + os << " key:[" << entry.first << "]" << std::endl; + } +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/client_db.hpp b/extras/deprecated/vom/vom/client_db.hpp new file mode 100644 index 00000000000..553b9420195 --- /dev/null +++ b/extras/deprecated/vom/vom/client_db.hpp @@ -0,0 +1,89 @@ +/* + * 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_KEY_DB_H__ +#define __VOM_KEY_DB_H__ + +#include +#include + +#include "vom/object_base.hpp" + +namespace VOM { +/** + * A convenitent typedef for set of objects owned. + * A set of shared pointers. This is how the reference counting + * of an object in the model it managed. Once all these shared ptr + * and hence references are gone, the object is deleted and any state + * in VPP is removed. + */ +typedef std::set object_ref_list; + +/** + * A DB storing the objects that each owner/key owns. + * Each object is reference counter by each key that owns it. When + * no more references exist the object is destroyed. + */ +class client_db +{ +public: + /** + * In the opflex world each entity is known by a URI which can be + * converted + * into a string. We use the string type, since it allows us to keep + * this VPP + * specific code independent of opflex types. I might consider making + * this + * a template parameter one day... + */ + typedef const std::string key_t; + + /** + * Find the objects owned by the key + */ + object_ref_list& find(const key_t& k); + + /** + * flush, i.e. un-reference, all objects owned by the key + */ + void flush(const key_t& k); + + /** + * Print each of the object in the DB into the stream provided + */ + void dump(const key_t& key, std::ostream& os); + + /** + * Print each KEY + */ + void dump(std::ostream& os); + +private: + /** + * A map of keys versus the object they reference + */ + std::map m_objs; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/cmd.cpp b/extras/deprecated/vom/vom/cmd.cpp new file mode 100644 index 00000000000..846854b5807 --- /dev/null +++ b/extras/deprecated/vom/vom/cmd.cpp @@ -0,0 +1,37 @@ +/* + * 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/cmd.hpp" + +namespace VOM { +/** + * Free ostream function to print a command + */ +std::ostream& +operator<<(std::ostream& os, const cmd& cmd) +{ + os << cmd.to_string(); + + return (os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/cmd.hpp b/extras/deprecated/vom/vom/cmd.hpp new file mode 100644 index 00000000000..b95de41095e --- /dev/null +++ b/extras/deprecated/vom/vom/cmd.hpp @@ -0,0 +1,80 @@ +/* + * 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_CMD_H__ +#define __VOM_CMD_H__ + +#include + +#include "vom/types.hpp" + +namespace VOM { +/** + * Forward declaration of the connection class + */ +class connection; + +/** + * A representation of a method call to VPP + */ +class cmd +{ +public: + /** + * Default constructor + */ + cmd() {} + /** + * Virtual destructor + */ + virtual ~cmd() {} + + /** + * Issue the command to VPP/HW + */ + virtual rc_t issue(connection& con) = 0; + + /** + * Retire/cancel a long running command + */ + virtual void retire(connection& con) = 0; + + /** + * Invoked on a Command when the HW queue is disabled to indicate + * that the commnad can be considered successful + */ + virtual void succeeded() = 0; + + /** + * convert to string format for debug purposes + */ + virtual std::string to_string() const = 0; +}; + +/** + * Free ostream function to print a command + */ +std::ostream& operator<<(std::ostream& os, const cmd& cmd); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/connection.cpp b/extras/deprecated/vom/vom/connection.cpp new file mode 100644 index 00000000000..3de44eaa0ce --- /dev/null +++ b/extras/deprecated/vom/vom/connection.cpp @@ -0,0 +1,61 @@ +/* + * 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 + +#include "vom/connection.hpp" + +namespace VOM { +connection::connection() + : m_vapi_conn(new vapi::Connection()) + , m_app_name("VOM") +{ +} + +connection::~connection() +{ +} + +void +connection::disconnect() +{ + m_vapi_conn->disconnect(); +} + +int +connection::connect() +{ + vapi_error_e rv; + + rv = m_vapi_conn->connect(m_app_name.c_str(), + NULL, // m_api_prefix.c_str(), + 128, 128); + return rv; +} + +vapi::Connection& +connection::ctx() +{ + return (*m_vapi_conn); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/connection.hpp b/extras/deprecated/vom/vom/connection.hpp new file mode 100644 index 00000000000..26b7d184596 --- /dev/null +++ b/extras/deprecated/vom/vom/connection.hpp @@ -0,0 +1,82 @@ +/* + * 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_CONNECTION_H__ +#define __VOM_CONNECTION_H__ + +#include +#include + +/** + * Forward declarations + */ +namespace vapi { +class Connection; +}; + +namespace VOM { +/** + * A representation of the connection to VPP + */ +class connection +{ +public: + /** + * Constructor + */ + connection(); + /** + * Destructor + */ + ~connection(); + + /** + * Blocking [re]connect call - always eventually succeeds, or the + * universe expires. Not much this system can do without one. + */ + int connect(); + + /** + * Blocking disconnect + */ + void disconnect(); + + /** + * Retrun the VAPI context the commands will use + */ + vapi::Connection& ctx(); + +private: + /** + * The VAPI connection context + */ + std::unique_ptr m_vapi_conn; + + /** + * The name of this application + */ + const std::string m_app_name; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/dhcp_client.cpp b/extras/deprecated/vom/vom/dhcp_client.cpp new file mode 100644 index 00000000000..1c1dd819fc0 --- /dev/null +++ b/extras/deprecated/vom/vom/dhcp_client.cpp @@ -0,0 +1,355 @@ +/* + * 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/dhcp_client.hpp" +#include "vom/dhcp_client_cmds.hpp" +#include "vom/route_api_types.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +const dhcp_client::state_t dhcp_client::state_t::DISCOVER(0, "discover"); +const dhcp_client::state_t dhcp_client::state_t::REQUEST(1, "request"); +const dhcp_client::state_t dhcp_client::state_t::BOUND(2, "bound"); + +dhcp_client::state_t::state_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const dhcp_client::state_t& +dhcp_client::state_t::from_vpp(int n) +{ + if (REQUEST == n) + return (REQUEST); + if (BOUND == n) + return (BOUND); + + return (DISCOVER); +} + +singular_db dhcp_client::m_db; +std::weak_ptr dhcp_client::m_s_event_cmd; +dhcp_client::dhcp_client_listener dhcp_client::m_listener; + +dhcp_client::event_handler dhcp_client::m_evh; + +dhcp_client::dhcp_client(const interface& itf, + const std::string& hostname, + bool set_broadcast_flag, + const ip_dscp_t& dscp, + event_listener* ev) + : m_itf(itf.singular()) + , m_hostname(hostname) + , m_client_id(l2_address_t::ZERO) + , m_set_broadcast_flag(set_broadcast_flag) + , m_dscp(dscp) + , m_binding(0) + , m_evl(ev) + , m_event_cmd(get_event_cmd()) +{ +} + +dhcp_client::dhcp_client(const interface& itf, + const std::string& hostname, + const l2_address_t& client_id, + bool set_broadcast_flag, + const ip_dscp_t& dscp, + event_listener* ev) + : m_itf(itf.singular()) + , m_hostname(hostname) + , m_client_id(client_id) + , m_set_broadcast_flag(set_broadcast_flag) + , m_dscp(dscp) + , m_binding(0) + , m_evl(ev) + , m_event_cmd(get_event_cmd()) +{ +} + +dhcp_client::dhcp_client(const dhcp_client& o) + : m_itf(o.m_itf) + , m_hostname(o.m_hostname) + , m_client_id(o.m_client_id) + , m_set_broadcast_flag(o.m_set_broadcast_flag) + , m_dscp(o.m_dscp) + , m_binding(0) + , m_evl(o.m_evl) + , m_event_cmd(o.m_event_cmd) +{ +} + +dhcp_client::~dhcp_client() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_itf->key(), this); +} + +bool +dhcp_client::operator==(const dhcp_client& l) const +{ + return ((key() == l.key()) && (m_hostname == l.m_hostname) && + (m_client_id == l.m_client_id && m_dscp == l.m_dscp)); +} + +const dhcp_client::key_t& +dhcp_client::key() const +{ + return (m_itf->key()); +} + +void +dhcp_client::sweep() +{ + if (m_binding) { + HW::enqueue( + new dhcp_client_cmds::unbind_cmd(m_binding, m_itf->handle(), m_hostname)); + } + HW::write(); +} + +void +dhcp_client::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +dhcp_client::replay() +{ + if (m_binding) { + HW::enqueue(new dhcp_client_cmds::bind_cmd( + m_binding, m_itf->handle(), m_hostname, m_client_id, false, m_dscp)); + } +} + +std::string +dhcp_client::to_string() const +{ + std::ostringstream s; + s << "DHCP-client: " << m_itf->to_string() << " hostname:" << m_hostname + << " client_id:[" << m_client_id << "] " + << "dscp:" << m_dscp.to_string() << " " << m_binding.to_string(); + if (m_lease) + s << " " << m_lease->to_string(); + else + s << " no-lease"; + + return (s.str()); +} + +void +dhcp_client::update(const dhcp_client& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (!m_binding) { + HW::enqueue(new dhcp_client_cmds::bind_cmd( + m_binding, m_itf->handle(), m_hostname, m_client_id, false, m_dscp)); + } + + if (desired.m_lease) + m_lease = desired.m_lease; + if (m_evl != desired.m_evl) { + m_evl = desired.m_evl; + } +} + +const std::shared_ptr +dhcp_client::lease() const +{ + return (m_lease); +} + +void +dhcp_client::lease(std::shared_ptr lease) +{ + m_lease = lease; +} + +std::shared_ptr +dhcp_client::find_or_add(const dhcp_client& temp) +{ + return (m_db.find_or_add(temp.m_itf->key(), temp)); +} + +std::shared_ptr +dhcp_client::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +dhcp_client::singular() const +{ + return find_or_add(*this); +} + +dhcp_client::lease_t::lease_t() + : state(state_t::DISCOVER) + , mac(mac_address_t::ZERO) +{ +} + +dhcp_client::lease_t::lease_t(const state_t& state, + std::shared_ptr itf, + const boost::asio::ip::address& router_address, + const route::prefix_t& host_prefix, + const std::string& hostname, + const mac_address_t& mac) + : state(state) + , itf(itf) + , router_address(router_address) + , host_prefix(host_prefix) + , hostname(hostname) + , mac(mac) +{ +} + +std::string +dhcp_client::lease_t::to_string() const +{ + std::stringstream ss; + + ss << "lease:[" << itf->to_string() << " state: " << state.to_string() + << " host: " << host_prefix.to_string() << " router: " << router_address + << " mac: " << mac.to_string() << "]"; + + return (ss.str()); +} + +dhcp_client::event_listener::event_listener() + : m_status(rc_t::NOOP) +{ +} + +HW::item& +dhcp_client::event_listener::status() +{ + return (m_status); +} + +dhcp_client::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "dhcp" }, "DHCP clients", this); +} + +void +dhcp_client::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +dhcp_client::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = + interface::find(payload.client.sw_if_index); + + if (!itf) { + VOM_LOG(log_level_t::ERROR) << "dhcp-client dump:" + << " itf:" << payload.client.sw_if_index; + continue; + } + + const dhcp_client::state_t& s = + dhcp_client::state_t::from_vpp(payload.lease.state); + route::prefix_t pfx(payload.lease.is_ipv6, + (uint8_t*)&payload.lease.host_address.un, + payload.lease.mask_width); + std::string hostname = + reinterpret_cast(payload.lease.hostname); + l2_address_t l2(payload.client.id + 1); + dhcp_client dc(*itf, hostname, l2, payload.client.set_broadcast_flag, + from_api(payload.client.dscp)); + dc.lease(std::make_shared( + s, itf, from_bytes(0, (uint8_t*)&payload.lease.router_address.un), pfx, + hostname, mac_address_t(payload.lease.host_mac))); + OM::commit(key, dc); + } +} + +dependency_t +dhcp_client::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +dhcp_client::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::shared_ptr +dhcp_client::get_event_cmd() +{ + if (m_s_event_cmd.expired()) { + std::shared_ptr c = + std::make_shared(m_listener); + + m_s_event_cmd = c; + + HW::enqueue(c); + HW::write(); + + return c; + } + + return (m_s_event_cmd.lock()); +} + +void +dhcp_client::handle_dhcp_event(std::shared_ptr lease) +{ + m_lease = lease; + if (m_evl) + m_evl->handle_dhcp_event(m_lease); +} + +void +dhcp_client::dhcp_client_listener::handle_dhcp_event(std::shared_ptr e) +{ + /* + * Find the client the event references + */ + std::shared_ptr client = find(e->itf->key()); + + if (client) { + client->handle_dhcp_event(e); + } +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/dhcp_client.hpp b/extras/deprecated/vom/vom/dhcp_client.hpp new file mode 100644 index 00000000000..8eccb9ac23f --- /dev/null +++ b/extras/deprecated/vom/vom/dhcp_client.hpp @@ -0,0 +1,317 @@ +/* + * 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_DHCP_CLIENT_H__ +#define __VOM_DHCP_CLIENT_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/prefix.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +namespace dhcp_client_cmds { +class events_cmd; +}; +/** + * A representation of DHCP client on an interface + */ +class dhcp_client : public object_base +{ +public: + /** + * typedef for the DHCP client key type + */ + typedef interface::key_t key_t; + + struct state_t : enum_base + { + const static state_t DISCOVER; + const static state_t REQUEST; + const static state_t BOUND; + + static const state_t& from_vpp(int i); + + private: + /** + * Private constructor taking the value and the string name + */ + state_t(int v, const std::string& s); + }; + + /** + * A DHCP lease data + */ + struct lease_t + { + lease_t(); + lease_t(const state_t& state, + std::shared_ptr itf, + const boost::asio::ip::address& router_address, + const route::prefix_t& host_prefix, + const std::string& hostname, + const mac_address_t& mac); + + std::string to_string() const; + + const state_t& state; + std::shared_ptr itf; + boost::asio::ip::address router_address; + route::prefix_t host_prefix; + std::string hostname; + mac_address_t mac; + }; + + /** + * A class that listens to DHCP Events + */ + class event_listener + { + public: + /** + * Constructor + */ + event_listener(); + + /** + * listener's virtual function invoked when a DHCP event is + * available to read + */ + virtual void handle_dhcp_event(std::shared_ptr e) = 0; + + /** + * Return the HW::item associated with this command + */ + HW::item& status(); + + protected: + /** + * The HW::item associated with this command + */ + HW::item m_status; + }; + + /** + * Construct a new object matching the desried state + */ + dhcp_client(const interface& itf, + const std::string& hostname, + bool set_broadcast_flag = true, + const ip_dscp_t& dscp = ip_dscp_t::DSCP_CS0, + event_listener* ev = nullptr); + + /** + * Construct a new object matching the desried state + */ + dhcp_client(const interface& itf, + const std::string& hostname, + const l2_address_t& client_id, + bool set_broadcast_flag = true, + const ip_dscp_t& dscp = ip_dscp_t::DSCP_CS0, + event_listener* ev = nullptr); + + /** + * Copy Constructor + */ + dhcp_client(const dhcp_client& o); + + /** + * Destructor + */ + ~dhcp_client(); + + /** + * Comparison operator - for UT + */ + bool operator==(const dhcp_client& d) const; + + /** + * Return the object's key + */ + const key_t& key() const; + + /** + * Return the 'singular' of the DHCP client that matches this object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all DHCP clients into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Find a DHCP client from its key + */ + static std::shared_ptr find(const key_t& k); + + /** + * return the current lease data + */ + const std::shared_ptr lease() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const dhcp_client& obj); + + /** + * Find or add DHCP client to the OM + */ + static std::shared_ptr find_or_add(const dhcp_client& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + void lease(std::shared_ptr l); + + /** + * A reference counting pointer to the interface on which DHCP client + * resides. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * The hostname in the DHCP client + */ + const std::string m_hostname; + + /** + * The option-61 client_id in the DHCP client + */ + const l2_address_t m_client_id; + + /** + * Flag to control the setting the of DHCP discover's broadcast flag + */ + const bool m_set_broadcast_flag; + + /** + * DSCP setting for generated IP packets + */ + const ip_dscp_t m_dscp; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A pointer to an event listener for client events + */ + event_listener* m_evl; + + /** + * Current lease state for this client + */ + std::shared_ptr m_lease; + + std::shared_ptr m_event_cmd; + + void handle_dhcp_event(std::shared_ptr e); + + /** + * A map of all Dhcp clients keyed against the interface. + */ + static singular_db m_db; + + static std::weak_ptr m_s_event_cmd; + static std::shared_ptr get_event_cmd(); + + class dhcp_client_listener : public event_listener + { + public: + /** + * listener's virtual function invoked when a DHCP event is + * available to read + */ + void handle_dhcp_event(std::shared_ptr e); + }; + static dhcp_client_listener m_listener; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/dhcp_client_cmds.cpp b/extras/deprecated/vom/vom/dhcp_client_cmds.cpp new file mode 100644 index 00000000000..f26ad6ecf1e --- /dev/null +++ b/extras/deprecated/vom/vom/dhcp_client_cmds.cpp @@ -0,0 +1,242 @@ +/* + * 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/dhcp_client_cmds.hpp" +#include "vom/route_api_types.hpp" + +DEFINE_VAPI_MSG_IDS_DHCP_API_JSON; + +namespace VOM { +namespace dhcp_client_cmds { + +bind_cmd::bind_cmd(HW::item& item, + const handle_t& itf, + const std::string& hostname, + const l2_address_t& client_id, + bool set_broadcast_flag, + const ip_dscp_t& dscp) + : rpc_cmd(item) + , m_itf(itf) + , m_hostname(hostname) + , m_client_id(client_id) + , m_set_broadcast_flag(set_broadcast_flag) + , m_dscp(dscp) +{ +} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_hostname == other.m_hostname)); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.client.sw_if_index = m_itf.value(); + payload.client.pid = getpid(); + payload.client.want_dhcp_event = 1; + payload.client.set_broadcast_flag = m_set_broadcast_flag; + payload.client.dscp = to_api(m_dscp); + + memset(payload.client.hostname, 0, sizeof(payload.client.hostname)); + memcpy(payload.client.hostname, m_hostname.c_str(), + std::min(sizeof(payload.client.hostname), m_hostname.length())); + + memset(payload.client.id, 0, sizeof(payload.client.id)); + payload.client.id[0] = 1; + std::copy_n(begin(m_client_id.bytes), + std::min(sizeof(payload.client.id), m_client_id.bytes.size()), + payload.client.id + 1); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "Dhcp-client-bind: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string() << " hostname:" << m_hostname + << " client_id:[" << m_client_id << "] " + << "dscp:" << m_dscp.to_string(); + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, + const handle_t& itf, + const std::string& hostname) + : rpc_cmd(item) + , m_itf(itf) + , m_hostname(hostname) +{ +} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_hostname == other.m_hostname)); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.client.sw_if_index = m_itf.value(); + payload.client.pid = getpid(); + payload.client.want_dhcp_event = 0; + + memcpy(payload.client.hostname, m_hostname.c_str(), + std::min(sizeof(payload.client.hostname), m_hostname.length())); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "Dhcp-client-unbind: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string() << " hostname:" << m_hostname; + + return (s.str()); +} + +events_cmd::events_cmd(dhcp_client::event_listener& el) + : event_cmd(el.status()) + , m_listener(el) +{ +} + +events_cmd::~events_cmd() +{ + VOM_LOG(log_level_t::INFO) << "DHCP events destroyed"; +} + +bool +events_cmd::operator==(const events_cmd& other) const +{ + return (true); +} + +rc_t +events_cmd::issue(connection& con) +{ + /* + * Set the call back to handle DHCP complete envets. + */ + m_reg.reset(new reg_t(con.ctx(), std::ref(*this))); + + /* + * return in-progress so the command stays in the pending list. + */ + return (rc_t::OK); +} + +void +events_cmd::retire(connection& con) +{ +} + +void +events_cmd::notify() +{ + for (auto& msg : *this) { + auto& payload = msg.get_payload(); + + const dhcp_client::state_t& s = + dhcp_client::state_t::from_vpp(payload.lease.state); + route::prefix_t pfx(payload.lease.is_ipv6, + (uint8_t*)&payload.lease.host_address.un, + payload.lease.mask_width); + std::shared_ptr itf = interface::find(payload.lease.sw_if_index); + + if (itf) { + std::shared_ptr ev = + std::make_shared( + s, itf, from_bytes(0, (uint8_t*)&payload.lease.router_address.un), + pfx, reinterpret_cast(payload.lease.hostname), + mac_address_t(payload.lease.host_mac)); + m_listener.handle_dhcp_event(ev); + + VOM_LOG(log_level_t::INFO) << "DHCP: " << ev->to_string(); + } else { + VOM_LOG(log_level_t::ERROR) << "DHCP: no interface: " + << payload.lease.sw_if_index; + } + } + + flush(); +} + +std::string +events_cmd::to_string() const +{ + return ("dhcp-events"); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("dhcp-client-dump"); +} + +}; // namespace dhcp_client_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/dhcp_client_cmds.hpp b/extras/deprecated/vom/vom/dhcp_client_cmds.hpp new file mode 100644 index 00000000000..5ee05fc0e24 --- /dev/null +++ b/extras/deprecated/vom/vom/dhcp_client_cmds.hpp @@ -0,0 +1,213 @@ +/* + * 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_DHCP_CLIENT_CMDS_H__ +#define __VOM_DHCP_CLIENT_CMDS_H__ + +#include "vom/dhcp_client.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/event_cmd.hpp" + +#include +#include + +namespace VOM { +namespace dhcp_client_cmds { + +/** + * A command class that binds the DHCP config to the interface + */ +class bind_cmd : public rpc_cmd, vapi::Dhcp_client_config> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, + const handle_t& itf, + const std::string& hostname, + const l2_address_t& client_id, + bool set_braodcast_flag, + const ip_dscp_t& dscp); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to bind + */ + const handle_t& m_itf; + + /** + * The DHCP client's hostname + */ + const std::string m_hostname; + + /** + * The DHCP client's ID + */ + const l2_address_t m_client_id; + + /** + * Flag to control the setting the of DHCP discover's broadcast flag + */ + const bool m_set_broadcast_flag; + + /** + * DSCP bits + */ + const ip_dscp_t& m_dscp; +}; + +/** + * A cmd class that Unbinds Dhcp Config from an interface + */ +class unbind_cmd : public rpc_cmd, vapi::Dhcp_client_config> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, + const handle_t& itf, + const std::string& hostname); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to unbind + */ + const handle_t& m_itf; + + /** + * The DHCP client's hostname + */ + const std::string m_hostname; +}; + +/** + * A functor class represents our desire to recieve interface events + */ +class events_cmd : public event_cmd +{ +public: + /** + * Constructor + */ + events_cmd(dhcp_client::event_listener& el); + ~events_cmd(); + + /** + * Issue the command to VPP/HW - subscribe to DHCP events + */ + rc_t issue(connection& con); + + /** + * Retire the command - unsubscribe + */ + void retire(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Comparison operator - only used for UT + */ + bool operator==(const events_cmd& i) const; + + /** + * called in the VAPI RX thread when data is available. + */ + void notify(); + +private: + void succeeded() {} + /** + * The listner of this command + */ + dhcp_client::event_listener& m_listener; +}; + +/** + * A cmd class that Dumps all the DHCP clients + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // namespace dhcp_client_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/dump_cmd.hpp b/extras/deprecated/vom/vom/dump_cmd.hpp new file mode 100644 index 00000000000..be85a46a7c7 --- /dev/null +++ b/extras/deprecated/vom/vom/dump_cmd.hpp @@ -0,0 +1,155 @@ +/* + * 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_DUMP_CMD_H__ +#define __VOM_DUMP_CMD_H__ + +#include + +#include "vom/cmd.hpp" +#include "vom/hw.hpp" + +#include + +namespace VOM { +/** + * A function type def for calculating a message's size + */ +typedef unsigned int (*get_msg_size_t)(void*); + +/** + * A base class for VPP dump commands. + * Dump commands are one of the sub-set of command types to VPP. Here the + * client + * makes a read request on the resource and VPP responds with all the + * records. + * This command is executed synchronously. Once complete the client can + * 'pop' + * the records from the command object + */ +template +class dump_cmd : public cmd +{ +public: + typedef MSG msg_t; + typedef typename MSG::resp_type record_t; + + typedef typename vapi::Result_set::const_iterator + const_iterator; + + /** + * Default Constructor + */ + dump_cmd() + : cmd() + { + } + + /** + * Destructor + */ + virtual ~dump_cmd() {} + + dump_cmd(const dump_cmd& d) = default; + + /** + * Constant iterator to the start of the records retunred during the dump + */ + const_iterator begin() + { + /* + * m_dump is NULL during client UT when the commands are not issued. + */ + if (!m_dump) + return const_iterator(); + return (m_dump->get_result_set().begin()); + } + + /** + * Constant iterator to the end of the records retunred during the dump + */ + const_iterator end() + { + if (!m_dump) + return const_iterator(); + return (m_dump->get_result_set().end()); + } + + /** + * Wait for the issue of the command to complete + */ + rc_t wait() + { + std::future_status status; + std::future result; + + result = m_promise.get_future(); + status = result.wait_for(std::chrono::seconds(5)); + + if (status != std::future_status::ready) { + return (rc_t::TIMEOUT); + } + + return (result.get()); + } + + /** + * Call operator called when the dump is complete + */ + vapi_error_e operator()(MSG& d) + { + m_promise.set_value(rc_t::OK); + + return (VAPI_OK); + } + + /** + * Retire/cancel a long running command + */ + virtual void retire(connection& con) {} + +protected: + /** + * The underlying promise that implements the synchornous nature + * of the command issue + */ + std::promise m_promise; + + /** + * Dump commands should not be issued whilst the HW is disabled + */ + void succeeded() {} + + /** + * The HW::cmd_q is a friend so it can call suceedded. + */ + friend class HW::cmd_q; + + /** + * The VAPI event registration + */ + std::unique_ptr m_dump; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/enum_base.hpp b/extras/deprecated/vom/vom/enum_base.hpp new file mode 100644 index 00000000000..2ac8edebfce --- /dev/null +++ b/extras/deprecated/vom/vom/enum_base.hpp @@ -0,0 +1,126 @@ +/* + * 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_ENUM_H__ +#define __VOM_ENUM_H__ + +#include + +namespace VOM { +/** + * A template base class for all enum types. + * This enum type exists to associate an enum value with a string for + * display/debug purposes. + * Concrete enum types use the CRTP. Derived classes thus inherit this + * base's function, but are not polymorphic. + */ +template +class enum_base +{ +public: + /** + * convert to string format for debug purposes + */ + const std::string& to_string() const { return (m_desc); } + + /** + * Comparison operator + */ + bool operator==(const enum_base& e) const { return (e.m_value == m_value); } + + /** + * Assignment + */ + enum_base& operator=(const enum_base& e) + { + m_value = e.m_value; + m_desc = e.m_desc; + + return (*this); + } + + /** + * bitwise or assignemnt + */ + enum_base& operator|=(const enum_base& e) + { + m_value += e.m_value; + m_desc += ":" + e.m_desc; + + return *this; + } + + /** + * bitwise or + */ + enum_base operator|(const enum_base& e1) const + { + enum_base e = *this; + e |= e1; + return e; + } + + /** + * Comparison operator + */ + bool operator!=(const enum_base& e) const { return (e.m_value != m_value); } + + /** + * integer conversion operator + */ + operator int() const { return (m_value); } + + /** + * Return the value of the enum - same as integer conversion + */ + int value() const { return (m_value); } + +protected: + /** + * Constructor of an enum - takes value and string description + */ + enum_base(int value, const std::string desc) + : m_value(value) + , m_desc(desc) + { + } + + /** + * Constructor + */ + virtual ~enum_base() {} + +private: + /** + * Integer value of the enum + */ + int m_value; + + /** + * String description + */ + std::string m_desc; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/event_cmd.hpp b/extras/deprecated/vom/vom/event_cmd.hpp new file mode 100644 index 00000000000..c7a561355c7 --- /dev/null +++ b/extras/deprecated/vom/vom/event_cmd.hpp @@ -0,0 +1,117 @@ +/* + * 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_EVENT_CMD_H__ +#define __VOM_EVENT_CMD_H__ + +#include + +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +/** + * An Event command base class. + * Events are one of the sub-set of command type to VPP. + * A client performs a one time 'registration/subsription' to VPP for the + * event in question and then is notified asynchronously when those events + * occur. + * The model here then is that the lifetime of the event command represensts + * the during of the clients subscription. When the command is 'issued' the + * subscription begins, when it is 'retired' the subscription ends. For the + * subscription duration the client will be notified as events are recieved. + * The client can then 'pop' these events from this command object. + */ +template +class event_cmd : public rpc_cmd, WANT> +{ +public: + /** + * Default constructor + */ + event_cmd(HW::item& b) + : rpc_cmd, WANT>(b) + { + } + + /** + * Default destructor + */ + virtual ~event_cmd() {} + + /** + * Typedef for the event type + */ + typedef typename vapi::Event_registration::resp_type event_t; + typedef typename vapi::Event_registration reg_t; + + typedef typename vapi::Result_set::const_iterator + const_iterator; + + const_iterator begin() { return (m_reg->get_result_set().begin()); } + + const_iterator end() { return (m_reg->get_result_set().end()); } + + void lock() { m_mutex.lock(); } + void unlock() { m_mutex.unlock(); } + + /** + * flush/free all the events thus far reeived. + * Call with the lock held! + */ + void flush() { m_reg->get_result_set().free_all_responses(); } + + /** + * Retire the command. This is only appropriate for Event Commands + * As they persist until retired. + */ + virtual void retire(connection& con) = 0; + + vapi_error_e operator()(reg_t& dl) + { + notify(); + + return (VAPI_OK); + } + +protected: + /** + * Notify the command that data from VPP has arrived and been stored. + * The command should now inform its clients/listeners. + */ + virtual void notify() = 0; + + /** + * The VAPI event registration + */ + std::unique_ptr> m_reg; + + /** + * Mutex protection for the events + */ + std::mutex m_mutex; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_bridge_domain.cpp b/extras/deprecated/vom/vom/gbp_bridge_domain.cpp new file mode 100644 index 00000000000..cc4e256c7aa --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_bridge_domain.cpp @@ -0,0 +1,355 @@ +/* + * 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/gbp_bridge_domain.hpp" +#include "vom/gbp_bridge_domain_cmds.hpp" +#include "vom/interface.hpp" +#include "vom/l2_binding.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::NONE(0, "none"); +const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::DO_NOT_LEARN( + 1, + "do-not-learn"); +const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::UU_FWD_DROP( + 2, + "uu-fwd-drop"); +const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::MCAST_DROP( + 4, + "mcast-drop"); +const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::UCAST_ARP( + 8, + "ucast-arp"); + +gbp_bridge_domain::flags_t::flags_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +/** + * A DB of al the interfaces, key on the name + */ +singular_db gbp_bridge_domain::m_db; + +gbp_bridge_domain::event_handler gbp_bridge_domain::m_evh; + +/** + * Construct a new object matching the desried state + */ +gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, + const interface& bvi, + const flags_t& flags) + : m_id(bd.id()) + , m_bd(bd.singular()) + , m_rd(rd.singular()) + , m_bvi(bvi.singular()) + , m_uu_fwd() + , m_bm_flood() + , m_flags(flags) +{ +} + +gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, + const interface& bvi, + const interface& uu_fwd, + const interface& bm_flood, + const flags_t& flags) + : m_id(bd.id()) + , m_bd(bd.singular()) + , m_rd(rd.singular()) + , m_bvi(bvi.singular()) + , m_uu_fwd(uu_fwd.singular()) + , m_bm_flood(bm_flood.singular()) + , m_flags(flags) +{ +} + +gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, + const std::shared_ptr bvi, + const std::shared_ptr uu_fwd, + const std::shared_ptr bm_flood, + const flags_t& flags) + : m_id(bd.id()) + , m_bd(bd.singular()) + , m_rd(rd.singular()) + , m_bvi(bvi) + , m_uu_fwd(uu_fwd) + , m_bm_flood(bm_flood) + , m_flags(flags) +{ + if (m_bvi) + m_bvi = m_bvi->singular(); + if (m_uu_fwd) + m_uu_fwd = m_uu_fwd->singular(); + if (m_bm_flood) + m_bm_flood = m_bm_flood->singular(); +} + +gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, + const interface& bvi, + const std::shared_ptr uu_fwd, + const std::shared_ptr bm_flood, + const flags_t& flags) + : m_id(bd.id()) + , m_bd(bd.singular()) + , m_rd(rd.singular()) + , m_bvi(bvi.singular()) + , m_uu_fwd(uu_fwd) + , m_bm_flood(bm_flood) + , m_flags(flags) +{ + if (m_uu_fwd) + m_uu_fwd = m_uu_fwd->singular(); + if (m_bm_flood) + m_bm_flood = m_bm_flood->singular(); +} + +gbp_bridge_domain::gbp_bridge_domain(const gbp_bridge_domain& bd) + : m_id(bd.id()) + , m_bd(bd.m_bd) + , m_rd(bd.m_rd) + , m_bvi(bd.m_bvi) + , m_uu_fwd(bd.m_uu_fwd) + , m_bm_flood(bd.m_bm_flood) + , m_flags(bd.m_flags) +{ +} + +const gbp_bridge_domain::key_t +gbp_bridge_domain::key() const +{ + return (m_bd->key()); +} + +uint32_t +gbp_bridge_domain::id() const +{ + return (m_bd->id()); +} + +const std::shared_ptr +gbp_bridge_domain::get_bridge_domain() const +{ + return m_bd; +} + +const std::shared_ptr +gbp_bridge_domain::get_bvi() const +{ + return m_bvi; +} + +bool +gbp_bridge_domain::operator==(const gbp_bridge_domain& b) const +{ + bool equal = true; + + if (m_bvi && b.m_bvi) + equal &= (m_bvi->key() == b.m_bvi->key()); + else if (!m_bvi && !b.m_bvi) + ; + else + equal = false; + + if (m_uu_fwd && b.m_uu_fwd) + equal &= (m_uu_fwd->key() == b.m_uu_fwd->key()); + else if (!m_uu_fwd && !b.m_uu_fwd) + ; + else + equal = false; + + if (m_bm_flood && b.m_bm_flood) + equal &= (m_bm_flood->key() == b.m_bm_flood->key()); + else if (!m_bm_flood && !b.m_bm_flood) + ; + else + equal = false; + + return ((m_bd->key() == b.m_bd->key()) && equal); +} + +void +gbp_bridge_domain::sweep() +{ + if (rc_t::OK == m_id.rc()) { + HW::enqueue(new gbp_bridge_domain_cmds::delete_cmd(m_id)); + } + HW::write(); +} + +void +gbp_bridge_domain::replay() +{ + if (rc_t::OK == m_id.rc()) { + HW::enqueue(new gbp_bridge_domain_cmds::create_cmd( + m_id, m_rd->id(), (m_bvi ? m_bvi->handle() : handle_t::INVALID), + (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID), + (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags)); + } +} + +gbp_bridge_domain::~gbp_bridge_domain() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_id.data(), this); +} + +std::string +gbp_bridge_domain::to_string() const +{ + std::ostringstream s; + s << "gbp-bridge-domain:[" << m_bd->to_string() + << " flags:" << m_flags.to_string(); + + if (m_bvi) + s << " bvi:" << m_bvi->to_string(); + if (m_uu_fwd) + s << " uu-fwd:" << m_uu_fwd->to_string(); + + s << "]"; + + return (s.str()); +} + +std::shared_ptr +gbp_bridge_domain::find(const key_t& key) +{ + return (m_db.find(key)); +} + +void +gbp_bridge_domain::update(const gbp_bridge_domain& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (rc_t::OK != m_id.rc()) { + HW::enqueue(new gbp_bridge_domain_cmds::create_cmd( + m_id, m_rd->id(), (m_bvi ? m_bvi->handle() : handle_t::INVALID), + (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID), + (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags)); + } +} + +std::shared_ptr +gbp_bridge_domain::find_or_add(const gbp_bridge_domain& temp) +{ + return (m_db.find_or_add(temp.m_id.data(), temp)); +} + +std::shared_ptr +gbp_bridge_domain::singular() const +{ + return find_or_add(*this); +} + +void +gbp_bridge_domain::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +gbp_bridge_domain::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump GBP Bridge domains + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr uu_fwd = + interface::find(payload.bd.uu_fwd_sw_if_index); + std::shared_ptr bm_flood = + interface::find(payload.bd.bm_flood_sw_if_index); + std::shared_ptr bvi = + interface::find(payload.bd.bvi_sw_if_index); + std::shared_ptr grd = + gbp_route_domain::find(payload.bd.rd_id); + + flags_t flags = gbp_bridge_domain::flags_t::NONE; + if (payload.bd.flags & GBP_BD_API_FLAG_DO_NOT_LEARN) + flags |= gbp_bridge_domain::flags_t::DO_NOT_LEARN; + if (payload.bd.flags & GBP_BD_API_FLAG_UU_FWD_DROP) + flags |= gbp_bridge_domain::flags_t::UU_FWD_DROP; + if (payload.bd.flags & GBP_BD_API_FLAG_MCAST_DROP) + flags |= gbp_bridge_domain::flags_t::MCAST_DROP; + if (payload.bd.flags & GBP_BD_API_FLAG_UCAST_ARP) + flags |= gbp_bridge_domain::flags_t::UCAST_ARP; + + if (uu_fwd && bm_flood && bvi && grd) { + gbp_bridge_domain bd(payload.bd.bd_id, *grd, bvi, uu_fwd, bm_flood, + flags); + OM::commit(key, bd); + VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); + } else if (bvi) { + gbp_bridge_domain bd(payload.bd.bd_id, *grd, *bvi, flags); + OM::commit(key, bd); + VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); + } else { + VOM_LOG(log_level_t::ERROR) + << "no BVI:" << payload.bd.bvi_sw_if_index + << " nor uu-fwd:" << payload.bd.uu_fwd_sw_if_index; + } + } +} + +gbp_bridge_domain::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "gbd", "gbridge" }, "GBP Bridge Domains", this); +} + +void +gbp_bridge_domain::event_handler::handle_replay() +{ + m_db.replay(); +} + +dependency_t +gbp_bridge_domain::event_handler::order() const +{ + /* order after gbp-route-domains */ + return (dependency_t::ACL); +} + +void +gbp_bridge_domain::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_bridge_domain.hpp b/extras/deprecated/vom/vom/gbp_bridge_domain.hpp new file mode 100644 index 00000000000..c6e5b1285b2 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_bridge_domain.hpp @@ -0,0 +1,221 @@ +/* + * 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_GBP_BRIDGE_DOMAIN_H__ +#define __VOM_GBP_BRIDGE_DOMAIN_H__ + +#include "vom/bridge_domain.hpp" +#include "vom/gbp_route_domain.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { + +/** + * A entry in the ARP termination table of a Bridge Domain + */ +class gbp_bridge_domain : public object_base +{ +public: + /** + * The key for a bridge_domain is the pair of EPG-IDs + */ + typedef bridge_domain::key_t key_t; + + struct flags_t : enum_base + { + const static flags_t NONE; + const static flags_t DO_NOT_LEARN; + const static flags_t UU_FWD_DROP; + const static flags_t MCAST_DROP; + const static flags_t UCAST_ARP; + + static const flags_t& from_vpp(int i); + + private: + flags_t(int v, const std::string& s); + flags_t(); + }; + + /** + * Construct a GBP bridge_domain + */ + gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, + const interface& bvi, + const flags_t& flags = flags_t::NONE); + gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, + const interface& bvi, + const interface& uu_fwd, + const interface& bm_flood, + const flags_t& flags = flags_t::NONE); + gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, + const std::shared_ptr bvi, + const std::shared_ptr uu_fwd, + const std::shared_ptr bm_flood, + const flags_t& flags = flags_t::NONE); + gbp_bridge_domain(const bridge_domain& bd, + const gbp_route_domain& rd, + const interface& bvi, + const std::shared_ptr uu_fwd, + const std::shared_ptr bm_flood, + const flags_t& flags = flags_t::NONE); + + /** + * Copy Construct + */ + gbp_bridge_domain(const gbp_bridge_domain& r); + + /** + * Destructor + */ + ~gbp_bridge_domain(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * Return the bridge domain's VPP ID + */ + uint32_t id() const; + + /** + * comparison operator + */ + bool operator==(const gbp_bridge_domain& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + + const std::shared_ptr get_bridge_domain() const; + const std::shared_ptr get_bvi() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_bridge_domain& obj); + + /** + * Find or add the instance of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add( + const gbp_bridge_domain& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the endpoint + */ + HW::item m_id; + + std::shared_ptr m_bd; + std::shared_ptr m_rd; + std::shared_ptr m_bvi; + std::shared_ptr m_uu_fwd; + std::shared_ptr m_bm_flood; + flags_t m_flags; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +}; // namespace + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_bridge_domain_cmds.cpp b/extras/deprecated/vom/vom/gbp_bridge_domain_cmds.cpp new file mode 100644 index 00000000000..b6124760a1d --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_bridge_domain_cmds.cpp @@ -0,0 +1,159 @@ +/* + * 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/gbp_bridge_domain_cmds.hpp" + +namespace VOM { +namespace gbp_bridge_domain_cmds { + +create_cmd::create_cmd(HW::item& item, + u32 rd_id, + const handle_t bvi, + const handle_t uu_fwd, + const handle_t bm_flood, + const gbp_bridge_domain::flags_t& flags) + : rpc_cmd(item) + , m_rd_id(rd_id) + , m_bvi(bvi) + , m_uu_fwd(uu_fwd) + , m_bm_flood(bm_flood) + , m_flags(flags) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_hw_item.data() == other.m_hw_item.data()) && + (m_rd_id == other.m_rd_id) && (m_bvi == other.m_bvi) && + (m_uu_fwd == other.m_uu_fwd) && (m_bm_flood == other.m_bm_flood) && + (m_flags == other.m_flags)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.bd.bd_id = m_hw_item.data(); + payload.bd.rd_id = m_rd_id; + payload.bd.bvi_sw_if_index = m_bvi.value(); + payload.bd.uu_fwd_sw_if_index = m_uu_fwd.value(); + payload.bd.bm_flood_sw_if_index = m_bm_flood.value(); + + vapi_enum_gbp_bridge_domain_flags flags = GBP_BD_API_FLAG_NONE; + if (gbp_bridge_domain::flags_t::DO_NOT_LEARN & m_flags) + flags = static_cast( + flags | GBP_BD_API_FLAG_DO_NOT_LEARN); + if (gbp_bridge_domain::flags_t::UU_FWD_DROP & m_flags) + flags = static_cast( + flags | GBP_BD_API_FLAG_UU_FWD_DROP); + if (gbp_bridge_domain::flags_t::MCAST_DROP & m_flags) + flags = static_cast( + flags | GBP_BD_API_FLAG_MCAST_DROP); + if (gbp_bridge_domain::flags_t::UCAST_ARP & m_flags) + flags = static_cast( + flags | GBP_BD_API_FLAG_UCAST_ARP); + + payload.bd.flags = flags; + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-bridge-domain: " << m_hw_item.to_string() + << " flags:" << m_flags.to_string() << " bvi:" << m_bvi.to_string() + << " uu-fwd:" << m_uu_fwd.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item) + : rpc_cmd(item) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_hw_item.data() == other.m_hw_item.data()); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.bd_id = m_hw_item.data(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-bridge-domain: " << m_hw_item.to_string(); + + return (s.str()); +} + +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 ("gbp-bridge-domain-dump"); +} + +}; // namespace gbp_bridge_domain_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_bridge_domain_cmds.hpp b/extras/deprecated/vom/vom/gbp_bridge_domain_cmds.hpp new file mode 100644 index 00000000000..76fc86d0b91 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_bridge_domain_cmds.hpp @@ -0,0 +1,137 @@ +/* + * 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_GBP_BRIDGE_DOMAIN_CMDS_H__ +#define __VOM_GBP_BRIDGE_DOMAIN_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_bridge_domain.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace gbp_bridge_domain_cmds { +/** + * A command class that creates an Bridge-Domain + */ +class create_cmd + : public rpc_cmd, vapi::Gbp_bridge_domain_add> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + u32 rd_id, + const handle_t bvi, + const handle_t uu_fwd, + const handle_t bm_flood, + const gbp_bridge_domain::flags_t& flags); + + /** + * 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; + +private: + u32 m_rd_id; + const handle_t m_bvi; + const handle_t m_uu_fwd; + const handle_t m_bm_flood; + const gbp_bridge_domain::flags_t& m_flags; +}; + +/** + * A cmd class that Delete an Bridge-Domain + */ +class delete_cmd + : public rpc_cmd, vapi::Gbp_bridge_domain_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item); + + /** + * 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; +}; + +/** + * A cmd class that Dumps all the bridge domains + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd() = default; + dump_cmd(const dump_cmd& d) = 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // gbp_bridge_domain_cmds +}; // VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_contract.cpp b/extras/deprecated/vom/vom/gbp_contract.cpp new file mode 100644 index 00000000000..f1b35ddf8c4 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_contract.cpp @@ -0,0 +1,254 @@ +/* + * 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/gbp_contract.hpp" +#include "vom/api_types.hpp" +#include "vom/gbp_contract_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +singular_db gbp_contract::m_db; + +gbp_contract::event_handler gbp_contract::m_evh; + +gbp_contract::gbp_contract(scope_t scope, + sclass_t sclass, + sclass_t dclass, + const ACL::l3_list& acl, + const gbp_rules_t& rules, + const ethertype_set_t& allowed_ethertypes) + : m_hw(false) + , m_scope(scope) + , m_sclass(sclass) + , m_dclass(dclass) + , m_acl(acl.singular()) + , m_gbp_rules(rules) + , m_allowed_ethertypes(allowed_ethertypes) +{ +} + +gbp_contract::gbp_contract(const gbp_contract& gbpc) + : m_hw(gbpc.m_hw) + , m_scope(gbpc.m_scope) + , m_sclass(gbpc.m_sclass) + , m_dclass(gbpc.m_dclass) + , m_acl(gbpc.m_acl) + , m_gbp_rules(gbpc.m_gbp_rules) + , m_allowed_ethertypes(gbpc.m_allowed_ethertypes) +{ +} + +gbp_contract::~gbp_contract() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +const gbp_contract::key_t +gbp_contract::key() const +{ + return (std::make_tuple(m_scope, m_sclass, m_dclass)); +} + +bool +gbp_contract::operator==(const gbp_contract& gbpc) const +{ + return ((key() == gbpc.key()) && (m_acl->handle() == gbpc.m_acl->handle())); +} + +void +gbp_contract::sweep() +{ + if (m_hw) { + HW::enqueue( + new gbp_contract_cmds::delete_cmd(m_hw, m_scope, m_sclass, m_dclass)); + } + HW::write(); +} + +void +gbp_contract::replay() +{ + if (m_hw) { + HW::enqueue(new gbp_contract_cmds::create_cmd( + m_hw, m_scope, m_sclass, m_dclass, m_acl->handle(), m_gbp_rules, + m_allowed_ethertypes)); + } +} + +std::string +gbp_contract::to_string() const +{ + std::ostringstream s; + s << "gbp-contract:[{" << m_scope << ", " << m_sclass << ", " << m_dclass + << "}, " << m_acl->to_string(); + if (m_gbp_rules.size()) { + auto it = m_gbp_rules.cbegin(); + while (it != m_gbp_rules.cend()) { + s << it->to_string(); + ++it; + } + } + s << "[ethertype:"; + for (auto e : m_allowed_ethertypes) + s << " " << e; + s << "]]"; + + return (s.str()); +} + +void +gbp_contract::update(const gbp_contract& r) +{ + /* + * create the table if it is not yet created + */ + if (rc_t::OK != m_hw.rc()) { + HW::enqueue(new gbp_contract_cmds::create_cmd( + m_hw, m_scope, m_sclass, m_dclass, m_acl->handle(), m_gbp_rules, + m_allowed_ethertypes)); + } +} + +std::shared_ptr +gbp_contract::find_or_add(const gbp_contract& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +gbp_contract::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +gbp_contract::singular() const +{ + return find_or_add(*this); +} + +void +gbp_contract::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +gbp_contract::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "gbp-contract" }, "GBP Contract", this); +} + +void +gbp_contract::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +gbp_contract::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr acl = + ACL::l3_list::find(payload.contract.acl_index); + + if (acl) { + gbp_contract::gbp_rules_t rules; + + for (uint8_t i = 0; i < payload.contract.n_rules; i++) { + const gbp_rule::action_t action = + gbp_rule::action_t::from_int(payload.contract.rules[i].action); + const gbp_rule::hash_mode_t hm = gbp_rule::hash_mode_t::from_int( + payload.contract.rules[i].nh_set.hash_mode); + gbp_rule::next_hops_t nhs; + for (u8 j = 0; j < payload.contract.rules[i].nh_set.n_nhs; j++) { + gbp_rule::next_hop_t nh( + from_api(payload.contract.rules[i].nh_set.nhs[j].ip), + from_api(payload.contract.rules[i].nh_set.nhs[j].mac), + payload.contract.rules[i].nh_set.nhs[j].bd_id, + payload.contract.rules[i].nh_set.nhs[j].rd_id); + nhs.insert(nh); + } + gbp_rule::next_hop_set_t next_hop_set(hm, nhs); + gbp_rule gr(i, next_hop_set, action); + rules.insert(gr); + } + + ethertype_set_t allowed_ethertypes; + u8 *data, n_et; + u16* et; + + data = (((u8*)&payload.contract.n_ether_types) + + (sizeof(payload.contract.rules[0]) * payload.contract.n_rules)); + n_et = *data; + et = (u16*)(++data); + + for (uint8_t i = 0; i < n_et; i++) { + allowed_ethertypes.insert(ethertype_t::from_numeric_val(et[i])); + } + + gbp_contract gbpc(payload.contract.scope, payload.contract.sclass, + payload.contract.dclass, *acl, rules, + allowed_ethertypes); + OM::commit(key, gbpc); + VOM_LOG(log_level_t::DEBUG) << "read: " << gbpc.to_string(); + } else { + VOM_LOG(log_level_t::ERROR) << " no ACL:" << payload.contract.acl_index; + } + } +} + +dependency_t +gbp_contract::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +gbp_contract::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const gbp_contract::key_t& key) +{ + os << "{ " << std::get<0>(key) << "," << std::get<1>(key) << ", " + << std::get<2>(key) << "}"; + + return (os); +} + +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_contract.hpp b/extras/deprecated/vom/vom/gbp_contract.hpp new file mode 100644 index 00000000000..d935030034e --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_contract.hpp @@ -0,0 +1,217 @@ +/* + * 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_GBP_CONTRACT_H__ +#define __VOM_GBP_CONTRACT_H__ + +#include "vom/acl_l3_list.hpp" +#include "vom/gbp_rule.hpp" +#include "vom/gbp_types.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" +#include "vom/types.hpp" + +namespace VOM { + +/** + * A entry in the ARP termination table of a Bridge Domain + */ +class gbp_contract : public object_base +{ +public: + /** + * set of gbp rules + */ + typedef std::set gbp_rules_t; + + /** + * The key for a contract is the pair of EPG-IDs + */ + typedef std::tuple key_t; + + /** + * A set of allowed ethertypes + */ + typedef std::set ethertype_set_t; + + /** + * Construct a GBP contract + */ + gbp_contract(scope_t scope, + sclass_t sclass, + sclass_t dclass, + const ACL::l3_list& acl, + const gbp_rules_t& gpb_rules, + const ethertype_set_t& allowed_ethertypes); + + /** + * Copy Construct + */ + gbp_contract(const gbp_contract& r); + + /** + * Destructor + */ + ~gbp_contract(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const gbp_contract& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_contract& obj); + + /** + * Find or add the instance of the contract domain in the OM + */ + static std::shared_ptr find_or_add(const gbp_contract& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the endpoint + */ + HW::item m_hw; + + /* + * The scope of the contract + */ + scope_t m_scope; + + /** + * The source EPG ID + */ + sclass_t m_sclass; + + /** + * The destination EPG ID + */ + sclass_t m_dclass; + + /** + * The ACL applied to traffic between the gourps + */ + std::shared_ptr m_acl; + + /** + * The gbp rules applied to traffic between the gourps + */ + gbp_rules_t m_gbp_rules; + + /** + * the set of Ether-types allowed by this contract + */ + ethertype_set_t m_allowed_ethertypes; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, const gbp_contract::key_t& key); +}; // namespace + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_contract_cmds.cpp b/extras/deprecated/vom/vom/gbp_contract_cmds.cpp new file mode 100644 index 00000000000..63d9334faf0 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_contract_cmds.cpp @@ -0,0 +1,200 @@ +/* + * 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/gbp_contract_cmds.hpp" +#include "vom/api_types.hpp" + +namespace VOM { +namespace gbp_contract_cmds { + +create_cmd::create_cmd(HW::item& item, + scope_t scope, + sclass_t sclass, + sclass_t dclass, + const handle_t& acl, + const gbp_contract::gbp_rules_t& gbp_rules, + const gbp_contract::ethertype_set_t& allowed_ethertypes) + : rpc_cmd(item) + , m_scope(scope) + , m_sclass(sclass) + , m_dclass(dclass) + , m_acl(acl) + , m_gbp_rules(gbp_rules) + , m_allowed_ethertypes(allowed_ethertypes) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_acl == other.m_acl) && (m_sclass == other.m_sclass) && + (m_scope == other.m_scope) && (m_dclass == other.m_dclass) && + (m_gbp_rules == other.m_gbp_rules) && + (m_allowed_ethertypes == other.m_allowed_ethertypes)); +} + +#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0])) + +rc_t +create_cmd::issue(connection& con) +{ + size_t n_rules = m_gbp_rules.size(); + uint32_t ii = 0; + + msg_t req(con.ctx(), n_rules, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.contract.acl_index = m_acl.value(); + payload.contract.scope = m_scope; + payload.contract.sclass = m_sclass; + payload.contract.dclass = m_dclass; + payload.contract.n_rules = n_rules; + payload.contract.n_ether_types = m_allowed_ethertypes.size(); + + for (auto tt : m_allowed_ethertypes) { + payload.contract.allowed_ethertypes[ii] = tt.value(); + ii++; + if (ii == ARRAY_LEN(payload.contract.allowed_ethertypes)) + break; + } + + ii = 0; + for (auto rule : m_gbp_rules) { + if (rule.action() == gbp_rule::action_t::REDIRECT) + payload.contract.rules[ii].action = GBP_API_RULE_REDIRECT; + else if (rule.action() == gbp_rule::action_t::PERMIT) + payload.contract.rules[ii].action = GBP_API_RULE_PERMIT; + else + payload.contract.rules[ii].action = GBP_API_RULE_DENY; + + if (rule.nhs().hash_mode() == gbp_rule::hash_mode_t::SYMMETRIC) + payload.contract.rules[ii].nh_set.hash_mode = GBP_API_HASH_MODE_SYMMETRIC; + else if (rule.nhs().hash_mode() == gbp_rule::hash_mode_t::SRC_IP) + payload.contract.rules[ii].nh_set.hash_mode = GBP_API_HASH_MODE_SRC_IP; + else + payload.contract.rules[ii].nh_set.hash_mode = GBP_API_HASH_MODE_DST_IP; + + const gbp_rule::next_hops_t& next_hops = rule.nhs().next_hops(); + uint8_t jj = 0, nh_size = (next_hops.size() > 8) ? 8 : next_hops.size(); + + payload.contract.rules[ii].nh_set.n_nhs = nh_size; + for (auto nh : next_hops) { + to_api(nh.getIp(), payload.contract.rules[ii].nh_set.nhs[jj].ip); + to_api(nh.getMac(), payload.contract.rules[ii].nh_set.nhs[jj].mac); + payload.contract.rules[ii].nh_set.nhs[jj].bd_id = nh.getBdId(); + payload.contract.rules[ii].nh_set.nhs[jj].rd_id = nh.getRdId(); + jj++; + } + ++ii; + } + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-contract-create: " << m_hw_item.to_string() + << " sclass:" << m_sclass << " dclass:" << m_dclass << " acl:" << m_acl; + s << "[ethertype:"; + for (auto e : m_allowed_ethertypes) + s << " " << e; + s << "]"; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + scope_t scope, + sclass_t sclass, + sclass_t dclass) + : rpc_cmd(item) + , m_scope(scope) + , m_sclass(sclass) + , m_dclass(dclass) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return ((m_sclass == other.m_sclass) && (m_dclass == other.m_dclass)); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), 0, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.contract.acl_index = ~0; + payload.contract.scope = m_scope; + payload.contract.sclass = m_sclass; + payload.contract.dclass = m_dclass; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-contract-delete: " << m_hw_item.to_string() << " scope: " << m_scope + << " sclass:" << m_sclass << " dclass:" << m_dclass; + + return (s.str()); +} + +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 ("gbp-contract-dump"); +} + +}; // namespace gbp_contract_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_contract_cmds.hpp b/extras/deprecated/vom/vom/gbp_contract_cmds.hpp new file mode 100644 index 00000000000..2146d5d732c --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_contract_cmds.hpp @@ -0,0 +1,147 @@ +/* + * 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_GBP_CONTRACT_CMDS_H__ +#define __VOM_GBP_CONTRACT_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_contract.hpp" + +#include + +namespace VOM { +namespace gbp_contract_cmds { + +/** + * A command class that creates or updates the GBP contract + */ +class create_cmd + : public rpc_cmd, vapi::Gbp_contract_add_del> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + scope_t scope, + sclass_t sclass, + sclass_t dclass, + const handle_t& acl, + const gbp_contract::gbp_rules_t& gbp_rules, + const gbp_contract::ethertype_set_t& allowed_ethertypes); + + /** + * 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; + +private: + const scope_t m_scope; + const sclass_t m_sclass; + const sclass_t m_dclass; + const handle_t m_acl; + const gbp_contract::gbp_rules_t& m_gbp_rules; + const gbp_contract::ethertype_set_t& m_allowed_ethertypes; +}; + +/** + * A cmd class that deletes a GBP contract + */ +class delete_cmd + : public rpc_cmd, vapi::Gbp_contract_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, + scope_t scope, + sclass_t sclass, + sclass_t dclass); + + /** + * 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: + const scope_t m_scope; + const sclass_t m_sclass; + const sclass_t m_dclass; +}; + +/** + * A cmd class that Dumps all the GBP contracts + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace gbp_contract_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_endpoint.cpp b/extras/deprecated/vom/vom/gbp_endpoint.cpp new file mode 100644 index 00000000000..fa8907dcc04 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_endpoint.cpp @@ -0,0 +1,224 @@ +/* + * 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/gbp_endpoint.hpp" +#include "vom/api_types.hpp" +#include "vom/gbp_endpoint_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +singular_db gbp_endpoint::m_db; + +gbp_endpoint::event_handler gbp_endpoint::m_evh; + +const gbp_endpoint::flags_t gbp_endpoint::flags_t::NONE(0, "none"); +const gbp_endpoint::flags_t gbp_endpoint::flags_t::BOUNCE(1, "bounce"); +const gbp_endpoint::flags_t gbp_endpoint::flags_t::LEARNT(2, "learnt"); +const gbp_endpoint::flags_t gbp_endpoint::flags_t::REMOTE(4, "remote"); +const gbp_endpoint::flags_t gbp_endpoint::flags_t::EXTERNAL(8, "external"); + +gbp_endpoint::flags_t::flags_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +gbp_endpoint::gbp_endpoint( + const interface& itf, + const std::vector& ip_addrs, + const mac_address_t& mac, + const gbp_endpoint_group& epg, + const flags_t& flags) + : m_hdl(handle_t::INVALID) + , m_itf(itf.singular()) + , m_ips(ip_addrs) + , m_mac(mac) + , m_epg(epg.singular()) + , m_flags(flags) +{ +} + +gbp_endpoint::gbp_endpoint(const gbp_endpoint& gbpe) + : m_hdl(gbpe.m_hdl) + , m_itf(gbpe.m_itf) + , m_ips(gbpe.m_ips) + , m_mac(gbpe.m_mac) + , m_epg(gbpe.m_epg) + , m_flags(gbpe.m_flags) +{ +} + +gbp_endpoint::~gbp_endpoint() +{ + sweep(); + m_db.release(key(), this); +} + +const gbp_endpoint::key_t +gbp_endpoint::key() const +{ + return (std::make_pair(m_itf->key(), m_mac)); +} + +bool +gbp_endpoint::operator==(const gbp_endpoint& gbpe) const +{ + return ((key() == gbpe.key()) && (m_epg == gbpe.m_epg) && + (m_flags == gbpe.m_flags)); +} + +void +gbp_endpoint::sweep() +{ + if (m_hdl) { + HW::enqueue(new gbp_endpoint_cmds::delete_cmd(m_hdl)); + } + HW::write(); +} + +void +gbp_endpoint::replay() +{ + if (m_hdl) { + HW::enqueue(new gbp_endpoint_cmds::create_cmd( + m_hdl, m_itf->handle(), m_ips, m_mac, m_epg->sclass(), m_flags)); + } +} + +std::string +gbp_endpoint::to_string() const +{ + std::ostringstream s; + s << "gbp-endpoint:[" << m_itf->to_string() << ", ips:["; + + for (auto ip : m_ips) + s << ip.to_string(); + + s << "], " << m_mac.to_string() << ", epg:" << m_epg->to_string() << "]"; + + return (s.str()); +} + +void +gbp_endpoint::update(const gbp_endpoint& r) +{ + if (rc_t::OK != m_hdl.rc()) { + HW::enqueue(new gbp_endpoint_cmds::create_cmd( + m_hdl, m_itf->handle(), m_ips, m_mac, m_epg->sclass(), m_flags)); + } +} + +std::shared_ptr +gbp_endpoint::find_or_add(const gbp_endpoint& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +gbp_endpoint::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +gbp_endpoint::singular() const +{ + return find_or_add(*this); +} + +void +gbp_endpoint::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +gbp_endpoint::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "gbp-endpoint" }, "GBP Endpoints", this); +} + +void +gbp_endpoint::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +gbp_endpoint::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::vector addresses; + + for (uint8_t n = 0; n < payload.endpoint.n_ips; n++) + addresses.push_back(from_api(payload.endpoint.ips[n])); + std::shared_ptr itf = + interface::find(payload.endpoint.sw_if_index); + std::shared_ptr epg = + gbp_endpoint_group::find(payload.endpoint.sclass); + mac_address_t mac = from_api(payload.endpoint.mac); + + VOM_LOG(log_level_t::DEBUG) << "data: " << payload.endpoint.sw_if_index; + + if (itf && epg) { + gbp_endpoint gbpe(*itf, addresses, mac, *epg); + OM::commit(key, gbpe); + + VOM_LOG(log_level_t::DEBUG) << "read: " << gbpe.to_string(); + } else { + VOM_LOG(log_level_t::ERROR) + << "no interface:" << payload.endpoint.sw_if_index + << "or sclass:" << payload.endpoint.sclass; + } + } +} + +dependency_t +gbp_endpoint::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +gbp_endpoint::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const gbp_endpoint::key_t& key) +{ + os << key.first << "," << key.second; + + return os; +} + +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_endpoint.hpp b/extras/deprecated/vom/vom/gbp_endpoint.hpp new file mode 100644 index 00000000000..3d92506d4ce --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_endpoint.hpp @@ -0,0 +1,218 @@ +/* + * 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_GBP_ENDPOINT_H__ +#define __VOM_GBP_ENDPOINT_H__ + +#include +#include + +#include "vom/gbp_endpoint_group.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A GBP Enpoint (i.e. a VM) + */ +class gbp_endpoint : public object_base +{ +public: + /** + * Endpoint flags + */ + struct flags_t : enum_base + { + const static flags_t NONE; + const static flags_t BOUNCE; + const static flags_t REMOTE; + const static flags_t LEARNT; + const static flags_t EXTERNAL; + + private: + /** + * Private constructor taking the value and the string name + */ + flags_t(int v, const std::string& s); + }; + + /** + * The key for a GBP endpoint; interface and IP + */ + typedef std::pair key_t; + + /** + * Construct a GBP endpoint + */ + gbp_endpoint(const interface& itf, + const std::vector& ip_addr, + const mac_address_t& mac, + const gbp_endpoint_group& epg, + const flags_t& flags = flags_t::NONE); + + /** + * Copy Construct + */ + gbp_endpoint(const gbp_endpoint& r); + + /** + * Destructor + */ + ~gbp_endpoint(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const gbp_endpoint& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_endpoint& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const gbp_endpoint& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the endpoint + */ + HW::item m_hdl; + + /** + * The interface the endpoint is attached to. + */ + std::shared_ptr m_itf; + + /** + * The IP address of the endpoint + */ + std::vector m_ips; + + /** + * The MAC address of the endpoint + */ + mac_address_t m_mac; + + /** + * The EPG the endpoint is in + */ + std::shared_ptr m_epg; + + /** + * Endpoint flags + */ + flags_t m_flags; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, const gbp_endpoint::key_t& key); +}; // namespace + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_endpoint_cmds.cpp b/extras/deprecated/vom/vom/gbp_endpoint_cmds.cpp new file mode 100644 index 00000000000..de7c77b41f6 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_endpoint_cmds.cpp @@ -0,0 +1,192 @@ +/* + * 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/gbp_endpoint_cmds.hpp" +#include "vom/api_types.hpp" + +DEFINE_VAPI_MSG_IDS_GBP_API_JSON; + +namespace VOM { +namespace gbp_endpoint_cmds { + +static vapi_enum_gbp_endpoint_flags +to_api(const gbp_endpoint::flags_t& in) +{ + vapi_enum_gbp_endpoint_flags out = GBP_API_ENDPOINT_FLAG_NONE; + + if (in & gbp_endpoint::flags_t::REMOTE) + out = (vapi_enum_gbp_endpoint_flags)(out | GBP_API_ENDPOINT_FLAG_REMOTE); + if (in & gbp_endpoint::flags_t::BOUNCE) + out = (vapi_enum_gbp_endpoint_flags)(out | GBP_API_ENDPOINT_FLAG_BOUNCE); + if (in & gbp_endpoint::flags_t::LEARNT) + out = (vapi_enum_gbp_endpoint_flags)(out | GBP_API_ENDPOINT_FLAG_LEARNT); + if (in & gbp_endpoint::flags_t::EXTERNAL) + out = (vapi_enum_gbp_endpoint_flags)(out | GBP_API_ENDPOINT_FLAG_EXTERNAL); + + return (out); +} + +create_cmd::create_cmd(HW::item& item, + const handle_t& itf, + const std::vector& ip_addrs, + const mac_address_t& mac, + sclass_t sclass, + const gbp_endpoint::flags_t& flags) + : rpc_cmd(item) + , m_itf(itf) + , m_ip_addrs(ip_addrs) + , m_mac(mac) + , m_sclass(sclass) + , m_flags(flags) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_ip_addrs == other.m_ip_addrs) && + (m_mac == other.m_mac) && (m_sclass == other.m_sclass) && + (m_flags == other.m_flags)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), m_ip_addrs.size() * sizeof(vapi_type_address), + std::ref(*this)); + uint8_t n; + + auto& payload = req.get_request().get_payload(); + payload.endpoint.sw_if_index = m_itf.value(); + payload.endpoint.sclass = m_sclass; + payload.endpoint.n_ips = m_ip_addrs.size(); + payload.endpoint.flags = to_api(m_flags); + + for (n = 0; n < payload.endpoint.n_ips; n++) { + VOM::to_api(m_ip_addrs[n], payload.endpoint.ips[n]); + } + to_api(m_mac, payload.endpoint.mac); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +vapi_error_e +create_cmd::operator()(vapi::Gbp_endpoint_add& reply) +{ + int handle = reply.get_response().get_payload().handle; + int retval = reply.get_response().get_payload().retval; + + VOM_LOG(log_level_t::DEBUG) << this->to_string() << " " << retval; + + rc_t rc = rc_t::from_vpp_retval(retval); + handle_t hdl = handle_t::INVALID; + + if (rc_t::OK == rc) { + hdl = handle; + } + + this->fulfill(HW::item(hdl, rc)); + + return (VAPI_OK); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-endpoint-create: " << m_hw_item.to_string() << " itf:" << m_itf + << " ips:["; + for (auto ip : m_ip_addrs) + s << ip.to_string(); + + s << "] mac:" << m_mac << " slcass:" << m_sclass + << " flags:" << m_flags.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item) + : rpc_cmd(item) +{ +} + +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)); + + auto& payload = req.get_request().get_payload(); + payload.handle = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-endpoint-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("gbp-endpoint-dump"); +} + +}; // namespace gbp_endpoint_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_endpoint_cmds.hpp b/extras/deprecated/vom/vom/gbp_endpoint_cmds.hpp new file mode 100644 index 00000000000..b0a62acace7 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_endpoint_cmds.hpp @@ -0,0 +1,141 @@ +/* + * 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_GBP_ENDPOINT_CMDS_H__ +#define __VOM_GBP_ENDPOINT_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_endpoint.hpp" + +#include + +namespace VOM { +namespace gbp_endpoint_cmds { + +/** + * A command class that creates or updates the GBP endpoint + */ +class create_cmd : public rpc_cmd, vapi::Gbp_endpoint_add> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + const handle_t& itf, + const std::vector& ip_addrs, + const mac_address_t& mac, + sclass_t sclass, + const gbp_endpoint::flags_t& flags); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + virtual vapi_error_e operator()(vapi::Gbp_endpoint_add& reply); + + /** + * Comparison operator - only used for UT + */ + bool operator==(const create_cmd& i) const; + +private: + const handle_t m_itf; + const std::vector m_ip_addrs; + const mac_address_t m_mac; + const sclass_t m_sclass; + const gbp_endpoint::flags_t m_flags; +}; + +/** + * A cmd class that deletes a GBP endpoint + */ +class delete_cmd : public rpc_cmd, vapi::Gbp_endpoint_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item); + + /** + * 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: + const handle_t m_hdl; +}; + +/** + * A cmd class that Dumps all the GBP endpoints + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace gbp_enpoint_cms +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_endpoint_group.cpp b/extras/deprecated/vom/vom/gbp_endpoint_group.cpp new file mode 100644 index 00000000000..03f17a7f4fe --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_endpoint_group.cpp @@ -0,0 +1,291 @@ +/* + * 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/gbp_endpoint_group.hpp" +#include "vom/gbp_endpoint_group_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +singular_db + gbp_endpoint_group::m_db; + +gbp_endpoint_group::event_handler gbp_endpoint_group::m_evh; + +gbp_endpoint_group::retention_t::retention_t() + : remote_ep_timeout(0xffffffff) +{ +} +gbp_endpoint_group::retention_t::retention_t(uint32_t remote_ep_timeout_) + : remote_ep_timeout(remote_ep_timeout_) +{ +} + +bool +gbp_endpoint_group::retention_t::operator==(const retention_t& o) const +{ + return (remote_ep_timeout == o.remote_ep_timeout); +} + +std::string +gbp_endpoint_group::retention_t::to_string() const +{ + return std::to_string(remote_ep_timeout); +} + +gbp_endpoint_group::gbp_endpoint_group(vnid_t vnid, + sclass_t sclass, + const interface& itf, + const gbp_route_domain& rd, + const gbp_bridge_domain& bd) + : m_hw(false) + , m_vnid(vnid) + , m_sclass(sclass) + , m_itf(itf.singular()) + , m_rd(rd.singular()) + , m_bd(bd.singular()) + , m_retention() +{ +} + +gbp_endpoint_group::gbp_endpoint_group(vnid_t vnid, + sclass_t sclass, + const gbp_route_domain& rd, + const gbp_bridge_domain& bd) + : m_hw(false) + , m_vnid(vnid) + , m_sclass(sclass) + , m_itf() + , m_rd(rd.singular()) + , m_bd(bd.singular()) + , m_retention() +{ +} + +gbp_endpoint_group::gbp_endpoint_group(sclass_t sclass, + const gbp_route_domain& rd, + const gbp_bridge_domain& bd) + : m_hw(false) + , m_vnid(~0) + , m_sclass(sclass) + , m_itf() + , m_rd(rd.singular()) + , m_bd(bd.singular()) + , m_retention() +{ +} + +gbp_endpoint_group::gbp_endpoint_group(const gbp_endpoint_group& epg) + : m_hw(epg.m_hw) + , m_vnid(epg.m_vnid) + , m_sclass(epg.m_sclass) + , m_itf(epg.m_itf) + , m_rd(epg.m_rd) + , m_bd(epg.m_bd) + , m_retention(epg.m_retention) +{ +} + +gbp_endpoint_group::~gbp_endpoint_group() +{ + sweep(); + m_db.release(key(), this); +} + +const gbp_endpoint_group::key_t +gbp_endpoint_group::key() const +{ + return (m_sclass); +} + +vnid_t +gbp_endpoint_group::vnid() const +{ + return (m_vnid); +} + +void +gbp_endpoint_group::set(const retention_t& retention) +{ + m_retention = retention; +} + +sclass_t +gbp_endpoint_group::sclass() const +{ + return (m_sclass); +} + +bool +gbp_endpoint_group::operator==(const gbp_endpoint_group& gg) const +{ + return (key() == gg.key() && (m_vnid == gg.m_vnid) && + (m_retention == gg.m_retention) && (m_itf == gg.m_itf) && + (m_rd == gg.m_rd) && (m_bd == gg.m_bd)); +} + +void +gbp_endpoint_group::sweep() +{ + if (m_hw) { + HW::enqueue(new gbp_endpoint_group_cmds::delete_cmd(m_hw, m_vnid)); + } + HW::write(); +} + +void +gbp_endpoint_group::replay() +{ + if (m_hw) { + HW::enqueue(new gbp_endpoint_group_cmds::create_cmd( + m_hw, m_vnid, m_sclass, m_bd->id(), m_rd->id(), m_retention, + (m_itf ? m_itf->handle() : handle_t::INVALID))); + } +} + +std::string +gbp_endpoint_group::to_string() const +{ + std::ostringstream s; + s << "gbp-endpoint-group:[" + << "vnid:" << m_vnid << ", sclass:" << m_sclass << ", " + << "retention:[" << m_retention.to_string() << "], " + << (m_itf ? m_itf->to_string() : "NULL") << ", " << m_bd->to_string() + << ", " << m_rd->to_string() << "]"; + + return (s.str()); +} + +void +gbp_endpoint_group::update(const gbp_endpoint_group& r) +{ + if (rc_t::OK != m_hw.rc()) { + HW::enqueue(new gbp_endpoint_group_cmds::create_cmd( + m_hw, m_vnid, m_sclass, m_bd->id(), m_rd->id(), m_retention, + (m_itf ? m_itf->handle() : handle_t::INVALID))); + } +} + +std::shared_ptr +gbp_endpoint_group::find_or_add(const gbp_endpoint_group& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +gbp_endpoint_group::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +gbp_endpoint_group::singular() const +{ + return find_or_add(*this); +} + +void +gbp_endpoint_group::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +const std::shared_ptr +gbp_endpoint_group::get_route_domain() const +{ + return m_rd; +} + +const std::shared_ptr +gbp_endpoint_group::get_bridge_domain() const +{ + return m_bd; +} + +gbp_endpoint_group::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "gbp-endpoint-group" }, "GBP Endpoint_Groups", + this); +} + +void +gbp_endpoint_group::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +gbp_endpoint_group::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = + interface::find(payload.epg.uplink_sw_if_index); + std::shared_ptr rd = + gbp_route_domain::find(payload.epg.rd_id); + std::shared_ptr bd = + gbp_bridge_domain::find(payload.epg.bd_id); + + VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.epg.uplink_sw_if_index + << ", " << payload.epg.rd_id << ", " + << payload.epg.bd_id << "]"; + + if (itf && bd && rd) { + gbp_endpoint_group gbpe(payload.epg.vnid, payload.epg.sclass, *itf, *rd, + *bd); + OM::commit(key, gbpe); + + VOM_LOG(log_level_t::DEBUG) << "read: " << gbpe.to_string(); + } else if (bd && rd) { + gbp_endpoint_group gbpe(payload.epg.sclass, *rd, *bd); + OM::commit(key, gbpe); + + VOM_LOG(log_level_t::DEBUG) << "read: " << gbpe.to_string(); + } else { + VOM_LOG(log_level_t::ERROR) << "no itf:" << payload.epg.uplink_sw_if_index + << " or BD:" << payload.epg.bd_id + << " or RD:" << payload.epg.rd_id; + } + } +} + +dependency_t +gbp_endpoint_group::event_handler::order() const +{ + return (dependency_t::ACL); +} + +void +gbp_endpoint_group::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_endpoint_group.hpp b/extras/deprecated/vom/vom/gbp_endpoint_group.hpp new file mode 100644 index 00000000000..ecc4c4f4baf --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_endpoint_group.hpp @@ -0,0 +1,245 @@ +/* + * 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_GBP_ENDPOINT_GROUP_H__ +#define __VOM_GBP_ENDPOINT_GROUP_H__ + +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" +#include "vom/types.hpp" + +#include "vom/gbp_bridge_domain.hpp" +#include "vom/gbp_route_domain.hpp" +#include "vom/gbp_types.hpp" + +namespace VOM { + +/** + * A entry in the ARP termination table of a Bridge Domain + */ +class gbp_endpoint_group : public object_base +{ +public: + /** + * Endpoint Retention Policy Settings + */ + struct retention_t + { + retention_t(); + retention_t(uint32_t remote_ep_timeout); + + retention_t(const retention_t&) = default; + retention_t& operator=(const retention_t&) = default; + + bool operator==(const retention_t& o) const; + std::string to_string() const; + + /** + * Remote Endpoint timeout/ageing + */ + uint32_t remote_ep_timeout; + }; + + /** + * The key for a GBP endpoint group is its ID + */ + typedef sclass_t key_t; + + /** + * Construct a GBP endpoint_group + */ + gbp_endpoint_group(vnid_t vnid, + sclass_t sclass, + const interface& itf, + const gbp_route_domain& rd, + const gbp_bridge_domain& bd); + gbp_endpoint_group(vnid_t vnid, + sclass_t sclass, + const gbp_route_domain& rd, + const gbp_bridge_domain& bd); + gbp_endpoint_group(sclass_t sclass, + const gbp_route_domain& rd, + const gbp_bridge_domain& bd); + + /** + * Copy Construct + */ + gbp_endpoint_group(const gbp_endpoint_group& r); + + /** + * Destructor + */ + ~gbp_endpoint_group(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const gbp_endpoint_group& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + + /** + * Get the ID of the EPG + */ + vnid_t vnid() const; + sclass_t sclass() const; + + const std::shared_ptr get_route_domain() const; + const std::shared_ptr get_bridge_domain() const; + + void set(const retention_t& retention); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_endpoint_group& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add( + const gbp_endpoint_group& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the endpoint_group + */ + HW::item m_hw; + + /** + * The EPG ID + */ + vnid_t m_vnid; + + /** + * The SClass on the wire + */ + uint16_t m_sclass; + + /** + * The uplink interface for the endpoint group + */ + std::shared_ptr m_itf; + + /** + * The route-domain the EPG uses + */ + std::shared_ptr m_rd; + + /** + * The bridge-domain the EPG uses + */ + std::shared_ptr m_bd; + + /** + * The Group's EP retention Policy + */ + retention_t m_retention; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +}; // namespace + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_endpoint_group_cmds.cpp b/extras/deprecated/vom/vom/gbp_endpoint_group_cmds.cpp new file mode 100644 index 00000000000..15a8858d5d6 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_endpoint_group_cmds.cpp @@ -0,0 +1,147 @@ +/* + * 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/gbp_endpoint_group_cmds.hpp" + +namespace VOM { +namespace gbp_endpoint_group_cmds { + +create_cmd::create_cmd(HW::item& item, + vnid_t vnid, + uint16_t sclass, + uint32_t bd_id, + route::table_id_t rd_id, + const gbp_endpoint_group::retention_t& retention, + const handle_t& itf) + : rpc_cmd(item) + , m_vnid(vnid) + , m_sclass(sclass) + , m_bd_id(bd_id) + , m_rd_id(rd_id) + , m_itf(itf) + , m_retention(retention) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_bd_id == other.m_bd_id) && + (m_rd_id == other.m_rd_id) && (m_vnid == other.m_vnid) && + (m_retention == other.m_retention)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.epg.uplink_sw_if_index = m_itf.value(); + payload.epg.vnid = m_vnid; + payload.epg.sclass = m_sclass; + payload.epg.bd_id = m_bd_id; + payload.epg.rd_id = m_rd_id; + payload.epg.retention.remote_ep_timeout = m_retention.remote_ep_timeout; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-endpoint-group-create: " << m_hw_item.to_string() + << " vnid:" << m_vnid << " bd-id:" << m_bd_id << " rd-id:" << m_rd_id + << " itf:" << m_itf; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, sclass_t sclass) + : rpc_cmd(item) + , m_sclass(sclass) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_sclass == other.m_sclass); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sclass = m_sclass; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-endpoint-group-delete: " << m_hw_item.to_string() + << " sclass:" << m_sclass; + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("gbp-endpoint-group-dump"); +} + +}; // namespace gbp_endpoint_group_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_endpoint_group_cmds.hpp b/extras/deprecated/vom/vom/gbp_endpoint_group_cmds.hpp new file mode 100644 index 00000000000..5e7e0633dfc --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_endpoint_group_cmds.hpp @@ -0,0 +1,141 @@ +/* + * 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_GBP_ENDPOINT_GROUP_CMDS_H__ +#define __VOM_GBP_ENDPOINT_GROUP_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_endpoint_group.hpp" + +#include + +namespace VOM { +namespace gbp_endpoint_group_cmds { + +/** +* A command class that creates or updates the GBP endpoint_group +*/ +class create_cmd : public rpc_cmd, vapi::Gbp_endpoint_group_add> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + vnid_t vnid, + uint16_t sclass, + uint32_t bd_id, + route::table_id_t rd_id, + const gbp_endpoint_group::retention_t& retention, + const handle_t& itf); + + /** + * 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; + +private: + const vnid_t m_vnid; + const uint16_t m_sclass; + const uint32_t m_bd_id; + const route::table_id_t m_rd_id; + const handle_t m_itf; + const gbp_endpoint_group::retention_t m_retention; +}; + +/** + * A cmd class that deletes a GBP endpoint_group + */ +class delete_cmd : public rpc_cmd, vapi::Gbp_endpoint_group_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, sclass_t sclass); + + /** + * 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: + const sclass_t m_sclass; +}; + +/** + * A cmd class that Dumps all the GBP endpoint_groups + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace gbp_enpoint_cms +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_ext_itf.cpp b/extras/deprecated/vom/vom/gbp_ext_itf.cpp new file mode 100644 index 00000000000..55a0fbd3d69 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_ext_itf.cpp @@ -0,0 +1,197 @@ +/* + * 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/gbp_ext_itf.hpp" +#include "vom/gbp_ext_itf_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +singular_db gbp_ext_itf::m_db; + +gbp_ext_itf::event_handler gbp_ext_itf::m_evh; + +gbp_ext_itf::gbp_ext_itf(const interface& itf, + const gbp_bridge_domain& gbd, + const gbp_route_domain& grd) + : m_hw(false) + , m_itf(itf.singular()) + , m_bd(gbd.singular()) + , m_rd(grd.singular()) +{ +} + +gbp_ext_itf::gbp_ext_itf(const gbp_ext_itf& gbpe) + : m_hw(gbpe.m_hw) + , m_itf(gbpe.m_itf) + , m_bd(gbpe.m_bd) + , m_rd(gbpe.m_rd) +{ +} + +gbp_ext_itf::~gbp_ext_itf() +{ + sweep(); + m_db.release(key(), this); +} + +const gbp_ext_itf::key_t +gbp_ext_itf::key() const +{ + return (m_itf->key()); +} + +const handle_t& +gbp_ext_itf::handle() const +{ + return m_itf->handle(); +} + +bool +gbp_ext_itf::operator==(const gbp_ext_itf& gei) const +{ + return ((key() == gei.key()) && (m_itf == gei.m_itf) && (m_rd == gei.m_rd) && + (m_bd == gei.m_bd)); +} + +void +gbp_ext_itf::sweep() +{ + if (m_hw) { + HW::enqueue(new gbp_ext_itf_cmds::delete_cmd(m_hw, m_itf->handle())); + } + HW::write(); +} + +void +gbp_ext_itf::replay() +{ + if (m_hw) { + HW::enqueue(new gbp_ext_itf_cmds::create_cmd(m_hw, m_itf->handle(), + m_bd->id(), m_rd->id())); + } +} + +std::string +gbp_ext_itf::to_string() const +{ + std::ostringstream s; + s << "gbp-ext_itf:[" << m_itf->to_string() << ", " << m_bd->to_string() + << ", " << m_rd->to_string() << "]"; + + return (s.str()); +} + +void +gbp_ext_itf::update(const gbp_ext_itf& r) +{ + if (rc_t::OK != m_hw.rc()) { + HW::enqueue(new gbp_ext_itf_cmds::create_cmd(m_hw, m_itf->handle(), + m_bd->id(), m_rd->id())); + } +} + +std::shared_ptr +gbp_ext_itf::find_or_add(const gbp_ext_itf& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +gbp_ext_itf::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +gbp_ext_itf::singular() const +{ + return find_or_add(*this); +} + +void +gbp_ext_itf::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +gbp_ext_itf::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "gbp-ext-itf" }, "GBP External-Itfs", this); +} + +void +gbp_ext_itf::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +gbp_ext_itf::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = + interface::find(payload.ext_itf.sw_if_index); + std::shared_ptr gbd = + gbp_bridge_domain::find(payload.ext_itf.bd_id); + std::shared_ptr grd = + gbp_route_domain::find(payload.ext_itf.rd_id); + + VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.ext_itf.sw_if_index + << ", " << payload.ext_itf.bd_id << ", " + << payload.ext_itf.rd_id << "]"; + + if (itf && gbd && grd) { + gbp_ext_itf ext_itf(*itf, *gbd, *grd); + OM::commit(key, ext_itf); + + VOM_LOG(log_level_t::DEBUG) << "read: " << ext_itf.to_string(); + } else { + VOM_LOG(log_level_t::ERROR) << "no itf:" << payload.ext_itf.sw_if_index + << " or BD:" << payload.ext_itf.bd_id + << " or RD:" << payload.ext_itf.rd_id; + } + } +} + +dependency_t +gbp_ext_itf::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +gbp_ext_itf::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_ext_itf.hpp b/extras/deprecated/vom/vom/gbp_ext_itf.hpp new file mode 100644 index 00000000000..5de85373a4d --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_ext_itf.hpp @@ -0,0 +1,186 @@ +/* + * 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_GBP_EXT_ITF_H__ +#define __VOM_GBP_EXT_ITF_H__ + +#include "vom/gbp_bridge_domain.hpp" +#include "vom/gbp_route_domain.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A enternal interface for GBP + */ +class gbp_ext_itf : public object_base +{ +public: + /** + * The key for a GBP ext_itf interface + */ + typedef interface::key_t key_t; + + /** + * Construct a GBP ext_itf + */ + gbp_ext_itf(const interface& itf, + const gbp_bridge_domain& gbd, + const gbp_route_domain& grd); + + /** + * Copy Construct + */ + gbp_ext_itf(const gbp_ext_itf& r); + + /** + * Destructor + */ + ~gbp_ext_itf(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const gbp_ext_itf& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the ext_itf interface in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + + /** + * return the ext_itfulation interface's handle + */ + const handle_t& handle() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_ext_itf& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const gbp_ext_itf& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the ext_itf + */ + HW::item m_hw; + + /** + * The interface the ext_itf is attached to. + */ + std::shared_ptr m_itf; + + /** + * The BD & RD the ext_itf is in + */ + std::shared_ptr m_bd; + std::shared_ptr m_rd; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_ext_itf_cmds.cpp b/extras/deprecated/vom/vom/gbp_ext_itf_cmds.cpp new file mode 100644 index 00000000000..cf22aac102e --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_ext_itf_cmds.cpp @@ -0,0 +1,135 @@ +/* + * 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/gbp_ext_itf_cmds.hpp" + +namespace VOM { +namespace gbp_ext_itf_cmds { + +create_cmd::create_cmd(HW::item& item, + const handle_t& itf, + uint32_t bd_id, + uint32_t rd_id) + : rpc_cmd(item) + , m_itf(itf) + , m_bd_id(bd_id) + , m_rd_id(rd_id) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_bd_id == other.m_bd_id) && + (m_rd_id == other.m_rd_id)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.ext_itf.sw_if_index = m_itf.value(); + payload.ext_itf.bd_id = m_bd_id; + payload.ext_itf.rd_id = m_rd_id; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-ext_itf-create: " << m_hw_item.to_string() << " itf:" << m_itf + << " bd-id:" << m_bd_id << " rd-id:" << m_rd_id; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.ext_itf.sw_if_index = m_itf.value(); + payload.ext_itf.bd_id = ~0; + payload.ext_itf.rd_id = ~0; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-ext-itf-delete: " << m_hw_item.to_string() << " itf:" << m_itf; + + return (s.str()); +} + +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 ("gbp-ext-itf-dump"); +} + +}; // namespace gbp_ext_itf_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_ext_itf_cmds.hpp b/extras/deprecated/vom/vom/gbp_ext_itf_cmds.hpp new file mode 100644 index 00000000000..3d14f05580a --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_ext_itf_cmds.hpp @@ -0,0 +1,134 @@ +/* + * 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_GBP_EXT_ITF_CMDS_H__ +#define __VOM_GBP_EXT_ITF_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_ext_itf.hpp" + +#include + +namespace VOM { +namespace gbp_ext_itf_cmds { + +/** +* A command class that creates or updates the GBP ext_itf +*/ +class create_cmd : public rpc_cmd, vapi::Gbp_ext_itf_add_del> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + const handle_t& itf, + uint32_t bd_id, + uint32_t rd_id); + + /** + * 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; + +private: + const handle_t m_itf; + const uint32_t m_bd_id; + const uint32_t m_rd_id; +}; + +/** + * A cmd class that deletes a GBP ext_itf + */ +class delete_cmd : public rpc_cmd, vapi::Gbp_ext_itf_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, const handle_t& itf); + + /** + * 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: + const handle_t m_itf; +}; + +/** + * A cmd class that Dumps all the GBP ext_itfs + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace gbp_ext_itf_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_recirc.cpp b/extras/deprecated/vom/vom/gbp_recirc.cpp new file mode 100644 index 00000000000..5b0d368d80d --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_recirc.cpp @@ -0,0 +1,200 @@ +/* + * 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/gbp_recirc.hpp" +#include "vom/gbp_recirc_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +gbp_recirc::type_t::type_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +const gbp_recirc::type_t gbp_recirc::type_t::INTERNAL(0, "internal"); +const gbp_recirc::type_t gbp_recirc::type_t::EXTERNAL(1, "external"); + +singular_db gbp_recirc::m_db; + +gbp_recirc::event_handler gbp_recirc::m_evh; + +gbp_recirc::gbp_recirc(const interface& itf, + const type_t& type, + const gbp_endpoint_group& epg) + : m_hw(false) + , m_itf(itf.singular()) + , m_type(type) + , m_epg(epg.singular()) +{ +} + +gbp_recirc::gbp_recirc(const gbp_recirc& gbpe) + : m_hw(gbpe.m_hw) + , m_itf(gbpe.m_itf) + , m_type(gbpe.m_type) + , m_epg(gbpe.m_epg) +{ +} + +gbp_recirc::~gbp_recirc() +{ + sweep(); + m_db.release(key(), this); +} + +const gbp_recirc::key_t +gbp_recirc::key() const +{ + return (m_itf->key()); +} + +const handle_t& +gbp_recirc::handle() const +{ + return m_itf->handle(); +} + +bool +gbp_recirc::operator==(const gbp_recirc& gbpe) const +{ + return ((key() == gbpe.key()) && (m_type == gbpe.m_type) && + (m_itf == gbpe.m_itf) && (m_epg == gbpe.m_epg)); +} + +void +gbp_recirc::sweep() +{ + if (m_hw) { + HW::enqueue(new gbp_recirc_cmds::delete_cmd(m_hw, m_itf->handle())); + } + HW::write(); +} + +void +gbp_recirc::replay() +{ + if (m_hw) { + HW::enqueue(new gbp_recirc_cmds::create_cmd( + m_hw, m_itf->handle(), (m_type == type_t::EXTERNAL), m_epg->sclass())); + } +} + +std::string +gbp_recirc::to_string() const +{ + std::ostringstream s; + s << "gbp-recirc:[" << m_itf->to_string() << ", type:" << m_type.to_string() + << ", " << m_epg->to_string() << "]"; + + return (s.str()); +} + +void +gbp_recirc::update(const gbp_recirc& r) +{ + if (rc_t::OK != m_hw.rc()) { + HW::enqueue(new gbp_recirc_cmds::create_cmd( + m_hw, m_itf->handle(), (m_type == type_t::EXTERNAL), m_epg->sclass())); + } +} + +std::shared_ptr +gbp_recirc::find_or_add(const gbp_recirc& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +gbp_recirc::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +gbp_recirc::singular() const +{ + return find_or_add(*this); +} + +void +gbp_recirc::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +gbp_recirc::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "gbp-recirc" }, "GBP Recircs", this); +} + +void +gbp_recirc::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +gbp_recirc::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = + interface::find(payload.recirc.sw_if_index); + std::shared_ptr epg = + gbp_endpoint_group::find(payload.recirc.sclass); + + VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.recirc.sw_if_index + << ", " << payload.recirc.sclass << "]"; + + if (itf && epg) { + gbp_recirc recirc( + *itf, (payload.recirc.is_ext ? type_t::EXTERNAL : type_t::INTERNAL), + *epg); + OM::commit(key, recirc); + + VOM_LOG(log_level_t::DEBUG) << "read: " << recirc.to_string(); + } + } +} + +dependency_t +gbp_recirc::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +gbp_recirc::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_recirc.hpp b/extras/deprecated/vom/vom/gbp_recirc.hpp new file mode 100644 index 00000000000..7cc3b938705 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_recirc.hpp @@ -0,0 +1,209 @@ +/* + * 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_GBP_RECIRC_H__ +#define __VOM_GBP_RECIRC_H__ + +#include "vom/gbp_endpoint_group.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A recirculation interface for GBP use pre/post NAT + */ +class gbp_recirc : public object_base +{ +public: + /** + * The key for a GBP recirc interface + */ + typedef interface::key_t key_t; + + struct type_t : public enum_base + { + /** + * Internal recirclation interfaces accept per-NAT translation + * traffic from the external/NAT EPG and inject into the + * private/NAT-inside EPG + */ + const static type_t INTERNAL; + + /** + * External recirculation interfaces accept post-NAT translation + * traffic from the internal EPG and inject into the + * NAT EPG + */ + const static type_t EXTERNAL; + + private: + type_t(int v, const std::string s); + }; + + /** + * Construct a GBP recirc + */ + gbp_recirc(const interface& itf, + const type_t& type, + const gbp_endpoint_group& epg); + + /** + * Copy Construct + */ + gbp_recirc(const gbp_recirc& r); + + /** + * Destructor + */ + ~gbp_recirc(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const gbp_recirc& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the recirc interface in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + + /** + * return the recirculation interface's handle + */ + const handle_t& handle() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_recirc& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const gbp_recirc& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the recirc + */ + HW::item m_hw; + + /** + * The interface the recirc is attached to. + */ + std::shared_ptr m_itf; + + /** + * Is the reicrc for the external (i.e. post-NAT) or internal + */ + type_t m_type; + + /** + * The EPG the recirc is in + */ + std::shared_ptr m_epg; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_recirc_cmds.cpp b/extras/deprecated/vom/vom/gbp_recirc_cmds.cpp new file mode 100644 index 00000000000..a1832977adf --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_recirc_cmds.cpp @@ -0,0 +1,138 @@ +/* + * 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/gbp_recirc_cmds.hpp" + +namespace VOM { +namespace gbp_recirc_cmds { + +create_cmd::create_cmd(HW::item& item, + const handle_t& itf, + bool is_ext, + sclass_t sclass) + : rpc_cmd(item) + , m_itf(itf) + , m_is_ext(is_ext) + , m_sclass(sclass) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_is_ext == other.m_is_ext) && + (m_sclass == other.m_sclass)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.recirc.sw_if_index = m_itf.value(); + payload.recirc.sclass = m_sclass; + payload.recirc.is_ext = m_is_ext; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-recirc-create: " << m_hw_item.to_string() << " itf:" << m_itf + << " ext:" << m_is_ext << " sclass:" << m_sclass; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.recirc.sw_if_index = m_itf.value(); + payload.recirc.sclass = ~0; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-recirc-delete: " << m_hw_item.to_string() << " itf:" << m_itf; + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("gbp-recirc-dump"); +} + +}; // namespace gbp_recirc_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_recirc_cmds.hpp b/extras/deprecated/vom/vom/gbp_recirc_cmds.hpp new file mode 100644 index 00000000000..4e74bd49b7d --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_recirc_cmds.hpp @@ -0,0 +1,135 @@ +/* + * 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_GBP_RECIRC_CMDS_H__ +#define __VOM_GBP_RECIRC_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_recirc.hpp" + +#include + +namespace VOM { +namespace gbp_recirc_cmds { + +/** +* A command class that creates or updates the GBP recirc +*/ +class create_cmd : public rpc_cmd, vapi::Gbp_recirc_add_del> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + const handle_t& itf, + bool is_ext, + sclass_t sclass); + + /** + * 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; + +private: + const handle_t m_itf; + bool m_is_ext; + const sclass_t m_sclass; +}; + +/** + * A cmd class that deletes a GBP recirc + */ +class delete_cmd : public rpc_cmd, vapi::Gbp_recirc_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, const handle_t& itf); + + /** + * 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: + const handle_t m_itf; +}; + +/** + * A cmd class that Dumps all the GBP recircs + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace gbp_enpoint_cms +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_route_domain.cpp b/extras/deprecated/vom/vom/gbp_route_domain.cpp new file mode 100644 index 00000000000..0bb516d02e9 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_route_domain.cpp @@ -0,0 +1,279 @@ +/* + * 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/gbp_route_domain.hpp" +#include "vom/gbp_route_domain_cmds.hpp" +#include "vom/interface.hpp" +#include "vom/l2_binding.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +/** + * A DB of al the interfaces, key on the name + */ +singular_db gbp_route_domain::m_db; + +gbp_route_domain::event_handler gbp_route_domain::m_evh; + +/** + * Construct a new object matching the desried state + */ +gbp_route_domain::gbp_route_domain(const gbp_route_domain& rd) + : m_id(rd.id()) + , m_rd(rd.m_rd) + , m_scope(rd.m_scope) + , m_ip4_uu_fwd(rd.m_ip4_uu_fwd) + , m_ip6_uu_fwd(rd.m_ip6_uu_fwd) +{ +} + +gbp_route_domain::gbp_route_domain(const route_domain& rd, + scope_t scope, + const interface& ip4_uu_fwd, + const interface& ip6_uu_fwd) + : m_id(rd.table_id()) + , m_rd(rd.singular()) + , m_scope(scope) + , m_ip4_uu_fwd(ip4_uu_fwd.singular()) + , m_ip6_uu_fwd(ip6_uu_fwd.singular()) +{ +} + +gbp_route_domain::gbp_route_domain(const route_domain& rd, + scope_t scope, + const std::shared_ptr ip4_uu_fwd, + const std::shared_ptr ip6_uu_fwd) + : m_id(rd.table_id()) + , m_rd(rd.singular()) + , m_scope(scope) + , m_ip4_uu_fwd(ip4_uu_fwd) + , m_ip6_uu_fwd(ip6_uu_fwd) +{ + if (m_ip4_uu_fwd) + m_ip4_uu_fwd = m_ip4_uu_fwd->singular(); + if (m_ip6_uu_fwd) + m_ip6_uu_fwd = m_ip6_uu_fwd->singular(); +} + +gbp_route_domain::gbp_route_domain(const route_domain& rd, scope_t scope) + : m_id(rd.table_id()) + , m_rd(rd.singular()) + , m_scope(scope) + , m_ip4_uu_fwd() + , m_ip6_uu_fwd() +{ +} + +const gbp_route_domain::key_t +gbp_route_domain::key() const +{ + return (m_rd->key()); +} + +route::table_id_t +gbp_route_domain::id() const +{ + return (m_rd->table_id()); +} + +const std::shared_ptr +gbp_route_domain::get_route_domain() const +{ + return m_rd; +} + +const std::shared_ptr +gbp_route_domain::get_ip4_uu_fwd() const +{ + return m_ip4_uu_fwd; +} + +const std::shared_ptr +gbp_route_domain::get_ip6_uu_fwd() const +{ + return m_ip6_uu_fwd; +} + +bool +gbp_route_domain::operator==(const gbp_route_domain& b) const +{ + bool equal = true; + + if (m_ip4_uu_fwd && b.m_ip4_uu_fwd) + equal &= (m_ip4_uu_fwd->key() == b.m_ip4_uu_fwd->key()); + else if (!m_ip4_uu_fwd && !b.m_ip4_uu_fwd) + ; + else + equal = false; + + if (m_ip6_uu_fwd && b.m_ip6_uu_fwd) + equal &= (m_ip6_uu_fwd->key() == b.m_ip6_uu_fwd->key()); + else if (!m_ip6_uu_fwd && !b.m_ip6_uu_fwd) + ; + else + equal = false; + + return ((m_rd->key() == b.m_rd->key()) && m_scope == b.m_scope && equal); +} + +void +gbp_route_domain::sweep() +{ + if (rc_t::OK == m_id.rc()) { + HW::enqueue(new gbp_route_domain_cmds::delete_cmd(m_id)); + } + HW::write(); +} + +void +gbp_route_domain::replay() +{ + if (rc_t::OK == m_id.rc()) { + if (m_ip4_uu_fwd && m_ip6_uu_fwd) + HW::enqueue(new gbp_route_domain_cmds::create_cmd( + m_id, m_scope, m_ip4_uu_fwd->handle(), m_ip6_uu_fwd->handle())); + else + HW::enqueue(new gbp_route_domain_cmds::create_cmd( + m_id, m_scope, handle_t::INVALID, handle_t::INVALID)); + } +} + +gbp_route_domain::~gbp_route_domain() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_id.data(), this); +} + +std::string +gbp_route_domain::to_string() const +{ + std::ostringstream s; + s << "gbp-route-domain:[" << m_rd->to_string() << "scope:" << m_scope; + + if (m_ip4_uu_fwd) + s << " v4-uu:[" << m_ip4_uu_fwd->to_string() << "]"; + if (m_ip6_uu_fwd) + s << " v6-uu:[" << m_ip6_uu_fwd->to_string() << "]"; + + s << "]"; + + return (s.str()); +} + +std::shared_ptr +gbp_route_domain::find(const key_t& key) +{ + return (m_db.find(key)); +} + +void +gbp_route_domain::update(const gbp_route_domain& desired) +{ + if (rc_t::OK != m_id.rc()) { + if (m_ip4_uu_fwd && m_ip6_uu_fwd) + HW::enqueue(new gbp_route_domain_cmds::create_cmd( + m_id, m_scope, m_ip4_uu_fwd->handle(), m_ip6_uu_fwd->handle())); + else + HW::enqueue(new gbp_route_domain_cmds::create_cmd( + m_id, m_scope, handle_t::INVALID, handle_t::INVALID)); + } +} + +std::shared_ptr +gbp_route_domain::find_or_add(const gbp_route_domain& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +gbp_route_domain::singular() const +{ + return find_or_add(*this); +} + +void +gbp_route_domain::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +gbp_route_domain::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump VPP Route domains + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr ip6_uu_fwd = + interface::find(payload.rd.ip6_uu_sw_if_index); + std::shared_ptr ip4_uu_fwd = + interface::find(payload.rd.ip4_uu_sw_if_index); + + if (ip6_uu_fwd && ip4_uu_fwd) { + gbp_route_domain rd(payload.rd.rd_id, payload.rd.scope, *ip4_uu_fwd, + *ip6_uu_fwd); + OM::commit(key, rd); + VOM_LOG(log_level_t::DEBUG) << "dump: " << rd.to_string(); + } else { + gbp_route_domain rd(payload.rd.rd_id, payload.rd.scope); + OM::commit(key, rd); + VOM_LOG(log_level_t::DEBUG) << "dump: " << rd.to_string(); + } + } +} + +gbp_route_domain::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "grd", "groute" }, "GBP Route Domains", this); +} + +void +gbp_route_domain::event_handler::handle_replay() +{ + m_db.replay(); +} + +dependency_t +gbp_route_domain::event_handler::order() const +{ + return (dependency_t::VIRTUAL_TABLE); +} + +void +gbp_route_domain::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_route_domain.hpp b/extras/deprecated/vom/vom/gbp_route_domain.hpp new file mode 100644 index 00000000000..310e9e328c8 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_route_domain.hpp @@ -0,0 +1,197 @@ +/* + * 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_GBP_ROUTE_DOMAIN_H__ +#define __VOM_GBP_ROUTE_DOMAIN_H__ + +#include "vom/gbp_types.hpp" +#include "vom/interface.hpp" +#include "vom/route_domain.hpp" +#include "vom/singular_db.hpp" +#include "vom/types.hpp" + +namespace VOM { + +/** + * A entry in the ARP termination table of a Route Domain + */ +class gbp_route_domain : public object_base +{ +public: + /** + * The key for a route_domain is the pair of EPG-IDs + */ + typedef route_domain::key_t key_t; + + /** + * Construct a GBP route_domain + */ + gbp_route_domain(const route_domain& rd, scope_t scope); + + gbp_route_domain(const route_domain& rd, + scope_t scope, + const interface& ip4_uu_fwd, + const interface& ip6_uu_fwd); + gbp_route_domain(const route_domain& rd, + scope_t scope, + const std::shared_ptr ip4_uu_fwd, + const std::shared_ptr ip6_uu_fwd); + + /** + * Copy Construct + */ + gbp_route_domain(const gbp_route_domain& r); + + /** + * Destructor + */ + ~gbp_route_domain(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * Return the route domain's VPP ID + */ + route::table_id_t id() const; + + /** + * comparison operator + */ + bool operator==(const gbp_route_domain& rdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the route_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all route_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + + /** + * Accessors for children + */ + const std::shared_ptr get_route_domain() const; + const std::shared_ptr get_ip4_uu_fwd() const; + const std::shared_ptr get_ip6_uu_fwd() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_route_domain& obj); + + /** + * Find or add the instance of the route_domain domain in the OM + */ + static std::shared_ptr find_or_add( + const gbp_route_domain& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the endpoint + */ + HW::item m_id; + + std::shared_ptr m_rd; + scope_t m_scope; + std::shared_ptr m_ip4_uu_fwd; + std::shared_ptr m_ip6_uu_fwd; + + /** + * A map of all route_domains + */ + static singular_db m_db; +}; + +}; // namespace + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_route_domain_cmds.cpp b/extras/deprecated/vom/vom/gbp_route_domain_cmds.cpp new file mode 100644 index 00000000000..9b6457e1333 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_route_domain_cmds.cpp @@ -0,0 +1,140 @@ +/* + * 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/gbp_route_domain_cmds.hpp" + +namespace VOM { +namespace gbp_route_domain_cmds { + +create_cmd::create_cmd(HW::item& item, + scope_t scope, + const handle_t ip4_uu_fwd, + const handle_t ip6_uu_fwd) + : rpc_cmd(item) + , m_scope(scope) + , m_ip4_uu_fwd(ip4_uu_fwd) + , m_ip6_uu_fwd(ip6_uu_fwd) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_hw_item.data() == other.m_hw_item.data()) && + (m_scope == other.m_scope) && (m_ip4_uu_fwd == other.m_ip4_uu_fwd) && + (m_ip6_uu_fwd == other.m_ip6_uu_fwd)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.rd.rd_id = m_hw_item.data(); + payload.rd.scope = m_scope; + payload.rd.ip4_table_id = m_hw_item.data(); + payload.rd.ip6_table_id = m_hw_item.data(); + payload.rd.ip4_uu_sw_if_index = m_ip4_uu_fwd.value(); + payload.rd.ip6_uu_sw_if_index = m_ip6_uu_fwd.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-route-domain: " << m_hw_item.to_string() << " scope:" << m_scope + << " ip4-uu-fwd:" << m_ip4_uu_fwd.to_string() + << " ip6-uu-fwd:" << m_ip6_uu_fwd.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item) + : rpc_cmd(item) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_hw_item.data() == other.m_hw_item.data()); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.rd_id = m_hw_item.data(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-route-domain: " << m_hw_item.to_string(); + + return (s.str()); +} + +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 ("gbp-route-domain-dump"); +} + +}; // namespace gbp_route_domain_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_route_domain_cmds.hpp b/extras/deprecated/vom/vom/gbp_route_domain_cmds.hpp new file mode 100644 index 00000000000..577f334154a --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_route_domain_cmds.hpp @@ -0,0 +1,133 @@ +/* + * 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_GBP_ROUTE_DOMAIN_CMDS_H__ +#define __VOM_GBP_ROUTE_DOMAIN_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_route_domain.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace gbp_route_domain_cmds { +/** + * A command class that creates an Route-Domain + */ +class create_cmd + : public rpc_cmd, vapi::Gbp_route_domain_add> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + scope_t scope, + const handle_t ip4_uu_fwd, + const handle_t ip6_uu_fwd); + + /** + * 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; + +private: + const scope_t m_scope; + const handle_t m_ip4_uu_fwd; + const handle_t m_ip6_uu_fwd; +}; + +/** + * A cmd class that Delete an Route-Domain + */ +class delete_cmd + : public rpc_cmd, vapi::Gbp_route_domain_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item); + + /** + * 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; +}; + +/** + * A cmd class that Dumps all the route domains + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd() = default; + dump_cmd(const dump_cmd& d) = 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // gbp_route_domain_cmds +}; // VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_rule.cpp b/extras/deprecated/vom/vom/gbp_rule.cpp new file mode 100644 index 00000000000..5d13850d2d9 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_rule.cpp @@ -0,0 +1,228 @@ +/* + * 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 + +#include "vom/gbp_rule.hpp" + +namespace VOM { +gbp_rule::next_hop_t::next_hop_t(const boost::asio::ip::address& ip, + const mac_address_t& mac, + uint32_t bd_id, + uint32_t rd_id) + : m_ip(ip) + , m_mac(mac) + , m_bd_id(bd_id) + , m_rd_id(rd_id) +{ +} + +std::string +gbp_rule::next_hop_t::to_string() const +{ + std::ostringstream s; + + s << "[" + << "ip:" << m_ip << " mac:" << m_mac.to_string() << " bd:" << m_bd_id + << " rd:" << m_rd_id << "]"; + + return (s.str()); +} + +bool +gbp_rule::next_hop_t::operator<(const gbp_rule::next_hop_t& nh) const +{ + return (nh.m_ip < m_ip); +} + +bool +gbp_rule::next_hop_t::operator==(const gbp_rule::next_hop_t& nh) const +{ + return ((m_ip == nh.m_ip) && (m_mac == nh.m_mac) && (m_bd_id == nh.m_bd_id) && + (m_rd_id == nh.m_rd_id)); +} + +const boost::asio::ip::address& +gbp_rule::next_hop_t::getIp() const +{ + return m_ip; +} + +const mac_address_t& +gbp_rule::next_hop_t::getMac() const +{ + return m_mac; +} + +const uint32_t +gbp_rule::next_hop_t::getBdId() const +{ + return m_bd_id; +} + +const uint32_t +gbp_rule::next_hop_t::getRdId() const +{ + return m_rd_id; +} + +const gbp_rule::hash_mode_t gbp_rule::hash_mode_t::SRC_IP(1, "src-ip"); +const gbp_rule::hash_mode_t gbp_rule::hash_mode_t::DST_IP(0, "dst-ip"); +const gbp_rule::hash_mode_t gbp_rule::hash_mode_t::SYMMETRIC(2, "symmetric"); + +gbp_rule::hash_mode_t::hash_mode_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +const gbp_rule::hash_mode_t& +gbp_rule::hash_mode_t::from_int(vapi_enum_gbp_hash_mode i) +{ + if (i == GBP_API_HASH_MODE_SYMMETRIC) + return gbp_rule::hash_mode_t::SYMMETRIC; + else if (i == GBP_API_HASH_MODE_SRC_IP) + return gbp_rule::hash_mode_t::SRC_IP; + + return gbp_rule::hash_mode_t::DST_IP; +} + +gbp_rule::next_hop_set_t::next_hop_set_t(const gbp_rule::hash_mode_t& hm, + gbp_rule::next_hops_t& nhs) + : m_hm(hm) + , m_nhs(nhs) +{ +} + +gbp_rule::next_hop_set_t::next_hop_set_t(const hash_mode_t& hm) + : m_hm(hm) + , m_nhs() +{ +} + +std::string +gbp_rule::next_hop_set_t::to_string() const +{ + std::ostringstream s; + + s << "hash-mode:" << m_hm.to_string() << " next-hops:["; + auto it = m_nhs.cbegin(); + while (it != m_nhs.cend()) { + s << " " << it->to_string(); + ++it; + } + s << " ] next-hop-size:" << m_nhs.size(); + + return (s.str()); +} + +bool +gbp_rule::next_hop_set_t::operator==(const next_hop_set_t& nhs) const +{ + return ((m_hm == nhs.m_hm) && (m_nhs == nhs.m_nhs)); +} + +const gbp_rule::hash_mode_t& +gbp_rule::next_hop_set_t::hash_mode() const +{ + return m_hm; +} + +const gbp_rule::next_hops_t& +gbp_rule::next_hop_set_t::next_hops() const +{ + return m_nhs; +} + +const gbp_rule::action_t gbp_rule::action_t::REDIRECT(2, "redirect"); +const gbp_rule::action_t gbp_rule::action_t::PERMIT(1, "permit"); +const gbp_rule::action_t gbp_rule::action_t::DENY(0, "deny"); + +gbp_rule::action_t::action_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +const gbp_rule::action_t& +gbp_rule::action_t::from_int(vapi_enum_gbp_rule_action i) +{ + if (i == GBP_API_RULE_REDIRECT) + return gbp_rule::action_t::REDIRECT; + else if (i == GBP_API_RULE_PERMIT) + return gbp_rule::action_t::PERMIT; + + return gbp_rule::action_t::DENY; +} + +gbp_rule::gbp_rule(uint32_t priority, + const gbp_rule::next_hop_set_t& nhs, + const gbp_rule::action_t& a) + : m_priority(priority) + , m_nhs(nhs) + , m_action(a) +{ +} + +gbp_rule::gbp_rule(uint32_t priority, const gbp_rule::action_t& a) + : m_priority(priority) + , m_nhs() + , m_action(a) +{ +} + +bool +gbp_rule::operator<(const gbp_rule& other) const +{ + return (other.m_priority < m_priority); +} + +bool +gbp_rule::operator==(const gbp_rule& rule) const +{ + return ((m_action == rule.m_action) && (m_nhs == rule.m_nhs) && + (m_priority == rule.m_priority)); +} + +std::string +gbp_rule::to_string() const +{ + std::ostringstream s; + + s << "gbp-rule:[" + << "priority:" << m_priority << " action:" << m_action.to_string() + << " next-hop-set:[" << m_nhs.to_string() << "]]"; + + return (s.str()); +} + +const gbp_rule::action_t& +gbp_rule::action() const +{ + return m_action; +} + +const gbp_rule::next_hop_set_t& +gbp_rule::nhs() const +{ + return m_nhs; +} +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_rule.hpp b/extras/deprecated/vom/vom/gbp_rule.hpp new file mode 100644 index 00000000000..1871e7e14a6 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_rule.hpp @@ -0,0 +1,282 @@ +/* + * 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_GBP_RULE_H__ +#define __VOM_GBP_RULE_H__ + +#include + +#include "vom/types.hpp" +#include +namespace VOM { +class gbp_rule +{ +public: + /** + * Representation of next hop + */ + struct next_hop_t + { + /** + * Constructor for next_hop_t + */ + next_hop_t(const boost::asio::ip::address& ip, + const mac_address_t& mac, + uint32_t bd_id, + uint32_t rd_id); + + /** + * default destructor + */ + ~next_hop_t() = default; + + /** + * convert to string + */ + std::string to_string() const; + + /** + * less-than operator + */ + bool operator<(const next_hop_t& nh) const; + + /** + * comparison operator (for testing) + */ + bool operator==(const next_hop_t& nh) const; + + /** + * get the IP address + */ + const boost::asio::ip::address& getIp(void) const; + + /** + * get the mac address + */ + const mac_address_t& getMac(void) const; + + /** + * get the bridge domain Id + */ + const uint32_t getBdId(void) const; + + /** + * get the route domain Id + */ + const uint32_t getRdId(void) const; + + private: + /** + * IP address for next hop + */ + const boost::asio::ip::address m_ip; + + /** + * mac address for interface lookup + */ + const mac_address_t m_mac; + + /** + * bridge domain in which redirected endpoints exist + */ + const uint32_t m_bd_id; + + /** + * route domain in which redirected endpoints exist + */ + const uint32_t m_rd_id; + }; + + /** + * hash mode enum + */ + struct hash_mode_t : public enum_base + { + /** + * Flow Hash is calculated based on SRC IP + * in case of load balancing + */ + const static hash_mode_t SRC_IP; + + /** + * Flow hash is calculated based on DST IP + */ + const static hash_mode_t DST_IP; + + /** + * Flow hash is calculated based on SRC IP, + * DST IP and Protocol. SRC IP and DST IP + * addresses are sorted before hash such that + * a same hash is generated in both directions. + */ + const static hash_mode_t SYMMETRIC; + + /** + * create the hash mode from int value + */ + static const hash_mode_t& from_int(vapi_enum_gbp_hash_mode i); + + private: + hash_mode_t(int v, const std::string s); + }; + + /** + * unordered set of next hops + */ + typedef std::set next_hops_t; + + /** + * Representation of set of next hops and + * associated hash mode profile + */ + struct next_hop_set_t + { + /** + * Constructor for next_hop_set_t + */ + next_hop_set_t(const hash_mode_t& hm, next_hops_t& nhs); + next_hop_set_t(const hash_mode_t& hm = hash_mode_t::SYMMETRIC); + + /** + * Destructor for next_hop_set_t + */ + ~next_hop_set_t() = default; + + /** + * convert to string + */ + std::string to_string() const; + + /** + * Comparison operator + */ + bool operator==(const next_hop_set_t& nhs) const; + + /** + * get the hash mode + */ + const hash_mode_t& hash_mode(void) const; + + /** + * get the set of next hops + */ + const next_hops_t& next_hops(void) const; + + private: + /** + * hash mode for this rule + */ + const hash_mode_t m_hm; + + /** + * set of next hops + */ + const next_hops_t m_nhs; + }; + + /** + * ACL rule action enum + */ + struct action_t : public enum_base + { + /** + * Permit action + */ + const static action_t PERMIT; + + /** + * Deny action + */ + const static action_t DENY; + + /** + * Redirect action + */ + const static action_t REDIRECT; + + /** + * create the action from int value + */ + static const action_t& from_int(vapi_enum_gbp_rule_action i); + + private: + action_t(int v, const std::string s); + }; + + /** + * Construct a new object matching the desried state + */ + gbp_rule(uint32_t priority, const next_hop_set_t& nhs, const action_t& a); + gbp_rule(uint32_t priority, const action_t& a); + + /** + * Copy Constructor + */ + gbp_rule(const gbp_rule& o) = default; + + /** + * Destructor + */ + ~gbp_rule() = default; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * less-than operator + */ + bool operator<(const gbp_rule& rule) const; + + /** + * comparison operator (for testing) + */ + bool operator==(const gbp_rule& rule) const; + + /** + * Getters + */ + const next_hop_set_t& nhs() const; + const action_t& action() const; + +private: + /** + * Priority. Used to sort the rules in a list in the order + * in which they are applied + */ + uint32_t m_priority; + + /** + * set of next hops along with hash mode profile + */ + const next_hop_set_t m_nhs; + + /** + * Action on match + */ + const action_t m_action; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_subnet.cpp b/extras/deprecated/vom/vom/gbp_subnet.cpp new file mode 100644 index 00000000000..13d1b41adc1 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_subnet.cpp @@ -0,0 +1,299 @@ +/* + * 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/gbp_subnet.hpp" +#include "vom/api_types.hpp" +#include "vom/gbp_subnet_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +gbp_subnet::type_t::type_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +const gbp_subnet::type_t gbp_subnet::type_t::STITCHED_INTERNAL( + 0, + "stitched-internal"); +const gbp_subnet::type_t gbp_subnet::type_t::STITCHED_EXTERNAL( + 1, + "stitched-external"); +const gbp_subnet::type_t gbp_subnet::type_t::TRANSPORT(2, "transport"); +const gbp_subnet::type_t gbp_subnet::type_t::L3_OUT(3, "l3-out"); +const gbp_subnet::type_t gbp_subnet::type_t::ANON_L3_OUT(4, "anon-l3-out"); + +singular_db gbp_subnet::m_db; + +gbp_subnet::event_handler gbp_subnet::m_evh; + +gbp_subnet::gbp_subnet(const gbp_route_domain& rd, + const route::prefix_t& prefix, + const type_t& type) + : m_hw(false) + , m_rd(rd.singular()) + , m_prefix(prefix) + , m_type(type) + , m_recirc(nullptr) + , m_epg(nullptr) + , m_sclass(~0) +{ +} + +gbp_subnet::gbp_subnet(const gbp_route_domain& rd, + const route::prefix_t& prefix, + const gbp_recirc& recirc, + const gbp_endpoint_group& epg) + : m_hw(false) + , m_rd(rd.singular()) + , m_prefix(prefix) + , m_type(type_t::STITCHED_EXTERNAL) + , m_recirc(recirc.singular()) + , m_epg(epg.singular()) + , m_sclass(~0) +{ +} + +gbp_subnet::gbp_subnet(const gbp_route_domain& rd, + const route::prefix_t& prefix, + sclass_t sclass, + const type_t& type) + : m_hw(false) + , m_rd(rd.singular()) + , m_prefix(prefix) + , m_type(type) + , m_recirc(nullptr) + , m_epg() + , m_sclass(sclass) +{ +} + +gbp_subnet::gbp_subnet(const gbp_subnet& o) + : m_hw(o.m_hw) + , m_rd(o.m_rd) + , m_prefix(o.m_prefix) + , m_type(o.m_type) + , m_recirc(o.m_recirc) + , m_epg(o.m_epg) + , m_sclass(o.m_sclass) +{ +} + +gbp_subnet::~gbp_subnet() +{ + sweep(); + m_db.release(key(), this); +} + +const gbp_subnet::key_t +gbp_subnet::key() const +{ + return (std::make_pair(m_rd->key(), m_prefix)); +} + +bool +gbp_subnet::operator==(const gbp_subnet& gs) const +{ + return ((key() == gs.key()) && (m_type == gs.m_type) && + (m_recirc == gs.m_recirc) && (m_epg == gs.m_epg) && + (m_sclass == gs.m_sclass)); +} + +void +gbp_subnet::sweep() +{ + if (m_hw) { + HW::enqueue(new gbp_subnet_cmds::delete_cmd(m_hw, m_rd->id(), m_prefix)); + } + HW::write(); +} + +void +gbp_subnet::replay() +{ + if (m_hw) { + HW::enqueue(new gbp_subnet_cmds::create_cmd( + m_hw, m_rd->id(), m_prefix, m_type, + (m_recirc ? m_recirc->handle() : handle_t::INVALID), + (m_epg ? m_epg->sclass() : m_sclass))); + } +} + +std::string +gbp_subnet::to_string() const +{ + std::ostringstream s; + s << "gbp-subnet:[" << m_type.to_string() << ", " << m_rd->to_string() << ":" + << m_prefix.to_string(); + if (m_recirc) + s << ", " << m_recirc->to_string(); + if (m_epg) + s << ", " << m_epg->to_string(); + + s << "]"; + + return (s.str()); +} + +void +gbp_subnet::update(const gbp_subnet& r) +{ + if (rc_t::OK != m_hw.rc()) { + HW::enqueue(new gbp_subnet_cmds::create_cmd( + m_hw, m_rd->id(), m_prefix, m_type, + (m_recirc ? m_recirc->handle() : handle_t::INVALID), + (m_epg ? m_epg->sclass() : m_sclass))); + } else { + if (m_type != r.m_type) { + m_epg = r.m_epg; + m_recirc = r.m_recirc; + m_type = r.m_type; + + HW::enqueue(new gbp_subnet_cmds::create_cmd( + m_hw, m_rd->id(), m_prefix, m_type, + (m_recirc ? m_recirc->handle() : handle_t::INVALID), + (m_epg ? m_epg->sclass() : m_sclass))); + } + } +} + +std::shared_ptr +gbp_subnet::find_or_add(const gbp_subnet& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +gbp_subnet::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +gbp_subnet::singular() const +{ + return find_or_add(*this); +} + +void +gbp_subnet::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +gbp_subnet::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "gbp-subnet" }, "GBP Subnets", this); +} + +void +gbp_subnet::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +gbp_subnet::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + route::prefix_t pfx = from_api(payload.subnet.prefix); + std::shared_ptr rd = + gbp_route_domain::find(payload.subnet.rd_id); + + if (rd) { + switch (payload.subnet.type) { + case GBP_API_SUBNET_TRANSPORT: { + gbp_subnet gs(*rd, pfx, type_t::TRANSPORT); + OM::commit(key, gs); + VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); + break; + } + case GBP_API_SUBNET_STITCHED_INTERNAL: { + gbp_subnet gs(*rd, pfx, type_t::STITCHED_INTERNAL); + OM::commit(key, gs); + VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); + break; + } + case GBP_API_SUBNET_L3_OUT: { + gbp_subnet gs(*rd, pfx, payload.subnet.sclass); + OM::commit(key, gs); + VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); + break; + } + case GBP_API_SUBNET_ANON_L3_OUT: { + gbp_subnet gs(*rd, pfx, payload.subnet.sclass, type_t::ANON_L3_OUT); + OM::commit(key, gs); + VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); + break; + } + case GBP_API_SUBNET_STITCHED_EXTERNAL: { + std::shared_ptr itf = + interface::find(payload.subnet.sw_if_index); + std::shared_ptr epg = + gbp_endpoint_group::find(payload.subnet.sclass); + + if (itf && epg) { + std::shared_ptr recirc = gbp_recirc::find(itf->key()); + + if (recirc) { + gbp_subnet gs(*rd, pfx, *recirc, *epg); + OM::commit(key, gs); + VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); + } + } + } + } + } + } +} + +dependency_t +gbp_subnet::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +gbp_subnet::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const gbp_subnet::key_t& key) +{ + os << "[" << key.first << ", " << key.second << "]"; + + return os; +} + +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_subnet.hpp b/extras/deprecated/vom/vom/gbp_subnet.hpp new file mode 100644 index 00000000000..09132763f0e --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_subnet.hpp @@ -0,0 +1,252 @@ +/* + * 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_GBP_SUBNET_H__ +#define __VOM_GBP_SUBNET_H__ + +#include + +#include "vom/gbp_endpoint_group.hpp" +#include "vom/gbp_recirc.hpp" +#include "vom/gbp_route_domain.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A GBP Enpoint (i.e. a VM) + */ +class gbp_subnet : public object_base +{ +public: + /** + * The key for a GBP subnet; table and prefix + */ + typedef std::pair key_t; + + struct type_t : public enum_base + { + /** + * Internal subnet is reachable through the source EPG's + * uplink interface. + */ + const static type_t STITCHED_INTERNAL; + + /** + * External subnet requires NAT translation before egress. + */ + const static type_t STITCHED_EXTERNAL; + + /** + * A transport subnet, sent via the RD's UU-fwd interface + */ + const static type_t TRANSPORT; + + /** + * A L3-out subnet + */ + const static type_t L3_OUT; + + /** + * An anonymous L3-out subnet + */ + const static type_t ANON_L3_OUT; + + private: + type_t(int v, const std::string s); + }; + + /** + * Construct an internal GBP subnet + */ + gbp_subnet(const gbp_route_domain& rd, + const route::prefix_t& prefix, + const type_t& type); + + /** + * Construct an stitched external GBP subnet + */ + gbp_subnet(const gbp_route_domain& rd, + const route::prefix_t& prefix, + const gbp_recirc& recirc, + const gbp_endpoint_group& epg); + + /** + * Construct an l3-out GBP subnet + */ + gbp_subnet(const gbp_route_domain& rd, + const route::prefix_t& prefix, + sclass_t sclass, + const type_t& type = type_t::L3_OUT); + + /** + * Copy Construct + */ + gbp_subnet(const gbp_subnet& r); + + /** + * Destructor + */ + ~gbp_subnet(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const gbp_subnet& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_subnet& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const gbp_subnet& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the subnet + */ + HW::item m_hw; + + /** + * the route domain the prefix is in + */ + const std::shared_ptr m_rd; + + /** + * prefix to match + */ + const route::prefix_t m_prefix; + + /* + * Subnet type + */ + type_t m_type; + + /** + * The interface the prefix is reachable through + */ + std::shared_ptr m_recirc; + + /** + * The EPG the subnet is in + */ + std::shared_ptr m_epg; + + /** + * Sclass for l3-out subnets + */ + sclass_t m_sclass; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, const gbp_subnet::key_t& key); + +}; // namespace + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_subnet_cmds.cpp b/extras/deprecated/vom/vom/gbp_subnet_cmds.cpp new file mode 100644 index 00000000000..765f9403629 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_subnet_cmds.cpp @@ -0,0 +1,166 @@ +/* + * 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/gbp_subnet_cmds.hpp" +#include "vom/api_types.hpp" + +namespace VOM { +namespace gbp_subnet_cmds { + +create_cmd::create_cmd(HW::item& item, + route::table_id_t rd, + const route::prefix_t& prefix, + const gbp_subnet::type_t& type, + const handle_t& itf, + sclass_t sclass) + : rpc_cmd(item) + , m_rd(rd) + , m_prefix(prefix) + , m_type(type) + , m_itf(itf) + , m_sclass(sclass) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_rd == other.m_rd) && + (m_prefix == other.m_prefix) && (m_type == other.m_type) && + (m_itf == other.m_itf) && (m_sclass == other.m_sclass)); +} + +static vapi_enum_gbp_subnet_type +gbp_subnet_type_to_api(const gbp_subnet::type_t& type) +{ + if (gbp_subnet::type_t::STITCHED_INTERNAL == type) + return (GBP_API_SUBNET_STITCHED_INTERNAL); + if (gbp_subnet::type_t::STITCHED_EXTERNAL == type) + return (GBP_API_SUBNET_STITCHED_EXTERNAL); + if (gbp_subnet::type_t::TRANSPORT == type) + return (GBP_API_SUBNET_TRANSPORT); + if (gbp_subnet::type_t::L3_OUT == type) + return (GBP_API_SUBNET_L3_OUT); + + return (GBP_API_SUBNET_STITCHED_INTERNAL); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.subnet.type = gbp_subnet_type_to_api(m_type); + payload.subnet.rd_id = m_rd; + payload.subnet.sw_if_index = m_itf.value(); + payload.subnet.sclass = m_sclass; + payload.subnet.prefix = to_api(m_prefix); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-subnet-create: " << m_hw_item.to_string() << "type:" << m_type + << ", " << m_rd << ":" << m_prefix.to_string() << " itf:" << m_itf + << " sclass:" << m_sclass; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + route::table_id_t rd, + const route::prefix_t& prefix) + : rpc_cmd(item) + , m_rd(rd) + , m_prefix(prefix) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return ((m_rd == other.m_rd) && (m_prefix == other.m_prefix)); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.subnet.rd_id = m_rd; + payload.subnet.prefix = to_api(m_prefix); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-subnet-delete: " << m_hw_item.to_string() << ", " << m_rd << ":" + << m_prefix.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("gbp-subnet-dump"); +} + +}; // namespace gbp_subnet_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_subnet_cmds.hpp b/extras/deprecated/vom/vom/gbp_subnet_cmds.hpp new file mode 100644 index 00000000000..3801a5b4783 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_subnet_cmds.hpp @@ -0,0 +1,142 @@ +/* + * 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_GBP_SUBNET_CMDS_H__ +#define __VOM_GBP_SUBNET_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_subnet.hpp" + +#include + +namespace VOM { +namespace gbp_subnet_cmds { + +/** + * A command class that creates or updates the GBP subnet + */ +class create_cmd : public rpc_cmd, vapi::Gbp_subnet_add_del> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + route::table_id_t rd, + const route::prefix_t& prefix, + const gbp_subnet::type_t& type, + const handle_t& itf, + sclass_t sclass); + + /** + * 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; + +private: + const route::table_id_t m_rd; + const route::prefix_t m_prefix; + const gbp_subnet::type_t& m_type; + const handle_t m_itf; + const sclass_t m_sclass; +}; + +/** + * A cmd class that deletes a GBP subnet + */ +class delete_cmd : public rpc_cmd, vapi::Gbp_subnet_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, + route::table_id_t rd, + const route::prefix_t& prefix); + + /** + * 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: + const route::table_id_t m_rd; + const route::prefix_t m_prefix; +}; + +/** + * A cmd class that Dumps all the GBP subnets + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace gbp_enpoint_cms +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_types.hpp b/extras/deprecated/vom/vom/gbp_types.hpp new file mode 100644 index 00000000000..bbcc9195da8 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_types.hpp @@ -0,0 +1,40 @@ +/* + * 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_GBP_TYPES_H__ +#define __VOM_GBP_TYPES_H__ + +#include + +namespace VOM { + +/** + * EPG IDs are 32 bit integers + */ +typedef uint32_t vnid_t; +typedef uint16_t sclass_t; +typedef uint16_t scope_t; + +}; // namespace + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_vxlan.cpp b/extras/deprecated/vom/vom/gbp_vxlan.cpp new file mode 100644 index 00000000000..32d1db9da64 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_vxlan.cpp @@ -0,0 +1,241 @@ +/* + * 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/gbp_vxlan.hpp" +#include "vom/api_types.hpp" +#include "vom/gbp_vxlan_cmds.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +const std::string GBP_VXLAN_NAME = "gbp-vxlan"; + +/** + * A DB of al the interfaces, key on the name + */ +singular_db gbp_vxlan::m_db; + +gbp_vxlan::event_handler gbp_vxlan::m_evh; + +gbp_vxlan::gbp_vxlan(uint32_t vni, + const gbp_route_domain& grd, + const boost::asio::ip::address_v4& src) + : interface(mk_name(vni), + interface::type_t::UNKNOWN, + interface::admin_state_t::UP) + , m_vni(vni) + , m_gbd() + , m_grd(grd.singular()) + , m_src(src) +{ +} +gbp_vxlan::gbp_vxlan(uint32_t vni, + const gbp_bridge_domain& gbd, + const boost::asio::ip::address_v4& src) + : interface(mk_name(vni), + interface::type_t::UNKNOWN, + interface::admin_state_t::UP) + , m_vni(vni) + , m_gbd(gbd.singular()) + , m_grd() + , m_src(src) +{ +} + +gbp_vxlan::gbp_vxlan(const gbp_vxlan& vt) + : interface(vt) + , m_vni(vt.m_vni) + , m_gbd(vt.m_gbd) + , m_grd(vt.m_grd) + , m_src(vt.m_src) +{ +} + +std::string +gbp_vxlan::mk_name(uint32_t vni) +{ + std::ostringstream s; + + s << GBP_VXLAN_NAME << "-" << vni; + + return (s.str()); +} + +const gbp_vxlan::key_t +gbp_vxlan::key() const +{ + return (m_vni); +} + +bool +gbp_vxlan::operator==(const gbp_vxlan& vt) const +{ + return (m_vni == vt.m_vni && m_src == vt.m_src); +} + +void +gbp_vxlan::sweep() +{ + if (rc_t::OK == m_hdl) { + HW::enqueue(new gbp_vxlan_cmds::delete_cmd(m_hdl, m_vni)); + } + HW::write(); +} + +void +gbp_vxlan::replay() +{ + if (rc_t::OK == m_hdl) { + if (m_grd) + HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni, + false, m_grd->id())); + else if (m_gbd) + HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni, + true, m_gbd->id())); + } +} + +gbp_vxlan::~gbp_vxlan() +{ + sweep(); + m_db.release(key(), this); +} + +std::string +gbp_vxlan::to_string() const +{ + std::ostringstream s; + s << "gbp-vxlan:[" << m_vni << "]"; + + return (s.str()); +} + +std::shared_ptr +gbp_vxlan::find(const key_t key) +{ + return (m_db.find(key)); +} + +void +gbp_vxlan::update(const gbp_vxlan& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (rc_t::OK != m_hdl) { + if (m_grd) + HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni, + false, m_grd->id())); + else if (m_gbd) + HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni, + true, m_gbd->id())); + } +} + +std::shared_ptr +gbp_vxlan::find_or_add(const gbp_vxlan& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +gbp_vxlan::singular() const +{ + return find_or_add(*this); +} + +std::shared_ptr +gbp_vxlan::singular_i() const +{ + return find_or_add(*this); +} + +void +gbp_vxlan::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +gbp_vxlan::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump VPP Bridge domains + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + boost::asio::ip::address_v4 src = from_api(payload.tunnel.src); + + if (GBP_VXLAN_TUNNEL_MODE_L3 == payload.tunnel.mode) { + auto rd = gbp_route_domain::find(payload.tunnel.bd_rd_id); + + if (rd) { + gbp_vxlan vt(payload.tunnel.vni, *rd, src); + OM::commit(key, vt); + VOM_LOG(log_level_t::DEBUG) << "dump: " << vt.to_string(); + } + } else { + auto bd = gbp_bridge_domain::find(payload.tunnel.bd_rd_id); + + if (bd) { + gbp_vxlan vt(payload.tunnel.vni, *bd, src); + OM::commit(key, vt); + VOM_LOG(log_level_t::DEBUG) << "dump: " << vt.to_string(); + } + } + } +} + +gbp_vxlan::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "gvt", "gbp-vxlan-tunnel" }, "GBP VXLAN Tunnels", + this); +} + +void +gbp_vxlan::event_handler::handle_replay() +{ + m_db.replay(); +} + +dependency_t +gbp_vxlan::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +gbp_vxlan::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_vxlan.hpp b/extras/deprecated/vom/vom/gbp_vxlan.hpp new file mode 100644 index 00000000000..a3e223b0b3f --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_vxlan.hpp @@ -0,0 +1,191 @@ +/* + * 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_GBP_VXLAN_H__ +#define __VOM_GBP_VXLAN_H__ + +#include "vom/gbp_bridge_domain.hpp" +#include "vom/gbp_route_domain.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of a GBP_VXLAN Tunnel in VPP + */ +class gbp_vxlan : public interface +{ +public: + /** + * The VNI is the key + */ + typedef uint32_t key_t; + + /** + * Construct a new object matching the desried state + */ + gbp_vxlan(uint32_t vni, + const gbp_bridge_domain& gbd, + const boost::asio::ip::address_v4& src); + gbp_vxlan(uint32_t vni, + const gbp_route_domain& grd, + const boost::asio::ip::address_v4& src); + + /* + * Destructor + */ + ~gbp_vxlan(); + + /** + * Copy constructor + */ + gbp_vxlan(const gbp_vxlan& o); + + bool operator==(const gbp_vxlan& vt) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * Debug rpint function + */ + virtual std::string to_string() const; + + /** + * Return VPP's handle to this object + */ + const handle_t& handle() const; + + /** + * Dump all L3Configs into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Find the GBP_VXLAN tunnel in the OM + */ + static std::shared_ptr find(const key_t k); + +private: + /** + * 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; + }; + + /** + * Event handle to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const gbp_vxlan& obj); + + /** + * Return the matching 'instance' of the sub-interface + * over-ride from the base class + */ + std::shared_ptr singular_i() const; + + /** + * Find the GBP_VXLAN tunnel in the OM + */ + static std::shared_ptr find_or_add(const gbp_vxlan& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Tunnel VNI/key + */ + uint32_t m_vni; + std::shared_ptr m_gbd; + std::shared_ptr m_grd; + boost::asio::ip::address_v4 m_src; + + /** + * A map of all VLAN tunnela against thier key + */ + static singular_db m_db; + + /** + * Construct a unique name for the tunnel + */ + static std::string mk_name(uint32_t vni); +}; + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/gbp_vxlan_cmds.cpp b/extras/deprecated/vom/vom/gbp_vxlan_cmds.cpp new file mode 100644 index 00000000000..e35e4e976bd --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_vxlan_cmds.cpp @@ -0,0 +1,139 @@ +/* + * 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/gbp_vxlan_cmds.hpp" +#include "vom/api_types.hpp" + +namespace VOM { +namespace gbp_vxlan_cmds { +create_cmd::create_cmd(HW::item& item, + const std::string& name, + const boost::asio::ip::address_v4& src, + uint32_t vni, + bool is_l2, + uint32_t bd_rd) + : interface::create_cmd(item, name) + , m_src(src) + , m_vni(vni) + , m_is_l2(is_l2) + , m_bd_rd(bd_rd) +{ +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.tunnel.vni = m_vni; + payload.tunnel.bd_rd_id = m_bd_rd; + if (m_is_l2) + payload.tunnel.mode = GBP_VXLAN_TUNNEL_MODE_L2; + else + payload.tunnel.mode = GBP_VXLAN_TUNNEL_MODE_L3; + to_api(m_src, payload.tunnel.src); + + VAPI_CALL(req.execute()); + + wait(); + if (m_hw_item.rc() == rc_t::OK) { + insert_interface(); + } + + return (m_hw_item.rc()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-vxlan-create: " << m_hw_item.to_string() << " vni:" << m_vni + << " bd/rd:" << m_bd_rd; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, uint32_t vni) + : interface::delete_cmd(item) + , m_vni(vni) +{ +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.vni = m_vni; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "gbp-vxlan-delete: " << m_hw_item.to_string() << " vni:" << m_vni; + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("gbp-vxlan-dump"); +} + +} // namespace gbp_vxlan_cmds +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/gbp_vxlan_cmds.hpp b/extras/deprecated/vom/vom/gbp_vxlan_cmds.hpp new file mode 100644 index 00000000000..396ef7443e7 --- /dev/null +++ b/extras/deprecated/vom/vom/gbp_vxlan_cmds.hpp @@ -0,0 +1,137 @@ +/* + * 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_GBP_VXLAN_CMDS_H__ +#define __VOM_GBP_VXLAN_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/gbp_vxlan.hpp" +#include "vom/interface.hpp" + +#include + +namespace VOM { +namespace gbp_vxlan_cmds { +/** + * A command class that creates an Bridge-Domain + */ +class create_cmd : public interface::create_cmd +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + const std::string& name, + const boost::asio::ip::address_v4& src, + uint32_t vni, + bool is_l2, + uint32_t bd_rd); + + /** + * 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; + +private: + boost::asio::ip::address_v4 m_src; + uint32_t m_vni; + bool m_is_l2; + uint32_t m_bd_rd; +}; + +/** + * A cmd class that Delete an Bridge-Domain + */ +class delete_cmd : public interface::delete_cmd +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, uint32_t vni); + + /** + * 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: + uint32_t m_vni; +}; + +/** + * A cmd class that Dumps all the bridge domains + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // gbp_vxlan_cmds +}; // VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/hw.cpp b/extras/deprecated/vom/vom/hw.cpp new file mode 100644 index 00000000000..932a014b9f7 --- /dev/null +++ b/extras/deprecated/vom/vom/hw.cpp @@ -0,0 +1,306 @@ +/* + * 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/hw.hpp" +#include "vom/hw_cmds.hpp" +#include "vom/logger.hpp" +#include "vom/stat_reader.hpp" + +namespace VOM { +HW::cmd_q::cmd_q() + : m_enabled(true) + , m_connected(false) + , m_conn() +{ +} + +HW::cmd_q::~cmd_q() +{ +} + +HW::cmd_q& +HW::cmd_q::operator=(const HW::cmd_q& f) +{ + return (*this); +} + +/** + * Run the connect/dispatch thread. + */ +void +HW::cmd_q::rx_run() +{ + while (m_connected) { + m_conn.ctx().dispatch(); + } +} + +void +HW::cmd_q::enqueue(cmd* c) +{ + std::shared_ptr sp(c); + + m_queue.push_back(sp); +} + +void +HW::cmd_q::enqueue(std::shared_ptr c) +{ + m_queue.push_back(c); +} + +void +HW::cmd_q::enqueue(std::queue& cmds) +{ + while (cmds.size()) { + std::shared_ptr sp(cmds.front()); + + m_queue.push_back(sp); + cmds.pop(); + } +} + +bool +HW::cmd_q::connect() +{ + if (m_connected) + return m_connected; + + if (0 == m_conn.connect()) { + m_connected = true; + m_rx_thread.reset(new std::thread(&HW::cmd_q::rx_run, this)); + } + return (m_connected); +} + +void +HW::cmd_q::disconnect() +{ + + if (!m_connected) + return; + + m_connected = false; + + if (m_rx_thread && m_rx_thread->joinable()) { + m_rx_thread->join(); + } + + m_conn.disconnect(); +} + +void +HW::cmd_q::enable() +{ + m_enabled = true; +} + +void +HW::cmd_q::disable() +{ + m_enabled = false; +} + +rc_t +HW::cmd_q::write() +{ + rc_t rc = rc_t::OK; + + /* + * The queue is enabled, Execute each command in the queue. + * If one execution fails, abort the rest + */ + auto it = m_queue.begin(); + + while (it != m_queue.end()) { + std::shared_ptr c = *it; + + VOM_LOG(log_level_t::DEBUG) << *c; + + if (m_enabled) { + /* + * before we issue the command we must move it to the pending + * store + * ince a async event can be recieved before the command + * completes + */ + rc = c->issue(m_conn); + + if (rc_t::OK == rc) { + /* + * move to the next + */ + } else { + /* + * barf out without issuing the rest + */ + VOM_LOG(log_level_t::ERROR) << "Failed to execute: " << c->to_string(); + break; + } + } else { + /* + * The HW is disabled, so set each command as succeeded + */ + c->succeeded(); + } + + ++it; + } + + /* + * erase all objects in the queue + */ + m_queue.erase(m_queue.begin(), m_queue.end()); + + return (rc); +} + +/* + * The single Command Queue + */ +HW::cmd_q* HW::m_cmdQ; + +/* + * single stat reader + */ +stat_reader* HW::m_statReader; +HW::item HW::m_poll_state; + +/** + * Initialse the connection to VPP + */ +void +HW::init(HW::cmd_q* f) +{ + m_cmdQ = f; + m_statReader = new stat_reader(); +} + +/** + * Initialse the connection to VPP + */ +void +HW::init(HW::cmd_q* f, stat_reader* s) +{ + m_cmdQ = f; + m_statReader = s; +} + +/** + * Initialse the connection to VPP + */ +void +HW::init() +{ + m_cmdQ = new cmd_q(); + m_statReader = new stat_reader(); +} + +void +HW::enqueue(cmd* cmd) +{ + m_cmdQ->enqueue(cmd); +} + +void +HW::enqueue(std::shared_ptr cmd) +{ + m_cmdQ->enqueue(cmd); +} + +void +HW::enqueue(std::queue& cmds) +{ + m_cmdQ->enqueue(cmds); +} + +bool +HW::connect() +{ + return (m_cmdQ->connect() && m_statReader->connect()); +} + +void +HW::disconnect() +{ + m_statReader->disconnect(); + m_cmdQ->disconnect(); +} + +void +HW::enable() +{ + m_cmdQ->enable(); +} + +void +HW::disable() +{ + m_cmdQ->disable(); +} + +rc_t +HW::write() +{ + return (m_cmdQ->write()); +} + +bool +HW::poll() +{ + std::shared_ptr poll(new hw_cmds::poll(m_poll_state)); + + HW::enqueue(poll); + HW::write(); + + return (m_poll_state); +} + +void +HW::read_stats() +{ + m_statReader->read(); +} + +template <> +std::string +HW::item::to_string() const +{ + std::ostringstream os; + + os << "hw-item:[" + << "rc:" << item_rc.to_string() << " data:" << item_data << "]"; + return (os.str()); +} + +template <> +std::string +HW::item::to_string() const +{ + std::ostringstream os; + + os << "hw-item:[" + << "rc:" << item_rc.to_string() << " data:" << item_data << "]"; + return (os.str()); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/hw.hpp b/extras/deprecated/vom/vom/hw.hpp new file mode 100644 index 00000000000..e828139c83c --- /dev/null +++ b/extras/deprecated/vom/vom/hw.hpp @@ -0,0 +1,396 @@ +/* + * 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_HW_H__ +#define __VOM_HW_H__ + +#include +#include +#include +#include +#include +#include + +#include "vom/cmd.hpp" +#include "vom/connection.hpp" +#include "vom/types.hpp" + +namespace VOM { + +class stat_reader; +class cmd; +class HW +{ +public: + /** + * A HW::item is data that is either to be written to or read from + * VPP/HW. + * The item is a pair of the data written/read and the result of that + * operation. + */ + template + class item + { + public: + /** + * Constructor + */ + item(const T& data) + : item_data(data) + , item_rc(rc_t::NOOP) + { + } + /** + * Constructor + */ + item() + : item_data() + , item_rc(rc_t::UNSET) + { + } + + /** + * Constructor + */ + item(rc_t rc) + : item_data() + , item_rc(rc) + { + } + + /** + * Constructor + */ + item(const T& data, rc_t rc) + : item_data(data) + , item_rc(rc) + { + } + + /** + * Destructor + */ + ~item() = default; + + /** + * Comparison operator + */ + bool operator==(const item& i) const + { + return (item_data == i.item_data); + } + + /** + * Copy assignment + */ + item& operator=(const item& other) + { + item_data = other.item_data; + item_rc = other.item_rc; + + return (*this); + } + + /** + * Return the data read/written + */ + T& data() { return (item_data); } + + /** + * Const reference to the data + */ + const T& data() const { return (item_data); } + + /** + * Get the HW return code + */ + rc_t rc() const { return (item_rc); } + + /** + * Set the HW return code - should only be called from the + * family of Command objects + */ + void set(const rc_t& rc) { item_rc = rc; } + + /** + * Return true if the HW item is configred in HW + */ + operator bool() const { return (rc_t::OK == item_rc); } + + /** + * update the item to the desired state. + * return true if a HW update is required + */ + bool update(const item& desired) + { + bool need_hw_update = false; + + /* + * if the deisred set is unset (i.e. defaulted, we've + * no update to make + */ + if (rc_t::UNSET == desired.rc()) { + return (false); + } + /* + * A HW update is needed if thestate is different + * or the state is not yet in HW + */ + need_hw_update = (item_data != desired.data() || rc_t::OK != rc()); + + item_data = desired.data(); + + return (need_hw_update); + } + + /** + * convert to string format for debug purposes + */ + std::string to_string() const + { + std::ostringstream os; + + os << "hw-item:[" + << "rc:" << item_rc.to_string() << " data:" << item_data.to_string() + << "]"; + + return (os.str()); + } + + private: + /** + * The data + */ + T item_data; + + /** + * The result when the item was written + */ + rc_t item_rc; + }; + + /** + * The pipe to VPP into which we write the commands + */ + class cmd_q + { + public: + /** + * Constructor + */ + cmd_q(); + /** + * Destructor + */ + ~cmd_q(); + + /** + * Copy assignement - only used in UT + */ + cmd_q& operator=(const cmd_q& f); + + /** + * Enqueue a command into the Q. + */ + virtual void enqueue(cmd* c); + /** + * Enqueue a command into the Q. + */ + virtual void enqueue(std::shared_ptr c); + + /** + * Enqueue a set of commands + */ + virtual void enqueue(std::queue& c); + + /** + * Write all the commands to HW + */ + virtual rc_t write(); + + /** + * Blocking Connect to VPP - call once at bootup + */ + virtual bool connect(); + + /** + * Disconnect to VPP + */ + virtual void disconnect(); + + /** + * Disable the passing of commands to VPP. Whilst disabled all + * writes will be discarded. Use this during the reset phase. + */ + void disable(); + + /** + * Enable the passing of commands to VPP - undoes the disable. + * The Q is enabled by default. + */ + void enable(); + + private: + /** + * A queue of enqueued commands, ready to be written + */ + std::deque> m_queue; + + /** + * A map of issued, but uncompleted, commands. + * i.e. those that we are waiting, async stylee, + * for VPP to complete + */ + std::map> m_pending; + + /** + * VPP Q poll function + */ + void rx_run(); + + /** + * The thread object running the poll/dispatch/connect thread + */ + std::unique_ptr m_rx_thread; + + /** + * A flag indicating the client has disabled the cmd Q. + */ + bool m_enabled; + + /** + * A flag for the thread to poll to see if the queue is still alive + */ + bool m_connected; + + /** + * The connection to VPP + */ + connection m_conn; + }; + + /** + * Initialise the HW connection to VPP - the UT version passing + * a mock Q. + */ + static void init(cmd_q* f); + + /** + * Initialise the HW connection to VPP - the UT version passing + * a mock Q. + */ + static void init(cmd_q* f, stat_reader* s); + + /** + * Initialise the HW + */ + static void init(); + + /** + * Enqueue A command for execution + */ + static void enqueue(cmd* f); + + /** + * Enqueue A command for execution + */ + static void enqueue(std::shared_ptr c); + + /** + * Enqueue A set of commands for execution + */ + static void enqueue(std::queue& c); + + /** + * Write/Execute all commands hitherto enqueued. + */ + static rc_t write(); + + /** + * Blocking Connect to VPP + */ + static bool connect(); + + /** + * Disconnect to VPP + */ + static void disconnect(); + + /** + * Blocking pool of the HW connection + */ + static bool poll(); + + /** + * read stats from stat segment + */ + static void read_stats(); + +private: + /** + * The command Q toward HW + */ + static cmd_q* m_cmdQ; + + /** + * The stat reader toward HW + */ + static stat_reader* m_statReader; + + /** + * HW::item representing the connection state as determined by polling + */ + static HW::item m_poll_state; + + /** + * Disable the passing of commands to VPP. Whilst disabled all writes + * will be discarded. Use this during the reset phase. + */ + static void disable(); + + /** + * Enable the passing of commands to VPP - undoes the disable. + * The Q is enabled by default. + */ + static void enable(); + + /** + * Only the OM can enable/disable HW + */ + friend class OM; +}; + +/** + * bool Specialisation for HW::item to_string + */ +template <> +std::string HW::item::to_string() const; + +/** + * uint Specialisation for HW::item to_string + */ +template <> +std::string HW::item::to_string() const; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/hw_cmds.cpp b/extras/deprecated/vom/vom/hw_cmds.cpp new file mode 100644 index 00000000000..5f36b865bb6 --- /dev/null +++ b/extras/deprecated/vom/vom/hw_cmds.cpp @@ -0,0 +1,54 @@ +/* + * 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/hw_cmds.hpp" + +namespace VOM { +namespace hw_cmds { + +poll::poll(HW::item& item) + : rpc_cmd(item) +{ +} + +rc_t +poll::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +poll::to_string() const +{ + std::ostringstream s; + + s << "poll: " << m_hw_item.to_string(); + + return (s.str()); +} +} +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/hw_cmds.hpp b/extras/deprecated/vom/vom/hw_cmds.hpp new file mode 100644 index 00000000000..031556a8337 --- /dev/null +++ b/extras/deprecated/vom/vom/hw_cmds.hpp @@ -0,0 +1,64 @@ +/* + * 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_HW_CMDS_H__ +#define __VOM_HW_CMDS_H__ + +#include +#include + +#include "vom/hw.hpp" +#include "vom/rpc_cmd.hpp" + +namespace VOM { +namespace hw_cmds { +/** +*A command poll the HW for liveness +*/ +class poll : public rpc_cmd, vapi::Control_ping> +{ +public: + /** + * Constructor taking the HW::item to update + */ + poll(HW::item& item); + + /** + * 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 poll& i) const; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/igmp_binding.cpp b/extras/deprecated/vom/vom/igmp_binding.cpp new file mode 100644 index 00000000000..5e4b0343d36 --- /dev/null +++ b/extras/deprecated/vom/vom/igmp_binding.cpp @@ -0,0 +1,162 @@ +/* + * 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/igmp_binding.hpp" +#include "vom/igmp_binding_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +/** + * A DB of all igmp bindings configs + */ +singular_db igmp_binding::m_db; + +igmp_binding::event_handler igmp_binding::m_evh; + +igmp_binding::igmp_binding(const interface& itf) + : m_itf(itf.singular()) + , m_binding(true) +{ +} + +igmp_binding::igmp_binding(const igmp_binding& o) + : m_itf(o.m_itf) + , m_binding(o.m_binding) +{ +} + +igmp_binding::~igmp_binding() +{ + sweep(); + m_db.release(key(), this); +} + +bool +igmp_binding::operator==(const igmp_binding& l) const +{ + return (*m_itf == *l.m_itf); +} + +const igmp_binding::key_t +igmp_binding::key() const +{ + return (m_itf->key()); +} + +void +igmp_binding::sweep() +{ + if (m_binding) { + HW::enqueue(new igmp_binding_cmds::unbind_cmd(m_binding, m_itf->handle())); + } + HW::write(); +} + +void +igmp_binding::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +igmp_binding::replay() +{ + if (m_binding) { + HW::enqueue(new igmp_binding_cmds::bind_cmd(m_binding, m_itf->handle())); + } +} + +std::string +igmp_binding::to_string() const +{ + std::ostringstream s; + s << "igmp-binding: [" << m_itf->to_string() << " mode:host]"; + + return (s.str()); +} + +void +igmp_binding::update(const igmp_binding& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (!m_binding) { + HW::enqueue(new igmp_binding_cmds::bind_cmd(m_binding, m_itf->handle())); + } +} + +std::shared_ptr +igmp_binding::find_or_add(const igmp_binding& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +igmp_binding::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +igmp_binding::singular() const +{ + return find_or_add(*this); +} + +std::shared_ptr +igmp_binding::itf() const +{ + return m_itf; +} + +igmp_binding::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "igmp-binding" }, "IGMP bindings", this); +} + +void +igmp_binding::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +igmp_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + /* done with igmp_dump in igmp_listen */ +} + +dependency_t +igmp_binding::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +igmp_binding::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/igmp_binding.hpp b/extras/deprecated/vom/vom/igmp_binding.hpp new file mode 100644 index 00000000000..484bea6e9eb --- /dev/null +++ b/extras/deprecated/vom/vom/igmp_binding.hpp @@ -0,0 +1,183 @@ +/* + * 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_IGMP_BINDING_H__ +#define __VOM_IGMP_BINDING_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of IGMP binding on an interface + */ +class igmp_binding : public object_base +{ +public: + /** + * A binding is tied to a given interface, hence its key is + * that of the interface + */ + typedef interface::key_t key_t; + + /** + * Construct a new object matching the desried state + */ + igmp_binding(const interface& itf); + + /** + * Copy Constructor + */ + igmp_binding(const igmp_binding& o); + + /** + * Destructor + */ + ~igmp_binding(); + + /** + * Equal operator + */ + bool operator==(const igmp_binding& l) const; + + /** + * Get the object's key + */ + const key_t key() const; + + /** + * Return the 'singular' of the IGMP binding that matches this object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Return the matching'singular' of the interface + */ + std::shared_ptr itf() const; + + /** + * Dump all IGMP bindings into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Find a listen from its key + */ + static std::shared_ptr find(const key_t& k); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const igmp_binding& obj); + + /** + * Find or add IGMP binding to the OM + */ + static std::shared_ptr find_or_add(const igmp_binding& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer to the interface on which IGMP config + * resides. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A map of all IGMP bindings keyed against the interface. + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/igmp_binding_cmds.cpp b/extras/deprecated/vom/vom/igmp_binding_cmds.cpp new file mode 100644 index 00000000000..e18cb5b0834 --- /dev/null +++ b/extras/deprecated/vom/vom/igmp_binding_cmds.cpp @@ -0,0 +1,105 @@ +/* + * 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/igmp_binding_cmds.hpp" + +namespace VOM { +namespace igmp_binding_cmds { + +bind_cmd::bind_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{ +} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.enable = 1; + payload.mode = 1; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "igmp-bind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string(); + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{ +} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.enable = 0; + payload.mode = 1; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "igmp-unbind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string(); + + return (s.str()); +} + +}; // namespace igmp_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/igmp_binding_cmds.hpp b/extras/deprecated/vom/vom/igmp_binding_cmds.hpp new file mode 100644 index 00000000000..29766151bb7 --- /dev/null +++ b/extras/deprecated/vom/vom/igmp_binding_cmds.hpp @@ -0,0 +1,101 @@ +/* + * 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_IGMP_BINDING_CMDS_H__ +#define __VOM_IGMP_BINDING_CMDS_H__ + +#include "vom/igmp_binding.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace igmp_binding_cmds { +/** + * A command class that binds the IGMP config to the interface + */ +class bind_cmd : public rpc_cmd, vapi::Igmp_enable_disable> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to bind + */ + const handle_t& m_itf; +}; + +/** + * A cmd class that Unbinds IGMP Config from an interface + */ +class unbind_cmd : public rpc_cmd, vapi::Igmp_enable_disable> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to unbind + */ + const handle_t& m_itf; +}; + +}; // namespace cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/igmp_listen.cpp b/extras/deprecated/vom/vom/igmp_listen.cpp new file mode 100644 index 00000000000..9536bfb8859 --- /dev/null +++ b/extras/deprecated/vom/vom/igmp_listen.cpp @@ -0,0 +1,188 @@ +/* + * 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/igmp_listen.hpp" +#include "vom/igmp_listen_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +singular_db igmp_listen::m_db; + +igmp_listen::event_handler igmp_listen::m_evh; + +/** + * Construct a new object matching the desried state + */ +igmp_listen::igmp_listen(const igmp_binding& igmp_bind, + const boost::asio::ip::address_v4& gaddr, + const igmp_listen::src_addrs_t& saddrs) + : m_igmp_bind(igmp_bind.singular()) + , m_gaddr(gaddr) + , m_saddrs(saddrs) + , m_listen(true, rc_t::NOOP) +{ +} + +igmp_listen::igmp_listen(const igmp_binding& igmp_bind, + const boost::asio::ip::address_v4& gaddr) + : m_igmp_bind(igmp_bind.singular()) + , m_gaddr(gaddr) + , m_saddrs() + , m_listen(true, rc_t::NOOP) +{ +} + +igmp_listen::igmp_listen(const igmp_listen& o) + : m_igmp_bind(o.m_igmp_bind) + , m_gaddr(o.m_gaddr) + , m_saddrs(o.m_saddrs) + , m_listen(o.m_listen) +{ +} + +igmp_listen::~igmp_listen() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +bool +igmp_listen::operator==(const igmp_listen& l) const +{ + return ((m_gaddr == l.m_gaddr) && (*m_igmp_bind == *l.m_igmp_bind) && + (m_saddrs == l.m_saddrs)); +} + +const igmp_listen::key_t +igmp_listen::key() const +{ + return (make_pair(m_igmp_bind->itf()->key(), m_gaddr)); +} + +void +igmp_listen::sweep() +{ + if (m_listen) { + HW::enqueue(new igmp_listen_cmds::unlisten_cmd( + m_listen, m_igmp_bind->itf()->handle(), m_gaddr)); + } + HW::write(); +} + +void +igmp_listen::replay() +{ + if (m_listen) { + HW::enqueue(new igmp_listen_cmds::listen_cmd( + m_listen, m_igmp_bind->itf()->handle(), m_gaddr, m_saddrs)); + } +} + +std::string +igmp_listen::to_string() const +{ + auto addr = m_saddrs.cbegin(); + + std::ostringstream s; + s << "igmp-listen:[" << m_igmp_bind->to_string() << " group:" << m_gaddr + << " src-addrs: ["; + while (addr != m_saddrs.cend()) { + s << " " << *addr; + ++addr; + } + s << " ] " << m_listen.to_string() << "]"; + + return (s.str()); +} + +void +igmp_listen::update(const igmp_listen& desired) +{ + /* + * no updates for the listen. chaning the interface or the group addr is a + * change to the key, hence a new object + */ + if (!m_listen) { + HW::enqueue(new igmp_listen_cmds::listen_cmd( + m_listen, m_igmp_bind->itf()->handle(), m_gaddr, m_saddrs)); + } +} + +std::shared_ptr +igmp_listen::find_or_add(const igmp_listen& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +igmp_listen::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +igmp_listen::singular() const +{ + return find_or_add(*this); +} + +void +igmp_listen::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +igmp_listen::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "igmp-listen" }, "igmp listener", this); +} + +void +igmp_listen::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +igmp_listen::event_handler::handle_populate(const client_db::key_t& key) +{ + /** + * This is done while populating the interfaces + */ +} + +dependency_t +igmp_listen::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +igmp_listen::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/igmp_listen.hpp b/extras/deprecated/vom/vom/igmp_listen.hpp new file mode 100644 index 00000000000..44701d4bf44 --- /dev/null +++ b/extras/deprecated/vom/vom/igmp_listen.hpp @@ -0,0 +1,201 @@ +/* + * 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_IGMP_LISTEN_H__ +#define __VOM_IGMP_LISTEN_H__ + +#include "vom/hw.hpp" +#include "vom/igmp_binding.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of igmp configuration on an interface + */ +class igmp_listen : public object_base +{ +public: + typedef std::set src_addrs_t; + + /** + * The key type for igmp_listens + */ + typedef std::pair key_t; + + /** + * Construct a new object matching the desried state + */ + igmp_listen(const igmp_binding& igmp_bind, + const boost::asio::ip::address_v4& gaddr, + const src_addrs_t& saddrs); + igmp_listen(const igmp_binding& igmp_bind, + const boost::asio::ip::address_v4& gaddr); + + /** + * Copy Constructor + */ + igmp_listen(const igmp_listen& o); + + /** + * Destructor + */ + ~igmp_listen(); + + /** + * Comparison operator + */ + bool operator==(const igmp_listen& l) const; + + /** + * Get the object's key + */ + const key_t key() const; + + /** + * Return the 'singular instance' of the IGMP that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all igmp_listens into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Find a listen from its key + */ + static std::shared_ptr find(const key_t& k); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const igmp_listen& obj); + + /** + * Find or add the singular instance in the DB + */ + static std::shared_ptr find_or_add(const igmp_listen& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer the igmp_binding that this 'igmp listen' + * represents. By holding the reference here, we can guarantee that + * this object will outlive the igmp_binding + */ + const std::shared_ptr m_igmp_bind; + + /** + * The group address for igmp configuration + */ + const boost::asio::ip::address_v4 m_gaddr; + + /** + * The set of src addresses to listen for + */ + const src_addrs_t m_saddrs; + + /** + * HW configuration for the listen. The bool representing the + * do/don't bind. + */ + HW::item m_listen; + + /** + * A map of all igmp listen keyed against a combination of the interface + * and group addr keys. + */ + static singular_db m_db; +}; + +/** + * Ostream output for the key + */ +std::ostream& operator<<(std::ostream& os, const igmp_listen::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/igmp_listen_cmds.cpp b/extras/deprecated/vom/vom/igmp_listen_cmds.cpp new file mode 100644 index 00000000000..99a994d8cc8 --- /dev/null +++ b/extras/deprecated/vom/vom/igmp_listen_cmds.cpp @@ -0,0 +1,177 @@ +/* + * 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/igmp_listen_cmds.hpp" +#include "vom/api_types.hpp" + +DEFINE_VAPI_MSG_IDS_IGMP_API_JSON; + +namespace VOM { +namespace igmp_listen_cmds { +listen_cmd::listen_cmd(HW::item& item, + const handle_t& itf, + const boost::asio::ip::address_v4& gaddr, + const igmp_listen::src_addrs_t& saddrs) + : rpc_cmd(item) + , m_itf(itf) + , m_gaddr(gaddr) + , m_saddrs(saddrs) +{ +} + +bool +listen_cmd::operator==(const listen_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_gaddr == other.m_gaddr) && + (m_saddrs == other.m_saddrs)); +} + +rc_t +listen_cmd::issue(connection& con) +{ + u8 size = m_saddrs.size(); + msg_t req(con.ctx(), sizeof(vapi_type_ip4_address) * size, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.group.sw_if_index = m_itf.value(); + to_api(m_gaddr, payload.group.gaddr); + + if (0 == size) { + // no sources => (*,G) join + payload.group.filter = EXCLUDE; + payload.group.n_srcs = 0; + } else { + // source => (S,G) join + payload.group.filter = INCLUDE; + u8 i = 0; + + for (auto addr : m_saddrs) { + to_api(addr, payload.group.saddrs[i]); + i++; + } + payload.group.n_srcs = i; + } + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +listen_cmd::to_string() const +{ + auto addr = m_saddrs.cbegin(); + std::ostringstream s; + s << "igmp-listen: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() + << " group:" << m_gaddr << " src-addrs:["; + while (addr != m_saddrs.cend()) { + s << " " << *addr; + addr++; + } + s << " ]"; + return (s.str()); +} + +unlisten_cmd::unlisten_cmd(HW::item& item, + const handle_t& itf, + const boost::asio::ip::address_v4& gaddr) + : rpc_cmd(item) + , m_itf(itf) + , m_gaddr(gaddr) +{ +} + +bool +unlisten_cmd::operator==(const unlisten_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_gaddr == other.m_gaddr)); +} + +rc_t +unlisten_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), 0, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.group.sw_if_index = m_itf.value(); + payload.group.n_srcs = 0; + payload.group.filter = INCLUDE; + to_api(m_gaddr, payload.group.gaddr); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unlisten_cmd::to_string() const +{ + std::ostringstream s; + s << "igmp-unlisten: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string() << " group:" << m_gaddr; + + return (s.str()); +} + +dump_cmd::dump_cmd(const handle_t& hdl) + : m_itf(hdl) +{ +} + +dump_cmd::dump_cmd(const dump_cmd& d) + : m_itf(d.m_itf) +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("igmp-listen-dump"); +} + +}; // namespace igmp_listen_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/igmp_listen_cmds.hpp b/extras/deprecated/vom/vom/igmp_listen_cmds.hpp new file mode 100644 index 00000000000..1a1ca0facdc --- /dev/null +++ b/extras/deprecated/vom/vom/igmp_listen_cmds.hpp @@ -0,0 +1,162 @@ +/* + * 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_IGMP_LISTEN_CMDS_H__ +#define __VOM_IGMP_LISTEN_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/igmp_listen.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace igmp_listen_cmds { + +/** + * A functor class that binds the igmp group to the interface + */ +class listen_cmd : public rpc_cmd, vapi::Igmp_listen> +{ +public: + /** + * Constructor + */ + listen_cmd(HW::item& item, + const handle_t& itf, + const boost::asio::ip::address_v4& gaddr, + const igmp_listen::src_addrs_t& saddrs); + + /** + * 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 listen_cmd& i) const; + +private: + /** + * Reference to the interface to bind to + */ + const handle_t& m_itf; + + /** + * The igmp group to bind + */ + const boost::asio::ip::address_v4& m_gaddr; + + /** + * The igmp srouce specific addresses to listen them + */ + const igmp_listen::src_addrs_t& m_saddrs; +}; + +/** + * A cmd class that Unbinds igmp group from an interface + */ +class unlisten_cmd : public rpc_cmd, vapi::Igmp_listen> +{ +public: + /** + * Constructor + */ + unlisten_cmd(HW::item& item, + const handle_t& itf, + const boost::asio::ip::address_v4& gaddr); + + /** + * 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 unlisten_cmd& i) const; + +private: + /** + * Reference to the interface to unbind + */ + const handle_t& m_itf; + + /** + * The igmp group to unlisten + */ + const boost::asio::ip::address_v4& m_gaddr; +}; + +/** + * A cmd class that Dumps all the igmp configs + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(const handle_t& itf); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; + + /** + * The interface to get the igmp config for + */ + const handle_t& m_itf; +}; + +}; // namespace igmp_listen_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/inspect.cpp b/extras/deprecated/vom/vom/inspect.cpp new file mode 100644 index 00000000000..436c1f571fa --- /dev/null +++ b/extras/deprecated/vom/vom/inspect.cpp @@ -0,0 +1,107 @@ +/* + * 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 +#include +#include + +#include "vom/inspect.hpp" +#include "vom/logger.hpp" +#include "vom/om.hpp" + +namespace VOM { +std::unique_ptr> + inspect::m_cmd_handlers; + +std::unique_ptr, std::string>>> + inspect::m_help_handlers; + +void +inspect::handle_input(const std::string& message, std::ostream& output) +{ + if (message.length()) { + if (message.find("help") != std::string::npos) { + output << "Command Options: " << std::endl; + output << " keys - Show all keys owning objects" + << std::endl; + output << " key:XXX - Show all object referenced by " + "key XXX" + << std::endl; + output << " all - Show All objects" << std::endl; + output << "Individual object_base Types:" << std::endl; + + for (auto h : *m_help_handlers) { + output << " {"; + + for (auto s : h.first) { + output << s << " "; + } + output << "} - \t"; + output << h.second; + output << std::endl; + } + } else if (message.find("keys") != std::string::npos) { + OM::dump(output); + } else if (message.find("key:") != std::string::npos) { + std::vector results; + boost::split(results, message, boost::is_any_of(":\n")); + OM::dump(results[1], output); + } else if (message.find("all") != std::string::npos) { + /* + * get the unique set of handlers, then invoke each + */ + std::set hdlrs; + for (auto h : *m_cmd_handlers) { + hdlrs.insert(h.second); + } + for (auto h : hdlrs) { + h->show(output); + } + } else { + auto it = m_cmd_handlers->find(message); + + if (it != m_cmd_handlers->end()) { + it->second->show(output); + } else { + output << "Unknown Command: " << message << std::endl; + } + } + } +} + +void +inspect::register_handler(const std::vector& cmds, + const std::string& help, + command_handler* handler) +{ + if (!m_cmd_handlers) { + m_cmd_handlers.reset(new std::map); + m_help_handlers.reset( + new std::deque, std::string>>); + } + + for (auto cmd : cmds) { + (*m_cmd_handlers)[cmd] = handler; + } + m_help_handlers->push_front(std::make_pair(cmds, help)); +} +} +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/inspect.hpp b/extras/deprecated/vom/vom/inspect.hpp new file mode 100644 index 00000000000..a3f3d4935c0 --- /dev/null +++ b/extras/deprecated/vom/vom/inspect.hpp @@ -0,0 +1,96 @@ +/* + * 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_INSPECT_H__ +#define __VOM_INSPECT_H__ + +#include +#include +#include +#include +#include +#include + +namespace VOM { +/** + * A means to inspect the state VPP has built, in total, and per-client + */ +class inspect +{ +public: + /** + * Constructor + */ + inspect() = default; + + /** + * Destructor to tidyup socket resources + */ + ~inspect() = default; + + /** + * handle input from the requester + * + * @param input command + * @param output output + */ + void handle_input(const std::string& input, std::ostream& output); + + /** + * inspect command handler Handler + */ + class command_handler + { + public: + command_handler() = default; + virtual ~command_handler() = default; + + /** + * Show each object + */ + virtual void show(std::ostream& os) = 0; + }; + + /** + * Register a command handler for inspection + */ + static void register_handler(const std::vector& cmds, + const std::string& help, + command_handler* ch); + +private: + /** + * command handler list + */ + static std::unique_ptr> + m_cmd_handlers; + /** + * help handler list + */ + static std::unique_ptr< + std::deque, std::string>>> + m_help_handlers; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/interface.cpp b/extras/deprecated/vom/vom/interface.cpp new file mode 100644 index 00000000000..fcb88b3554c --- /dev/null +++ b/extras/deprecated/vom/vom/interface.cpp @@ -0,0 +1,776 @@ +/* + * 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/interface.hpp" +#include "vom/api_types.hpp" +#include "vom/bond_group_binding.hpp" +#include "vom/bond_group_binding_cmds.hpp" +#include "vom/bond_interface_cmds.hpp" +#include "vom/interface_cmds.hpp" +#include "vom/interface_factory.hpp" +#include "vom/l3_binding_cmds.hpp" +#include "vom/logger.hpp" +#include "vom/prefix.hpp" +#include "vom/singular_db_funcs.hpp" +#include "vom/stat_reader.hpp" +#include "vom/tap_interface_cmds.hpp" + +namespace VOM { +/** + * A DB of all the interfaces, key on the name + */ +singular_db interface::m_db; + +/** + * A DB of all the interfaces, key on VPP's handle + */ +std::map> interface::m_hdl_db; + +interface::event_handler interface::m_evh; + +/** + * the event enable command. + */ +std::shared_ptr interface::m_events_cmd; + +/** + * Construct a new object matching the desried state + */ +interface::interface(const std::string& name, + interface::type_t itf_type, + interface::admin_state_t itf_state, + const std::string& tag) + : m_hdl(handle_t::INVALID) + , m_name(name) + , m_type(itf_type) + , m_state(itf_state) + , m_table_id(route::DEFAULT_TABLE) + , m_l2_address(l2_address_t::ZERO, rc_t::UNSET) + , m_stats_type(stats_type_t::NORMAL) + , m_stats({}) + , m_listener(nullptr) + , m_oper(oper_state_t::DOWN) + , m_tag(tag) +{ +} + +interface::interface(const std::string& name, + interface::type_t itf_type, + interface::admin_state_t itf_state, + const route_domain& rd, + const std::string& tag) + : m_hdl(handle_t::INVALID) + , m_name(name) + , m_type(itf_type) + , m_rd(rd.singular()) + , m_state(itf_state) + , m_table_id(m_rd->table_id()) + , m_l2_address(l2_address_t::ZERO, rc_t::UNSET) + , m_stats_type(stats_type_t::NORMAL) + , m_stats({}) + , m_listener(nullptr) + , m_oper(oper_state_t::DOWN) + , m_tag(tag) +{ +} + +interface::interface(const interface& o) + : m_hdl(o.m_hdl) + , m_name(o.m_name) + , m_type(o.m_type) + , m_rd(o.m_rd) + , m_state(o.m_state) + , m_table_id(o.m_table_id) + , m_l2_address(o.m_l2_address) + , m_stats_type(o.m_stats_type) + , m_stats(o.m_stats) + , m_listener(o.m_listener) + , m_oper(o.m_oper) + , m_tag(o.m_tag) +{ +} + +bool +interface::operator==(const interface& i) const +{ + return ((key() == i.key()) && + (m_l2_address.data() == i.m_l2_address.data()) && + (m_state == i.m_state) && (m_rd == i.m_rd) && (m_type == i.m_type) && + (m_oper == i.m_oper)); +} + +interface::event_listener::event_listener() + : m_status(rc_t::NOOP) +{ +} + +HW::item& +interface::event_listener::status() +{ + return (m_status); +} + +interface::stat_listener::stat_listener() + : m_status(rc_t::NOOP) +{ +} + +HW::item& +interface::stat_listener::status() +{ + return (m_status); +} + +/** + * Return the interface type + */ +const interface::type_t& +interface::type() const +{ + return (m_type); +} + +const handle_t& +interface::handle() const +{ + return (singular()->handle_i()); +} + +const handle_t& +interface::handle_i() const +{ + return (m_hdl.data()); +} + +const l2_address_t& +interface::l2_address() const +{ + return (m_l2_address.data()); +} + +const interface::admin_state_t& +interface::admin_state() const +{ + return (m_state.data()); +} + +interface::const_iterator_t +interface::cbegin() +{ + return m_db.begin(); +} + +interface::const_iterator_t +interface::cend() +{ + return m_db.end(); +} + +void +interface::sweep() +{ + if (m_table_id && (m_table_id.data() != route::DEFAULT_TABLE)) { + m_table_id.data() = route::DEFAULT_TABLE; + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); + } + + if (m_listener) { + disable_stats_i(); + } + + // If the interface is up, bring it down + if (m_state && interface::admin_state_t::UP == m_state.data()) { + m_state.data() = interface::admin_state_t::DOWN; + HW::enqueue(new interface_cmds::state_change_cmd(m_state, m_hdl)); + } + + if (m_hdl) { + std::queue cmds; + HW::enqueue(mk_delete_cmd(cmds)); + } + HW::write(); +} + +void +interface::replay() +{ + if (m_hdl) { + std::queue cmds; + HW::enqueue(mk_create_cmd(cmds)); + } + + if (m_state && interface::admin_state_t::UP == m_state.data()) { + HW::enqueue(new interface_cmds::state_change_cmd(m_state, m_hdl)); + } + + if (m_listener) { + enable_stats(m_listener, m_stats_type.data()); + } + + if (m_table_id && (m_table_id.data() != route::DEFAULT_TABLE)) { + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); + } +} + +interface::~interface() +{ + sweep(); + release(); +} + +void +interface::release() +{ + // not in the DB anymore. + m_db.release(m_name, this); +} + +std::string +interface::to_string() const +{ + std::ostringstream s; + s << "interface:[" << m_name << " type:" << m_type.to_string() + << " hdl:" << m_hdl.to_string() << " l2-address:[" + << m_l2_address.to_string() << "]"; + + if (m_rd) { + s << " rd:" << m_rd->to_string(); + } + + s << " admin-state:" << m_state.to_string() + << " oper-state:" << m_oper.to_string(); + + if (!m_tag.empty()) { + s << " tag:[" << m_tag << "]"; + } + + s << "]"; + + return (s.str()); +} + +const std::string& +interface::name() const +{ + return (m_name); +} + +const interface::key_t& +interface::key() const +{ + return (name()); +} + +std::queue& +interface::mk_create_cmd(std::queue& q) +{ + if (type_t::LOOPBACK == m_type) { + q.push(new interface_cmds::loopback_create_cmd(m_hdl, m_name)); + q.push(new interface_cmds::set_tag(m_hdl, m_name)); + /* + * set the m_tag for pretty-print + */ + m_tag = m_name; + } else if (type_t::BVI == m_type) { + q.push(new interface_cmds::bvi_create_cmd(m_hdl, m_name)); + q.push(new interface_cmds::set_tag(m_hdl, m_name)); + m_tag = m_name; + } else if (type_t::AFPACKET == m_type) { + q.push(new interface_cmds::af_packet_create_cmd(m_hdl, m_name)); + if (!m_tag.empty()) + q.push(new interface_cmds::set_tag(m_hdl, m_tag)); + } else if (type_t::TAPV2 == m_type) { + if (!m_tag.empty()) + q.push(new interface_cmds::set_tag(m_hdl, m_tag)); + } else if (type_t::VHOST == m_type) { + q.push(new interface_cmds::vhost_create_cmd(m_hdl, m_name, m_tag)); + } else { + m_hdl.set(rc_t::OK); + } + + return (q); +} + +std::queue& +interface::mk_delete_cmd(std::queue& q) +{ + if (type_t::LOOPBACK == m_type) { + q.push(new interface_cmds::loopback_delete_cmd(m_hdl)); + } else if (type_t::BVI == m_type) { + q.push(new interface_cmds::bvi_delete_cmd(m_hdl)); + } else if (type_t::AFPACKET == m_type) { + q.push(new interface_cmds::af_packet_delete_cmd(m_hdl, m_name)); + } else if (type_t::VHOST == m_type) { + q.push(new interface_cmds::vhost_delete_cmd(m_hdl, m_name)); + } + + return (q); +} + +void +interface::update(const interface& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (rc_t::OK != m_hdl.rc()) { + std::queue cmds; + HW::enqueue(mk_create_cmd(cmds)); + /* + * interface create now, so we can barf early if it fails + */ + HW::write(); + } + + /* + * If the interface is not created do other commands should be issued + */ + if (rc_t::OK != m_hdl.rc()) + return; + + /* + * change the interface state to that which is deisred + */ + if (m_state.update(desired.m_state)) { + HW::enqueue(new interface_cmds::state_change_cmd(m_state, m_hdl)); + } + + /* + * change the interface state to that which is deisred + */ + if (m_l2_address.update(desired.m_l2_address)) { + HW::enqueue(new interface_cmds::set_mac_cmd(m_l2_address, m_hdl)); + } + + /* + * If the interface is mapped into a route domain, set VPP's + * table ID + */ + if (m_rd != desired.m_rd) { + /* + * changing route domains. need to remove all L3 bindings, swap the table + * then reapply the bindings. + */ + auto it = l3_binding::cbegin(); + + while (it != l3_binding::cend()) { + if (it->second.lock()->itf().key() == key()) + it->second.lock()->sweep(); + ++it; + } + m_rd = desired.m_rd; + m_table_id.update(m_rd ? m_rd->table_id() : route::DEFAULT_TABLE); + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); + HW::write(); + + it = l3_binding::cbegin(); + while (it != l3_binding::cend()) { + if (it->second.lock()->itf().key() == key()) + it->second.lock()->replay(); //(*it->second.lock()); + ++it; + } + } else if (!m_table_id && m_rd) { + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); + } +} + +void +interface::set(const admin_state_t& state) +{ + m_state = state; +} + +void +interface::set(const l2_address_t& addr) +{ + m_l2_address = { addr, rc_t::NOOP }; +} + +void +interface::set(const handle_t& hdl) +{ + m_hdl = hdl; +} + +void +interface::set(const oper_state_t& state) +{ + m_oper = state; +} + +void +interface::set(const std::string& tag) +{ + m_tag = tag; +} + +void +interface::set(const counter_t& count, const std::string& stat_type) +{ + if ("rx" == stat_type) + m_stats.m_rx = count; + else if ("tx" == stat_type) + m_stats.m_tx = count; + else if ("drops" == stat_type) + m_stats.m_drop = count; + else if ("rx-unicast" == stat_type) + m_stats.m_rx_unicast = count; + else if ("tx-unicast" == stat_type) + m_stats.m_tx_unicast = count; + else if ("rx-multicast" == stat_type) + m_stats.m_rx_multicast = count; + else if ("tx-multicast" == stat_type) + m_stats.m_tx_multicast = count; + else if ("rx-broadcast" == stat_type) + m_stats.m_rx_broadcast = count; + else if ("tx-broadcast" == stat_type) + m_stats.m_rx_broadcast = count; +} + +const interface::stats_t& +interface::get_stats(void) const +{ + return m_stats; +} + +void +interface::publish_stats() +{ + m_listener->handle_interface_stat(*this); +} + +std::ostream& +operator<<(std::ostream& os, const interface::stats_t& stats) +{ + os << "[" + << "rx " << stats.m_rx << " rx-unicast " << stats.m_rx_unicast + << " rx-multicast " << stats.m_rx_multicast << " rx-broadcast " + << stats.m_rx_broadcast << " tx " << stats.m_tx << " tx-unicast " + << stats.m_tx_unicast << " tx-multicast " << stats.m_tx_multicast + << " tx-broadcast " << stats.m_tx_broadcast << " drops " << stats.m_drop + << "]" << std::endl; + + return (os); +} + +void +interface::enable_stats_i(interface::stat_listener* el, const stats_type_t& st) +{ + if (el != NULL) { + if (stats_type_t::DETAILED == st) { + m_stats_type.set(rc_t::NOOP); + HW::enqueue(new interface_cmds::collect_detail_stats_change_cmd( + m_stats_type, handle_i(), true)); + } + stat_reader::registers(*this); + m_listener = el; + } +} + +void +interface::enable_stats(interface::stat_listener* el, const stats_type_t& st) +{ + singular()->enable_stats_i(el, st); +} + +void +interface::disable_stats_i() +{ + if (m_listener != NULL) { + if (stats_type_t::DETAILED == m_stats_type) { + HW::enqueue(new interface_cmds::collect_detail_stats_change_cmd( + m_stats_type, handle_i(), false)); + } + stat_reader::unregisters(*this); + m_listener = NULL; + } +} + +void +interface::disable_stats() +{ + singular()->disable_stats_i(); +} + +std::shared_ptr +interface::singular_i() const +{ + return (m_db.find_or_add(key(), *this)); +} + +std::shared_ptr +interface::singular() const +{ + return singular_i(); +} + +std::shared_ptr +interface::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +interface::find(const handle_t& handle) +{ + return (m_hdl_db[handle].lock()); +} + +void +interface::add(const key_t& key, const HW::item& item) +{ + std::shared_ptr sp = find(key); + + if (sp && item) { + m_hdl_db[item.data()] = sp; + } +} + +void +interface::remove(const HW::item& item) +{ + m_hdl_db.erase(item.data()); +} + +void +interface::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +interface::enable_events(interface::event_listener& el) +{ + m_events_cmd = std::make_shared(el); + HW::enqueue(m_events_cmd); + HW::write(); +} + +void +interface::disable_events() +{ + m_events_cmd.reset(); +} + +void +interface::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump VPP vhost-user interfaces + */ + std::shared_ptr vcmd = + std::make_shared(); + + HW::enqueue(vcmd); + HW::write(); + + for (auto& vhost_itf_record : *vcmd) { + std::shared_ptr vitf = + interface_factory::new_vhost_user_interface( + vhost_itf_record.get_payload()); + VOM_LOG(log_level_t::DEBUG) << " vhost-dump: " << vitf->to_string(); + OM::commit(key, *vitf); + } + + /* + * dump VPP af-packet interfaces + */ + std::shared_ptr afcmd = + std::make_shared(); + + HW::enqueue(afcmd); + HW::write(); + + for (auto& af_packet_itf_record : *afcmd) { + std::shared_ptr afitf = + interface_factory::new_af_packet_interface( + af_packet_itf_record.get_payload()); + VOM_LOG(log_level_t::DEBUG) << " af_packet-dump: " << afitf->to_string(); + OM::commit(key, *afitf); + } + + /* + * dump VPP tapv2 interfaces + */ + std::shared_ptr tapv2cmd = + std::make_shared(); + + HW::enqueue(tapv2cmd); + HW::write(); + + for (auto& tapv2_record : *tapv2cmd) { + std::shared_ptr tapv2itf = + interface_factory::new_tap_interface(tapv2_record.get_payload()); + VOM_LOG(log_level_t::DEBUG) << "tapv2-dump: " << tapv2itf->to_string(); + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, *tapv2itf); + } + + /* + * dump VPP interfaces + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& itf_record : *cmd) { + auto payload = itf_record.get_payload(); + VOM_LOG(log_level_t::DEBUG) << "dump: [" << payload.sw_if_index + << " name:" << (char*)payload.interface_name + << " tag:" << (char*)payload.tag << "]"; + + std::shared_ptr itf = interface_factory::new_interface(payload); + + if (itf && interface::type_t::LOCAL != itf->type()) { + VOM_LOG(log_level_t::DEBUG) << "dump: " << itf->to_string(); + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, *itf); + + /** + * Get the address configured on the interface + */ + std::shared_ptr dcmd = + std::make_shared( + l3_binding_cmds::dump_v4_cmd(itf->handle())); + + HW::enqueue(dcmd); + HW::write(); + + for (auto& l3_record : *dcmd) { + auto& payload = l3_record.get_payload(); + const route::prefix_t pfx = from_api(payload.prefix); + + VOM_LOG(log_level_t::DEBUG) << "dump: " << pfx.to_string(); + + l3_binding l3(*itf, pfx); + OM::commit(key, l3); + } + } + } + + /* + * dump VPP bond interfaces + */ + std::shared_ptr bcmd = + std::make_shared(); + + HW::enqueue(bcmd); + HW::write(); + + for (auto& bond_itf_record : *bcmd) { + std::shared_ptr bond_itf = + interface_factory::new_bond_interface(bond_itf_record.get_payload()); + + VOM_LOG(log_level_t::DEBUG) << " bond-dump:" << bond_itf->to_string(); + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, *bond_itf); + + std::shared_ptr scmd = + std::make_shared( + bond_group_binding_cmds::dump_cmd(bond_itf->handle())); + + HW::enqueue(scmd); + HW::write(); + + bond_group_binding::enslaved_itf_t enslaved_itfs; + + for (auto& slave_itf_record : *scmd) { + bond_member slave_itf = interface_factory::new_bond_member_interface( + slave_itf_record.get_payload()); + + VOM_LOG(log_level_t::DEBUG) << " slave-dump:" << slave_itf.to_string(); + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + // OM::commit(slave_itf->key(), *slave_itf); + enslaved_itfs.insert(slave_itf); + } + + if (!enslaved_itfs.empty()) { + bond_group_binding bid(*bond_itf, enslaved_itfs); + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, bid); + } + } +} + +interface::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "interface", "intf" }, "interfaces", this); +} + +void +interface::event_handler::handle_replay() +{ + m_db.replay(); +} + +dependency_t +interface::event_handler::order() const +{ + return (dependency_t::INTERFACE); +} + +void +interface::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/interface.hpp b/extras/deprecated/vom/vom/interface.hpp new file mode 100644 index 00000000000..53225f9b192 --- /dev/null +++ b/extras/deprecated/vom/vom/interface.hpp @@ -0,0 +1,758 @@ +/* + * 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_INTERFACE_H__ +#define __VOM_INTERFACE_H__ + +#include "vom/enum_base.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/prefix.hpp" +#include "vom/route_domain.hpp" +#include "vom/rpc_cmd.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * Forward declaration of the stats and events command + */ +namespace interface_cmds { +class events_cmd; +}; +class stat_reader; + +/** + * A representation of an interface in VPP + */ +class interface : public object_base +{ +public: + struct stats_type_t : public enum_base + { + const static stats_type_t DETAILED; + const static stats_type_t NORMAL; + + private: + stats_type_t(int v, const std::string& s); + }; + + /** + * The key for interface's key + */ + typedef std::string key_t; + + /** + * The iterator type + */ + typedef singular_db::const_iterator + const_iterator_t; + + /** + * An interface type + */ + struct type_t : enum_base + { + /** + * Unknown type + */ + const static type_t UNKNOWN; + /** + * A brideged Virtual interface (aka SVI or IRB) + */ + const static type_t BVI; + /** + * VXLAN interface + */ + const static type_t VXLAN; + /** + * Ethernet interface type + */ + const static type_t ETHERNET; + /** + * AF-Packet interface type + */ + const static type_t AFPACKET; + /** + * loopback interface type + */ + const static type_t LOOPBACK; + /** + * Local interface type (specific to VPP) + */ + const static type_t LOCAL; + + /** + * TAPv2 interface type + */ + const static type_t TAPV2; + + /** + * vhost-user interface type + */ + const static type_t VHOST; + + /** + * bond interface type + */ + 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 + */ + static type_t from_string(const std::string& str); + + private: + /** + * Private constructor taking the value and the string name + */ + type_t(int v, const std::string& s); + }; + + /** + * The admin state of the interface + */ + struct admin_state_t : enum_base + { + /** + * Admin DOWN state + */ + const static admin_state_t DOWN; + /** + * Admin UP state + */ + const static admin_state_t UP; + + /** + * Convert VPP's numerical value to enum type + */ + static admin_state_t from_int(uint8_t val); + + private: + /** + * Private constructor taking the value and the string name + */ + admin_state_t(int v, const std::string& s); + }; + + /** + * The oper state of the interface + */ + struct oper_state_t : enum_base + { + /** + * Operational DOWN state + */ + const static oper_state_t DOWN; + /** + * Operational UP state + */ + const static oper_state_t UP; + + /** + * Convert VPP's numerical value to enum type + */ + static oper_state_t from_int(uint8_t val); + + private: + /** + * Private constructor taking the value and the string name + */ + oper_state_t(int v, const std::string& s); + }; + + /** + * stats_t: + */ + struct stats_t + { + counter_t m_rx; + counter_t m_tx; + counter_t m_rx_unicast; + counter_t m_tx_unicast; + counter_t m_rx_multicast; + counter_t m_tx_multicast; + counter_t m_rx_broadcast; + counter_t m_tx_broadcast; + counter_t m_drop; + }; + + /** + * Construct a new object matching the desried state + */ + interface(const std::string& name, + type_t type, + admin_state_t state, + const std::string& tag = ""); + /** + * Construct a new object matching the desried state mapped + * to a specific route_domain + */ + interface(const std::string& name, + type_t type, + admin_state_t state, + const route_domain& rd, + const std::string& tag = ""); + /** + * Destructor + */ + virtual ~interface(); + + /** + * Copy Constructor + */ + interface(const interface& o); + + static const_iterator_t cbegin(); + static const_iterator_t cend(); + + /** + * Return the matching'singular' of the interface + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + virtual std::string to_string(void) const; + + /** + * Return VPP's handle to this object + */ + const handle_t& handle() const; + + /** + * Return the interface type + */ + const type_t& type() const; + + /** + * Return the interface type + */ + const std::string& name() const; + + /** + * Return the interface type + */ + const key_t& key() const; + + /** + * Return the L2 Address + */ + const l2_address_t& l2_address() const; + + /** + * Return the admin state + */ + const admin_state_t& admin_state() const; + + /** + * Set the admin state of the interface + * + * N.B. All set function change only the attibute of the object on whcih + * they act, they do not make changes in VPP + */ + void set(const admin_state_t& state); + + /** + * Set the L2 Address + */ + void set(const l2_address_t& addr); + + /** + * Set the operational state of the interface, as reported by VPP + */ + void set(const oper_state_t& state); + + /** + * Set the tag to the interface + */ + void set(const std::string& tag); + + /** + * Get the interface stats + */ + const stats_t& get_stats(void) const; + + /** + * Comparison operator - only used for UT + */ + virtual bool operator==(const interface& i) const; + + /** + * A base class for interface Create commands + */ + template + class create_cmd : public rpc_cmd, MSG> + { + public: + create_cmd(HW::item& item, const std::string& name) + : rpc_cmd, MSG>(item) + , m_name(name) + { + } + + /** + * Destructor + */ + virtual ~create_cmd() = default; + + /** + * Comparison operator - only used for UT + */ + virtual bool operator==(const create_cmd& o) const + { + return (m_name == o.m_name); + } + + /** + * Indicate the succeeded, when the HW Q is disabled. + */ + void succeeded() + { + rpc_cmd, MSG>::succeeded(); + interface::add(m_name, this->item()); + } + + /** + * add the created interface to the DB + */ + void insert_interface() { interface::add(m_name, this->item()); } + + virtual vapi_error_e operator()(MSG& reply) + { + int sw_if_index = reply.get_response().get_payload().sw_if_index; + int retval = reply.get_response().get_payload().retval; + + VOM_LOG(log_level_t::DEBUG) << this->to_string() << " res:" << retval + << " sw-if-index:" << sw_if_index; + + rc_t rc = rc_t::from_vpp_retval(retval); + handle_t handle = handle_t::INVALID; + + if (rc_t::OK == rc) { + handle = sw_if_index; + } + + this->fulfill(HW::item(handle, rc)); + + return (VAPI_OK); + } + + protected: + /** + * The name of the interface to be created + */ + const std::string& m_name; + }; + + /** + * Base class for intterface Delete commands + */ + template + class delete_cmd : public rpc_cmd, MSG> + { + public: + delete_cmd(HW::item& item, const std::string& name) + : rpc_cmd, MSG>(item) + , m_name(name) + { + } + + delete_cmd(HW::item& item) + : rpc_cmd, MSG>(item) + , m_name() + { + } + + /** + * Destructor + */ + virtual ~delete_cmd() = default; + + /** + * Comparison operator - only used for UT + */ + virtual bool operator==(const delete_cmd& o) const + { + return (this->m_hw_item == o.m_hw_item); + } + + /** + * Indicate the succeeded, when the HW Q is disabled. + */ + void succeeded() {} + + /** + * remove the deleted interface from the DB + */ + void remove_interface() { interface::remove(this->item()); } + + protected: + /** + * The name of the interface to be created + */ + const std::string m_name; + }; + + struct event + { + event(const interface& itf, const interface::oper_state_t& state) + : itf(itf) + , state(state) + { + } + + const interface& itf; + interface::oper_state_t state; + }; + + /** + * A class that listens to interface Events + */ + class event_listener + { + public: + /** + * Default Constructor + */ + event_listener(); + + /** + * Virtual function called on the listener when the command has data + * ready to process + */ + virtual void handle_interface_event(std::vector es) = 0; + + /** + * Return the HW::item representing the status + */ + HW::item& status(); + + protected: + /** + * The status of the subscription + */ + HW::item m_status; + }; + + /** + * A class that listens to interface Stats + */ + class stat_listener + { + public: + /** + * Default Constructor + */ + stat_listener(); + + virtual ~stat_listener() = default; + + /** + * Virtual function called on the listener when the command has data + * ready to process + */ + virtual void handle_interface_stat(const interface&) = 0; + + /** + * Return the HW::item representing the status + */ + HW::item& status(); + + protected: + /** + * The status of the subscription + */ + HW::item m_status; + }; + + /** + * The the singular instance of the interface in the DB by handle + */ + static std::shared_ptr find(const handle_t& h); + + /** + * The the singular instance of the interface in the DB by key + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all interfaces into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Enable stats for this interface + */ + void enable_stats(stat_listener* el, + const stats_type_t& st = stats_type_t::NORMAL); + + /** + * Disable stats for this interface + */ + void disable_stats(); + + /** + * Enable the reception of events of all interfaces + */ + static void enable_events(interface::event_listener& el); + + /** + * disable the reception of events of all interfaces + */ + static void disable_events(); + +protected: + /** + * Set the handle of an interface object. Only called by the interface + * factory during the populate + */ + void set(const handle_t& handle); + friend class interface_factory; + friend class pipe; + /** + * The SW interface handle VPP has asigned to the interface + */ + HW::item m_hdl; + + /** + * Return the matching 'singular' of the interface + */ + virtual std::shared_ptr singular_i() const; + + /** + * release/remove an interface form the singular store + */ + void release(); + + /** + * Virtual functions to construct an interface create commands. + * Overridden in derived classes like the sub_interface + */ + virtual std::queue& mk_create_cmd(std::queue& cmds); + + /** + * Virtual functions to construct an interface delete commands. + * Overridden in derived classes like the sub_interface + */ + virtual std::queue& mk_delete_cmd(std::queue& cmds); + + /** + * Sweep/reap the object if still stale + */ + virtual void sweep(void); + + /** + * A map of all interfaces key against the interface's name + */ + static singular_db m_db; + + /** + * Add an interface to the DB keyed on handle + */ + static void add(const key_t& name, const HW::item& item); + + /** + * remove an interface from the DB keyed on handle + */ + static void remove(const HW::item& item); + +private: + /** + * 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; + + /** + * friend with stat_reader + */ + friend stat_reader; + + /** + * publish stats + */ + void publish_stats(); + + /** + * Set the interface stat + */ + void set(const counter_t& count, const std::string& stat_type); + + /** + * enable the interface stats in the singular instance + */ + void enable_stats_i(stat_listener* el, const stats_type_t& st); + + /** + * disable the interface stats in the singular instance + */ + void disable_stats_i(); + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const interface& obj); + + /* + * return the interface's handle in the singular instance + */ + const handle_t& handle_i() const; + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * The interfaces name + */ + const std::string m_name; + + /** + * The interface type. clearly this cannot be changed + * once the interface has been created. + */ + const type_t m_type; + + /** + * shared pointer to the routeDoamin the interface is in. + * NULL is not mapped - i.e. in the default table + */ + std::shared_ptr m_rd; + + /** + * The state of the interface + */ + HW::item m_state; + + /** + * HW state of the VPP table mapping + */ + HW::item m_table_id; + + /** + * HW state of the L2 address + */ + HW::item m_l2_address; + + /** + * The state of the detailed stats collection + */ + HW::item m_stats_type; + + /** + * Interface stats + */ + stats_t m_stats; + + /** + * reference to stat listener + */ + stat_listener* m_listener; + + /** + * Operational state of the interface + */ + oper_state_t m_oper; + + /** + * tag of the interface + */ + std::string m_tag; + + /** + * A map of all interfaces keyed against VPP's handle + */ + static std::map> m_hdl_db; + + /** + * replay the object to create it in hardware + */ + virtual void replay(void); + + /** + * Create commands are firends so they can add interfaces to the + * handle store. + */ + template + friend class create_cmd; + + /** + * Create commands are firends so they can remove interfaces from the + * handle store. + */ + template + friend class delete_cmd; + + static std::shared_ptr m_events_cmd; +}; + +/** + * stream insertion operator for interface stats + */ +std::ostream& operator<<(std::ostream& os, const interface::stats_t& stats); +}; +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ +#endif diff --git a/extras/deprecated/vom/vom/interface_cmds.cpp b/extras/deprecated/vom/vom/interface_cmds.cpp new file mode 100644 index 00000000000..d043a38b068 --- /dev/null +++ b/extras/deprecated/vom/vom/interface_cmds.cpp @@ -0,0 +1,668 @@ +/* + * 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/interface_cmds.hpp" +#include "vom/cmd.hpp" + +DEFINE_VAPI_MSG_IDS_VPE_API_JSON; +DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON; +DEFINE_VAPI_MSG_IDS_AF_PACKET_API_JSON; +DEFINE_VAPI_MSG_IDS_VHOST_USER_API_JSON; + +namespace VOM { +namespace interface_cmds { + +bvi_create_cmd::bvi_create_cmd(HW::item& item, + const std::string& name) + : create_cmd(item, name) +{ +} + +rc_t +bvi_create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.user_instance = ~0; + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) { + insert_interface(); + } + + return rc_t::OK; +} +std::string +bvi_create_cmd::to_string() const +{ + std::ostringstream s; + s << "bvi-itf-create: " << m_hw_item.to_string() << " name:" << m_name; + + return (s.str()); +} + +loopback_create_cmd::loopback_create_cmd(HW::item& item, + const std::string& name) + : create_cmd(item, name) +{ +} + +rc_t +loopback_create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) { + insert_interface(); + } + + return rc_t::OK; +} +std::string +loopback_create_cmd::to_string() const +{ + std::ostringstream s; + s << "loopback-itf-create: " << m_hw_item.to_string() << " name:" << m_name; + + return (s.str()); +} + +af_packet_create_cmd::af_packet_create_cmd(HW::item& item, + const std::string& name) + : create_cmd(item, name) +{ +} + +rc_t +af_packet_create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.use_random_hw_addr = 1; + memset(payload.host_if_name, 0, sizeof(payload.host_if_name)); + memcpy(payload.host_if_name, m_name.c_str(), + std::min(m_name.length(), sizeof(payload.host_if_name))); + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) { + insert_interface(); + } + + return rc_t::OK; +} +std::string +af_packet_create_cmd::to_string() const +{ + std::ostringstream s; + s << "af-packet-itf-create: " << m_hw_item.to_string() << " name:" << m_name; + + return (s.str()); +} + +vhost_create_cmd::vhost_create_cmd(HW::item& item, + const std::string& name, + const std::string& tag) + : create_cmd(item, name) + , m_tag(tag) +{ +} + +rc_t +vhost_create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + memset(payload.sock_filename, 0, sizeof(payload.sock_filename)); + memcpy(payload.sock_filename, m_name.c_str(), + std::min(m_name.length(), sizeof(payload.sock_filename))); + memset(payload.tag, 0, sizeof(payload.tag)); + + if (!m_tag.empty()) + memcpy(payload.tag, m_tag.c_str(), + std::min(m_tag.length(), sizeof(payload.tag))); + + payload.is_server = 0; + payload.use_custom_mac = 0; + payload.renumber = 0; + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) { + insert_interface(); + } + + return rc_t::OK; +} + +std::string +vhost_create_cmd::to_string() const +{ + std::ostringstream s; + s << "vhost-intf-create: " << m_hw_item.to_string() << " name:" << m_name + << " tag:" << m_tag; + + return (s.str()); +} + +bvi_delete_cmd::bvi_delete_cmd(HW::item& item) + : delete_cmd(item) +{ +} + +rc_t +bvi_delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return rc_t::OK; +} + +std::string +bvi_delete_cmd::to_string() const +{ + std::ostringstream s; + s << "bvi-itf-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +loopback_delete_cmd::loopback_delete_cmd(HW::item& item) + : delete_cmd(item) +{ +} + +rc_t +loopback_delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return rc_t::OK; +} + +std::string +loopback_delete_cmd::to_string() const +{ + std::ostringstream s; + s << "loopback-itf-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +af_packet_delete_cmd::af_packet_delete_cmd(HW::item& item, + const std::string& name) + : delete_cmd(item, name) +{ +} + +rc_t +af_packet_delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + memset(payload.host_if_name, 0, sizeof(payload.host_if_name)); + memcpy(payload.host_if_name, m_name.c_str(), + std::min(m_name.length(), sizeof(payload.host_if_name))); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return rc_t::OK; +} +std::string +af_packet_delete_cmd::to_string() const +{ + std::ostringstream s; + s << "af_packet-itf-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +vhost_delete_cmd::vhost_delete_cmd(HW::item& item, + const std::string& name) + : delete_cmd(item, name) +{ +} + +rc_t +vhost_delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + wait(); + remove_interface(); + + return rc_t::OK; +} +std::string +vhost_delete_cmd::to_string() const +{ + std::ostringstream s; + s << "vhost-itf-delete: " << m_hw_item.to_string() << " name:" << m_name; + + return (s.str()); +} + +state_change_cmd::state_change_cmd(HW::item& state, + const HW::item& hdl) + : rpc_cmd(state) + , m_hdl(hdl) +{ +} + +bool +state_change_cmd::operator==(const state_change_cmd& other) const +{ + return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item)); +} + +rc_t +state_change_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hdl.data().value(); + payload.flags = (vapi_enum_if_status_flags)m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +state_change_cmd::to_string() const +{ + std::ostringstream s; + s << "itf-state-change: " << m_hw_item.to_string() + << " hdl:" << m_hdl.to_string(); + return (s.str()); +} + +set_table_cmd::set_table_cmd(HW::item& table, + const l3_proto_t& proto, + const HW::item& hdl) + : rpc_cmd(table) + , m_hdl(hdl) + , m_proto(proto) +{ +} + +bool +set_table_cmd::operator==(const set_table_cmd& other) const +{ + return ((m_hdl == other.m_hdl) && (m_proto == other.m_proto) && + (m_hw_item == other.m_hw_item)); +} + +rc_t +set_table_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hdl.data().value(); + payload.is_ipv6 = m_proto.is_ipv6(); + payload.vrf_id = m_hw_item.data(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +set_table_cmd::to_string() const +{ + std::ostringstream s; + s << "itf-set-table: " << m_hw_item.to_string() + << " proto:" << m_proto.to_string() << " hdl:" << m_hdl.to_string(); + return (s.str()); +} + +set_mac_cmd::set_mac_cmd(HW::item& mac, + const HW::item& hdl) + : rpc_cmd(mac) + , m_hdl(hdl) +{ +} + +bool +set_mac_cmd::operator==(const set_mac_cmd& other) const +{ + return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item)); +} + +rc_t +set_mac_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hdl.data().value(); + m_hw_item.data().to_mac().to_bytes(payload.mac_address, + sizeof(payload.mac_address)); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +set_mac_cmd::to_string() const +{ + std::ostringstream s; + s << "itf-set-mac: " << m_hw_item.to_string() << " hdl:" << m_hdl.to_string(); + return (s.str()); +} + +collect_detail_stats_change_cmd::collect_detail_stats_change_cmd( + HW::item& item, + const handle_t& hdl, + bool enable) + : rpc_cmd(item) + , m_hdl(hdl) + , m_enable(enable) +{ +} + +bool +collect_detail_stats_change_cmd::operator==( + const collect_detail_stats_change_cmd& other) const +{ + return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item) && + (m_enable == other.m_enable)); +} + +rc_t +collect_detail_stats_change_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hdl.value(); + payload.enable_disable = m_enable; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +collect_detail_stats_change_cmd::to_string() const +{ + std::ostringstream s; + s << "itf-stats: " << m_hw_item.to_string() << " hdl:" << m_hdl.to_string(); + return (s.str()); +} + +events_cmd::events_cmd(interface::event_listener& el) + : event_cmd(el.status()) + , m_listener(el) +{ +} + +bool +events_cmd::operator==(const events_cmd& other) const +{ + return (true); +} + +rc_t +events_cmd::issue(connection& con) +{ + /* + * First set the call back to handle the interface events + */ + m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast(this))))); + + /* + * then send the request to enable them + */ + msg_t req(con.ctx(), std::ref(*(static_cast(this)))); + + auto& payload = req.get_request().get_payload(); + payload.enable_disable = 1; + payload.pid = getpid(); + + VAPI_CALL(req.execute()); + + wait(); + + return (rc_t::OK); +} + +void +events_cmd::retire(connection& con) +{ + /* + * disable interface events. + */ + msg_t req(con.ctx(), std::ref(*(static_cast(this)))); + + auto& payload = req.get_request().get_payload(); + payload.enable_disable = 0; + payload.pid = getpid(); + + VAPI_CALL(req.execute()); + + wait(); +} + +void +events_cmd::notify() +{ + std::lock_guard lg(*this); + std::vector events; + + for (auto& msg : *this) { + auto& payload = msg.get_payload(); + + handle_t handle(payload.sw_if_index); + std::shared_ptr sp = interface::find(handle); + + if (sp) { + interface::oper_state_t oper_state = interface::oper_state_t::from_int( + payload.flags & vapi_enum_if_status_flags::IF_STATUS_API_FLAG_LINK_UP); + + VOM_LOG(log_level_t::DEBUG) << "Interface Event: " << sp->to_string() + << " state: " << oper_state.to_string(); + + sp->set(oper_state); + events.push_back({ *sp, oper_state }); + } + } + + flush(); + + m_listener.handle_interface_event(events); +} + +std::string +events_cmd::to_string() const +{ + return ("itf-events"); +} + +dump_cmd::dump_cmd() +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.name_filter_valid = 0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("itf-dump"); +} + +vhost_dump_cmd::vhost_dump_cmd() +{ +} + +bool +vhost_dump_cmd::operator==(const vhost_dump_cmd& other) const +{ + return (true); +} + +rc_t +vhost_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 +vhost_dump_cmd::to_string() const +{ + return ("vhost-itf-dump"); +} + +bool +af_packet_dump_cmd::operator==(const af_packet_dump_cmd& other) const +{ + return (true); +} + +rc_t +af_packet_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 +af_packet_dump_cmd::to_string() const +{ + return ("af-packet-itf-dump"); +} + +set_tag::set_tag(HW::item& item, const std::string& name) + : rpc_cmd(item) + , m_name(name) +{ +} + +rc_t +set_tag::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.sw_if_index = m_hw_item.data().value(); + memset(payload.tag, 0, sizeof(payload.tag)); + memcpy(payload.tag, m_name.c_str(), m_name.length()); + + VAPI_CALL(req.execute()); + + return (wait()); +} +std::string +set_tag::to_string() const +{ + std::ostringstream s; + s << "itf-set-tag: " << m_hw_item.to_string() << " name:" << m_name; + + return (s.str()); +} + +bool +set_tag::operator==(const set_tag& o) const +{ + return ((m_name == o.m_name) && (m_hw_item.data() == o.m_hw_item.data())); +} +}; // namespace interface_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/interface_cmds.hpp b/extras/deprecated/vom/vom/interface_cmds.hpp new file mode 100644 index 00000000000..7c527ff85a0 --- /dev/null +++ b/extras/deprecated/vom/vom/interface_cmds.hpp @@ -0,0 +1,539 @@ +/* + * 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_INTERFACE_CMDS_H__ +#define __VOM_INTERFACE_CMDS_H__ + +#include + +#include "vom/dump_cmd.hpp" +#include "vom/event_cmd.hpp" +#include "vom/interface.hpp" +#include "vom/rpc_cmd.hpp" + +#include +#include +#include +#include +#include + +namespace VOM { + +namespace interface_cmds { +/** + * Factory method to construct a new interface from the VPP record + */ +std::unique_ptr new_interface( + const vapi_payload_sw_interface_details& vd); + +/** + * A command class to create bvi interfaces in VPP + */ +class bvi_create_cmd : public interface::create_cmd +{ +public: + /** + * Constructor taking the HW::item to update + * and the name of the interface to create + */ + bvi_create_cmd(HW::item& item, const std::string& name); + ~bvi_create_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; +}; + +/** + * A command class to create Loopback interfaces in VPP + */ +class loopback_create_cmd : public interface::create_cmd +{ +public: + /** + * Constructor taking the HW::item to update + * and the name of the interface to create + */ + loopback_create_cmd(HW::item& item, const std::string& name); + ~loopback_create_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; +}; + +/** + * A command class to create af_packet interfaces in VPP + */ +class af_packet_create_cmd + : public interface::create_cmd +{ +public: + /** + * Constructor taking the HW::item to update + * and the name of the interface to create + */ + af_packet_create_cmd(HW::item& item, const std::string& name); + ~af_packet_create_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; +}; + +/** + * A functor class that creates an interface + */ +class vhost_create_cmd + : public interface::create_cmd +{ +public: + vhost_create_cmd(HW::item& item, + const std::string& name, + const std::string& tag); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + +private: + const std::string m_tag; +}; + +/** + * A command class to delete bvi interfaces in VPP + */ +class bvi_delete_cmd : public interface::delete_cmd +{ +public: + /** + * Constructor taking the HW::item to update + */ + bvi_delete_cmd(HW::item& item); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; +}; + +/** + * A command class to delete loopback interfaces in VPP + */ +class loopback_delete_cmd : public interface::delete_cmd +{ +public: + /** + * Constructor taking the HW::item to update + */ + loopback_delete_cmd(HW::item& item); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; +}; + +/** + * A command class to delete af-packet interfaces in VPP + */ +class af_packet_delete_cmd + : public interface::delete_cmd +{ +public: + /** + * Constructor taking the HW::item to update + * and the name of the interface to delete + */ + af_packet_delete_cmd(HW::item& item, const std::string& name); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; +}; + +/** + * A functor class that deletes a Vhost interface + */ +class vhost_delete_cmd + : public interface::delete_cmd +{ +public: + vhost_delete_cmd(HW::item& item, const std::string& name); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; +}; + +/** + * A command class to set tag on interfaces + */ +class set_tag + : public rpc_cmd, vapi::Sw_interface_tag_add_del> +{ +public: + /** + * Constructor taking the HW::item to update + */ + set_tag(HW::item& item, const std::string& name); + + /** + * 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 set_tag& i) const; + +private: + /** + * The tag to add + */ + const std::string m_name; +}; + +/** + * A cmd class that changes the admin state + */ +class state_change_cmd : public rpc_cmd, + vapi::Sw_interface_set_flags> +{ +public: + /** + * Constructor taking the HW::item to update + * and the name handle of the interface whose state is to change + */ + state_change_cmd(HW::item& s, + const HW::item& h); + + /** + * 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 state_change_cmd& i) const; + +private: + /** + * the handle of the interface to update + */ + const HW::item& m_hdl; +}; + +/** + * A command class that binds an interface to an L3 table + */ +class set_table_cmd + : public rpc_cmd, vapi::Sw_interface_set_table> +{ +public: + /** + * Constructor taking the HW::item to update + * and the name handle of the interface whose table is to change + */ + set_table_cmd(HW::item& item, + const l3_proto_t& proto, + const HW::item& h); + + /** + * 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 set_table_cmd& i) const; + +private: + /** + * the handle of the interface to update + */ + const HW::item& m_hdl; + + /** + * The L3 protocol of the table + */ + l3_proto_t m_proto; +}; + +/** + * A command class that changes the MAC address on an interface + */ +class set_mac_cmd + : public rpc_cmd, vapi::Sw_interface_set_mac_address> +{ +public: + /** + * Constructor taking the HW::item to update + * and the handle of the interface + */ + set_mac_cmd(HW::item& item, const HW::item& h); + + /** + * 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 set_mac_cmd& i) const; + +private: + /** + * the handle of the interface to update + */ + const HW::item& m_hdl; +}; + +/** + * A command class that enables detailed stats collection on an interface + */ +class collect_detail_stats_change_cmd + : public rpc_cmd, + vapi::Collect_detailed_interface_stats> +{ +public: + /** + * Constructor taking the HW::item to update + * and the handle of the interface + */ + collect_detail_stats_change_cmd(HW::item& item, + const handle_t& h, + bool enable); + + /** + * 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 collect_detail_stats_change_cmd& i) const; + +private: + /** + * the handle of the interface to update + */ + const handle_t& m_hdl; + + /** + * enable or disable the detailed stats collection + */ + bool m_enable; +}; + +/** + * A command class represents our desire to recieve interface events + */ +class events_cmd + : public event_cmd +{ +public: + /** + * Constructor taking the listner to notify + */ + events_cmd(interface::event_listener& el); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + + /** + * Retires the command - unsubscribe from the events. + */ + void retire(connection& con); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Comparison operator - only used for UT + */ + bool operator==(const events_cmd& i) const; + + /** + * Called when it's time to poke the listeners + */ + void notify(); + +private: + /** + * The listeners to notify when data/events arrive + */ + interface::event_listener& m_listener; +}; + +/** + * A cmd class that Dumps all the Vpp interfaces + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + dump_cmd(); + + /** + * 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; +}; + +/** + * A cmd class that Dumps all the Vpp Interfaces + */ +class vhost_dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + vhost_dump_cmd(); + + /** + * 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 vhost_dump_cmd& i) const; +}; + +/** + * A cmd class that Dumps all the Vpp interfaces + */ +class af_packet_dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + af_packet_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 af_packet_dump_cmd& i) const; +}; +}; +}; +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ +#endif diff --git a/extras/deprecated/vom/vom/interface_factory.cpp b/extras/deprecated/vom/vom/interface_factory.cpp new file mode 100644 index 00000000000..746fbe38809 --- /dev/null +++ b/extras/deprecated/vom/vom/interface_factory.cpp @@ -0,0 +1,253 @@ +/* + * 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 + +#include "vom/bond_interface.hpp" +#include "vom/bond_member.hpp" +#include "vom/interface_factory.hpp" +#include "vom/sub_interface.hpp" +#include "vom/tap_interface.hpp" + +namespace VOM { +std::shared_ptr +interface_factory::new_interface(const vapi_payload_sw_interface_details& vd) +{ + std::shared_ptr sp; + + /** + * Determine the interface type from the name and VLAN attributes + */ + std::string name = reinterpret_cast(vd.interface_name); + std::string device_type = + reinterpret_cast(vd.interface_dev_type); + interface::type_t type = interface::type_t::from_string(device_type); + interface::admin_state_t state = interface::admin_state_t::from_int( + vd.flags & vapi_enum_if_status_flags::IF_STATUS_API_FLAG_ADMIN_UP); + handle_t hdl(vd.sw_if_index); + l2_address_t l2_address(vd.l2_address, 6); + std::string tag = ""; + + if (interface::type_t::UNKNOWN == type) { + return sp; + } + + sp = interface::find(hdl); + if (sp) { + sp->set(state); + sp->set(l2_address); + if (!tag.empty()) + sp->set(tag); + return sp; + } + + /* + * If here, Fall back to old routine + */ + if (interface::type_t::AFPACKET == type) { + /* + * need to strip VPP's "host-" prefix from the interface name + */ + name = name.substr(5); + } + /** + * if the tag is set, then we wrote that to specify a name to make + * the interface type more specific + */ + if (vd.tag[0] != 0) { + tag = std::string(reinterpret_cast(vd.tag)); + } + + if (!tag.empty() && interface::type_t::LOOPBACK == type) { + name = tag; + type = interface::type_t::from_string(name); + } + + /* + * pull out the other special cases + */ + if (interface::type_t::TAPV2 == type) { + /* + * TAP interfaces + */ + 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 + * split the name into the parent and VLAN + */ + std::vector parts; + std::shared_ptr parent; + boost::split(parts, name, boost::is_any_of(".")); + + if ((parent = interface::find(parts[0]))) + sp = sub_interface(*parent, state, vd.sub_id).singular(); + else { + interface parent_itf(parts[0], type, state, tag); + sp = sub_interface(parent_itf, state, vd.sub_id).singular(); + } + } else if (interface::type_t::VXLAN == type) { + /* + * there's not enough information in a SW interface record to + * construct a VXLAN tunnel. so skip it. They have + * their own dump routines + */ + } else if (interface::type_t::VHOST == type) { + /* + * vhost interface already exist in db, look for it using + * sw_if_index + */ + } else if (interface::type_t::BOND == type) { + sp = bond_interface( + name, state, l2_address, bond_interface::mode_t::UNSPECIFIED) + .singular(); + } else { + sp = interface(name, type, state, tag).singular(); + sp->set(l2_address); + } + + /* + * set the handle on the intterface - N.B. this is the sigluar instance + * not a stack local. + */ + if (sp) + sp->set(hdl); + + return (sp); +} + +std::shared_ptr +interface_factory::new_vhost_user_interface( + const vapi_payload_sw_interface_vhost_user_details& vd) +{ + std::shared_ptr sp; + std::string name = reinterpret_cast(vd.sock_filename); + handle_t hdl(vd.sw_if_index); + + sp = interface(name, interface::type_t::VHOST, interface::admin_state_t::DOWN) + .singular(); + sp->set(hdl); + return (sp); +} + +std::shared_ptr +interface_factory::new_af_packet_interface( + const vapi_payload_af_packet_details& vd) +{ + std::shared_ptr sp; + std::string name = reinterpret_cast(vd.host_if_name); + handle_t hdl(vd.sw_if_index); + + sp = + interface(name, interface::type_t::AFPACKET, interface::admin_state_t::DOWN) + .singular(); + sp->set(hdl); + return (sp); +} + +std::shared_ptr +interface_factory::new_tap_interface( + const vapi_payload_sw_interface_tap_v2_details& vd) +{ + std::shared_ptr sp; + handle_t hdl(vd.sw_if_index); + std::string name = reinterpret_cast(vd.host_if_name); + route::prefix_t pfx(route::prefix_t::ZERO); + boost::asio::ip::address addr; + + if (vd.host_ip4_prefix.len) + pfx = route::prefix_t( + 0, (uint8_t*)vd.host_ip4_prefix.address, vd.host_ip4_prefix.len); + else if (vd.host_ip6_prefix.len) + pfx = route::prefix_t( + 1, (uint8_t*)vd.host_ip6_prefix.address, vd.host_ip6_prefix.len); + + l2_address_t l2_address(vd.host_mac_addr, 6); + sp = tap_interface(name, interface::admin_state_t::UP, pfx, l2_address) + .singular(); + + sp->set(hdl); + + return (sp); +} + +std::shared_ptr +interface_factory::new_bond_interface( + const vapi_payload_sw_interface_bond_details& vd) +{ + std::shared_ptr sp; + std::string name = reinterpret_cast(vd.interface_name); + handle_t hdl(vd.sw_if_index); + bond_interface::mode_t mode = + bond_interface::mode_t::from_numeric_val(vd.mode); + bond_interface::lb_t lb = bond_interface::lb_t::from_numeric_val(vd.lb); + sp = bond_interface::find(hdl); + if (sp) { + sp->set(mode); + sp->set(lb); + } + return (sp); +} + +bond_member +interface_factory::new_bond_member_interface( + const vapi_payload_sw_interface_slave_details& vd) +{ + std::shared_ptr sp; + std::string name = reinterpret_cast(vd.interface_name); + handle_t hdl(vd.sw_if_index); + bond_member::mode_t mode = + bond_member::mode_t::from_numeric_val(vd.is_passive); + bond_member::rate_t rate = + bond_member::rate_t::from_numeric_val(vd.is_long_timeout); + std::shared_ptr itf = interface::find(hdl); + bond_member bm(*itf, mode, rate); + return (bm); +} + +std::shared_ptr +interface_factory::new_pipe_interface(const vapi_payload_pipe_details& payload) +{ + std::shared_ptr 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 + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/interface_factory.hpp b/extras/deprecated/vom/vom/interface_factory.hpp new file mode 100644 index 00000000000..7b9703aab56 --- /dev/null +++ b/extras/deprecated/vom/vom/interface_factory.hpp @@ -0,0 +1,72 @@ +/* + * 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_INTERFACE_FACTORY_H__ +#define __VOM_INTERFACE_FACTORY_H__ + +#include + +#include "vom/bond_interface.hpp" +#include "vom/bond_member.hpp" +#include "vom/interface.hpp" +#include "vom/pipe.hpp" +#include "vom/tap_interface.hpp" + +#include +#include +#include +#include +#include +#include + +namespace VOM { + +class interface_factory +{ +public: + /** + * Factory method to construct a new interface from the VPP record + */ + static std::shared_ptr new_interface( + const vapi_payload_sw_interface_details& vd); + + static std::shared_ptr new_vhost_user_interface( + const vapi_payload_sw_interface_vhost_user_details& vd); + + static std::shared_ptr new_af_packet_interface( + const vapi_payload_af_packet_details& vd); + + static std::shared_ptr new_tap_interface( + const vapi_payload_sw_interface_tap_v2_details& vd); + + static std::shared_ptr new_bond_interface( + const vapi_payload_sw_interface_bond_details& vd); + + static bond_member new_bond_member_interface( + const vapi_payload_sw_interface_slave_details& vd); + + static std::shared_ptr new_pipe_interface( + const vapi_payload_pipe_details& payload); +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ +#endif diff --git a/extras/deprecated/vom/vom/interface_ip6_nd.hpp b/extras/deprecated/vom/vom/interface_ip6_nd.hpp new file mode 100644 index 00000000000..b8933ee1574 --- /dev/null +++ b/extras/deprecated/vom/vom/interface_ip6_nd.hpp @@ -0,0 +1,382 @@ +/* + * 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_INTERFACE_IP6_ND_H__ +#define __VOM_INTERFACE_IP6_ND_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/ra_config.hpp" +#include "vom/ra_prefix.hpp" +#include "vom/rpc_cmd.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of L3 configuration on an interface + */ +template +class interface_ip6_nd : public object_base +{ +public: + typedef CLASS class_t; + /** + * Construct a new object matching the desried state + */ + interface_ip6_nd(const interface& itf, const class_t cls) + : m_itf(itf.singular()) + , m_cls(cls) + , m_config(true) + { + } + + /** + * Copy Constructor + */ + interface_ip6_nd(const interface_ip6_nd& o) + : m_itf(o.m_itf) + , m_cls(o.m_cls) + , m_config(o.m_config) + { + } + + /** + * Destructor + */ + ~interface_ip6_nd() + { + sweep(); + m_db.release(m_itf->key(), this); + } + + /** + * Return the 'singular instance' of the interface ip6nd that matches + * this object + */ + std::shared_ptr singular() const + { + return find_or_add(*this); + } + + /** + * convert to string format for debug purposes + */ + std::string to_string() const + { + std::ostringstream s; + s << "interface-ip6-nd:[" + << " itf:" << m_itf->to_string() << " " << m_cls.to_string() << " " + << m_config.to_string() << "]"; + + return (s.str()); + } + + /** + * Dump all config into the stream provided + */ + static void dump(std::ostream& os) { m_db.dump(os); } + + /** + * The key type for interface ip6 nd + */ + typedef interface::key_t key_t; + + /** + * Find an singular instance in the DB for the interface passed + */ + static std::shared_ptr find(const interface& i) + { + /* + * Loop throught the entire map looking for matching interface. + * not the most efficient algorithm, but it will do for now. The + * number of ra configs is low. + */ + std::deque> rac; + + auto it = m_db.cbegin(); + + while (it != m_db.cend()) { + /* + * The key in the DB is a pair of the interface's name. + * If the keys match, save the ra-config + */ + auto key = it->first; + + if (i.key() == key.first) { + rac.push_back(it->second.lock()); + } + + ++it; + } + + return (rac); + } + + /** + * A functor class that binds the ra config to the interface + */ + class config_cmd : public rpc_cmd, CMD> + { + public: + /** + * Constructor + */ + config_cmd(HW::item& item, const handle_t& itf, const class_t& cls) + : rpc_cmd, CMD>(item) + , m_itf(itf) + , m_cls(cls) + { + } + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const + { + std::ostringstream s; + s << "interface-ip6-nd: " << this->item().to_string() + << " itf:" << m_itf.to_string() << " " << m_cls.to_string(); + + return (s.str()); + } + + /** + * Comparison operator - only used for UT + */ + bool operator==(const config_cmd& other) const + { + return ((m_itf == other.m_itf) && (m_cls == other.m_cls)); + } + + private: + /** + * Reference to the interface to bind to + */ + const handle_t& m_itf; + + /** + * Reference to the config class + */ + const class_t& m_cls; + }; + + /** + * A cmd class that Unbinds L3 Config from an interface + */ + class unconfig_cmd : public rpc_cmd, CMD> + { + public: + /** + * Constructor + */ + unconfig_cmd(HW::item& item, const handle_t& itf, const class_t& cls) + : rpc_cmd, CMD>(item) + , m_itf(itf) + , m_cls(cls) + { + } + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const + { + std::ostringstream s; + s << "interface-ip6-nd: " << this->item().to_string() + << " itf:" << m_itf.to_string() << " " << m_cls.to_string(); + + return (s.str()); + } + + /** + * Comparison operator - only used for UT + */ + bool operator==(const unconfig_cmd& other) const + { + return ((m_itf == other.m_itf) && (m_cls == other.m_cls)); + } + + private: + /** + * Reference to the interface to unbind fomr + */ + const handle_t& m_itf; + + /** + * Reference to the config class to undo configurations + */ + const class_t& m_cls; + }; + +private: + /** + * Class definition for listeners to OM events + */ + class event_handler : public OM::listener, public inspect::command_handler + { + public: + event_handler() + { + OM::register_listener(this); + inspect::register_handler({ "ip6_nd " }, "interface ip6 nd", this); + } + + virtual ~event_handler() = default; + + /** + * Handle a populate event + */ + void handle_populate(const client_db::key_t& key) + { + /** + * VPP provides no dump for ra config + */ + } + + /** + * Handle a replay event + */ + void handle_replay() { m_db.replay(); } + + /** + * Show the object in the Singular DB + */ + void show(std::ostream& os) { m_db.dump(os); } + + /** + * Get the sortable Id of the listener + */ + dependency_t order() const { return (dependency_t::BINDING); } + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enqueue commands to the VPP for the update + */ + void update(const interface_ip6_nd& obj) + { + if (!m_config) { + HW::enqueue(new config_cmd(m_config, m_itf->handle(), m_cls)); + } + } + + void sweep() + { + if (m_config) { + HW::enqueue(new unconfig_cmd(m_config, m_itf->handle(), m_cls)); + } + HW::write(); + } + + /** + * Replay the objects state to HW + */ + void replay(void) + { + if (m_config) { + HW::enqueue(new config_cmd(m_config, m_itf->handle(), m_cls)); + } + } + + /** + * Find or add the singular instance in the DB + */ + static std::shared_ptr find_or_add( + const interface_ip6_nd& temp) + { + return (m_db.find_or_add(temp.m_itf->key(), temp)); + } + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + const std::shared_ptr m_itf; + + const class_t m_cls; + + const key_t m_key; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_config; + + /** + * A map of all interface ip6 nd keyed against a combination of the + * interface and subnet's keys. + */ + static singular_db m_db; +}; + +/** + * Typedef the ip6nd_ra_config + */ +typedef interface_ip6_nd + ip6nd_ra_config; + +/** + * Typedef the ip6nd_ra_prefix + */ +typedef interface_ip6_nd + ip6nd_ra_prefix; + +/** + * Definition of the static singular_db for ACL Lists + */ +template +singular_db::key_t, + interface_ip6_nd> + interface_ip6_nd::m_db; + +template +typename interface_ip6_nd::event_handler + interface_ip6_nd::m_evh; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/interface_ip6_nd_cmds.cpp b/extras/deprecated/vom/vom/interface_ip6_nd_cmds.cpp new file mode 100644 index 00000000000..c8a8d75dbec --- /dev/null +++ b/extras/deprecated/vom/vom/interface_ip6_nd_cmds.cpp @@ -0,0 +1,98 @@ +/* + * 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/interface_ip6_nd.hpp" + +#include + +namespace VOM { +template<> +rc_t +ip6nd_ra_config::config_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + m_cls.to_vpp(payload); + payload.is_no = 0; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +template<> +rc_t +ip6nd_ra_config::unconfig_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + m_cls.to_vpp(payload); + payload.is_no = 1; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +template<> +rc_t +ip6nd_ra_prefix::config_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + m_cls.to_vpp(payload); + payload.is_no = 0; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +template<> +rc_t +ip6nd_ra_prefix::unconfig_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + m_cls.to_vpp(payload); + payload.is_no = 1; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/interface_span.cpp b/extras/deprecated/vom/vom/interface_span.cpp new file mode 100644 index 00000000000..4dee9f2fd82 --- /dev/null +++ b/extras/deprecated/vom/vom/interface_span.cpp @@ -0,0 +1,219 @@ +/* + * 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/interface_span.hpp" +#include "vom/interface_span_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +/** + * A DB of all interface_span config + */ +singular_db interface_span::m_db; + +interface_span::event_handler interface_span::m_evh; + +interface_span::interface_span(const interface& itf_from, + const interface& itf_to, + interface_span::state_t state) + : m_itf_from(itf_from.singular()) + , m_itf_to(itf_to.singular()) + , m_state(state) + , m_config(true) +{ +} + +interface_span::interface_span(const interface_span& o) + : m_itf_from(o.m_itf_from) + , m_itf_to(o.m_itf_to) + , m_state(o.m_state) + , m_config(o.m_config) +{ +} + +interface_span::~interface_span() +{ + sweep(); + + // not in the DB anymore. + m_db.release(make_pair(m_itf_from->key(), m_itf_to->key()), this); +} + +void +interface_span::sweep() +{ + if (m_config) { + HW::enqueue(new interface_span_cmds::unconfig_cmd( + m_config, m_itf_from->handle(), m_itf_to->handle())); + } + HW::write(); +} + +void +interface_span::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +interface_span::replay() +{ + if (m_config) { + HW::enqueue(new interface_span_cmds::config_cmd( + m_config, m_itf_from->handle(), m_itf_to->handle(), m_state)); + } +} + +std::string +interface_span::to_string() const +{ + std::ostringstream s; + s << "Itf Span-config:" + << " itf-from:" << m_itf_from->to_string() + << " itf-to:" << m_itf_to->to_string() << " state:" << m_state.to_string(); + + return (s.str()); +} + +void +interface_span::update(const interface_span& desired) +{ + if (!m_config) { + HW::enqueue(new interface_span_cmds::config_cmd( + m_config, m_itf_from->handle(), m_itf_to->handle(), m_state)); + } +} + +std::ostream& +operator<<(std::ostream& os, const interface_span::key_t& key) +{ + os << "[" << key.first << ", " << key.second << "]"; + + return (os); +} + +std::shared_ptr +interface_span::find_or_add(const interface_span& temp) +{ + return (m_db.find_or_add( + make_pair(temp.m_itf_from->key(), temp.m_itf_to->key()), temp)); +} + +std::shared_ptr +interface_span::singular() const +{ + return find_or_add(*this); +} + +interface_span::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "itf-span" }, "interface span configurations", + this); +} + +void +interface_span::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +interface_span::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf_from = + interface::find(payload.sw_if_index_from); + std::shared_ptr itf_to = interface::find(payload.sw_if_index_to); + + interface_span itf_span(*itf_from, *itf_to, + state_t::from_int(payload.state)); + + VOM_LOG(log_level_t::DEBUG) << "span-dump: " << itf_from->to_string() + << itf_to->to_string() + << state_t::from_int(payload.state).to_string(); + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, itf_span); + } +} + +dependency_t +interface_span::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +interface_span::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +const interface_span::state_t interface_span::state_t::DISABLED(0, "disable"); +const interface_span::state_t interface_span::state_t::RX_ENABLED(1, + "rx-enable"); +const interface_span::state_t interface_span::state_t::TX_ENABLED(2, + "tx-enable"); +const interface_span::state_t interface_span::state_t::TX_RX_ENABLED( + 3, + "tx-rx-enable"); + +interface_span::state_t::state_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +interface_span::state_t +interface_span::state_t::from_int(uint8_t i) +{ + switch (i) { + case 0: + return interface_span::state_t::DISABLED; + break; + case 1: + return interface_span::state_t::RX_ENABLED; + break; + case 2: + return interface_span::state_t::TX_ENABLED; + break; + case 3: + default: + break; + } + + return interface_span::state_t::TX_RX_ENABLED; +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/interface_span.hpp b/extras/deprecated/vom/vom/interface_span.hpp new file mode 100644 index 00000000000..7eabb1c4ab3 --- /dev/null +++ b/extras/deprecated/vom/vom/interface_span.hpp @@ -0,0 +1,222 @@ +/* + * 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_INTERFACE_SPAN_H__ +#define __VOM_INTERFACE_SPAN_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of interface span configuration + */ +class interface_span : public object_base +{ +public: + /** + * The state of the interface - rx/tx or both to be mirrored + */ + struct state_t : enum_base + { + /** + * DISABLED state + */ + const static state_t DISABLED; + /** + * RX enable state + */ + const static state_t RX_ENABLED; + /** + * TX enable state + */ + const static state_t TX_ENABLED; + /** + * TX and RX enable state + */ + const static state_t TX_RX_ENABLED; + + /** + * Convert VPP's numerical value to enum type + */ + static state_t from_int(uint8_t val); + + private: + /** + * Private constructor taking the value and the string name + */ + state_t(int v, const std::string& s); + }; + + /** + * Construct a new object matching the desried state + * + * @param itf_from - The interface to be mirrored + * @param itf_to - The interface where the traffic is mirrored + */ + interface_span(const interface& itf_from, + const interface& itf_to, + state_t state); + + /** + * Copy Constructor + */ + interface_span(const interface_span& o); + + /** + * Destructor + */ + ~interface_span(); + + /** + * Return the 'singular instance' of the interface_span that matches + * this object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all interface_spans into the stream provided + */ + static void dump(std::ostream& os); + + /** + * The key type for interface_spans + */ + typedef std::pair key_t; + + /** + * Find a singular instance in the DB for the interface passed + */ + static std::shared_ptr find(const interface& i); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const interface_span& obj); + + /** + * Find or add the singular instance in the DB + */ + static std::shared_ptr find_or_add( + const interface_span& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + e* It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer the interface to be mirrored + */ + const std::shared_ptr m_itf_from; + /** + * A reference counting pointer the interface where the traffic is + * mirrored + */ + const std::shared_ptr m_itf_to; + + /** + * the state (rx, tx or both) of the interface to be mirrored + */ + const state_t m_state; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_config; + + /** + * A map of all interface span keyed against the interface to be + * mirrored. + */ + static singular_db m_db; +}; + +/** + * Ostream output for the key + */ +std::ostream& operator<<(std::ostream& os, const interface_span::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/interface_span_cmds.cpp b/extras/deprecated/vom/vom/interface_span_cmds.cpp new file mode 100644 index 00000000000..7ee68d3a2e7 --- /dev/null +++ b/extras/deprecated/vom/vom/interface_span_cmds.cpp @@ -0,0 +1,149 @@ +/* + * 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/interface_span_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_SPAN_API_JSON; + +namespace VOM { +namespace interface_span_cmds { + +config_cmd::config_cmd(HW::item& item, + const handle_t& itf_from, + const handle_t& itf_to, + const interface_span::state_t& state) + : rpc_cmd(item) + , m_itf_from(itf_from) + , m_itf_to(itf_to) + , m_state(state) +{} + +bool +config_cmd::operator==(const config_cmd& o) const +{ + return ((m_itf_from == o.m_itf_from) && (m_itf_to == o.m_itf_to) && + (m_state == o.m_state)); +} + +rc_t +config_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_l2 = 0; + payload.sw_if_index_from = m_itf_from.value(); + payload.sw_if_index_to = m_itf_to.value(); + payload.state = (vapi_enum_span_state)m_state.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +config_cmd::to_string() const +{ + std::ostringstream s; + s << "itf-span-config: " << m_hw_item.to_string() + << " itf-from:" << m_itf_from.to_string() + << " itf-to:" << m_itf_to.to_string() << " state:" << m_state.to_string(); + + return (s.str()); +} + +unconfig_cmd::unconfig_cmd(HW::item& item, + const handle_t& itf_from, + const handle_t& itf_to) + : rpc_cmd(item) + , m_itf_from(itf_from) + , m_itf_to(itf_to) +{} + +bool +unconfig_cmd::operator==(const unconfig_cmd& o) const +{ + return ((m_itf_from == o.m_itf_from) && (m_itf_to == o.m_itf_to)); +} + +rc_t +unconfig_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_l2 = 0; + payload.sw_if_index_from = m_itf_from.value(); + payload.sw_if_index_to = m_itf_to.value(); + payload.state = SPAN_STATE_API_DISABLED; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unconfig_cmd::to_string() const +{ + std::ostringstream s; + s << "itf-span-unconfig: " << m_hw_item.to_string() + << " itf-from:" << m_itf_from.to_string() + << " itf-to:" << m_itf_to.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() {} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.is_l2 = 0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("interface-span-dump"); +} + +}; // namespace interface_span_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/interface_span_cmds.hpp b/extras/deprecated/vom/vom/interface_span_cmds.hpp new file mode 100644 index 00000000000..c1573e9af1c --- /dev/null +++ b/extras/deprecated/vom/vom/interface_span_cmds.hpp @@ -0,0 +1,154 @@ +/* + * 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_INTERFACE_SPAN_CMDS_H__ +#define __VOM_INTERFACE_SPAN_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/interface_span.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace interface_span_cmds { + +/** + * A command class that configures the interface span + */ +class config_cmd + : public rpc_cmd, vapi::Sw_interface_span_enable_disable> +{ +public: + /** + * Constructor + */ + config_cmd(HW::item& item, + const handle_t& itf_from, + const handle_t& itf_to, + const interface_span::state_t& state); + + /** + * 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 config_cmd& i) const; + +private: + /** + * Reference to the interface to be mirrored + */ + const handle_t& m_itf_from; + /** + * Reference to the interface where the traffic is mirrored + */ + const handle_t& m_itf_to; + /** + * the state (rx, tx or both) of the interface to be mirrored + */ + const interface_span::state_t& m_state; +}; + +/** + * A cmd class that Unconfigs interface span + */ +class unconfig_cmd + : public rpc_cmd, vapi::Sw_interface_span_enable_disable> +{ +public: + /** + * Constructor + */ + unconfig_cmd(HW::item& item, + const handle_t& itf_from, + const handle_t& itf_to); + + /** + * 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 unconfig_cmd& i) const; + +private: + /** + * Reference to the interface to be mirrored + */ + const handle_t& m_itf_from; + /** + * Reference to the interface where the traffic is mirrored + */ + const handle_t& m_itf_to; +}; + +/** + * A cmd class that Dumps all the interface spans + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/interface_types.cpp b/extras/deprecated/vom/vom/interface_types.cpp new file mode 100644 index 00000000000..e63204bd0aa --- /dev/null +++ b/extras/deprecated/vom/vom/interface_types.cpp @@ -0,0 +1,119 @@ +/* + * 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/interface.hpp" +namespace VOM { +/* + * constants and enums + */ +const interface::type_t interface::type_t::UNKNOWN(0, "unknown"); +const interface::type_t interface::type_t::BVI(1, "BVI"); +const interface::type_t interface::type_t::ETHERNET(2, "Ethernet"); +const interface::type_t interface::type_t::VXLAN(3, "VXLAN"); +const interface::type_t interface::type_t::AFPACKET(4, "AFPACKET"); +const interface::type_t interface::type_t::LOOPBACK(5, "LOOPBACK"); +const interface::type_t interface::type_t::LOCAL(6, "LOCAL"); +const interface::type_t interface::type_t::TAPV2(7, "TAPV2"); +const interface::type_t interface::type_t::VHOST(8, "VHOST"); +const interface::type_t interface::type_t::BOND(9, "Bond"); +const interface::type_t interface::type_t::PIPE(10, "Pipe"); +const interface::type_t interface::type_t::PIPE_END(11, "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"); + +const interface::admin_state_t interface::admin_state_t::DOWN(0, "down"); +const interface::admin_state_t interface::admin_state_t::UP(1, "up"); + +const interface::stats_type_t interface::stats_type_t::DETAILED(0, "detailed"); +const interface::stats_type_t interface::stats_type_t::NORMAL(1, "normal"); + +interface::type_t +interface::type_t::from_string(const std::string& str) +{ + if ((str.find("Virtual") != std::string::npos) || + (str.find("vhost") != std::string::npos) || + (str.find("vhu") != std::string::npos) || + (str.find("vhost-user") != std::string::npos)) { + return interface::type_t::VHOST; + } else if (str.find("bond") != std::string::npos) { + return interface::type_t::BOND; + } else if (str.find("dpdk") != std::string::npos) { + return interface::type_t::ETHERNET; + } else if (str.find("VXLAN") != std::string::npos) { + return interface::type_t::VXLAN; + } else if ((str.find("Loopback") != std::string::npos) || + (str.find("recirc") != std::string::npos)) { + return interface::type_t::LOOPBACK; + } else if (str.find("af-packet") != std::string::npos) { + return interface::type_t::AFPACKET; + } else if (str.find("local") != std::string::npos) { + return interface::type_t::LOCAL; + } else if ((str.find("tapcli") != std::string::npos) || + (str.find("tuntap") != std::string::npos)) { + return interface::type_t::UNKNOWN; + } else if (str.find("virtio") != std::string::npos) { + 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; +} + +interface::type_t::type_t(int v, const std::string& s) + : enum_base(v, s) +{} + +interface::oper_state_t::oper_state_t(int v, const std::string& s) + : enum_base(v, s) +{} + +interface::admin_state_t::admin_state_t(int v, const std::string& s) + : enum_base(v, s) +{} + +interface::stats_type_t::stats_type_t(int v, const std::string& s) + : enum_base(v, s) +{} + +interface::admin_state_t +interface::admin_state_t::from_int(uint8_t v) +{ + if (0 == v) { + return (interface::admin_state_t::DOWN); + } + return (interface::admin_state_t::UP); +} + +interface::oper_state_t +interface::oper_state_t::from_int(uint8_t v) +{ + if (0 == v) { + return (interface::oper_state_t::DOWN); + } + return (interface::oper_state_t::UP); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/ip_punt_redirect.cpp b/extras/deprecated/vom/vom/ip_punt_redirect.cpp new file mode 100644 index 00000000000..667a2a0b60e --- /dev/null +++ b/extras/deprecated/vom/vom/ip_punt_redirect.cpp @@ -0,0 +1,197 @@ +/* + * 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/ip_punt_redirect.hpp" +#include "vom/api_types.hpp" +#include "vom/ip_punt_redirect_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +/** + * A DB of all IP Punt configs + */ +singular_db ip_punt_redirect::m_db; + +ip_punt_redirect::event_handler ip_punt_redirect::m_evh; + +ip_punt_redirect::ip_punt_redirect(const interface& rx_itf, + const interface& tx_itf, + const boost::asio::ip::address& addr) + : m_rx_itf(rx_itf.singular()) + , m_tx_itf(tx_itf.singular()) + , m_addr(addr) +{ +} + +ip_punt_redirect::ip_punt_redirect(const interface& tx_itf, + const boost::asio::ip::address& addr) + : m_rx_itf(nullptr) + , m_tx_itf(tx_itf.singular()) + , m_addr(addr) +{ +} + +ip_punt_redirect::ip_punt_redirect(const ip_punt_redirect& o) + : m_rx_itf(o.m_rx_itf) + , m_tx_itf(o.m_tx_itf) + , m_addr(o.m_addr) + , m_config(o.m_config) +{ +} + +ip_punt_redirect::~ip_punt_redirect() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +const ip_punt_redirect::key_t +ip_punt_redirect::key() const +{ + if (m_rx_itf) + return m_rx_itf->key(); + else + return ("ALL"); +} + +void +ip_punt_redirect::sweep() +{ + if (m_config) { + HW::enqueue(new ip_punt_redirect_cmds::unconfig_cmd( + m_config, (m_rx_itf ? m_rx_itf->handle() : handle_t::INVALID), + m_tx_itf->handle(), m_addr)); + } + HW::write(); +} + +void +ip_punt_redirect::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +ip_punt_redirect::replay() +{ + if (m_config) { + HW::enqueue(new ip_punt_redirect_cmds::config_cmd( + m_config, (m_rx_itf ? m_rx_itf->handle() : handle_t::INVALID), + m_tx_itf->handle(), m_addr)); + } +} + +std::string +ip_punt_redirect::to_string() const +{ + std::ostringstream s; + s << "IP-punt-redirect:" + << " rx-itf:" << key() << " tx-itf:" << m_tx_itf->to_string() + << " next-hop:" << m_addr; + + return (s.str()); +} + +void +ip_punt_redirect::update(const ip_punt_redirect& desired) +{ + if (!m_config) { + HW::enqueue(new ip_punt_redirect_cmds::config_cmd( + m_config, (m_rx_itf ? m_rx_itf->handle() : handle_t::INVALID), + m_tx_itf->handle(), m_addr)); + } +} + +std::shared_ptr +ip_punt_redirect::find_or_add(const ip_punt_redirect& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +ip_punt_redirect::singular() const +{ + return find_or_add(*this); +} + +ip_punt_redirect::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "ip-punt-redirect" }, + "IP punt redirect configurations", this); +} + +void +ip_punt_redirect::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +ip_punt_redirect::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr tx_itf = + interface::find(payload.punt.tx_sw_if_index); + std::shared_ptr rx_itf = + interface::find(payload.punt.rx_sw_if_index); + boost::asio::ip::address nh = from_api(payload.punt.nh); + + VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.punt.tx_sw_if_index + << ", " << payload.punt.rx_sw_if_index << ", " + << nh << "]"; + + if (rx_itf && tx_itf) { + ip_punt_redirect ipr(*rx_itf, *tx_itf, nh); + OM::commit(key, ipr); + VOM_LOG(log_level_t::DEBUG) << "read: " << ipr.to_string(); + } else if (tx_itf) { + ip_punt_redirect ipr(*tx_itf, nh); + OM::commit(key, ipr); + VOM_LOG(log_level_t::DEBUG) << "read: " << ipr.to_string(); + } + } +} + +dependency_t +ip_punt_redirect::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +ip_punt_redirect::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/ip_punt_redirect.hpp b/extras/deprecated/vom/vom/ip_punt_redirect.hpp new file mode 100644 index 00000000000..59e54566ef7 --- /dev/null +++ b/extras/deprecated/vom/vom/ip_punt_redirect.hpp @@ -0,0 +1,196 @@ +/* + * 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_IP_PUNT_REDIRECT_H__ +#define __VOM_IP_PUNT_REDIRECT_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of IP punt_redirect configuration on an interface + */ +class ip_punt_redirect : public object_base +{ +public: + /** + * Construct a new object matching the desried state + * + * @param rx_itf - The interface from where the punt traffic should come. + * @param tx_itf - The interface to which traffic should be redirected. + * @param addr - The next hop ip address to redirect the traffic. + */ + ip_punt_redirect(const interface& rx_itf, + const interface& tx_itf, + const boost::asio::ip::address& addr); + + /** + * Construct a new object matching the desried state + * + * @param tx_itf - The interface to which traffic should be redirected. + * @param addr - The next hop ip address to redirect the traffic. + */ + ip_punt_redirect(const interface& tx_itf, + const boost::asio::ip::address& addr); + + /** + * Copy Constructor + */ + ip_punt_redirect(const ip_punt_redirect& o); + + /** + * Destructor + */ + ~ip_punt_redirect(); + + /** + * Return the 'singular instance' of the ip_punt_redirect that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all ip_punt_redirects into the stream provided + */ + static void dump(std::ostream& os); + + /** + * The key type for ip_punt_redirects + */ + typedef interface::key_t key_t; + + /** + * return the object's key + */ + const key_t key() const; + + /** + * Find an singular instance in the DB for the interface passed + */ + static std::shared_ptr find(const interface& i); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const ip_punt_redirect& obj); + + /** + * Find or add the singular instance in the DB + */ + static std::shared_ptr find_or_add( + const ip_punt_redirect& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer the interface that requires an address. + */ + const std::shared_ptr m_rx_itf; + /** + * A reference counting pointer the interface that has an address. + */ + const std::shared_ptr m_tx_itf; + + /** + * host Ip Prefix to redirect traffic to + */ + const boost::asio::ip::address m_addr; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_config; + + /** + * A map of all ip punt redirect keyed against a combination of the interface. + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/ip_punt_redirect_cmds.cpp b/extras/deprecated/vom/vom/ip_punt_redirect_cmds.cpp new file mode 100644 index 00000000000..95ce7b48035 --- /dev/null +++ b/extras/deprecated/vom/vom/ip_punt_redirect_cmds.cpp @@ -0,0 +1,150 @@ +/* + * 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/ip_punt_redirect_cmds.hpp" +#include + +namespace VOM { +namespace ip_punt_redirect_cmds { + +config_cmd::config_cmd(HW::item& item, + const handle_t rx_itf, + const handle_t tx_itf, + const boost::asio::ip::address& addr) + : rpc_cmd(item) + , m_rx_itf(rx_itf) + , m_tx_itf(tx_itf) + , m_addr(addr) +{ +} + +bool +config_cmd::operator==(const config_cmd& o) const +{ + return ((m_rx_itf == o.m_rx_itf) && (m_tx_itf == o.m_tx_itf) && + (m_addr == o.m_addr)); +} + +rc_t +config_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.is_add = 1; + payload.punt.rx_sw_if_index = m_rx_itf.value(); + payload.punt.tx_sw_if_index = m_tx_itf.value(); + to_api(m_addr, payload.punt.nh); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +config_cmd::to_string() const +{ + std::ostringstream s; + s << "IP-punt-redirect: " << m_hw_item.to_string() + << " rx-itf:" << m_rx_itf.to_string() << " tx-itf:" << m_tx_itf.to_string() + << " next-hop:" << m_addr; + + return (s.str()); +} + +unconfig_cmd::unconfig_cmd(HW::item& item, + const handle_t rx_itf, + const handle_t tx_itf, + const boost::asio::ip::address& addr) + : rpc_cmd(item) + , m_rx_itf(rx_itf) + , m_tx_itf(tx_itf) + , m_addr(addr) +{ +} + +bool +unconfig_cmd::operator==(const unconfig_cmd& o) const +{ + return ((m_rx_itf == o.m_rx_itf) && (m_tx_itf == o.m_tx_itf) && + (m_addr == o.m_addr)); +} + +rc_t +unconfig_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.is_add = 0; + payload.punt.rx_sw_if_index = m_rx_itf.value(); + payload.punt.tx_sw_if_index = m_tx_itf.value(); + to_api(m_addr, payload.punt.nh); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unconfig_cmd::to_string() const +{ + std::ostringstream s; + s << "IP-punt-redirect-unconfig: " << m_hw_item.to_string() + << " rx-itf:" << m_rx_itf.to_string() << " tx-itf:" << m_tx_itf.to_string() + << " next-hop:" << m_addr.to_string(); + + return (s.str()); +} + +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 ("ip-punt-redirect-dump"); +} + +}; // namespace ip_punt_redirect_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/ip_punt_redirect_cmds.hpp b/extras/deprecated/vom/vom/ip_punt_redirect_cmds.hpp new file mode 100644 index 00000000000..236e6e310af --- /dev/null +++ b/extras/deprecated/vom/vom/ip_punt_redirect_cmds.hpp @@ -0,0 +1,159 @@ +/* + * 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_IP_PUNT_REDIRECT_CMDS_H__ +#define __VOM_IP_PUNT_REDIRECT_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/ip_punt_redirect.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace ip_punt_redirect_cmds { + +/** +*A command class that configures the IP punt_redirect +*/ +class config_cmd : public rpc_cmd, vapi::Ip_punt_redirect> +{ +public: + /** + * Constructor + */ + config_cmd(HW::item& item, + const handle_t rx_itf, + const handle_t tx_itf, + const boost::asio::ip::address& addr); + + /** + * 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 config_cmd& i) const; + +private: + /** + * Reference to the interface from which traffic is coming + */ + const handle_t m_rx_itf; + /** + * Reference to the interface where traffic will be redirected + */ + const handle_t m_tx_itf; + + /** + * Reference to nexh hop ip address + */ + const boost::asio::ip::address& m_addr; +}; + +/** + * A cmd class that Unconfigs Ip punt redirect + */ +class unconfig_cmd : public rpc_cmd, vapi::Ip_punt_redirect> +{ +public: + /** + * Constructor + */ + unconfig_cmd(HW::item& item, + const handle_t rx_itf, + const handle_t tx_itf, + const boost::asio::ip::address& addr); + + /** + * 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 unconfig_cmd& i) const; + +private: + /** + * Reference to the interface from which traffic is coming + */ + const handle_t m_rx_itf; + /** + * Reference to the interface where traffic will be redirected + */ + const handle_t m_tx_itf; + + /** + * Reference to nexh hop ip address + */ + const boost::asio::ip::address& m_addr; +}; + +/** + * A cmd class that Dumps all the IP punt redirect + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // namespace ip_punt_redirect_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/ip_unnumbered.cpp b/extras/deprecated/vom/vom/ip_unnumbered.cpp new file mode 100644 index 00000000000..59834ecfc64 --- /dev/null +++ b/extras/deprecated/vom/vom/ip_unnumbered.cpp @@ -0,0 +1,162 @@ +/* + * 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/ip_unnumbered.hpp" +#include "vom/ip_unnumbered_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +/** + * A DB of all LLDP configs + */ +singular_db ip_unnumbered::m_db; + +ip_unnumbered::event_handler ip_unnumbered::m_evh; + +ip_unnumbered::ip_unnumbered(const interface& itf, const interface& l3_itf) + : m_itf(itf.singular()) + , m_l3_itf(l3_itf.singular()) +{ +} + +ip_unnumbered::ip_unnumbered(const ip_unnumbered& o) + : m_itf(o.m_itf) + , m_l3_itf(o.m_l3_itf) + , m_config(o.m_config) +{ +} + +ip_unnumbered::~ip_unnumbered() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_itf->key(), this); +} + +void +ip_unnumbered::sweep() +{ + if (m_config) { + HW::enqueue(new ip_unnumbered_cmds::unconfig_cmd(m_config, m_itf->handle(), + m_l3_itf->handle())); + } + HW::write(); +} + +void +ip_unnumbered::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +ip_unnumbered::replay() +{ + if (m_config) { + HW::enqueue(new ip_unnumbered_cmds::config_cmd(m_config, m_itf->handle(), + m_l3_itf->handle())); + } +} + +std::string +ip_unnumbered::to_string() const +{ + std::ostringstream s; + s << "IP Unnumbered-config:" + << " itf:" << m_itf->to_string() << " l3-itf:" << m_l3_itf->to_string(); + + return (s.str()); +} + +void +ip_unnumbered::update(const ip_unnumbered& desired) +{ + if (!m_config) { + HW::enqueue(new ip_unnumbered_cmds::config_cmd(m_config, m_itf->handle(), + m_l3_itf->handle())); + } +} + +std::shared_ptr +ip_unnumbered::find_or_add(const ip_unnumbered& temp) +{ + return (m_db.find_or_add(temp.m_itf->key(), temp)); +} + +std::shared_ptr +ip_unnumbered::singular() const +{ + return find_or_add(*this); +} + +ip_unnumbered::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "ip-un" }, "IP unnumbered configurations", this); +} + +void +ip_unnumbered::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +ip_unnumbered::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& ip_record : *cmd) { + auto& payload = ip_record.get_payload(); + + VOM_LOG(log_level_t::DEBUG) << "ip-unnumbered dump: " + << " itf: " << payload.sw_if_index + << " ip: " << payload.ip_sw_if_index; + + std::shared_ptr itf = interface::find(payload.sw_if_index); + std::shared_ptr ip_itf = interface::find(payload.ip_sw_if_index); + + if (itf && ip_itf) { + ip_unnumbered ipun(*itf, *ip_itf); + OM::commit(key, ipun); + } + } +} + +dependency_t +ip_unnumbered::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +ip_unnumbered::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/ip_unnumbered.hpp b/extras/deprecated/vom/vom/ip_unnumbered.hpp new file mode 100644 index 00000000000..f6fef88adbb --- /dev/null +++ b/extras/deprecated/vom/vom/ip_unnumbered.hpp @@ -0,0 +1,175 @@ +/* + * 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_IP_UNNUMBERED_H__ +#define __VOM_IP_UNNUMBERED_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of IP unnumbered configuration on an interface + */ +class ip_unnumbered : public object_base +{ +public: + /** + * Construct a new object matching the desried state + * + * @param itf - The interface with no IP address + * @param l3_itf - The interface that has the IP address we wish to + * share. + */ + ip_unnumbered(const interface& itf, const interface& l3_itf); + + /** + * Copy Constructor + */ + ip_unnumbered(const ip_unnumbered& o); + + /** + * Destructor + */ + ~ip_unnumbered(); + + /** + * Return the 'singular instance' of the L3-Config that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all ip_unnumbereds into the stream provided + */ + static void dump(std::ostream& os); + + /** + * The key type for ip_unnumbereds + */ + typedef interface::key_t key_t; + + /** + * Find an singular instance in the DB for the interface passed + */ + static std::shared_ptr find(const interface& i); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const ip_unnumbered& obj); + + /** + * Find or add the singular instance in the DB + */ + static std::shared_ptr find_or_add(const ip_unnumbered& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer the interface that requires an address. + */ + const std::shared_ptr m_itf; + /** + * A reference counting pointer the interface that has an address. + */ + const std::shared_ptr m_l3_itf; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_config; + + /** + * A map of all L3 configs keyed against a combination of the interface + * and subnet's keys. + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/ip_unnumbered_cmds.cpp b/extras/deprecated/vom/vom/ip_unnumbered_cmds.cpp new file mode 100644 index 00000000000..fd5020537c0 --- /dev/null +++ b/extras/deprecated/vom/vom/ip_unnumbered_cmds.cpp @@ -0,0 +1,142 @@ +/* + * 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/ip_unnumbered_cmds.hpp" + +#include + +namespace VOM { +namespace ip_unnumbered_cmds { + +config_cmd::config_cmd(HW::item& item, + const handle_t& itf, + const handle_t& l3_itf) + : rpc_cmd(item) + , m_itf(itf) + , m_l3_itf(l3_itf) +{ +} + +bool +config_cmd::operator==(const config_cmd& o) const +{ + return ((m_itf == o.m_itf) && (m_l3_itf == o.m_l3_itf)); +} + +rc_t +config_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.sw_if_index = m_l3_itf.value(); + payload.unnumbered_sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +config_cmd::to_string() const +{ + std::ostringstream s; + s << "IP-unnumberd-config: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string() << " l3-itf:" << m_l3_itf.to_string(); + + return (s.str()); +} + +unconfig_cmd::unconfig_cmd(HW::item& item, + const handle_t& itf, + const handle_t& l3_itf) + : rpc_cmd(item) + , m_itf(itf) + , m_l3_itf(l3_itf) +{ +} + +bool +unconfig_cmd::operator==(const unconfig_cmd& o) const +{ + return ((m_itf == o.m_itf) && (m_l3_itf == o.m_l3_itf)); +} + +rc_t +unconfig_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.sw_if_index = m_l3_itf.value(); + payload.unnumbered_sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unconfig_cmd::to_string() const +{ + std::ostringstream s; + s << "IP-unnumberd-unconfig: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string() << " l3-itf:" << m_l3_itf.to_string(); + + return (s.str()); +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("ip-unnumbered-dump"); +} + +}; // namespace ip_unnumbered_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/ip_unnumbered_cmds.hpp b/extras/deprecated/vom/vom/ip_unnumbered_cmds.hpp new file mode 100644 index 00000000000..7320122d643 --- /dev/null +++ b/extras/deprecated/vom/vom/ip_unnumbered_cmds.hpp @@ -0,0 +1,147 @@ +/* + * 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_IP_UNNUMBERED_CMDS_H__ +#define __VOM_IP_UNNUMBERED_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/ip_unnumbered.hpp" +#include "vom/rpc_cmd.hpp" + +#include +#include + +namespace VOM { +namespace ip_unnumbered_cmds { + +/** +*A command class that configures the IP unnumbered +*/ +class config_cmd + : public rpc_cmd, vapi::Sw_interface_set_unnumbered> +{ +public: + /** + * Constructor + */ + config_cmd(HW::item& item, const handle_t& itf, const handle_t& l3_itf); + + /** + * 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 config_cmd& i) const; + +private: + /** + * Reference to the interface for which the address is required + */ + const handle_t& m_itf; + /** + * Reference to the interface which has an address + */ + const handle_t& m_l3_itf; +}; + +/** + * A cmd class that Unconfigs L3 Config from an interface + */ +class unconfig_cmd + : public rpc_cmd, vapi::Sw_interface_set_unnumbered> +{ +public: + /** + * Constructor + */ + unconfig_cmd(HW::item& item, + const handle_t& itf, + const handle_t& l3_itf); + + /** + * 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 unconfig_cmd& i) const; + +private: + /** + * Reference to the interface for which the address is required + */ + const handle_t& m_itf; + /** + * Reference to the interface which has an address + */ + const handle_t& m_l3_itf; +}; + +/** + * A cmd class that Dumps all the IP unnumbered interfaces + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace ip_unnumbered_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l2_binding.cpp b/extras/deprecated/vom/vom/l2_binding.cpp new file mode 100644 index 00000000000..e6de3035658 --- /dev/null +++ b/extras/deprecated/vom/vom/l2_binding.cpp @@ -0,0 +1,240 @@ +/* + * 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/l2_binding.hpp" +#include "vom/l2_binding_cmds.hpp" +#include "vom/l2_vtr_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +/** + * A DB of all the L2 Configs + */ +singular_db l2_binding::m_db; + +l2_binding::event_handler l2_binding::m_evh; + +const l2_binding::l2_port_type_t + l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL(0, "normal"); +const l2_binding::l2_port_type_t l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI( + 1, + "bvi"); +const l2_binding::l2_port_type_t + l2_binding::l2_port_type_t::L2_PORT_TYPE_UU_FWD(2, "uu-fwd"); + +l2_binding::l2_port_type_t::l2_port_type_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +/** + * Construct a new object matching the desried state + */ +l2_binding::l2_binding(const interface& itf, const bridge_domain& bd) + : m_itf(itf.singular()) + , m_bd(bd.singular()) + , m_port_type(l2_port_type_t::L2_PORT_TYPE_NORMAL) + , m_binding(0) + , m_vtr_op(l2_vtr::option_t::DISABLED, rc_t::UNSET) + , m_vtr_op_tag(0) +{ + if (interface::type_t::BVI == m_itf->type()) + m_port_type = l2_port_type_t::L2_PORT_TYPE_BVI; +} + +/** + * Construct a new object matching the desried state + */ +l2_binding::l2_binding(const interface& itf, + const bridge_domain& bd, + const l2_port_type_t& port_type) + : m_itf(itf.singular()) + , m_bd(bd.singular()) + , m_port_type(port_type) + , m_binding(0) + , m_vtr_op(l2_vtr::option_t::DISABLED, rc_t::UNSET) + , m_vtr_op_tag(0) +{ +} + +l2_binding::l2_binding(const l2_binding& o) + : m_itf(o.m_itf) + , m_bd(o.m_bd) + , m_port_type(o.m_port_type) + , m_binding(0) + , m_vtr_op(o.m_vtr_op) + , m_vtr_op_tag(o.m_vtr_op_tag) +{ +} + +const l2_binding::key_t& +l2_binding::key() const +{ + return (m_itf->key()); +} + +bool +l2_binding::operator==(const l2_binding& l) const +{ + return ((*m_itf == *l.m_itf) && (*m_bd == *l.m_bd) && + (m_port_type == l.m_port_type)); +} + +std::shared_ptr +l2_binding::find(const key_t& key) +{ + return (m_db.find(key)); +} + +void +l2_binding::sweep() +{ + if (m_binding && handle_t::INVALID != m_itf->handle()) { + HW::enqueue(new l2_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), + m_bd->id(), m_port_type)); + } + + // no need to undo the VTR operation. + HW::write(); +} + +void +l2_binding::replay() +{ + if (m_binding && handle_t::INVALID != m_itf->handle()) { + HW::enqueue(new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), + m_bd->id(), m_port_type)); + } + + if (m_vtr_op && handle_t::INVALID != m_itf->handle()) { + HW::enqueue( + new l2_vtr_cmds::set_cmd(m_vtr_op, m_itf->handle(), m_vtr_op_tag)); + } +} + +l2_binding::~l2_binding() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_itf->key(), this); +} + +std::string +l2_binding::to_string() const +{ + std::ostringstream s; + s << "L2-binding:[" << m_itf->to_string() << " " << m_bd->to_string() << " " + << m_port_type.to_string() << " " << m_binding.to_string() << "]"; + + return (s.str()); +} + +void +l2_binding::set(const l2_vtr::option_t& op, uint16_t tag) +{ + assert(rc_t::UNSET == m_vtr_op.rc()); + m_vtr_op.set(rc_t::NOOP); + m_vtr_op.update(op); + m_vtr_op_tag = tag; +} + +void +l2_binding::update(const l2_binding& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (rc_t::OK != m_binding.rc()) { + HW::enqueue(new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), + m_bd->id(), m_port_type)); + } else if (!(*m_bd == *desired.m_bd)) { + /* + * re-binding to a different BD. do unbind, bind. + */ + HW::enqueue(new l2_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), + m_bd->id(), m_port_type)); + m_bd = desired.m_bd; + HW::enqueue(new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), + m_bd->id(), m_port_type)); + } + + /* + * set the VTR operation if request + */ + if (m_vtr_op.update(desired.m_vtr_op)) { + HW::enqueue( + new l2_vtr_cmds::set_cmd(m_vtr_op, m_itf->handle(), m_vtr_op_tag)); + } +} + +std::shared_ptr +l2_binding::find_or_add(const l2_binding& temp) +{ + return (m_db.find_or_add(temp.m_itf->key(), temp)); +} + +std::shared_ptr +l2_binding::singular() const +{ + return find_or_add(*this); +} + +void +l2_binding::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +l2_binding::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "l2" }, "L2 bindings", this); +} + +void +l2_binding::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +l2_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + /** + * This is done while populating the bridge-domain + */ +} + +dependency_t +l2_binding::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +l2_binding::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l2_binding.hpp b/extras/deprecated/vom/vom/l2_binding.hpp new file mode 100644 index 00000000000..a8dfbe76f7d --- /dev/null +++ b/extras/deprecated/vom/vom/l2_binding.hpp @@ -0,0 +1,224 @@ +/* + * 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_L2_BINDING_H__ +#define __VOM_L2_BINDING_H__ + +#include "vom/bridge_domain.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/l2_vtr.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A Clas representing the binding of an L2 interface to a bridge-domain + * and the properties of that binding. + */ +class l2_binding : public object_base +{ +public: + /** + * Key type for an L2 binding in the singular DB + */ + typedef interface::key_t key_t; + + struct l2_port_type_t : public enum_base + { + l2_port_type_t(const l2_port_type_t& l) = default; + ~l2_port_type_t() = default; + + const static l2_port_type_t L2_PORT_TYPE_NORMAL; + const static l2_port_type_t L2_PORT_TYPE_BVI; + const static l2_port_type_t L2_PORT_TYPE_UU_FWD; + + private: + l2_port_type_t(int v, const std::string s); + }; + + /** + * Construct a new object matching the desried state + */ + l2_binding(const interface& itf, const bridge_domain& bd); + l2_binding(const interface& itf, + const bridge_domain& bd, + const l2_port_type_t& port_type); + + /** + * Copy Constructor + */ + l2_binding(const l2_binding& o); + + /** + * Destructor + */ + ~l2_binding(); + + /** + * Return the binding's key + */ + const key_t& key() const; + + /** + * Comparison operator - for UT + */ + bool operator==(const l2_binding& l) const; + + /** + * Return the 'singular instance' of the L2 config that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all l2_bindings into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Set the VTR operation on the binding/interface + */ + void set(const l2_vtr::option_t& op, uint16_t tag); + + /** + * Static function to find the bridge_domain in the model + */ + static std::shared_ptr find(const key_t& key); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const l2_binding& obj); + + /** + * Find or Add the singular instance in the DB + */ + static std::shared_ptr find_or_add(const l2_binding& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer the interface that this L2 layer + * represents. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * A reference counting pointer the Bridge-Domain that this L2 + * interface is bound to. By holding the reference here, we can + * guarantee that this object will outlive the BD. + */ + std::shared_ptr m_bd; + + /** + * l2 port type i.e. normal, bvi or unknown unicast + */ + l2_port_type_t m_port_type; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * HW configuration for the VTR option + */ + HW::item m_vtr_op; + + /** + * The Dot1q tag for the VTR operation + */ + uint16_t m_vtr_op_tag; + + /** + * A map of all L2 interfaces key against the interface's handle_t + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l2_binding_cmds.cpp b/extras/deprecated/vom/vom/l2_binding_cmds.cpp new file mode 100644 index 00000000000..6e7adac44d2 --- /dev/null +++ b/extras/deprecated/vom/vom/l2_binding_cmds.cpp @@ -0,0 +1,133 @@ +/* + * 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/l2_binding_cmds.hpp" + +namespace VOM { +namespace l2_binding_cmds { +bind_cmd::bind_cmd(HW::item& item, + const handle_t& itf, + uint32_t bd, + const l2_binding::l2_port_type_t& port_type) + : rpc_cmd(item) + , m_itf(itf) + , m_bd(bd) + , m_port_type(port_type) +{ +} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_bd == other.m_bd) && + (m_port_type == other.m_port_type)); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.rx_sw_if_index = m_itf.value(); + payload.bd_id = m_bd; + payload.shg = 0; + if (m_port_type == l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI) + payload.port_type = L2_API_PORT_TYPE_BVI; + else if (m_port_type == l2_binding::l2_port_type_t::L2_PORT_TYPE_UU_FWD) + payload.port_type = L2_API_PORT_TYPE_UU_FWD; + else + payload.port_type = L2_API_PORT_TYPE_NORMAL; + + payload.enable = 1; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "L2-bind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() + << " bd:" << m_bd << " port-type:" << m_port_type.to_string(); + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, + const handle_t& itf, + uint32_t bd, + const l2_binding::l2_port_type_t& port_type) + : rpc_cmd(item) + , m_itf(itf) + , m_bd(bd) + , m_port_type(port_type) +{ +} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_bd == other.m_bd) && + (m_port_type == other.m_port_type)); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.rx_sw_if_index = m_itf.value(); + payload.bd_id = m_bd; + payload.shg = 0; + if (m_port_type == l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI) + payload.port_type = L2_API_PORT_TYPE_BVI; + else if (m_port_type == l2_binding::l2_port_type_t::L2_PORT_TYPE_UU_FWD) + payload.port_type = L2_API_PORT_TYPE_UU_FWD; + else + payload.port_type = L2_API_PORT_TYPE_NORMAL; + + payload.enable = 0; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return (rc_t::OK); +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "L2-unbind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() + << " bd:" << m_bd << " port-type:" << m_port_type; + + return (s.str()); +} +}; // namespace l2_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l2_binding_cmds.hpp b/extras/deprecated/vom/vom/l2_binding_cmds.hpp new file mode 100644 index 00000000000..625f6483c0e --- /dev/null +++ b/extras/deprecated/vom/vom/l2_binding_cmds.hpp @@ -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_L2_BINDING_CMDS_H__ +#define __VOM_L2_BINDING_CMDS_H__ + +#include "vom/l2_binding.hpp" +#include "vom/rpc_cmd.hpp" + +#include +#include + +namespace VOM { +namespace l2_binding_cmds { + +/** + * A functor class that binds L2 configuration to an interface + */ +class bind_cmd + : public rpc_cmd, vapi::Sw_interface_set_l2_bridge> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, + const handle_t& itf, + uint32_t bd, + const l2_binding::l2_port_type_t& port_type); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The bridge-domain to bind to + */ + uint32_t m_bd; + + /** + * What is the port type i.e. normal, bvi, uu-fwd that is being bound + */ + const l2_binding::l2_port_type_t& m_port_type; +}; + +/** + * A cmd class that Unbinds L2 configuration from an interface + */ +class unbind_cmd + : public rpc_cmd, vapi::Sw_interface_set_l2_bridge> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, + const handle_t& itf, + uint32_t bd, + const l2_binding::l2_port_type_t& port_type); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The bridge-domain to bind to + */ + uint32_t m_bd; + + /** + * What is the port type i.e. bvi, normal or uu-fwd that is being bound + */ + const l2_binding::l2_port_type_t& m_port_type; +}; + +}; // namespace l2_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l2_emulation.cpp b/extras/deprecated/vom/vom/l2_emulation.cpp new file mode 100644 index 00000000000..b665528b8ae --- /dev/null +++ b/extras/deprecated/vom/vom/l2_emulation.cpp @@ -0,0 +1,168 @@ +/* + * 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/l2_emulation.hpp" +#include "vom/l2_emulation_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +/** + * A DB of all the L2 Configs + */ +singular_db l2_emulation::m_db; + +l2_emulation::event_handler l2_emulation::m_evh; + +/** + * Construct a new object matching the desried state + */ +l2_emulation::l2_emulation(const interface& itf) + : m_itf(itf.singular()) + , m_emulation(0) +{ +} + +l2_emulation::l2_emulation(const l2_emulation& o) + : m_itf(o.m_itf) + , m_emulation(0) +{ +} + +const l2_emulation::key_t& +l2_emulation::key() const +{ + return (m_itf->key()); +} + +bool +l2_emulation::operator==(const l2_emulation& l) const +{ + return ((*m_itf == *l.m_itf)); +} + +std::shared_ptr +l2_emulation::find(const key_t& key) +{ + return (m_db.find(key)); +} + +void +l2_emulation::sweep() +{ + if (m_emulation && handle_t::INVALID != m_itf->handle()) { + HW::enqueue( + new l2_emulation_cmds::disable_cmd(m_emulation, m_itf->handle())); + } + + // no need to undo the VTR operation. + HW::write(); +} + +void +l2_emulation::replay() +{ + if (m_emulation && handle_t::INVALID != m_itf->handle()) { + HW::enqueue( + new l2_emulation_cmds::enable_cmd(m_emulation, m_itf->handle())); + } +} + +l2_emulation::~l2_emulation() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_itf->key(), this); +} + +std::string +l2_emulation::to_string() const +{ + std::ostringstream s; + s << "L2-emulation:[" << m_itf->to_string() << "]"; + + return (s.str()); +} + +void +l2_emulation::update(const l2_emulation& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (rc_t::OK != m_emulation.rc()) { + HW::enqueue( + new l2_emulation_cmds::enable_cmd(m_emulation, m_itf->handle())); + } +} + +std::shared_ptr +l2_emulation::find_or_add(const l2_emulation& temp) +{ + return (m_db.find_or_add(temp.m_itf->key(), temp)); +} + +std::shared_ptr +l2_emulation::singular() const +{ + return find_or_add(*this); +} + +void +l2_emulation::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +l2_emulation::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "l2e" }, "L2 Emulation", this); +} + +void +l2_emulation::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +l2_emulation::event_handler::handle_populate(const client_db::key_t& key) +{ + /** + * This is done while populating the bridge-domain + */ +} + +dependency_t +l2_emulation::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +l2_emulation::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l2_emulation.hpp b/extras/deprecated/vom/vom/l2_emulation.hpp new file mode 100644 index 00000000000..3a929a99daf --- /dev/null +++ b/extras/deprecated/vom/vom/l2_emulation.hpp @@ -0,0 +1,180 @@ +/* + * 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_L2_EMULATION_H__ +#define __VOM_L2_EMULATION_H__ + +#include "vom/bridge_domain.hpp" +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A Clas representing the binding of an L2 interface to a bridge-domain + * and the properties of that binding. + */ +class l2_emulation : public object_base +{ +public: + /** + * Key type for an L2 emulation in the singular DB + */ + typedef interface::key_t key_t; + + /** + * Construct a new object matching the desried state + */ + l2_emulation(const interface& itf); + + /** + * Copy Constructor + */ + l2_emulation(const l2_emulation& o); + + /** + * Destructor + */ + ~l2_emulation(); + + /** + * Return the binding's key + */ + const key_t& key() const; + + /** + * Comparison operator - for UT + */ + bool operator==(const l2_emulation& l) const; + + /** + * Return the 'singular instance' of the L2 config that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all l2_emulations into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Static function to find the bridge_domain in the model + */ + static std::shared_ptr find(const key_t& key); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const l2_emulation& obj); + + /** + * Find or Add the singular instance in the DB + */ + static std::shared_ptr find_or_add(const l2_emulation& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer the interface that this L2 layer + * represents. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * HW configuration for the emulation. The bool representing the + * enable/disable. + */ + HW::item m_emulation; + + /** + * A map of all L2 emulation configurations + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l2_emulation_cmds.cpp b/extras/deprecated/vom/vom/l2_emulation_cmds.cpp new file mode 100644 index 00000000000..4083b3962ae --- /dev/null +++ b/extras/deprecated/vom/vom/l2_emulation_cmds.cpp @@ -0,0 +1,105 @@ +/* + * 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/l2_emulation_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_L2E_API_JSON; + +namespace VOM { +namespace l2_emulation_cmds { +enable_cmd::enable_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{ +} + +bool +enable_cmd::operator==(const enable_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +enable_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.enable = 1; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +enable_cmd::to_string() const +{ + std::ostringstream s; + s << "L2-emulation-enable: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string(); + + return (s.str()); +} + +disable_cmd::disable_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{ +} + +bool +disable_cmd::operator==(const disable_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +disable_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.enable = 0; + + VAPI_CALL(req.execute()); + + wait(); + + return (rc_t::OK); +} + +std::string +disable_cmd::to_string() const +{ + std::ostringstream s; + s << "L2-emulation-disable: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string(); + + return (s.str()); +} + +}; // namespace l2_emulation_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l2_emulation_cmds.hpp b/extras/deprecated/vom/vom/l2_emulation_cmds.hpp new file mode 100644 index 00000000000..b4f10f80f28 --- /dev/null +++ b/extras/deprecated/vom/vom/l2_emulation_cmds.hpp @@ -0,0 +1,102 @@ +/* + * 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_L2_EMULATION_CMDS_H__ +#define __VOM_L2_EMULATION_CMDS_H__ + +#include "vom/l2_emulation.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace l2_emulation_cmds { + +/** + * A functor class that enable L2 emulation to an interface + */ +class enable_cmd : public rpc_cmd, vapi::L2_emulation> +{ +public: + /** + * Constructor + */ + enable_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 enable_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; +}; + +/** + * A cmd class that Unbinds L2 configuration from an interface + */ +class disable_cmd : public rpc_cmd, vapi::L2_emulation> +{ +public: + /** + * Constructor + */ + disable_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 disable_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; +}; + +}; // namespace l2_emulation_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l2_vtr.cpp b/extras/deprecated/vom/vom/l2_vtr.cpp new file mode 100644 index 00000000000..40c6ce4d894 --- /dev/null +++ b/extras/deprecated/vom/vom/l2_vtr.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019 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/l2_vtr.hpp" + +namespace VOM { +namespace l2_vtr { + +/* + * Make sure these are in sync with the smae enum in VPP + */ +const option_t option_t::DISABLED(0, "disabled"); +const option_t option_t::PUSH_1(1, "push-1"); +const option_t option_t::PUSH_2(2, "push-2"); +const option_t option_t::POP_1(3, "pop-1"); +const option_t option_t::POP_2(4, "pop-2"); +const option_t option_t::TRANSLATE_1_1(5, "translate-1-1"); +const option_t option_t::TRANSLATE_1_2(6, "translate-1-2"); +const option_t option_t::TRANSLATE_2_1(7, "translate-2-1"); +const option_t option_t::TRANSLATE_2_2(5, "translate-2-2"); + +option_t::option_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +}; // namespace l2_vtr +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l2_vtr.hpp b/extras/deprecated/vom/vom/l2_vtr.hpp new file mode 100644 index 00000000000..7f9840b970e --- /dev/null +++ b/extras/deprecated/vom/vom/l2_vtr.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 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_L2_VTR_H__ +#define __VOM_L2_VTR_H__ + +#include "vom/hw.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" + +namespace VOM { +namespace l2_vtr { +struct option_t : public enum_base +{ + option_t(const option_t& l) = default; + ~option_t() = default; + + const static option_t DISABLED; + const static option_t PUSH_1; + const static option_t PUSH_2; + const static option_t POP_1; + const static option_t POP_2; + const static option_t TRANSLATE_1_1; + const static option_t TRANSLATE_1_2; + const static option_t TRANSLATE_2_1; + const static option_t TRANSLATE_2_2; + +private: + option_t(int v, const std::string s); +}; +}; // namespace l2_vtr +}; // namesapce VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ +#endif diff --git a/extras/deprecated/vom/vom/l2_vtr_cmds.cpp b/extras/deprecated/vom/vom/l2_vtr_cmds.cpp new file mode 100644 index 00000000000..24b49ddbed0 --- /dev/null +++ b/extras/deprecated/vom/vom/l2_vtr_cmds.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019 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/l2_vtr_cmds.hpp" + +namespace VOM { +namespace l2_vtr_cmds { + +set_cmd::set_cmd(HW::item& item, + const handle_t& itf, + uint16_t tag) + : rpc_cmd(item) + , m_itf(itf) + , m_tag(tag) +{ +} + +bool +set_cmd::operator==(const set_cmd& other) const +{ + return ( + (m_hw_item.data() == other.m_hw_item.data() && m_itf == other.m_itf) && + (m_tag == other.m_tag)); +} + +rc_t +set_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.vtr_op = m_hw_item.data().value(); + payload.push_dot1q = 1; + payload.tag1 = m_tag; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +set_cmd::to_string() const +{ + std::ostringstream s; + s << "L2-vtr-set: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() + << " tag:" << m_tag; + + return (s.str()); +} + +}; // namespace vtr_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l2_vtr_cmds.hpp b/extras/deprecated/vom/vom/l2_vtr_cmds.hpp new file mode 100644 index 00000000000..b30fdc88b7d --- /dev/null +++ b/extras/deprecated/vom/vom/l2_vtr_cmds.hpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019 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_L2_VTR_CMDS_H__ +#define __VOM_L2_VTR_CMDS_H__ + +#include "vom/l2_vtr.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace l2_vtr_cmds { +/** + * A cmd class sets the VTR operation + */ +class set_cmd : public rpc_cmd, + vapi::L2_interface_vlan_tag_rewrite> +{ +public: + /** + * Constructor + */ + set_cmd(HW::item& item, const handle_t& itf, uint16_t tag); + + /** + * 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 set_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The tag for the operation + */ + uint16_t m_tag; +}; + +}; // namespace vtr_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l2_xconnect.cpp b/extras/deprecated/vom/vom/l2_xconnect.cpp new file mode 100644 index 00000000000..91065ab3c08 --- /dev/null +++ b/extras/deprecated/vom/vom/l2_xconnect.cpp @@ -0,0 +1,237 @@ +/* + * 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/l2_xconnect.hpp" +#include "vom/l2_vtr_cmds.hpp" +#include "vom/l2_xconnect_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +/** + * A DB of all the L2 x-connect Configs + */ +singular_db l2_xconnect::m_db; + +l2_xconnect::event_handler l2_xconnect::m_evh; + +/** + * Construct a new object matching the desried state + */ +l2_xconnect::l2_xconnect(const interface& east_itf, const interface& west_itf) + : m_east_itf(east_itf.singular()) + , m_west_itf(west_itf.singular()) + , m_xconnect_east(0) + , m_xconnect_west(0) + , m_vtr_op(l2_vtr::option_t::DISABLED, rc_t::UNSET) + , m_vtr_op_tag(0) +{ +} + +l2_xconnect::l2_xconnect(const l2_xconnect& o) + : m_east_itf(o.m_east_itf) + , m_west_itf(o.m_west_itf) + , m_xconnect_east(o.m_xconnect_east) + , m_xconnect_west(o.m_xconnect_west) + , m_vtr_op(o.m_vtr_op) + , m_vtr_op_tag(o.m_vtr_op_tag) +{ +} + +const l2_xconnect::key_t +l2_xconnect::key() const +{ + if (m_east_itf->name() < m_west_itf->name()) + return (std::make_pair(m_east_itf->key(), m_west_itf->key())); + return (std::make_pair(m_west_itf->key(), m_east_itf->key())); +} + +bool +l2_xconnect::operator==(const l2_xconnect& l) const +{ + return ((*m_east_itf == *l.m_east_itf) && (*m_west_itf == *l.m_west_itf)); +} + +std::shared_ptr +l2_xconnect::find(const key_t& key) +{ + return (m_db.find(key)); +} + +void +l2_xconnect::sweep() +{ + if (m_xconnect_east && m_xconnect_west && + handle_t::INVALID != m_east_itf->handle() && + handle_t::INVALID != m_west_itf->handle()) { + HW::enqueue(new l2_xconnect_cmds::unbind_cmd( + m_xconnect_east, m_east_itf->handle(), m_west_itf->handle())); + HW::enqueue(new l2_xconnect_cmds::unbind_cmd( + m_xconnect_west, m_west_itf->handle(), m_east_itf->handle())); + } + + HW::write(); +} + +void +l2_xconnect::replay() +{ + if (m_xconnect_east && m_xconnect_west && + handle_t::INVALID != m_east_itf->handle() && + handle_t::INVALID != m_west_itf->handle()) { + HW::enqueue(new l2_xconnect_cmds::bind_cmd( + m_xconnect_east, m_east_itf->handle(), m_west_itf->handle())); + HW::enqueue(new l2_xconnect_cmds::bind_cmd( + m_xconnect_west, m_west_itf->handle(), m_east_itf->handle())); + } + + if (m_vtr_op && handle_t::INVALID != m_east_itf->handle()) { + HW::enqueue( + new l2_vtr_cmds::set_cmd(m_vtr_op, m_east_itf->handle(), m_vtr_op_tag)); + } +} + +l2_xconnect::~l2_xconnect() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +std::string +l2_xconnect::to_string() const +{ + std::ostringstream s; + s << "L2-xconnect:[" << m_east_itf->to_string() << " " + << m_west_itf->to_string() << " " << m_xconnect_east.to_string() << " " + << m_xconnect_west.to_string() << "]"; + + return (s.str()); +} + +void +l2_xconnect::set(const l2_vtr::option_t& op, uint16_t tag) +{ + assert(rc_t::UNSET == m_vtr_op.rc()); + m_vtr_op.set(rc_t::NOOP); + m_vtr_op.update(op); + m_vtr_op_tag = tag; +} + +void +l2_xconnect::update(const l2_xconnect& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (rc_t::OK != m_xconnect_east.rc() && rc_t::OK != m_xconnect_west.rc()) { + HW::enqueue(new l2_xconnect_cmds::bind_cmd( + m_xconnect_east, m_east_itf->handle(), m_west_itf->handle())); + HW::enqueue(new l2_xconnect_cmds::bind_cmd( + m_xconnect_west, m_west_itf->handle(), m_east_itf->handle())); + } + + /* + * set the VTR operation if request + */ + if (m_vtr_op.update(desired.m_vtr_op)) { + HW::enqueue( + new l2_vtr_cmds::set_cmd(m_vtr_op, m_east_itf->handle(), m_vtr_op_tag)); + } +} + +std::shared_ptr +l2_xconnect::find_or_add(const l2_xconnect& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +l2_xconnect::singular() const +{ + return find_or_add(*this); +} + +void +l2_xconnect::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +l2_xconnect::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "l2-xconnect" }, "L2 xconnects", this); +} + +void +l2_xconnect::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +l2_xconnect::event_handler::handle_populate(const client_db::key_t& key) +{ + /** + * This needs to be done here + */ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& x_record : *cmd) { + auto& payload = x_record.get_payload(); + + VOM_LOG(log_level_t::DEBUG) << "l2-xconnect dump: " + << " east-itf: " << payload.rx_sw_if_index + << " west-itf: " << payload.tx_sw_if_index; + + std::shared_ptr east_itf = + interface::find(payload.rx_sw_if_index); + std::shared_ptr west_itf = + interface::find(payload.tx_sw_if_index); + + if (east_itf && west_itf) { + if (east_itf->name() > west_itf->name()) + continue; + l2_xconnect l2_xc(*east_itf, *west_itf); + OM::commit(key, l2_xc); + } + } +} + +dependency_t +l2_xconnect::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +l2_xconnect::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l2_xconnect.hpp b/extras/deprecated/vom/vom/l2_xconnect.hpp new file mode 100644 index 00000000000..6fddf1507e1 --- /dev/null +++ b/extras/deprecated/vom/vom/l2_xconnect.hpp @@ -0,0 +1,210 @@ +/* + * 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_L2_XCONNECT_H__ +#define __VOM_L2_XCONNECT_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/l2_vtr.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A Class representing the cross connnect of an L2 interface with another + * l2 interface + */ +class l2_xconnect : public object_base +{ +public: + /** + * Key type for an L2 xconnect in the singular DB + */ + typedef std::pair key_t; + + /** + * Construct a new object matching the desried state + */ + l2_xconnect(const interface& east_itf, const interface& west_itf); + + /** + * Copy Constructor + */ + l2_xconnect(const l2_xconnect& o); + + /** + * Destructor + */ + ~l2_xconnect(); + + /** + * Return the xconnect's key + */ + const key_t key() const; + + /** + * Comparison operator - for UT + */ + bool operator==(const l2_xconnect& l) const; + + /** + * Return the 'singular instance' of the L2 config that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all l2_xconnects into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Set the VTR operation on the binding/interface + */ + void set(const l2_vtr::option_t& op, uint16_t tag); + + /** + * Static function to find the bridge_domain in the model + */ + static std::shared_ptr find(const key_t& key); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enque commands to the VPP command Q for the update + */ + void update(const l2_xconnect& obj); + + /** + * Find or Add the singular instance in the DB + */ + static std::shared_ptr find_or_add(const l2_xconnect& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer the interface that this L2 layer + * represents. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_east_itf; + + /** + * A reference counting pointer the Bridge-Domain that this L2 + * interface is bound to. By holding the reference here, we can + * guarantee that this object will outlive the BD. + */ + const std::shared_ptr m_west_itf; + + /** + * HW configuration for the xconnect. The bool representing the + * do/don't bind. + */ + HW::item m_xconnect_east; + + /** + * HW configuration for the xconnect. The bool representing the + * do/don't bind. + */ + HW::item m_xconnect_west; + + /** + * HW configuration for the VTR option + */ + HW::item m_vtr_op; + + /** + * The Dot1q tag for the VTR operation + */ + uint16_t m_vtr_op_tag; + + /** + * A map of all L2 interfaces key against the interface's handle_t + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, const l2_xconnect::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l2_xconnect_cmds.cpp b/extras/deprecated/vom/vom/l2_xconnect_cmds.cpp new file mode 100644 index 00000000000..426a3dd2554 --- /dev/null +++ b/extras/deprecated/vom/vom/l2_xconnect_cmds.cpp @@ -0,0 +1,144 @@ +/* + * 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/l2_xconnect_cmds.hpp" + +namespace VOM { +namespace l2_xconnect_cmds { +bind_cmd::bind_cmd(HW::item& item, + const handle_t& east_itf, + const handle_t& west_itf) + : rpc_cmd(item) + , m_east_itf(east_itf) + , m_west_itf(west_itf) +{ +} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return ((m_east_itf == other.m_east_itf) && (m_west_itf == other.m_west_itf)); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.rx_sw_if_index = m_east_itf.value(); + payload.tx_sw_if_index = m_west_itf.value(); + payload.enable = 1; + + VAPI_CALL(req.execute()); + + wait(); + + return (rc_t::OK); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "L2-bind: " << m_hw_item.to_string() + << " east-itf:" << m_east_itf.to_string() + << " west-itf:" << m_west_itf.to_string(); + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, + const handle_t& east_itf, + const handle_t& west_itf) + : rpc_cmd(item) + , m_east_itf(east_itf) + , m_west_itf(west_itf) +{ +} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return ((m_east_itf == other.m_east_itf) && (m_west_itf == other.m_west_itf)); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.rx_sw_if_index = m_east_itf.value(); + payload.tx_sw_if_index = m_west_itf.value(); + payload.enable = 0; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return (rc_t::OK); +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "L2-unbind: " << m_hw_item.to_string() + << " east-itf:" << m_east_itf.to_string() + << " west-itf:" << m_west_itf.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("l2-xconnect-dump"); +} + +}; // namespace l2_xconnect_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l2_xconnect_cmds.hpp b/extras/deprecated/vom/vom/l2_xconnect_cmds.hpp new file mode 100644 index 00000000000..9d2dddd8fdd --- /dev/null +++ b/extras/deprecated/vom/vom/l2_xconnect_cmds.hpp @@ -0,0 +1,147 @@ +/* + * 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_L2_XCONNECT_CMDS_H__ +#define __VOM_L2_XCONNECT_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/l2_xconnect.hpp" +#include "vom/rpc_cmd.hpp" + +#include +#include + +namespace VOM { +namespace l2_xconnect_cmds { + +/** + * A functor class that binds L2 configuration to an interface + */ +class bind_cmd + : public rpc_cmd, vapi::Sw_interface_set_l2_xconnect> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, + const handle_t& east_itf, + const handle_t& west_itf); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * The east interface for cross_connect + */ + const handle_t m_east_itf; + + /** + * The west interface for x-connect + */ + const handle_t m_west_itf; +}; + +/** + * A cmd class that Unbinds L2 configuration from an interface + */ +class unbind_cmd + : public rpc_cmd, vapi::Sw_interface_set_l2_xconnect> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, + const handle_t& east_itf, + const handle_t& west_itf); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * The east interface for x-connect + */ + const handle_t m_east_itf; + + /** + * The west interface for x-connect + */ + const handle_t m_west_itf; +}; + +/** + * A cmd class that Dumps all the bridge domains + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + + /** + * 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 l2_xconnect_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l3_binding.cpp b/extras/deprecated/vom/vom/l3_binding.cpp new file mode 100644 index 00000000000..f34859fbaf9 --- /dev/null +++ b/extras/deprecated/vom/vom/l3_binding.cpp @@ -0,0 +1,200 @@ +/* + * 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/l3_binding.hpp" +#include "vom/l3_binding_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +singular_db l3_binding::m_db; + +l3_binding::event_handler l3_binding::m_evh; + +/** + * Construct a new object matching the desried state + */ +l3_binding::l3_binding(const interface& itf, const route::prefix_t& pfx) + : m_itf(itf.singular()) + , m_pfx(pfx) + , m_binding(true, rc_t::NOOP) +{ +} + +l3_binding::l3_binding(const l3_binding& o) + : m_itf(o.m_itf) + , m_pfx(o.m_pfx) + , m_binding(o.m_binding) +{ +} + +l3_binding::~l3_binding() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +bool +l3_binding::operator==(const l3_binding& l) const +{ + return ((m_pfx == l.m_pfx) && (*m_itf == *l.m_itf)); +} + +const l3_binding::key_t +l3_binding::key() const +{ + return (make_pair(m_itf->key(), m_pfx)); +} + +void +l3_binding::sweep() +{ + if (m_binding) { + HW::enqueue( + new l3_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), m_pfx)); + } + HW::write(); +} + +void +l3_binding::replay() +{ + if (m_binding) { + HW::enqueue( + new l3_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_pfx)); + } +} + +const route::prefix_t& +l3_binding::prefix() const +{ + return (m_pfx); +} + +const interface& +l3_binding::itf() const +{ + return (*m_itf); +} + +l3_binding::const_iterator_t +l3_binding::cbegin() +{ + return m_db.begin(); +} + +l3_binding::const_iterator_t +l3_binding::cend() +{ + return m_db.end(); +} + +std::string +l3_binding::to_string() const +{ + std::ostringstream s; + s << "L3-binding:[" << m_itf->to_string() << " prefix:" << m_pfx.to_string() + << " " << m_binding.to_string() << "]"; + + return (s.str()); +} + +void +l3_binding::update(const l3_binding& desired) +{ + /* + * no updates for the binding. chaning the interface or the prefix is a change + * to the + * key, hence a new object + */ + if (!m_binding) { + HW::enqueue( + new l3_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_pfx)); + } +} + +std::shared_ptr +l3_binding::find_or_add(const l3_binding& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +l3_binding::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +l3_binding::singular() const +{ + return find_or_add(*this); +} + +void +l3_binding::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const l3_binding::key_t& key) +{ + os << "[" << key.first << ", " << key.second << "]"; + + return (os); +} + +l3_binding::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "l3" }, "L3 bindings", this); +} + +void +l3_binding::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +l3_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + /** + * This is done while populating the interfaces + */ +} + +dependency_t +l3_binding::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +l3_binding::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l3_binding.hpp b/extras/deprecated/vom/vom/l3_binding.hpp new file mode 100644 index 00000000000..6babe90c6a9 --- /dev/null +++ b/extras/deprecated/vom/vom/l3_binding.hpp @@ -0,0 +1,209 @@ +/* + * 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_L3_BINDING_H__ +#define __VOM_L3_BINDING_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of L3 configuration on an interface + */ +class l3_binding : public object_base +{ +public: + /** + * The key type for l3_bindings + */ + typedef std::pair key_t; + + /** + * Construct a new object matching the desried state + */ + l3_binding(const interface& itf, const route::prefix_t& pfx); + + /** + * Copy Constructor + */ + l3_binding(const l3_binding& o); + + /** + * Destructor + */ + ~l3_binding(); + + /** + * Comparison operator + */ + bool operator==(const l3_binding& l) const; + + /** + * Get the object's key + */ + const key_t key() const; + + /** + * The iterator type + */ + typedef singular_db::const_iterator const_iterator_t; + + static const_iterator_t cbegin(); + static const_iterator_t cend(); + + /** + * Return the 'singular instance' of the L3-Config that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Return the prefix associated with this L3 binding + */ + const route::prefix_t& prefix() const; + + /** + * Return the interface associated with this L3 binding + */ + const interface& itf() const; + + /** + * Dump all l3_bindings into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Find a binding from its key + */ + static std::shared_ptr find(const key_t& k); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const l3_binding& obj); + + /** + * Find or add the singular instance in the DB + */ + static std::shared_ptr find_or_add(const l3_binding& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + e* It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + friend class interface; + + /** + * A reference counting pointer the interface that this L3 layer + * represents. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * The prefix for this L3 configuration + */ + const route::prefix_t m_pfx; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A map of all L3 configs keyed against a combination of the interface + * and subnet's keys. + */ + static singular_db m_db; +}; + +/** + * Ostream output for the key + */ +std::ostream& operator<<(std::ostream& os, const l3_binding::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/l3_binding_cmds.cpp b/extras/deprecated/vom/vom/l3_binding_cmds.cpp new file mode 100644 index 00000000000..d3510c85400 --- /dev/null +++ b/extras/deprecated/vom/vom/l3_binding_cmds.cpp @@ -0,0 +1,160 @@ +/* + * 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/l3_binding_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_IP_API_JSON; + +namespace VOM { +namespace l3_binding_cmds { +bind_cmd::bind_cmd(HW::item& item, + const handle_t& itf, + const route::prefix_t& pfx) + : rpc_cmd(item) + , m_itf(itf) + , m_pfx(pfx) +{ +} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_pfx == other.m_pfx)); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.is_add = 1; + payload.del_all = 0; + + m_pfx.to_vpp((uint8_t*)&payload.prefix.address.af, + (uint8_t*)&payload.prefix.address, + (uint8_t*)&payload.prefix.len); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "L3-bind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() + << " pfx:" << m_pfx.to_string(); + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, + const handle_t& itf, + const route::prefix_t& pfx) + : rpc_cmd(item) + , m_itf(itf) + , m_pfx(pfx) +{ +} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_pfx == other.m_pfx)); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.is_add = 0; + payload.del_all = 0; + + m_pfx.to_vpp((uint8_t*)&payload.prefix.address.af, + (uint8_t*)&payload.prefix.address, + (uint8_t*)&payload.prefix.len); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "L3-unbind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() + << " pfx:" << m_pfx.to_string(); + + return (s.str()); +} + +dump_v4_cmd::dump_v4_cmd(const handle_t& hdl) + : m_itf(hdl) +{ +} + +dump_v4_cmd::dump_v4_cmd(const dump_v4_cmd& d) + : m_itf(d.m_itf) +{ +} + +bool +dump_v4_cmd::operator==(const dump_v4_cmd& other) const +{ + return (true); +} + +rc_t +dump_v4_cmd::issue(connection& con) +{ + m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.is_ipv6 = 0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_v4_cmd::to_string() const +{ + return ("L3-binding-dump"); +} + +}; // namespace l3_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/l3_binding_cmds.hpp b/extras/deprecated/vom/vom/l3_binding_cmds.hpp new file mode 100644 index 00000000000..42d5c0bf8c8 --- /dev/null +++ b/extras/deprecated/vom/vom/l3_binding_cmds.hpp @@ -0,0 +1,158 @@ +/* + * 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_L3_BINDING_CMDS_H__ +#define __VOM_L3_BINDING_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/l3_binding.hpp" +#include "vom/rpc_cmd.hpp" + +#include +#include + +namespace VOM { +namespace l3_binding_cmds { + +/** + * A functor class that binds the L3 config to the interface + */ +class bind_cmd + : public rpc_cmd, vapi::Sw_interface_add_del_address> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, + const handle_t& itf, + const route::prefix_t& pfx); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * Reference to the interface to bind to + */ + const handle_t& m_itf; + + /** + * The prefix to bind + */ + const route::prefix_t& m_pfx; +}; + +/** + * A cmd class that Unbinds L3 Config from an interface + */ +class unbind_cmd + : public rpc_cmd, vapi::Sw_interface_add_del_address> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, + const handle_t& itf, + const route::prefix_t& pfx); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * Reference to the interface to unbind fomr + */ + const handle_t& m_itf; + + /** + * The prefix to unbind + */ + const route::prefix_t& m_pfx; +}; + +/** + * A cmd class that Dumps all the IPv4 L3 configs + */ +class dump_v4_cmd : public dump_cmd +{ +public: + /** + * Constructor + */ + dump_v4_cmd(const handle_t& itf); + dump_v4_cmd(const dump_v4_cmd& d); + + /** + * 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_v4_cmd& i) const; + +private: + /** + * HW reutrn code + */ + HW::item item; + + /** + * The interface to get the addresses for + */ + const handle_t& m_itf; +}; + +}; // namespace l3_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/lldp_binding.cpp b/extras/deprecated/vom/vom/lldp_binding.cpp new file mode 100644 index 00000000000..e2067a045ad --- /dev/null +++ b/extras/deprecated/vom/vom/lldp_binding.cpp @@ -0,0 +1,163 @@ +/* + * 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/lldp_binding.hpp" +#include "vom/lldp_binding_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +/** + * A DB of all LLDP configs + */ +singular_db lldp_binding::m_db; + +lldp_binding::event_handler lldp_binding::m_evh; + +lldp_binding::lldp_binding(const interface& itf, const std::string& port_desc) + : m_itf(itf.singular()) + , m_port_desc(port_desc) + , m_binding(0) +{ +} + +lldp_binding::lldp_binding(const lldp_binding& o) + : m_itf(o.m_itf) + , m_port_desc(o.m_port_desc) + , m_binding(0) +{ +} + +lldp_binding::~lldp_binding() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_itf->key(), this); +} + +bool +lldp_binding::operator==(const lldp_binding& l) const +{ + return ((key() == l.key()) && (m_port_desc == l.m_port_desc)); +} + +const lldp_binding::key_t& +lldp_binding::key() const +{ + return (m_itf->key()); +} + +void +lldp_binding::sweep() +{ + if (m_binding) { + HW::enqueue(new lldp_binding_cmds::unbind_cmd(m_binding, m_itf->handle())); + } + HW::write(); +} + +void +lldp_binding::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +lldp_binding::replay() +{ + if (m_binding) { + HW::enqueue( + new lldp_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_port_desc)); + } +} + +std::string +lldp_binding::to_string() const +{ + std::ostringstream s; + s << "Lldp-binding: " << m_itf->to_string() << " port_desc:" << m_port_desc + << " " << m_binding.to_string(); + + return (s.str()); +} + +void +lldp_binding::update(const lldp_binding& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (!m_binding) { + HW::enqueue( + new lldp_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_port_desc)); + } +} + +std::shared_ptr +lldp_binding::find_or_add(const lldp_binding& temp) +{ + return (m_db.find_or_add(temp.m_itf->key(), temp)); +} + +std::shared_ptr +lldp_binding::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +lldp_binding::singular() const +{ + return find_or_add(*this); +} + +lldp_binding::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "lldp" }, "LLDP bindings", this); +} + +void +lldp_binding::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +lldp_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + // FIXME +} + +dependency_t +lldp_binding::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +lldp_binding::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/lldp_binding.hpp b/extras/deprecated/vom/vom/lldp_binding.hpp new file mode 100644 index 00000000000..d93425f88ba --- /dev/null +++ b/extras/deprecated/vom/vom/lldp_binding.hpp @@ -0,0 +1,182 @@ +/* + * 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_LLDP_BINDING_H__ +#define __VOM_LLDP_BINDING_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of LLDP client configuration on an interface + */ +class lldp_binding : public object_base +{ +public: + /** + * Typedef for the key of a LLDP binding + */ + typedef interface::key_t key_t; + + /** + * Construct a new object matching the desried state + */ + lldp_binding(const interface& itf, const std::string& hostname); + + /** + * Copy Constructor + */ + lldp_binding(const lldp_binding& o); + + /** + * Destructor + */ + ~lldp_binding(); + + /** + * Comparison operator + */ + bool operator==(const lldp_binding& b) const; + + /** + * Return this object's key + */ + const key_t& key() const; + + /** + * Return the 'singular' of the LLDP binding that matches this object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all LLDP bindings into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Find or add LLDP binding based on its key + */ + static std::shared_ptr find(const key_t& k); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const lldp_binding& obj); + + /** + * Find or add LLDP binding to the OM + */ + static std::shared_ptr find_or_add(const lldp_binding& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * A reference counting pointer to the interface on which LLDP config + * resides. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * The port-description in the LLDP configuration + */ + const std::string m_port_desc; + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A map of all Lldp bindings keyed against the interface. + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/lldp_binding_cmds.cpp b/extras/deprecated/vom/vom/lldp_binding_cmds.cpp new file mode 100644 index 00000000000..05b6a663825 --- /dev/null +++ b/extras/deprecated/vom/vom/lldp_binding_cmds.cpp @@ -0,0 +1,110 @@ +/* + * 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/lldp_binding_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_LLDP_API_JSON; + +namespace VOM { +namespace lldp_binding_cmds { + +bind_cmd::bind_cmd(HW::item& item, + const handle_t& itf, + const std::string& port_desc) + : rpc_cmd(item) + , m_itf(itf) + , m_port_desc(port_desc) +{} + +bool +bind_cmd::operator==(const bind_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_port_desc == other.m_port_desc)); +} + +rc_t +bind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.enable = 1; + + memcpy(payload.port_desc.buf, m_port_desc.c_str(), m_port_desc.length()); + payload.port_desc.length = m_port_desc.length(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_cmd::to_string() const +{ + std::ostringstream s; + s << "Lldp-bind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() + << " port_desc:" << m_port_desc; + + return (s.str()); +} + +unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) + : rpc_cmd(item) + , m_itf(itf) +{} + +bool +unbind_cmd::operator==(const unbind_cmd& other) const +{ + return (m_itf == other.m_itf); +} + +rc_t +unbind_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.enable = 0; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +unbind_cmd::to_string() const +{ + std::ostringstream s; + s << "Lldp-unbind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string(); + + return (s.str()); +} + +}; // namespace lldp_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/lldp_binding_cmds.hpp b/extras/deprecated/vom/vom/lldp_binding_cmds.hpp new file mode 100644 index 00000000000..d880b2cf8a6 --- /dev/null +++ b/extras/deprecated/vom/vom/lldp_binding_cmds.hpp @@ -0,0 +1,110 @@ +/* + * 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_LLDP_BINDING_CMDS_H__ +#define __VOM_LLDP_BINDING_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/lldp_binding.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace lldp_binding_cmds { + +/** +*A command class that binds the LLDP config to the interface +*/ +class bind_cmd : public rpc_cmd, vapi::Sw_interface_set_lldp> +{ +public: + /** + * Constructor + */ + bind_cmd(HW::item& item, + const handle_t& itf, + const std::string& port_desc); + + /** + * 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 bind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to bind + */ + const handle_t& m_itf; + + /** + * The LLDP client's hostname + */ + const std::string m_port_desc; +}; + +/** + * A cmd class that Unbinds Lldp Config from an interface + */ +class unbind_cmd : public rpc_cmd, vapi::Sw_interface_set_lldp> +{ +public: + /** + * Constructor + */ + unbind_cmd(HW::item& item, const handle_t& itf); + + /** + * 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 unbind_cmd& i) const; + +private: + /** + * Reference to the HW::item of the interface to unbind + */ + const handle_t& m_itf; +}; + +}; // namespace lldp_binding_cmds +}; // naemspace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/lldp_global.cpp b/extras/deprecated/vom/vom/lldp_global.cpp new file mode 100644 index 00000000000..11ab54b1605 --- /dev/null +++ b/extras/deprecated/vom/vom/lldp_global.cpp @@ -0,0 +1,162 @@ +/* + * 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/lldp_global.hpp" +#include "vom/lldp_global_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +/** + * A DB of all LLDP configs + */ +singular_db lldp_global::m_db; + +lldp_global::event_handler lldp_global::m_evh; + +lldp_global::lldp_global(const std::string& system_name, + uint32_t tx_hold, + uint32_t tx_interval) + : m_system_name(system_name) + , m_tx_hold(tx_hold) + , m_tx_interval(tx_interval) +{ +} + +lldp_global::lldp_global(const lldp_global& o) + : m_system_name(o.m_system_name) + , m_tx_hold(o.m_tx_hold) + , m_tx_interval(o.m_tx_interval) +{ +} + +lldp_global::~lldp_global() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_system_name, this); +} + +const lldp_global::key_t& +lldp_global::key() const +{ + return (m_system_name); +} + +bool +lldp_global::operator==(const lldp_global& l) const +{ + return ((key() == l.key()) && (m_tx_hold == l.m_tx_hold) && + (m_tx_interval == l.m_tx_interval)); +} + +void +lldp_global::sweep() +{ + // no means to remove this in VPP +} + +void +lldp_global::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +lldp_global::replay() +{ + if (m_binding) { + HW::enqueue(new lldp_global_cmds::config_cmd(m_binding, m_system_name, + m_tx_hold, m_tx_interval)); + } +} + +std::string +lldp_global::to_string() const +{ + std::ostringstream s; + s << "LLDP-global:" + << " system_name:" << m_system_name << " tx-hold:" << m_tx_hold + << " tx-interval:" << m_tx_interval; + + return (s.str()); +} + +void +lldp_global::update(const lldp_global& desired) +{ + if (!m_binding) { + HW::enqueue(new lldp_global_cmds::config_cmd(m_binding, m_system_name, + m_tx_hold, m_tx_interval)); + } +} + +std::shared_ptr +lldp_global::find_or_add(const lldp_global& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +lldp_global::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +lldp_global::singular() const +{ + return find_or_add(*this); +} + +lldp_global::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "lldp-global" }, "LLDP global configurations", + this); +} + +void +lldp_global::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +lldp_global::event_handler::handle_populate(const client_db::key_t& key) +{ + // FIXME +} + +dependency_t +lldp_global::event_handler::order() const +{ + return (dependency_t::GLOBAL); +} + +void +lldp_global::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/lldp_global.hpp b/extras/deprecated/vom/vom/lldp_global.hpp new file mode 100644 index 00000000000..b0e86bfdf1d --- /dev/null +++ b/extras/deprecated/vom/vom/lldp_global.hpp @@ -0,0 +1,183 @@ +/* + * 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_LLDP_GLOBAL_H__ +#define __VOM_LLDP_GLOBAL_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of LLDP global configuration + */ +class lldp_global : public object_base +{ +public: + /** + * The key for the global conifugration is the 'system' namse + */ + typedef std::string key_t; + + /** + * Construct a new object matching the desried state + */ + lldp_global(const std::string& system_name, + uint32_t tx_hold, + uint32_t tx_interval); + + /** + * Copy Constructor + */ + lldp_global(const lldp_global& o); + + /** + * Destructor + */ + ~lldp_global(); + + /** + * Get this objects key + */ + const key_t& key() const; + + /** + * Comparison operator + */ + bool operator==(const lldp_global& l) const; + + /** + * Return the 'singular' of the LLDP global that matches this object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Dump all LLDP globals into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Find LLDP global config from its key + */ + static std::shared_ptr find(const key_t& k); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const lldp_global& obj); + + /** + * Find or add LLDP global to the OM + */ + static std::shared_ptr find_or_add(const lldp_global& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * The system name + */ + const std::string m_system_name; + + /** + * TX timer configs + */ + uint32_t m_tx_hold; + uint32_t m_tx_interval; + + /** + * HW globaluration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A map of all Lldp globals keyed against the system name. + * there needs to be some sort of key, that will do. + */ + static singular_db m_db; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/lldp_global_cmds.cpp b/extras/deprecated/vom/vom/lldp_global_cmds.cpp new file mode 100644 index 00000000000..5aeb941e9b2 --- /dev/null +++ b/extras/deprecated/vom/vom/lldp_global_cmds.cpp @@ -0,0 +1,74 @@ +/* + * 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/lldp_global_cmds.hpp" + +namespace VOM { +namespace lldp_global_cmds { +config_cmd::config_cmd(HW::item& item, + const std::string& system_name, + uint32_t tx_hold, + uint32_t tx_interval) + : rpc_cmd(item) + , m_system_name(system_name) + , m_tx_hold(tx_hold) + , m_tx_interval(tx_interval) +{} + +bool +config_cmd::operator==(const config_cmd& other) const +{ + return (m_system_name == other.m_system_name); +} + +rc_t +config_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.tx_hold = m_tx_hold; + payload.tx_interval = m_tx_interval; + + memcpy( + payload.system_name.buf, m_system_name.c_str(), m_system_name.length()); + payload.system_name.length = m_system_name.length(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +config_cmd::to_string() const +{ + std::ostringstream s; + s << "Lldp-global-config: " << m_hw_item.to_string() + << " system_name:" << m_system_name << " tx-hold:" << m_tx_hold + << " tx-interval:" << m_tx_interval; + + return (s.str()); +} + +}; // namespace lldp_global_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/lldp_global_cmds.hpp b/extras/deprecated/vom/vom/lldp_global_cmds.hpp new file mode 100644 index 00000000000..4ce989689f6 --- /dev/null +++ b/extras/deprecated/vom/vom/lldp_global_cmds.hpp @@ -0,0 +1,80 @@ +/* + * 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_LLDP_GLOBAL_CMDS_H__ +#define __VOM_LLDP_GLOBAL_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/lldp_global.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace lldp_global_cmds { + +/** + * A command class that binds the LLDP global to the interface + */ +class config_cmd : public rpc_cmd, vapi::Lldp_config> +{ +public: + /** + * Constructor + */ + config_cmd(HW::item& item, + const std::string& system_name, + uint32_t tx_hold, + uint32_t tx_interval); + + /** + * 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 config_cmd& i) const; + +private: + /** + * The system name + */ + const std::string m_system_name; + + /** + * TX timer configs + */ + uint32_t m_tx_hold; + uint32_t m_tx_interval; +}; + +}; // namespace lldp_global_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/logger.cpp b/extras/deprecated/vom/vom/logger.cpp new file mode 100644 index 00000000000..69de2f8f58e --- /dev/null +++ b/extras/deprecated/vom/vom/logger.cpp @@ -0,0 +1,170 @@ +/* + * 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 +#include +#include + +#include + +#include "vom/logger.hpp" + +namespace VOM { +const log_level_t log_level_t::CRITICAL(4, "critical"); +const log_level_t log_level_t::ERROR(3, "error"); +const log_level_t log_level_t::WARNING(2, "warning"); +const log_level_t log_level_t::INFO(1, "info"); +const log_level_t log_level_t::DEBUG(0, "debug"); + +log_level_t::log_level_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +static log_t slog; + +log_t& +logger() +{ + return slog; +} + +log_t::log_t() + : m_level(log_level_t::ERROR) + , m_handler(new cout_handler()) +{ +} + +void +log_t::set(const log_level_t& level) +{ + m_level = level; +} + +void +log_t::set(handler* h) +{ + m_handler = h; +} + +void +log_t::write(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message) +{ + m_handler->handle_message(file, line, function, level, message); +} + +/** + * The configured level + */ +const log_level_t& +log_t::level() const +{ + return (m_level); +} + +static std::string +get_filename(const std::string& file) +{ + std::vector dirs; + boost::split(dirs, file, boost::is_any_of("/")); + + return dirs.back(); +} + +log_t::entry::entry(const char* file, + const char* function, + int line, + const log_level_t& level) + : m_file(get_filename(file)) + , m_function(function) + , m_level(level) + , m_line(line) +{ +} + +log_t::entry::~entry() +{ + logger().write(m_file, m_line, m_function, m_level, m_stream.str()); +} + +std::stringstream& +log_t::entry::stream() +{ + return (m_stream); +} + +static std::string +get_timestamp() +{ + auto end = std::chrono::system_clock::now(); + auto end_time = std::chrono::system_clock::to_time_t(end); + + /* + * put-time is not support in gcc in 4.8 + * so we play this dance with ctime + */ + std::string display = std::ctime(&end_time); + display.pop_back(); + + return (display); +} + +file_handler::file_handler(const std::string& ofile) +{ + m_file_stream.open(ofile); +} + +file_handler::~file_handler() +{ + m_file_stream.close(); +} + +void +file_handler::handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message) +{ + m_file_stream << get_timestamp(); + m_file_stream << " [" << level.to_string() << "]" << file << ":" << line + << " " << function << "() " << message << std::endl; +} + +void +cout_handler::handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message) +{ + std::cout << get_timestamp(); + std::cout << " [" << level.to_string() << "]" << file << ":" << line << " " + << function << "() " << message << std::endl; +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/logger.hpp b/extras/deprecated/vom/vom/logger.hpp new file mode 100644 index 00000000000..9791d15624d --- /dev/null +++ b/extras/deprecated/vom/vom/logger.hpp @@ -0,0 +1,194 @@ +/* + * 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_LOGGER_H__ +#define __VOM_LOGGER_H__ + +#include +#include +#include + +#include "vom/enum_base.hpp" + +namespace VOM { +struct log_level_t : enum_base +{ + const static log_level_t CRITICAL; + const static log_level_t ERROR; + const static log_level_t WARNING; + const static log_level_t INFO; + const static log_level_t DEBUG; + +private: + /** + * Private constructor taking the value and the string name + */ + log_level_t(int v, const std::string& s); + + /* + * not allowed to construct + */ + log_level_t() = delete; +}; + +/** + * Ideally we'd use the boost logger but that is not prevelent + * in many distros. So something simple here instead. + */ +class log_t +{ +public: + /** + * + */ + class handler + { + public: + /** + * Default Constructor + */ + handler() = default; + + /** + * Default Destructor + */ + virtual ~handler() = default; + + /** + * Handle a log message + */ + virtual void handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message) = 0; + }; + + /** + * Construct a logger + */ + log_t(handler* h); + log_t(); + + /** + * The configured level + */ + const log_level_t& level() const; + + /** + * set the logging level + */ + void set(const log_level_t& level); + + /** + * set a file to receive the logging data + */ + void set(handler* h); + + /** + * An entry in the log + */ + class entry + { + public: + entry(const char* file, + const char* function, + int line, + const log_level_t& level); + ~entry(); + + std::stringstream& stream(); + + private: + const std::string m_file; + const std::string m_function; + const log_level_t m_level; + const int m_line; + + std::stringstream m_stream; + }; + /** + * Register a log handler to receive the log output + */ + void register_handler(handler& h); + +private: + void write(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message); + + /** + * the configured logging level + */ + log_level_t m_level; + + /** + * Pointer to a registered handler. Null if no handler registerd + */ + handler* m_handler; +}; + +class file_handler : public log_t::handler +{ +public: + file_handler(const std::string& ofile); + ~file_handler(); + + virtual void handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message); + +private: + /** + * Opened file for debugging + */ + std::ofstream m_file_stream; +}; + +class cout_handler : public log_t::handler +{ +public: + cout_handler() = default; + ~cout_handler() = default; + virtual void handle_message(const std::string& file, + const int line, + const std::string& function, + const log_level_t& level, + const std::string& message); +}; + +/** + * Return a log object into which VPP objects can write + */ +log_t& logger(); + +#define VOM_LOG(lvl) \ + if (lvl >= logger().level()) \ + log_t::entry(__FILE__, __FUNCTION__, __LINE__, lvl).stream() +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/mroute_cmds.cpp b/extras/deprecated/vom/vom/mroute_cmds.cpp new file mode 100644 index 00000000000..e18e97d9d63 --- /dev/null +++ b/extras/deprecated/vom/vom/mroute_cmds.cpp @@ -0,0 +1,174 @@ +/* + * 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 + +#include "vom/api_types.hpp" +#include "vom/mroute_cmds.hpp" +#include "vom/route_api_types.hpp" + +namespace VOM { +namespace route { +namespace ip_mroute_cmds { + +update_cmd::update_cmd(HW::item& item, + table_id_t id, + const mprefix_t& mprefix, + const path& path, + const itf_flags_t& flags) + : rpc_cmd(item) + , m_id(id) + , m_mprefix(mprefix) + , m_path(path) + , m_flags(flags) +{ +} + +bool +update_cmd::operator==(const update_cmd& other) const +{ + return ((m_mprefix == other.m_mprefix) && (m_id == other.m_id)); +} + +rc_t +update_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), 1, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.is_add = 1; + + payload.route.table_id = m_id; + payload.route.prefix = to_api(m_mprefix); + + to_api(m_path, payload.route.paths[0].path); + payload.route.paths[0].itf_flags = to_api(m_flags); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +update_cmd::to_string() const +{ + std::ostringstream s; + s << "ip-mroute-create: " << m_hw_item.to_string() << " table-id:" << m_id + << " mprefix:" << m_mprefix.to_string() << " path:" << m_path.to_string() + << " flags:" << m_flags; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + table_id_t id, + const mprefix_t& mprefix, + const path& path, + const itf_flags_t& flags) + : rpc_cmd(item) + , m_id(id) + , m_mprefix(mprefix) + , m_path(path) + , m_flags(flags) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return ((m_mprefix == other.m_mprefix) && (m_id == other.m_id)); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), 1, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + + payload.route.table_id = m_id; + payload.route.prefix = to_api(m_mprefix); + + to_api(m_path, payload.route.paths[0].path); + payload.route.paths[0].itf_flags = to_api(m_flags); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "ip-mroute-delete: " << m_hw_item.to_string() << " id:" << m_id + << " mprefix:" << m_mprefix.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd(route::table_id_t id, const l3_proto_t& proto) + : m_id(id) + , m_proto(proto) +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + + payload.table.table_id = m_id; + payload.table.is_ip6 = m_proto.is_ipv6(); + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + std::ostringstream s; + s << "ip-mroute-dump: id:" << m_id << " proto:" << m_proto.to_string(); + + return (s.str()); +} + +} // namespace ip_mroute_cmds +} // namespace mroute +} // namespace vom + /* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/mroute_cmds.hpp b/extras/deprecated/vom/vom/mroute_cmds.hpp new file mode 100644 index 00000000000..c9b8ad6afb9 --- /dev/null +++ b/extras/deprecated/vom/vom/mroute_cmds.hpp @@ -0,0 +1,149 @@ +/* + * 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_MROUTE_CMDS_H__ +#define __VOM_MROUTE_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/route.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace route { +namespace ip_mroute_cmds { + +/** + * A command class that creates or updates the route + */ +class update_cmd : public rpc_cmd, vapi::Ip_mroute_add_del> +{ +public: + /** + * Constructor + */ + update_cmd(HW::item& item, + table_id_t id, + const mprefix_t& mprefix, + const path& path, + const itf_flags_t& flags); + + /** + * 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 update_cmd& i) const; + +private: + route::table_id_t m_id; + mprefix_t m_mprefix; + const path m_path; + const itf_flags_t& m_flags; +}; + +/** + * A cmd class that deletes a route + */ +class delete_cmd : public rpc_cmd, vapi::Ip_mroute_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, + table_id_t id, + const mprefix_t& mprefix, + const path& path, + const itf_flags_t& flags); + + /** + * 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: + route::table_id_t m_id; + mprefix_t m_mprefix; + const path m_path; + const itf_flags_t& m_flags; +}; + +/** + * A cmd class that Dumps ipv4 fib + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(route::table_id_t id, const l3_proto_t& proto); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; + route::table_id_t m_id; + const l3_proto_t& m_proto; +}; + +}; // namespace ip_mroute_cmds +}; // namespace route +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/nat_binding.cpp b/extras/deprecated/vom/vom/nat_binding.cpp new file mode 100644 index 00000000000..dda7e7802e7 --- /dev/null +++ b/extras/deprecated/vom/vom/nat_binding.cpp @@ -0,0 +1,296 @@ +/* + * 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/nat_binding.hpp" +#include "vom/cmd.hpp" +#include "vom/nat_binding_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +singular_db nat_binding::m_db; + +nat_binding::event_handler nat_binding::m_evh; + +const nat_binding::zone_t nat_binding::zone_t::INSIDE(0, "inside"); +const nat_binding::zone_t nat_binding::zone_t::OUTSIDE(0, "outside"); + +nat_binding::zone_t::zone_t(int v, const std::string s) + : enum_base(v, s) +{ +} +const nat_binding::zone_t& +nat_binding::zone_t::from_vpp(u8 is_inside) +{ + if (is_inside) + return zone_t::INSIDE; + return zone_t::OUTSIDE; +} + +/** + * Construct a new object matching the desried state + */ +nat_binding::nat_binding(const interface& itf, + const direction_t& dir, + const l3_proto_t& proto, + const zone_t& zone) + : m_binding(false) + , m_itf(itf.singular()) + , m_dir(dir) + , m_proto(proto) + , m_zone(zone) +{ +} + +nat_binding::nat_binding(const nat_binding& o) + : m_binding(o.m_binding) + , m_itf(o.m_itf) + , m_dir(o.m_dir) + , m_proto(o.m_proto) + , m_zone(o.m_zone) +{ +} + +nat_binding::~nat_binding() +{ + sweep(); + m_db.release(key(), this); +} + +const nat_binding::key_t +nat_binding::key() const +{ + return (make_tuple(m_itf->key(), m_dir, m_proto)); +} + +bool +nat_binding::operator==(const nat_binding& n) const +{ + return ((key() == n.key()) && (m_zone == n.m_zone)); +} + +void +nat_binding::sweep() +{ + if (m_binding) { + if (direction_t::INPUT == m_dir) { + if (l3_proto_t::IPV4 == m_proto) { + HW::enqueue(new nat_binding_cmds::unbind_44_input_cmd( + m_binding, m_itf->handle(), m_zone)); + } else { + HW::enqueue(new nat_binding_cmds::unbind_66_input_cmd( + m_binding, m_itf->handle(), m_zone)); + } + } else { + if (l3_proto_t::IPV4 == m_proto) { + HW::enqueue(new nat_binding_cmds::unbind_44_output_cmd( + m_binding, m_itf->handle(), m_zone)); + } else { + VOM_LOG(log_level_t::ERROR) << "NAT 66 output feature not supported"; + } + } + } + HW::write(); +} + +void +nat_binding::replay() +{ + if (m_binding) { + if (direction_t::INPUT == m_dir) { + if (l3_proto_t::IPV4 == m_proto) { + HW::enqueue(new nat_binding_cmds::bind_44_input_cmd( + m_binding, m_itf->handle(), m_zone)); + } else { + HW::enqueue(new nat_binding_cmds::bind_66_input_cmd( + m_binding, m_itf->handle(), m_zone)); + } + } else { + if (l3_proto_t::IPV4 == m_proto) { + HW::enqueue(new nat_binding_cmds::bind_44_output_cmd( + m_binding, m_itf->handle(), m_zone)); + } else { + VOM_LOG(log_level_t::ERROR) << "NAT 66 output feature not supported"; + } + } + } +} + +void +nat_binding::update(const nat_binding& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (!m_binding) { + if (direction_t::INPUT == m_dir) { + if (l3_proto_t::IPV4 == m_proto) { + HW::enqueue(new nat_binding_cmds::bind_44_input_cmd( + m_binding, m_itf->handle(), m_zone)); + } else { + HW::enqueue(new nat_binding_cmds::bind_66_input_cmd( + m_binding, m_itf->handle(), m_zone)); + } + } else { + if (l3_proto_t::IPV4 == m_proto) { + HW::enqueue(new nat_binding_cmds::bind_44_output_cmd( + m_binding, m_itf->handle(), m_zone)); + } else { + VOM_LOG(log_level_t::ERROR) << "NAT 66 output feature not supported"; + } + } + } +} + +std::string +nat_binding::to_string() const +{ + std::ostringstream s; + s << "nat-binding:[" << m_itf->to_string() + << " direction:" << m_dir.to_string() << " proto:" << m_proto.to_string() + << " zone:" << m_zone.to_string() << "]"; + + return (s.str()); +} + +std::shared_ptr +nat_binding::find_or_add(const nat_binding& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +nat_binding::find(const key_t& key) +{ + return (m_db.find(key)); +} + +std::shared_ptr +nat_binding::singular() const +{ + return find_or_add(*this); +} + +void +nat_binding::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const nat_binding::key_t& key) +{ + os << "[" << std::get<0>(key) << ", " << std::get<1>(key) << ", " + << std::get<2>(key) << "]"; + + return (os); +} + +nat_binding::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "nat-binding" }, "NAT bindings", this); +} + +void +nat_binding::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +nat_binding::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr icmd = + std::make_shared(); + + HW::enqueue(icmd); + HW::write(); + + for (auto& record : *icmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = interface::find(payload.sw_if_index); + + if (itf) { + nat_binding nb(*itf, direction_t::INPUT, l3_proto_t::IPV4, + zone_t::from_vpp(payload.flags & NAT_IS_INSIDE)); + OM::commit(key, nb); + } else { + VOM_LOG(log_level_t::ERROR) << "nat-binding-input-44 no sw_if_index: " + << payload.sw_if_index; + } + } + + std::shared_ptr ocmd = + std::make_shared(); + + HW::enqueue(ocmd); + HW::write(); + + for (auto& record : *ocmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = interface::find(payload.sw_if_index); + if (itf) { + nat_binding nb(*itf, direction_t::OUTPUT, l3_proto_t::IPV4, + zone_t::from_vpp(payload.flags & NAT_IS_INSIDE)); + OM::commit(key, nb); + } else { + VOM_LOG(log_level_t::ERROR) << "nat-binding-output-44 no sw_if_index: " + << payload.sw_if_index; + } + } + + std::shared_ptr i6cmd = + std::make_shared(); + + HW::enqueue(i6cmd); + HW::write(); + + for (auto& record : *i6cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr itf = interface::find(payload.sw_if_index); + if (itf) { + nat_binding nb(*itf, direction_t::INPUT, l3_proto_t::IPV6, + zone_t::from_vpp(payload.flags & NAT_IS_INSIDE)); + OM::commit(key, nb); + } else { + VOM_LOG(log_level_t::ERROR) << "nat-binding-input-66 no sw_if_index: " + << payload.sw_if_index; + } + } +} + +dependency_t +nat_binding::event_handler::order() const +{ + return (dependency_t::BINDING); +} + +void +nat_binding::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/nat_binding.hpp b/extras/deprecated/vom/vom/nat_binding.hpp new file mode 100644 index 00000000000..49557e5cda0 --- /dev/null +++ b/extras/deprecated/vom/vom/nat_binding.hpp @@ -0,0 +1,232 @@ +/* + * 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_NAT_BINDING_H__ +#define __VOM_NAT_BINDING_H__ + +#include "vom/hw.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A Class representing the binding of an L2 interface to a bridge-domain + * and the properties of that binding. + */ +class nat_binding : public object_base +{ +public: + /** + * NAT Zoness + */ + struct zone_t : public enum_base + { + /** + * Constructor + */ + zone_t(int v, const std::string s); + + /** + * Destructor + */ + ~zone_t() = default; + + /** + * Permit Zone + */ + const static zone_t INSIDE; + + /** + * Deny Zone + */ + const static zone_t OUTSIDE; + + const static zone_t& from_vpp(u8 is_inside); + }; + + /** + * The key for a NAT Binding. + * The zoe is not included, since the same interface is never inside + * and outside. + */ + typedef std::tuple key_t; + + /** + * Construct a new object matching the desried state + * @param itf The interface onto which we bind/apply the feature + * @param dir The direction (input/output) + * @param proto The L3 proto used inside. + * @param zone The NAT zone for the link + */ + nat_binding(const interface& itf, + const direction_t& dir, + const l3_proto_t& proto, + const zone_t& zone); + + /** + * Copy Constructor + */ + nat_binding(const nat_binding& o); + + /** + * Destructor + */ + ~nat_binding(); + + /** + * Comparison operator - for UT + */ + bool operator==(const nat_binding& n) const; + + /** + * Return the binding's key + */ + const key_t key() const; + + /** + * Return the 'singular instance' of the L2 config that matches this + * object + */ + std::shared_ptr singular() const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Static function to find the bridge_domain in the model + */ + static std::shared_ptr find(const key_t& key); + + /** + * Dump all nat_bindings into the stream provided + */ + static void dump(std::ostream& os); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Enquue commonds to the VPP command Q for the update + */ + void update(const nat_binding& obj); + + /** + * Find or Add the singular instance in the DB + */ + static std::shared_ptr find_or_add(const nat_binding& temp); + + /* + * It's the OM class that calls singular() + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * HW configuration for the binding. The bool representing the + * do/don't bind. + */ + HW::item m_binding; + + /** + * A reference counting pointer the interface that this NAT binding + * represents. By holding the reference here, we can guarantee that + * this object will outlive the interface + */ + const std::shared_ptr m_itf; + + /** + * The direction in which the feature applies + */ + direction_t m_dir; + + /** + * The L3 protocol used on the inside + */ + l3_proto_t m_proto; + + /** + * The NAT zone the interface is in + */ + zone_t m_zone; + + /** + * A map of all L2 interfaces key against the interface's handle_t + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, const nat_binding::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/nat_binding_cmds.cpp b/extras/deprecated/vom/vom/nat_binding_cmds.cpp new file mode 100644 index 00000000000..2d2973ffa36 --- /dev/null +++ b/extras/deprecated/vom/vom/nat_binding_cmds.cpp @@ -0,0 +1,375 @@ +/* + * 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/nat_binding_cmds.hpp" + +namespace VOM { +namespace nat_binding_cmds { +bind_44_input_cmd::bind_44_input_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone) + : rpc_cmd(item) + , m_itf(itf) + , m_zone(zone) +{ +} + +bool +bind_44_input_cmd::operator==(const bind_44_input_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); +} + +rc_t +bind_44_input_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.flags = (vapi_enum_nat_config_flags)( + nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_44_input_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-44-input-binding-create: " << m_hw_item.to_string() + << " itf:" << m_itf << " " << m_zone.to_string(); + + return (s.str()); +} + +unbind_44_input_cmd::unbind_44_input_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone) + : rpc_cmd(item) + , m_itf(itf) + , m_zone(zone) +{ +} + +bool +unbind_44_input_cmd::operator==(const unbind_44_input_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); +} + +rc_t +unbind_44_input_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.flags = (vapi_enum_nat_config_flags)( + nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +unbind_44_input_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-44-input-binding-create: " << m_hw_item.to_string() + << " itf:" << m_itf << " " << m_zone.to_string(); + + return (s.str()); +} + +bind_44_output_cmd::bind_44_output_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone) + : rpc_cmd(item) + , m_itf(itf) + , m_zone(zone) +{ +} + +bool +bind_44_output_cmd::operator==(const bind_44_output_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); +} + +rc_t +bind_44_output_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.flags = (vapi_enum_nat_config_flags)( + nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +bind_44_output_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-44-output-binding-create: " << m_hw_item.to_string() + << " itf:" << m_itf << " " << m_zone.to_string(); + + return (s.str()); +} + +unbind_44_output_cmd::unbind_44_output_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone) + : rpc_cmd(item) + , m_itf(itf) + , m_zone(zone) +{ +} + +bool +unbind_44_output_cmd::operator==(const unbind_44_output_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); +} + +rc_t +unbind_44_output_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.flags = (vapi_enum_nat_config_flags)( + nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +unbind_44_output_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-44-output-binding-create: " << m_hw_item.to_string() + << " itf:" << m_itf << " " << m_zone.to_string(); + + return (s.str()); +} + +dump_input_44_cmd::dump_input_44_cmd() +{ +} + +dump_input_44_cmd::dump_input_44_cmd(const dump_input_44_cmd& d) +{ +} + +bool +dump_input_44_cmd::operator==(const dump_input_44_cmd& other) const +{ + return (true); +} + +rc_t +dump_input_44_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_input_44_cmd::to_string() const +{ + return ("nat-44-input-binding-dump"); +} + +dump_output_44_cmd::dump_output_44_cmd() +{ +} + +dump_output_44_cmd::dump_output_44_cmd(const dump_output_44_cmd& d) +{ +} + +bool +dump_output_44_cmd::operator==(const dump_output_44_cmd& other) const +{ + return (true); +} + +rc_t +dump_output_44_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_output_44_cmd::to_string() const +{ + return ("nat-44-output-binding-dump"); +} + +bind_66_input_cmd::bind_66_input_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone) + : rpc_cmd(item) + , m_itf(itf) + , m_zone(zone) +{ +} + +bool +bind_66_input_cmd::operator==(const bind_66_input_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); +} + +rc_t +bind_66_input_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.flags = (vapi_enum_nat_config_flags)( + nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + wait(); + + return rc_t::OK; +} + +std::string +bind_66_input_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-66-input-binding-create: " << m_hw_item.to_string() + << " itf:" << m_itf << " " << m_zone.to_string(); + + return (s.str()); +} + +unbind_66_input_cmd::unbind_66_input_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone) + : rpc_cmd(item) + , m_itf(itf) + , m_zone(zone) +{ +} + +bool +unbind_66_input_cmd::operator==(const unbind_66_input_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); +} + +rc_t +unbind_66_input_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.flags = (vapi_enum_nat_config_flags)( + nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); + payload.sw_if_index = m_itf.value(); + + VAPI_CALL(req.execute()); + + wait(); + + return rc_t::OK; +} + +std::string +unbind_66_input_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-66-input-binding-create: " << m_hw_item.to_string() + << " itf:" << m_itf << " " << m_zone.to_string(); + + return (s.str()); +} + +dump_input_66_cmd::dump_input_66_cmd() +{ +} + +dump_input_66_cmd::dump_input_66_cmd(const dump_input_66_cmd& d) +{ +} + +bool +dump_input_66_cmd::operator==(const dump_input_66_cmd& other) const +{ + return (true); +} + +rc_t +dump_input_66_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_input_66_cmd::to_string() const +{ + return ("nat-66-input-binding-dump"); +} + +}; // namespace nat_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/nat_binding_cmds.hpp b/extras/deprecated/vom/vom/nat_binding_cmds.hpp new file mode 100644 index 00000000000..d64f474b228 --- /dev/null +++ b/extras/deprecated/vom/vom/nat_binding_cmds.hpp @@ -0,0 +1,380 @@ +/* + * 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_NAT_BINDING_CMDS_H__ +#define __VOM_NAT_BINDING_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/nat_binding.hpp" +#include "vom/rpc_cmd.hpp" + +#include +#include + +namespace VOM { +namespace nat_binding_cmds { +/** + * A functor class that binds a NAT configuration to an input interface + */ +class bind_44_input_cmd + : public rpc_cmd, vapi::Nat44_interface_add_del_feature> +{ +public: + /** + * Constructor + */ + bind_44_input_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone); + + /** + * 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 bind_44_input_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The zone the interface is in + */ + const nat_binding::zone_t m_zone; +}; + +/** + * A cmd class that unbinds a NAT configuration from an input interface + */ +class unbind_44_input_cmd + : public rpc_cmd, vapi::Nat44_interface_add_del_feature> +{ +public: + /** + * Constructor + */ + unbind_44_input_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone); + + /** + * 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 unbind_44_input_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The zone the interface is in + */ + const nat_binding::zone_t m_zone; +}; + +/** + * A functor class that binds a NAT configuration to an output interface + */ +class bind_44_output_cmd + : public rpc_cmd, vapi::Nat44_interface_add_del_output_feature> +{ +public: + /** + * Constructor + */ + bind_44_output_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone); + + /** + * 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 bind_44_output_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The zone the interface is in + */ + const nat_binding::zone_t m_zone; +}; + +/** + * A cmd class that unbinds a NAT configuration from an output interface + */ +class unbind_44_output_cmd + : public rpc_cmd, vapi::Nat44_interface_add_del_output_feature> +{ +public: + /** + * Constructor + */ + unbind_44_output_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone); + + /** + * 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 unbind_44_output_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The zone the interface is in + */ + const nat_binding::zone_t m_zone; +}; + +/** + * A cmd class that Dumps all the nat_statics + */ +class dump_input_44_cmd : public dump_cmd +{ +public: + /** + * Constructor + */ + dump_input_44_cmd(); + dump_input_44_cmd(const dump_input_44_cmd& d); + + /** + * 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_input_44_cmd& i) const; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +/** + * A cmd class that Dumps all the nat_statics + */ +class dump_output_44_cmd + : public dump_cmd +{ +public: + /** + * Constructor + */ + dump_output_44_cmd(); + dump_output_44_cmd(const dump_output_44_cmd& d); + + /** + * 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_output_44_cmd& i) const; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +///// +/** + * A functor class that binds a NAT configuration to an input interface + */ +class bind_66_input_cmd + : public rpc_cmd, vapi::Nat66_add_del_interface> +{ +public: + /** + * Constructor + */ + bind_66_input_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone); + + /** + * 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 bind_66_input_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The zone the interface is in + */ + const nat_binding::zone_t m_zone; +}; + +/** + * A cmd class that unbinds a NAT configuration from an input interface + */ +class unbind_66_input_cmd + : public rpc_cmd, vapi::Nat66_add_del_interface> +{ +public: + /** + * Constructor + */ + unbind_66_input_cmd(HW::item& item, + const handle_t& itf, + const nat_binding::zone_t& zone); + + /** + * 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 unbind_66_input_cmd& i) const; + +private: + /** + * The interface to bind + */ + const handle_t m_itf; + + /** + * The zone the interface is in + */ + const nat_binding::zone_t m_zone; +}; + +/** + * A cmd class that Dumps all the nat_statics + */ +class dump_input_66_cmd : public dump_cmd +{ +public: + /** + * Constructor + */ + dump_input_66_cmd(); + dump_input_66_cmd(const dump_input_66_cmd& d); + + /** + * 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_input_66_cmd& i) const; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // namespace nat_binding_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/nat_static.cpp b/extras/deprecated/vom/vom/nat_static.cpp new file mode 100644 index 00000000000..10660dc45e2 --- /dev/null +++ b/extras/deprecated/vom/vom/nat_static.cpp @@ -0,0 +1,236 @@ +/* + * 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/nat_static.hpp" +#include "vom/nat_static_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +singular_db nat_static::m_db; +nat_static::event_handler nat_static::m_evh; + +nat_static::nat_static(const boost::asio::ip::address& inside, + const boost::asio::ip::address& outside) + : m_hw(false) + , m_rd(route_domain::get_default()) + , m_inside(inside) + , m_outside(outside) +{ +} + +nat_static::nat_static(const route_domain& rd, + const boost::asio::ip::address& inside, + const boost::asio::ip::address& outside) + : m_hw(false) + , m_rd(rd.singular()) + , m_inside(inside) + , m_outside(outside) +{ +} + +nat_static::nat_static(const nat_static& ns) + : m_hw(ns.m_hw) + , m_rd(ns.m_rd) + , m_inside(ns.m_inside) + , m_outside(ns.m_outside) +{ +} + +nat_static::~nat_static() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +const nat_static::key_t +nat_static::key() const +{ + return (std::make_pair(m_rd->key(), m_outside)); +} + +bool +nat_static::operator==(const nat_static& n) const +{ + return ((key() == n.key()) && (m_inside == n.m_inside)); +} + +void +nat_static::sweep() +{ + if (m_hw) { + if (m_inside.is_v4()) { + HW::enqueue(new nat_static_cmds::delete_44_cmd( + m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside.to_v4())); + } else { + HW::enqueue(new nat_static_cmds::delete_66_cmd( + m_hw, m_rd->table_id(), m_inside.to_v6(), m_outside.to_v6())); + } + } + HW::write(); +} + +void +nat_static::replay() +{ + if (m_hw) { + if (m_inside.is_v4()) { + HW::enqueue(new nat_static_cmds::create_44_cmd( + m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside.to_v4())); + } else { + HW::enqueue(new nat_static_cmds::create_66_cmd( + m_hw, m_rd->table_id(), m_inside.to_v6(), m_outside.to_v6())); + } + } +} + +void +nat_static::update(const nat_static& r) +{ + /* + * create the table if it is not yet created + */ + if (rc_t::OK != m_hw.rc()) { + if (m_inside.is_v4()) { + HW::enqueue(new nat_static_cmds::create_44_cmd( + m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside.to_v4())); + } else { + HW::enqueue(new nat_static_cmds::create_66_cmd( + m_hw, m_rd->table_id(), m_inside.to_v6(), m_outside.to_v6())); + } + } +} + +std::string +nat_static::to_string() const +{ + std::ostringstream s; + s << "nat-static:[" + << "table:" << m_rd->to_string() << " inside:" << m_inside.to_string() + << " outside:" << m_outside.to_string() << "]"; + + return (s.str()); +} + +std::shared_ptr +nat_static::find_or_add(const nat_static& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +nat_static::find(const key_t& key) +{ + return (m_db.find(key)); +} + +std::shared_ptr +nat_static::singular() const +{ + return find_or_add(*this); +} + +void +nat_static::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +nat_static::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "nat-static" }, "NAT Statics", this); +} + +void +nat_static::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +nat_static::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump VPP current states + */ + std::shared_ptr cmd44 = + std::make_shared(); + + HW::enqueue(cmd44); + HW::write(); + + for (auto& record : *cmd44) { + + auto& payload = record.get_payload(); + + boost::asio::ip::address inside = from_bytes(0, payload.local_ip_address); + boost::asio::ip::address outside = + from_bytes(0, payload.external_ip_address); + nat_static n(route_domain(payload.vrf_id), inside, outside); + + /* + * Write each of the discovered mappings into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, n); + } + + std::shared_ptr cmd66 = + std::make_shared(); + + HW::enqueue(cmd66); + HW::write(); + + for (auto& record : *cmd66) { + + auto& payload = record.get_payload(); + + boost::asio::ip::address inside = from_bytes(1, payload.local_ip_address); + boost::asio::ip::address outside = + from_bytes(1, payload.external_ip_address); + nat_static n(route_domain(payload.vrf_id), inside, outside); + + /* + * Write each of the discovered mappings into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, n); + } +} + +dependency_t +nat_static::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +nat_static::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/nat_static.hpp b/extras/deprecated/vom/vom/nat_static.hpp new file mode 100644 index 00000000000..b313667a82e --- /dev/null +++ b/extras/deprecated/vom/vom/nat_static.hpp @@ -0,0 +1,195 @@ +/* + * 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_NAT_STATIC_H__ +#define __VOM_NAT_STATIC_H__ + +#include "vom/route.hpp" +#include "vom/singular_db.hpp" +#include "vom/types.hpp" + +namespace VOM { +/** + * A entry in the ARP termination table of a Bridge Domain + */ +class nat_static : public object_base +{ +public: + /** + * The key for a NAT static mapping. + * So far only model the address only case. The address + * is the outside. + */ + typedef std::pair key_t; + + /** + * Construct an NAT Static binding with the outside address in default + * table + */ + nat_static(const boost::asio::ip::address& inside, + const boost::asio::ip::address& outside); + + /** + * Construct an NAT Static binding with the outside address in + * route-domain specified + */ + nat_static(const route_domain& rd, + const boost::asio::ip::address& inside, + const boost::asio::ip::address& outside); + + /** + * Copy Construct + */ + nat_static(const nat_static& r); + + /** + * Destructor + */ + ~nat_static(); + + /** + * Comparison operator - for UT + */ + bool operator==(const nat_static& n) const; + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& key); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const nat_static& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const nat_static& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the bridge_domain + */ + HW::item m_hw; + + /** + * The table-ID the outside address resides in + */ + std::shared_ptr m_rd; + + /** + * The 'inside' IP address, could be v4 or v6 + */ + const boost::asio::ip::address m_inside; + + /** + * The 'outside' IP address + */ + const boost::asio::ip::address m_outside; + + /** + * A map of all NAT statics + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, const nat_static::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/nat_static_cmds.cpp b/extras/deprecated/vom/vom/nat_static_cmds.cpp new file mode 100644 index 00000000000..296b226a650 --- /dev/null +++ b/extras/deprecated/vom/vom/nat_static_cmds.cpp @@ -0,0 +1,271 @@ +/* + * 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/nat_static_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_NAT_API_JSON; +DEFINE_VAPI_MSG_IDS_NAT66_API_JSON; + +namespace VOM { +namespace nat_static_cmds { + +create_44_cmd::create_44_cmd(HW::item& item, + route::table_id_t id, + const boost::asio::ip::address_v4& inside, + const boost::asio::ip::address_v4& outside) + : rpc_cmd(item) + , m_id(id) + , m_inside(inside) + , m_outside(outside) +{} + +bool +create_44_cmd::operator==(const create_44_cmd& other) const +{ + return ((m_id == other.m_id) && (m_inside == other.m_inside) && + (m_outside == other.m_outside)); +} + +rc_t +create_44_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.flags = NAT_IS_ADDR_ONLY; + payload.local_port = 0; + payload.external_port = 0; + payload.vrf_id = m_id; + payload.external_sw_if_index = ~0; + to_bytes(m_inside, payload.local_ip_address); + to_bytes(m_outside, payload.external_ip_address); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_44_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-44-static-create: " << m_hw_item.to_string() << " table:" << m_id + << " inside:" << m_inside.to_string() + << " outside:" << m_outside.to_string(); + + return (s.str()); +} + +delete_44_cmd::delete_44_cmd(HW::item& item, + route::table_id_t id, + const boost::asio::ip::address_v4& inside, + const boost::asio::ip::address_v4& outside) + : rpc_cmd(item) + , m_id(id) + , m_inside(inside) + , m_outside(outside) +{} + +bool +delete_44_cmd::operator==(const delete_44_cmd& other) const +{ + return ((m_id == other.m_id) && (m_inside == other.m_inside) && + (m_outside == other.m_outside)); +} + +rc_t +delete_44_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.flags = NAT_IS_ADDR_ONLY; + payload.local_port = 0; + payload.external_port = 0; + payload.vrf_id = m_id; + payload.external_sw_if_index = ~0; + to_bytes(m_inside, payload.local_ip_address); + to_bytes(m_outside, payload.external_ip_address); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_44_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-44-static-delete: " << m_hw_item.to_string() << " table:" << m_id + << " inside:" << m_inside.to_string() + << " outside:" << m_outside.to_string(); + + return (s.str()); +} + +bool +dump_44_cmd::operator==(const dump_44_cmd& other) const +{ + return (true); +} + +rc_t +dump_44_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_44_cmd::to_string() const +{ + return ("nat-44-static-dump"); +} + +create_66_cmd::create_66_cmd(HW::item& item, + route::table_id_t id, + const boost::asio::ip::address_v6& inside, + const boost::asio::ip::address_v6& outside) + : rpc_cmd(item) + , m_id(id) + , m_inside(inside) + , m_outside(outside) +{} + +bool +create_66_cmd::operator==(const create_66_cmd& other) const +{ + return ((m_id == other.m_id) && (m_inside == other.m_inside) && + (m_outside == other.m_outside)); +} + +rc_t +create_66_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.vrf_id = m_id; + to_bytes(m_inside, payload.local_ip_address); + to_bytes(m_outside, payload.external_ip_address); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_66_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-66-static-create: " << m_hw_item.to_string() << " table:" << m_id + << " inside:" << m_inside.to_string() + << " outside:" << m_outside.to_string(); + + return (s.str()); +} + +delete_66_cmd::delete_66_cmd(HW::item& item, + route::table_id_t id, + const boost::asio::ip::address_v6& inside, + const boost::asio::ip::address_v6& outside) + : rpc_cmd(item) + , m_id(id) + , m_inside(inside) + , m_outside(outside) +{} + +bool +delete_66_cmd::operator==(const delete_66_cmd& other) const +{ + return ((m_id == other.m_id) && (m_inside == other.m_inside) && + (m_outside == other.m_outside)); +} + +rc_t +delete_66_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.vrf_id = m_id; + to_bytes(m_inside, payload.local_ip_address); + to_bytes(m_outside, payload.external_ip_address); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_66_cmd::to_string() const +{ + std::ostringstream s; + s << "nat-66-static-delete: " << m_hw_item.to_string() << " table:" << m_id + << " inside:" << m_inside.to_string() + << " outside:" << m_outside.to_string(); + + return (s.str()); +} + +bool +dump_66_cmd::operator==(const dump_66_cmd& other) const +{ + return (true); +} + +rc_t +dump_66_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_66_cmd::to_string() const +{ + return ("nat-static-dump"); +} + +}; // namespace nat_static_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/nat_static_cmds.hpp b/extras/deprecated/vom/vom/nat_static_cmds.hpp new file mode 100644 index 00000000000..281c05fa0d0 --- /dev/null +++ b/extras/deprecated/vom/vom/nat_static_cmds.hpp @@ -0,0 +1,249 @@ +/* + * 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_NAT_STATIC_CMDS_H__ +#define __VOM_NAT_STATIC_CMDS_H__ + +#include "nat_static.hpp" +#include "vom/dump_cmd.hpp" + +#include +#include + +namespace VOM { +namespace nat_static_cmds { + +/** + * A command class that creates NAT 44 static mapping + */ +class create_44_cmd + : public rpc_cmd, vapi::Nat44_add_del_static_mapping> +{ +public: + /** + * Constructor + */ + create_44_cmd(HW::item& item, + route::table_id_t id, + const boost::asio::ip::address_v4& inside, + const boost::asio::ip::address_v4& outside); + + /** + * 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_44_cmd& i) const; + +private: + route::table_id_t m_id; + const boost::asio::ip::address_v4 m_inside; + const boost::asio::ip::address_v4 m_outside; +}; + +/** + * A cmd class that deletes a NAT 44 static mapping + */ +class delete_44_cmd + : public rpc_cmd, vapi::Nat44_add_del_static_mapping> +{ +public: + /** + * Constructor + */ + delete_44_cmd(HW::item& item, + route::table_id_t id, + const boost::asio::ip::address_v4& inside, + const boost::asio::ip::address_v4& outside); + + /** + * 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_44_cmd& i) const; + +private: + route::table_id_t m_id; + const boost::asio::ip::address_v4 m_inside; + const boost::asio::ip::address_v4 m_outside; +}; + +/** + * A cmd class that Dumps all the nat_statics + */ +class dump_44_cmd : public dump_cmd +{ +public: + /** + * Constructor + */ + dump_44_cmd() = default; + ~dump_44_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_44_cmd& i) const; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +/** + * A command class that creates NAT 66 static mapping + */ +class create_66_cmd + : public rpc_cmd, vapi::Nat66_add_del_static_mapping> +{ +public: + /** + * Constructor + */ + create_66_cmd(HW::item& item, + route::table_id_t id, + const boost::asio::ip::address_v6& inside, + const boost::asio::ip::address_v6& outside); + + /** + * 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_66_cmd& i) const; + +private: + route::table_id_t m_id; + const boost::asio::ip::address_v6 m_inside; + const boost::asio::ip::address_v6 m_outside; +}; + +/** + * A cmd class that deletes a NAT 66 static mapping + */ +class delete_66_cmd + : public rpc_cmd, vapi::Nat66_add_del_static_mapping> +{ +public: + /** + * Constructor + */ + delete_66_cmd(HW::item& item, + route::table_id_t id, + const boost::asio::ip::address_v6& inside, + const boost::asio::ip::address_v6& outside); + + /** + * 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_66_cmd& i) const; + +private: + route::table_id_t m_id; + const boost::asio::ip::address_v6 m_inside; + const boost::asio::ip::address_v6 m_outside; +}; + +/** + * A cmd class that Dumps all the nat_statics + */ +class dump_66_cmd : public dump_cmd +{ +public: + /** + * Constructor + */ + dump_66_cmd() = default; + ~dump_66_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_66_cmd& i) const; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // namespace nat_static_cmds +}; // namespace vom + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/neighbour.cpp b/extras/deprecated/vom/vom/neighbour.cpp new file mode 100644 index 00000000000..01653f6ced1 --- /dev/null +++ b/extras/deprecated/vom/vom/neighbour.cpp @@ -0,0 +1,232 @@ +/* + * 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/neighbour.hpp" +#include "vom/api_types.hpp" +#include "vom/neighbour_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +singular_db neighbour::m_db; +neighbour::event_handler neighbour::m_evh; + +const neighbour::flags_t neighbour::flags_t::NONE(0, ""); +const neighbour::flags_t neighbour::flags_t::STATIC(1, "static"); +const neighbour::flags_t neighbour::flags_t::NO_FIB_ENTRY(2, "no-fib-entry"); + +neighbour::flags_t::flags_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +neighbour::neighbour(const interface& itf, + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac, + const flags_t flags) + : m_hw(false) + , m_itf(itf.singular()) + , m_ip_addr(ip_addr) + , m_mac(mac) + , m_flags(flags) +{ +} + +neighbour::neighbour(const neighbour& n) + : m_hw(n.m_hw) + , m_itf(n.m_itf) + , m_ip_addr(n.m_ip_addr) + , m_mac(n.m_mac) + , m_flags(n.m_flags) +{ +} + +neighbour::~neighbour() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); +} + +bool +neighbour::operator==(const neighbour& n) const +{ + return ((key() == n.key()) && (m_mac == n.m_mac)); +} + +const neighbour::key_t +neighbour::key() const +{ + return (std::make_pair(m_itf->key(), m_ip_addr)); +} + +void +neighbour::sweep() +{ + if (m_hw) { + HW::enqueue(new neighbour_cmds::delete_cmd(m_hw, m_itf->handle(), m_mac, + m_ip_addr, m_flags)); + } + HW::write(); +} + +void +neighbour::replay() +{ + if (m_hw) { + HW::enqueue(new neighbour_cmds::create_cmd(m_hw, m_itf->handle(), m_mac, + m_ip_addr, m_flags)); + } +} + +std::string +neighbour::to_string() const +{ + std::ostringstream s; + s << "neighbour:[" << m_itf->to_string() << ", " << m_mac.to_string() << ", " + << m_ip_addr.to_string() << " " << m_flags.to_string() << "]"; + + return (s.str()); +} + +void +neighbour::update(const neighbour& r) +{ + /* + * create the table if it is not yet created + */ + if (rc_t::OK != m_hw.rc()) { + HW::enqueue(new neighbour_cmds::create_cmd(m_hw, m_itf->handle(), m_mac, + m_ip_addr, m_flags)); + } +} + +std::shared_ptr +neighbour::find_or_add(const neighbour& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +neighbour::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +neighbour::singular() const +{ + return find_or_add(*this); +} + +void +neighbour::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const neighbour::key_t& key) +{ + os << "[" << key.first << ", " << key.second << "]"; + + return (os); +} + +neighbour::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "neighbour" }, "Neighbours", this); +} + +void +neighbour::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +neighbour::populate_i(const client_db::key_t& key, + std::shared_ptr itf, + const l3_proto_t& proto) +{ + /* + * dump VPP current states + */ + std::shared_ptr cmd = + std::make_shared( + neighbour_cmds::dump_cmd(itf->handle(), proto)); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + /* + * construct a neighbour from each recieved record. + */ + auto& payload = record.get_payload(); + + mac_address_t mac = from_api(payload.neighbor.mac_address); + boost::asio::ip::address ip_addr = from_api(payload.neighbor.ip_address); + neighbour::flags_t f = from_api(payload.neighbor.flags); + neighbour n(*itf, ip_addr, mac, f); + ; + + VOM_LOG(log_level_t::DEBUG) << "neighbour-dump: " << itf->to_string() << " " + << mac.to_string() << " " << ip_addr.to_string() + << " " << f.to_string(); + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, n); + } +} + +void +neighbour::event_handler::handle_populate(const client_db::key_t& key) +{ + auto it = interface::cbegin(); + + while (it != interface::cend()) { + neighbour::populate_i(key, it->second.lock(), l3_proto_t::IPV4); + neighbour::populate_i(key, it->second.lock(), l3_proto_t::IPV6); + + ++it; + } +} + +dependency_t +neighbour::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +neighbour::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/neighbour.hpp b/extras/deprecated/vom/vom/neighbour.hpp new file mode 100644 index 00000000000..396b05e076b --- /dev/null +++ b/extras/deprecated/vom/vom/neighbour.hpp @@ -0,0 +1,223 @@ +/* + * 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_NEIGHBOUR_H__ +#define __VOM_NEIGHBOUR_H__ + +#include "vom/interface.hpp" +#include "vom/singular_db.hpp" +#include "vom/types.hpp" + +namespace VOM { +/** + * A entry in the neighbour entry (ARP or IPv6 ND) + */ +class neighbour : public object_base +{ +public: + struct flags_t : public enum_base + { + /** + * Constructor + */ + flags_t(int v, const std::string s); + + /** + * Destructor + */ + ~flags_t() = default; + + flags_t operator|(const flags_t& e1) const + { + flags_t e = *this; + e |= e1; + return e; + } + + const static flags_t NONE; + const static flags_t STATIC; + const static flags_t NO_FIB_ENTRY; + }; + + /** + * The key for a neighbour entry; + * the interface and IP address + */ + typedef std::pair key_t; + + /** + * Construct an ARP entry + */ + neighbour(const interface& itf, + const boost::asio::ip::address& ip_addr, + const mac_address_t& mac, + const flags_t flags = flags_t::STATIC); + + /** + * Copy Construct + */ + neighbour(const neighbour& r); + + /** + * Destructor + */ + ~neighbour(); + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * Comparison operator + */ + bool operator==(const neighbour& n) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the neighbour fromits key + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all neighbours into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const neighbour& obj); + + /** + * Do the populate work + */ + static void populate_i(const client_db::key_t& key, + std::shared_ptr itf, + const l3_proto_t& proto); + + /** + * Find or add the instnace of the neighbour in the OM + */ + static std::shared_ptr find_or_add(const neighbour& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the bridge_domain + */ + HW::item m_hw; + + /** + * The bridge_domain domain the bridge_domain is in. + */ + std::shared_ptr m_itf; + + /** + * The IP address + */ + boost::asio::ip::address m_ip_addr; + + /** + * The mac to match + */ + mac_address_t m_mac; + + /** + * flags on the entry + */ + flags_t m_flags; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, const neighbour::key_t& key); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/neighbour_cmds.cpp b/extras/deprecated/vom/vom/neighbour_cmds.cpp new file mode 100644 index 00000000000..4bf4f320cae --- /dev/null +++ b/extras/deprecated/vom/vom/neighbour_cmds.cpp @@ -0,0 +1,172 @@ +/* + * 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/neighbour_cmds.hpp" +#include "vom/api_types.hpp" + +DEFINE_VAPI_MSG_IDS_IP_NEIGHBOR_API_JSON; + +namespace VOM { +namespace neighbour_cmds { +create_cmd::create_cmd(HW::item& item, + handle_t itf, + const mac_address_t& mac, + const boost::asio::ip::address& ip_addr, + const neighbour::flags_t& flags) + : srpc_cmd(item) + , m_itf(itf) + , m_mac(mac) + , m_ip_addr(ip_addr) + , m_flags(flags) +{} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_mac == other.m_mac) && (m_ip_addr == other.m_ip_addr) && + (m_itf == other.m_itf) && (m_flags == other.m_flags)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + payload.neighbor.sw_if_index = m_itf.value(); + + to_api(m_mac, payload.neighbor.mac_address); + to_api(m_ip_addr, payload.neighbor.ip_address); + payload.neighbor.flags = to_api(m_flags); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "nieghbour-create: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string() << " mac:" << m_mac.to_string() + << " ip:" << m_ip_addr.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + handle_t itf, + const mac_address_t& mac, + const boost::asio::ip::address& ip_addr, + const neighbour::flags_t& flags) + : srpc_cmd(item) + , m_itf(itf) + , m_mac(mac) + , m_ip_addr(ip_addr) + , m_flags(flags) +{} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return ((m_mac == other.m_mac) && (m_ip_addr == other.m_ip_addr) && + (m_itf == other.m_itf)); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.neighbor.sw_if_index = m_itf.value(); + + to_api(m_mac, payload.neighbor.mac_address); + to_api(m_ip_addr, payload.neighbor.ip_address); + payload.neighbor.flags = to_api(m_flags); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "neighbour-delete: " << m_hw_item.to_string() + << " itf:" << m_itf.to_string() << " mac:" << m_mac.to_string() + << " ip:" << m_ip_addr.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd(const handle_t& hdl, const l3_proto_t& proto) + : m_itf(hdl) + , m_proto(proto) +{} + +dump_cmd::dump_cmd(const dump_cmd& d) + : m_itf(d.m_itf) + , m_proto(d.m_proto) +{} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = m_itf.value(); + payload.af = to_api(m_proto); + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + std::ostringstream s; + + s << "neighbour-dump: " << m_itf.to_string() << " " << m_proto.to_string(); + + return (s.str()); +} +} // namespace neighbour_cmds +} // namespace vom + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/neighbour_cmds.hpp b/extras/deprecated/vom/vom/neighbour_cmds.hpp new file mode 100644 index 00000000000..024a021ce8d --- /dev/null +++ b/extras/deprecated/vom/vom/neighbour_cmds.hpp @@ -0,0 +1,148 @@ +/* + * 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_NEIGHBOUR_CMDS_H__ +#define __VOM_NEIGHBOUR_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/srpc_cmd.hpp" +#include "neighbour.hpp" + +#include + +namespace VOM { +namespace neighbour_cmds { + +/** + * A command class that creates or updates the bridge domain ARP Entry + */ +class create_cmd : public srpc_cmd +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + handle_t itf, + const mac_address_t& mac, + const boost::asio::ip::address& ip_addr, + const neighbour::flags_t &flags); + + /** + * 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; + +private: + handle_t m_itf; + mac_address_t m_mac; + boost::asio::ip::address m_ip_addr; + const neighbour::flags_t &m_flags; +}; + +/** + * A cmd class that deletes a bridge domain ARP entry + */ +class delete_cmd : public srpc_cmd +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, + handle_t itf, + const mac_address_t& mac, + const boost::asio::ip::address& ip_addr, + const neighbour::flags_t &flags); + + /** + * 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: + handle_t m_itf; + mac_address_t m_mac; + boost::asio::ip::address m_ip_addr; + const neighbour::flags_t &m_flags; +}; + +/** + * A cmd class that Dumps all the neighbours + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(const handle_t& itf, const l3_proto_t& proto); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; + + /** + * The interface to dump + */ + handle_t m_itf; + + /** + * V4 or V6 + */ + l3_proto_t m_proto; +}; + +}; // namespace neighbour_cmds +}; // namespace vom +#endif + diff --git a/extras/deprecated/vom/vom/object_base.cpp b/extras/deprecated/vom/vom/object_base.cpp new file mode 100644 index 00000000000..ea39270b0f6 --- /dev/null +++ b/extras/deprecated/vom/vom/object_base.cpp @@ -0,0 +1,70 @@ +/* + * 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/object_base.hpp" + +namespace VOM { +object_ref::object_ref(std::shared_ptr obj) + : m_obj(obj) + , m_state(OBJECT_STATE_NONE) +{ +} + +bool +object_ref::operator<(const object_ref& other) const +{ + return (m_obj.get() < other.m_obj.get()); +} + +std::shared_ptr +object_ref::obj() const +{ + return (m_obj); +} + +void +object_ref::mark() const +{ + m_state = OBJECT_STATE_STALE; +} + +void +object_ref::clear() const +{ + m_state = OBJECT_STATE_NONE; +} + +bool +object_ref::stale() const +{ + return (m_state == OBJECT_STATE_STALE); +} + +std::ostream& +operator<<(std::ostream& os, const object_base& o) +{ + os << o.to_string(); + + return (os); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/object_base.hpp b/extras/deprecated/vom/vom/object_base.hpp new file mode 100644 index 00000000000..fb49d738eaf --- /dev/null +++ b/extras/deprecated/vom/vom/object_base.hpp @@ -0,0 +1,146 @@ +/* + * 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_OBJECT_H__ +#define __VOM_OBJECT_H__ + +#include +#include + +#include "vom/types.hpp" + +namespace VOM { +/** + * A base class for all object_base in the VPP object_base-Model. + * provides the abstract interface. + */ +class object_base +{ +public: + /** + * convert to string format for debug purposes + */ + virtual std::string to_string() const = 0; + + /** + * Sweep/reap the object if still stale + */ + virtual void sweep(void) = 0; + + /** + * replay the object to create it in hardware + */ + virtual void replay(void) = 0; + +protected: + /** + * Constructable by derived classes only + */ + object_base() = default; + /** + * Destructor + */ + virtual ~object_base() = default; + +private: + /** + * note we are not maintaining dependencies back to the + * keys. i.e. this object does not know all the keys that + * refer to it. + */ +}; + +/** + * object state + */ +enum obj_state_t +{ + OBJECT_STATE_NONE = 0, + /** + * indicates the object is stale. This flag is set + * when a new epoch is declared. the flag is cleared + * when the object is updated in the new epoch. If the + * flag is still set after convergence is declared then + * the object is deleted + */ + OBJECT_STATE_STALE, +}; + +/** + * A represenation of a reference to a VPP object. + * the reference counting is held through the use of shared pointers. + * We also maintain the state of the object ready for mark n' sweep. + */ +class object_ref +{ +public: + /** + * Constructor + */ + object_ref(std::shared_ptr obj); + + /** + * less than operator + */ + bool operator<(const object_ref& other) const; + + /** + * Return the shared pointer + */ + std::shared_ptr obj() const; + + /** + * Mark the reference object as stale + */ + void mark() const; + + /** + * Clear the stale flag on the object + */ + void clear() const; + + /** + * Query if the object is stale + */ + bool stale() const; + +private: + /** + * The reference object + */ + std::shared_ptr m_obj; + + /** + * Not part of the key (in the set) so we can change it + * whilst iterating + */ + mutable obj_state_t m_state; +}; + +/** + * ostream print of a VPP Obect + */ +std::ostream& operator<<(std::ostream& os, const object_base& o); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/om.cpp b/extras/deprecated/vom/vom/om.cpp new file mode 100644 index 00000000000..b522168fcd6 --- /dev/null +++ b/extras/deprecated/vom/vom/om.cpp @@ -0,0 +1,156 @@ +/* + * 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 + +#include "vom/logger.hpp" +#include "vom/om.hpp" + +namespace VOM { +client_db* OM::m_db; + +std::unique_ptr OM::m_listeners; + +/** + * Initialse the connection to VPP + */ +void +OM::init() +{ + m_db = new client_db(); +} + +void +OM::mark(const client_db::key_t& key) +{ + /* + * Find if the object already stored on behalf of this key. + * and mark them stale + */ + object_ref_list& objs = m_db->find(key); + + auto mark_obj = [](const object_ref& oref) { oref.mark(); }; + + std::for_each(objs.begin(), objs.end(), mark_obj); +} + +void +OM::sweep(const client_db::key_t& key) +{ + /* + * Find if the object already stored on behalf of this key. + * and mark them stale + */ + object_ref_list& objs = m_db->find(key); + + for (auto it = objs.begin(); it != objs.end();) { + if (it->stale()) { + it = objs.erase(it); + } else { + ++it; + } + } + + HW::write(); +} + +void +OM::remove(const client_db::key_t& key) +{ + /* + * Simply reset the list for this key. This will desctruct the + * object list and shared_ptrs therein. When the last shared_ptr + * goes the objects desctructor is called and the object is + * removed from OM + */ + m_db->flush(key); + + HW::write(); +} + +void +OM::replay() +{ + VOM_LOG(log_level_t::INFO) << "replay"; + /* + * the listeners are sorted in dependency order + */ + for (listener* l : *m_listeners) { + l->handle_replay(); + HW::write(); + } +} + +void +OM::dump(const client_db::key_t& key, std::ostream& os) +{ + m_db->dump(key, os); +} + +void +OM::dump(std::ostream& os) +{ + m_db->dump(os); +} + +void +OM::populate(const client_db::key_t& key) +{ + VOM_LOG(log_level_t::INFO) << "populate"; + + /* + * the listeners are sorted in dependency order + */ + for (listener* l : *m_listeners) { + l->handle_populate(key); + } + + /* + * once we have it all, mark it stale. + */ + mark(key); +} + +bool +OM::register_listener(OM::listener* listener) +{ + if (!m_listeners) { + m_listeners.reset(new listener_list); + } + + m_listeners->insert(listener); + + return (true); +} + +OM::mark_n_sweep::mark_n_sweep(const client_db::key_t& key) + : m_key(key) +{ + OM::mark(m_key); +} + +OM::mark_n_sweep::~mark_n_sweep() +{ + OM::sweep(m_key); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/om.hpp b/extras/deprecated/vom/vom/om.hpp new file mode 100644 index 00000000000..0990393df8c --- /dev/null +++ b/extras/deprecated/vom/vom/om.hpp @@ -0,0 +1,356 @@ +/* + * 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_OM_H__ +#define __VOM_OM_H__ + +#include +#include +#include + +#include "vom/client_db.hpp" +#include "vom/hw.hpp" + +/** + +The VPP Object Model (VOM) library. + +Before we begin, a glossary of terms: + - Agent or client: A user mode process that links to and uses the VOM library + to programme VPP + - VPP: A running instance of VPP + - High Availability (HA): Scenarios where the client and/or VPP restart with + minimal service interruption. + - CReate, Update, Delete (CRUD): An API style where the producer issues + notifications to changes to objects + +The VOM is a C++ library that models entities in VPP as C++ classes. The + relationships between VOM objects and VPP entities is not always 1:1. Some + effort has been made to construct a higher level, more abstract API to VPP + programming*. +The client programming model is simple (or at least I intended it to be..). The +client deals in ‘desired’ state, that is, it expresses the objects it wants to +exists (in VPP) and the properties that the object should have, i.e**; + Interface af1(“my-af-packet-1”, AFPACKET, admin::UP); +Then the client ‘writes’ this object into the ‘model’ + OM::write(“clients-thing-1”, af1); + +“clients-thing-1” is a description of the entity within the client’s domain that +‘owns’ (or has locked or has a reference to) the VOM object. There can be many +owners of each VOM object. It will be the last owner’s update that will be +programmed in VPP. This model means that the client is not burdened with +maintaining which of its objects have created which VOM objects. If the client +is itself driven by a CRUD API, then create notifications are implemented as + above. Update notifications add two extra statements; + OM::mark(“clients-thing-1”); + … do writes …. + OM::sweep(“clients-thing-1”); +These ‘mark’ and ‘sweep’ statements are indications to OM that firstly, indicate +that all the objects owned by “clients-thing-1” are now stale, i.e that the +client may no longer need them. If one of the subsequent writes should update a +stale object, then it is no longer stale. The sweep statement will ‘remove’ all +the remaining stale objects. In this model, the client does not need to maintain +the mapping of VOM objects to its own objects – it can simply express what it +needs now. +The delete notification is simply: + OM::remove(“clients-thing-1”); +Which will remove all the objects in VOM that are owned by “clients-thing-1”. +Where ‘remove’ in this sense means unlock and unreference, the VOM object, and +VPP state, will only be truly removed once there are no more owners. This is +equivalent to a mark & sweep with no intermediate writes. + +To provide this client side model the VOM is a stateful library, meaning that +for each entity it creates in VPP, VOM maintains its own representation of that +object. VOM can therefore be memory hungry. The desired state is expressed by +the client, the ‘actual’ state is maintained by VOM. VOM will consolidate the +two states when the client writes to the OM and thus issue VPP only the changes +required. + +The concepts of ownership and statefulness also allow the support for HA +scenarios. +VPP restart: When VPP restarts, VOM will reconnect and ‘replay’ its state, in +dependency order, to VPP. The client does not need to regenerate its desired +state. +Client restart: when the client restarts, VOM will read/dump the current state +of all VPP objects and store them in the OM owned by the special owner “boot”. +As the client reprogrammes its desired state, objects will become owned by both +the boot process and the client. At the point in time, as determined by the +client, all stale state, that owned only by boot, can be purged. Hence the +system reaches the correct final state, with no interruption to VPP forwarding. + + +Basic Design: + +Each object in VOM (i.e. an interface, route, bridge-domain, etc) is stored in a +per-type object database, with an object-type specific key. This ‘singular’ DB +has a value-type of a weak pointer to the object. I use the term ‘singular’ to +refer to the instance of the object stored in these databases, to be distinct +from the instances the client constructs to represent desired state. +The ‘client’ DB maintains the mapping of owner to object. The value type of the +client DB is a shared pointer to the singular instance of the owned object. +Once all the owners are gone, and all the shared pointers are destroyed, the +singular instance is also destroyed. + +Each VOM object has some basic behaviour: + update: issue to VPP an update to this object’s state. This could include the + create + sweep: delete the VPP entity – called when the object is destroyed. + replay: issue to VPP all the commands needed to re-programme (VPP restart HA + scenario) + populate: read state from VPP and add it to the OM (client restart HA +scenario) + +The object code is boiler-plate, in some cases (like the ACLs) even template. +The objects are purposefully left as simple, functionality free as possible. + +Communication with VPP is through a ‘queue’ of ‘commands’. A command is +essentially an object wrapper around a VPP binary API call (although we do use +the VAPI C++ bindings too). Commands come in three flavours: + RPC: do this; done. + DUMP: give me all of these things; here you go + EVENT; tell me about these events; here’s one …. Here’s one…. Oh here’s + another….. etc. + +RPC and DUMP commands are handled synchronously. Therefore on return from +OM::write(…) VPP has been issued with the request and responded. EVENTs are +asynchronous and will be delivered to the listeners in a different thread – so +beware!! + +* As such VOM provides some level of insulation to the changes to the VPP + binary API. +** some of the type names are shorten for brevity’s sake. + +*/ +namespace VOM { +/** + * The interface to writing objects into VPP OM. + */ +class OM +{ +public: + /** + * A class providing the RAII pattern for mark and sweep + */ + class mark_n_sweep + { + public: + /** + * Constructor - will call mark on the key + */ + mark_n_sweep(const client_db::key_t& key); + + /** + * Destructor - will call sweep on the key + */ + ~mark_n_sweep(); + + private: + /** + * no copies + */ + mark_n_sweep(const mark_n_sweep& ms) = delete; + + /** + * The client whose state we are guarding. + */ + client_db::key_t m_key; + }; + + /** + * Init + */ + static void init(); + + /** + * populate the OM with state read from HW. + */ + static void populate(const client_db::key_t& key); + + /** + * Mark all state owned by this key as stale + */ + static void mark(const client_db::key_t& key); + + /** + * Sweep all the key's objects that are stale + */ + static void sweep(const client_db::key_t& key); + + /** + * Replay all of the objects to HW. + */ + static void replay(void); + + /** + * Make the State in VPP reflect the expressed desired state. + * But don't call the HW - use this whilst processing dumped + * data from HW + */ + template + static rc_t commit(const client_db::key_t& key, const OBJ& obj) + { + rc_t rc = rc_t::OK; + + HW::disable(); + rc = OM::write(key, obj); + HW::enable(); + + return (rc); + } + + /** + * Make the State in VPP reflect the expressed desired state. + * After processing all the objects in the queue, in FIFO order, + * any remaining state owned by the client_db::key_t is purged. + * This is a template function so the object's update() function is + * always called with the derived type. + */ + template + static rc_t write(const client_db::key_t& key, const OBJ& obj) + { + rc_t rc = rc_t::OK; + + /* + * Find the singular instance another owner may have created. + * this always returns something. + */ + std::shared_ptr inst = obj.singular(); + + /* + * Update the existing object with the new desired state + */ + inst->update(obj); + + /* + * Find if the object already stored on behalf of this key. + * and mark them stale + */ + object_ref_list& objs = m_db->find(key); + + /* + * Iterate through this list to find a matchin' object + * to the one requested. + */ + auto match_ptr = [inst](const object_ref& oref) { + return (inst == oref.obj()); + }; + auto it = std::find_if(objs.begin(), objs.end(), match_ptr); + + if (it != objs.end()) { + /* + * yes, this key already owns this object. + */ + it->clear(); + } else { + /* + * Add the singular instance to the owners list + */ + objs.insert(object_ref(inst)); + } + + return (HW::write()); + } + + /** + * Remove all object in the OM referenced by the key + */ + static void remove(const client_db::key_t& key); + + /** + * Print each of the object in the DB into the stream provided + */ + static void dump(const client_db::key_t& key, std::ostream& os); + + /** + * Print each of the KEYS + */ + static void dump(std::ostream& os); + + /** + * Class definition for listeners to OM events + */ + class listener + { + public: + listener() = default; + virtual ~listener() = default; + + /** + * Handle a populate event + */ + virtual void handle_populate(const client_db::key_t& key) = 0; + + /** + * Handle a replay event + */ + virtual void handle_replay() = 0; + + /** + * Get the sortable Id of the listener + */ + virtual dependency_t order() const = 0; + + /** + * less than operator for set sorting + */ + bool operator<(const listener& listener) const + { + return (order() < listener.order()); + } + }; + + /** + * Register a listener of events + */ + static bool register_listener(listener* listener); + +private: + /** + * Database of object state created for each key + */ + static client_db* m_db; + + /** + * Comparator to keep the pointers to listeners in sorted order + */ + struct listener_comparator_t + { + bool operator()(const listener* l1, const listener* l2) const + { + return (l1->order() < l2->order()); + } + }; + + /** + * convenient typedef for the sorted set of listeners + */ + typedef std::multiset listener_list; + + /** + * The listeners for events + */ + static std::unique_ptr m_listeners; +}; +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/pipe.cpp b/extras/deprecated/vom/vom/pipe.cpp new file mode 100644 index 00000000000..5f6a66d6a3e --- /dev/null +++ b/extras/deprecated/vom/vom/pipe.cpp @@ -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& +pipe::mk_create_cmd(std::queue& q) +{ + q.push(new pipe_cmds::create_cmd(m_hdl, m_name, m_instance, m_hdl_pair)); + + return (q); +} + +std::queue& +pipe::mk_delete_cmd(std::queue& q) +{ + q.push(new pipe_cmds::delete_cmd(m_hdl, m_hdl_pair)); + + return (q); +} + +std::shared_ptr +pipe::singular() const +{ + return std::dynamic_pointer_cast(singular_i()); +} + +std::shared_ptr +pipe::singular_i() const +{ + return m_db.find_or_add(key(), *this); +} + +std::shared_ptr +pipe::find(const key_t& k) +{ + return std::dynamic_pointer_cast(m_db.find(k)); +} + +std::shared_ptr +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 +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& +pipe::pipe_end::mk_create_cmd(std::queue& q) +{ + return (q); +} + +std::queue& +pipe::pipe_end::mk_delete_cmd(std::queue& 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 cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + std::shared_ptr 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: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/pipe.hpp b/extras/deprecated/vom/vom/pipe.hpp new file mode 100644 index 00000000000..4468208a1c5 --- /dev/null +++ b/extras/deprecated/vom/vom/pipe.hpp @@ -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_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 singular() const; + + /** + * Find a subinterface from its key + */ + static std::shared_ptr find(const key_t& k); + + /** + * The interface that is the east end of the pipe + */ + std::shared_ptr 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 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& mk_create_cmd(std::queue& cmds); + virtual std::queue& mk_delete_cmd(std::queue& cmds); + + std::shared_ptr 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 singular_i() const; + + /** + * Virtual functions to construct an interface create commands. + */ + virtual std::queue& mk_create_cmd(std::queue& cmds); + + /** + * Virtual functions to construct an interface delete commands. + */ + virtual std::queue& mk_delete_cmd(std::queue& cmds); + + /** + * the handles that are set during the create command + */ + HW::item m_hdl_pair; + + /** + * The ends of the pipe + */ + std::shared_ptr m_ends[2]; + + /** + * Instance number + */ + uint32_t m_instance; +}; + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/pipe_cmds.cpp b/extras/deprecated/vom/vom/pipe_cmds.cpp new file mode 100644 index 00000000000..c866b048ddf --- /dev/null +++ b/extras/deprecated/vom/vom/pipe_cmds.cpp @@ -0,0 +1,152 @@ +/* + * 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& item, + const std::string& name, + uint32_t instance, + HW::item& ends) + : interface::create_cmd(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( + static_cast(payload.pipe_sw_if_index[0]), + static_cast(payload.pipe_sw_if_index[1])), + rc }; + + fulfill(HW::item(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& item, + HW::item& end_pair) + : interface::delete_cmd(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: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/pipe_cmds.hpp b/extras/deprecated/vom/vom/pipe_cmds.hpp new file mode 100644 index 00000000000..b3921393e6a --- /dev/null +++ b/extras/deprecated/vom/vom/pipe_cmds.hpp @@ -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 + +namespace VOM { +namespace pipe_cmds { +/** + * A functor class that creates an interface + */ +class create_cmd : public interface::create_cmd +{ +public: + /** + * Cstrunctor taking the reference to the parent + * and the sub-interface's VLAN + */ + create_cmd(HW::item& item, + const std::string& name, + uint32_t instance, + HW::item& 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& m_hdl_pair; + uint32_t m_instance; +}; + +/** + * A cmd class that Delete an interface + */ +class delete_cmd : public interface::delete_cmd +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, HW::item& 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& m_hdl_pair; +}; + +/** + * A cmd class that Dumps all the Vpp interfaces + */ +class dump_cmd : public VOM::dump_cmd +{ +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: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/prefix.cpp b/extras/deprecated/vom/vom/prefix.cpp new file mode 100644 index 00000000000..b9910d3f2fc --- /dev/null +++ b/extras/deprecated/vom/vom/prefix.cpp @@ -0,0 +1,592 @@ +/* + * 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 +#include + +#include "vom/prefix.hpp" + +namespace VOM { +/* + * Keep this in sync with VPP's fib_protocol_t + */ +const l3_proto_t l3_proto_t::IPV4(0, "ipv4"); +const l3_proto_t l3_proto_t::IPV6(1, "ipv6"); +const l3_proto_t l3_proto_t::MPLS(2, "mpls"); + +l3_proto_t::l3_proto_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +bool +l3_proto_t::is_ipv6() const +{ + return (*this == IPV6); +} + +bool +l3_proto_t::is_ipv4() const +{ + return (*this == IPV4); +} + +const l3_proto_t& +l3_proto_t::from_address(const boost::asio::ip::address& addr) +{ + if (addr.is_v6()) { + return IPV6; + } + + return IPV4; +} + +const nh_proto_t& +l3_proto_t::to_nh_proto() const +{ + if (*this == IPV4) + return nh_proto_t::IPV4; + else if (*this == IPV6) + return nh_proto_t::IPV6; + else if (*this == MPLS) + return nh_proto_t::MPLS; + + return nh_proto_t::IPV4; +} + +std::ostream& +operator<<(std::ostream& os, const l3_proto_t& l3p) +{ + os << l3p.to_string(); + return os; +} + +/* + * Keep this in sync with VPP's dpo_proto_t + */ +const nh_proto_t nh_proto_t::IPV4(0, "ipv4"); +const nh_proto_t nh_proto_t::IPV6(1, "ipv6"); +const nh_proto_t nh_proto_t::MPLS(2, "mpls"); +const nh_proto_t nh_proto_t::ETHERNET(3, "ethernet"); + +nh_proto_t::nh_proto_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const nh_proto_t& +nh_proto_t::from_address(const boost::asio::ip::address& addr) +{ + if (addr.is_v6()) { + return IPV6; + } + + return IPV4; +} + +const ip_dscp_t ip_dscp_t::DSCP_CS0(0, "CS0"); +const ip_dscp_t ip_dscp_t::DSCP_CS1(8, "CS1"); +const ip_dscp_t ip_dscp_t::DSCP_CS2(16, "CS2"); +const ip_dscp_t ip_dscp_t::DSCP_CS3(24, "CS3"); +const ip_dscp_t ip_dscp_t::DSCP_CS4(32, "CS4"); +const ip_dscp_t ip_dscp_t::DSCP_CS5(40, "CS5"); +const ip_dscp_t ip_dscp_t::DSCP_CS6(48, "CS6"); +const ip_dscp_t ip_dscp_t::DSCP_CS7(50, "CS7"); +const ip_dscp_t ip_dscp_t::DSCP_AF11(10, "AF11"); +const ip_dscp_t ip_dscp_t::DSCP_AF12(12, "AF12"); +const ip_dscp_t ip_dscp_t::DSCP_AF13(14, "AF13"); +const ip_dscp_t ip_dscp_t::DSCP_AF21(18, "AF21"); +const ip_dscp_t ip_dscp_t::DSCP_AF22(20, "AF22"); +const ip_dscp_t ip_dscp_t::DSCP_AF23(22, "AF23"); +const ip_dscp_t ip_dscp_t::DSCP_AF31(26, "AF31"); +const ip_dscp_t ip_dscp_t::DSCP_AF32(28, "AF32"); +const ip_dscp_t ip_dscp_t::DSCP_AF33(30, "AF33"); +const ip_dscp_t ip_dscp_t::DSCP_AF41(34, "AF41"); +const ip_dscp_t ip_dscp_t::DSCP_AF42(36, "AF42"); +const ip_dscp_t ip_dscp_t::DSCP_AF43(38, "AF43"); +const ip_dscp_t ip_dscp_t::DSCP_EF(46, "EF"); + +ip_dscp_t::ip_dscp_t(int v, const std::string& s) + : enum_base(v, s) +{ +} +ip_dscp_t::ip_dscp_t(int v) + : enum_base(v, std::to_string(v)) +{ +} + +/** + * The all Zeros prefix + */ +const route::prefix_t route::prefix_t::ZERO("0.0.0.0", 0); +const route::prefix_t route::prefix_t::ZEROv6("::", 0); + +route::prefix_t::prefix_t(const boost::asio::ip::address& addr, uint8_t len) + : m_addr(addr) + , m_len(len) +{ +} + +route::prefix_t::prefix_t(const boost::asio::ip::address& addr) + : m_addr(addr) + , m_len(VOM::mask_width(addr)) +{ +} + +route::prefix_t::prefix_t(const std::string& s, uint8_t len) + : m_addr(boost::asio::ip::address::from_string(s)) + , m_len(len) +{ +} + +route::prefix_t::prefix_t(const prefix_t& o) + : m_addr(o.m_addr) + , m_len(o.m_len) +{ +} + +route::prefix_t::prefix_t() + : m_addr() + , m_len(0) +{ +} + +route::prefix_t::~prefix_t() +{ +} + +route::prefix_t& +route::prefix_t::operator=(const route::prefix_t& o) +{ + m_addr = o.m_addr; + m_len = o.m_len; + + return (*this); +} + +const boost::asio::ip::address& +route::prefix_t::address() const +{ + return (m_addr); +} + +uint8_t +route::prefix_t::mask_width() const +{ + return (m_len); +} + +bool +route::prefix_t::operator<(const route::prefix_t& o) const +{ + if (m_len == o.m_len) { + return (m_addr < o.m_addr); + } else { + return (m_len < o.m_len); + } +} + +bool +route::prefix_t::operator==(const route::prefix_t& o) const +{ + return (m_len == o.m_len && m_addr == o.m_addr); +} + +bool +route::prefix_t::operator!=(const route::prefix_t& o) const +{ + return (!(*this == o)); +} + +std::string +route::prefix_t::to_string() const +{ + std::ostringstream s; + + s << m_addr.to_string() << "/" << std::to_string(m_len); + + return (s.str()); +} + +boost::asio::ip::address +from_bytes(uint8_t is_ip6, const uint8_t* bytes) +{ + boost::asio::ip::address addr; + + if (is_ip6) { + std::array a; + std::copy(bytes, bytes + 16, std::begin(a)); + boost::asio::ip::address_v6 v6(a); + addr = v6; + } else { + std::array a; + std::copy(bytes, bytes + 4, std::begin(a)); + boost::asio::ip::address_v4 v4(a); + addr = v4; + } + + return (addr); +} + +route::prefix_t::prefix_t(uint8_t is_ip6, uint8_t* addr, uint8_t len) + : m_addr(from_bytes(is_ip6, addr)) + , m_len(len) +{ +} +void +to_bytes(const boost::asio::ip::address_v6& addr, uint8_t* array) +{ + memcpy(array, addr.to_bytes().data(), 16); +} + +void +to_bytes(const boost::asio::ip::address_v4& addr, uint8_t* array) +{ + memcpy(array, addr.to_bytes().data(), 4); +} + +void +to_bytes(const boost::asio::ip::address& addr, uint8_t* is_ip6, uint8_t* array) +{ + if (addr.is_v6()) { + *is_ip6 = 1; + to_bytes(addr.to_v6(), array); + } else { + *is_ip6 = 0; + to_bytes(addr.to_v4(), array); + } +} + +uint32_t +mask_width(const boost::asio::ip::address& addr) +{ + if (addr.is_v6()) { + return 128; + } + return 32; +} + +void +route::prefix_t::to_vpp(uint8_t* is_ip6, uint8_t* addr, uint8_t* len) const +{ + *len = m_len; + to_bytes(m_addr, is_ip6, addr); +} + +l3_proto_t +route::prefix_t::l3_proto() const +{ + if (m_addr.is_v6()) { + return (l3_proto_t::IPV6); + } else { + return (l3_proto_t::IPV4); + } + + return (l3_proto_t::IPV4); +} + +std::ostream& +operator<<(std::ostream& os, const route::prefix_t& pfx) +{ + os << pfx.to_string(); + + return (os); +} + +boost::asio::ip::address_v4 +operator|(const boost::asio::ip::address_v4& addr1, + const boost::asio::ip::address_v4& addr2) +{ + uint32_t a; + a = addr1.to_ulong() | addr2.to_ulong(); + boost::asio::ip::address_v4 addr(a); + return (addr); +} + +boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4& addr1, + const boost::asio::ip::address_v4& addr2) +{ + uint32_t a; + a = addr1.to_ulong() & addr2.to_ulong(); + boost::asio::ip::address_v4 addr(a); + return (addr); +} + +boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1) +{ + uint32_t a; + a = ~addr1.to_ulong(); + boost::asio::ip::address_v4 addr(a); + return (addr); +} + +boost::asio::ip::address_v6 +operator|(const boost::asio::ip::address_v6& addr1, + const boost::asio::ip::address_v6& addr2) +{ + boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes(); + boost::asio::ip::address_v6::bytes_type b2 = addr2.to_bytes(); + + for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0; + ii < b1.max_size(); ii++) { + b1[ii] |= b2[ii]; + } + + boost::asio::ip::address_v6 addr(b1); + return (addr); +} + +boost::asio::ip::address_v6 operator&(const boost::asio::ip::address_v6& addr1, + const boost::asio::ip::address_v6& addr2) +{ + boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes(); + boost::asio::ip::address_v6::bytes_type b2 = addr2.to_bytes(); + + for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0; + ii < b1.max_size(); ii++) { + b1[ii] &= b2[ii]; + } + + boost::asio::ip::address_v6 addr(b1); + return (addr); +} + +boost::asio::ip::address_v6 operator~(const boost::asio::ip::address_v6& addr1) +{ + boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes(); + + for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0; + ii < b1.max_size(); ii++) { + b1[ii] = ~b1[ii]; + } + + boost::asio::ip::address_v6 addr(b1); + return (addr); +} +boost::asio::ip::address +operator|(const boost::asio::ip::address& addr1, + const boost::asio::ip::address& addr2) +{ + if (addr1.is_v6()) + return (addr1.to_v6() | addr2.to_v6()); + else + return (addr1.to_v4() | addr2.to_v4()); +} + +boost::asio::ip::address operator&(const boost::asio::ip::address& addr1, + const boost::asio::ip::address& addr2) +{ + if (addr1.is_v6()) + return (addr1.to_v6() & addr2.to_v6()); + else + return (addr1.to_v4() & addr2.to_v4()); +} + +boost::asio::ip::address operator~(const boost::asio::ip::address& addr1) +{ + if (addr1.is_v6()) + return ~(addr1.to_v6()); + else + return ~(addr1.to_v4()); +} + +boost::asio::ip::address +route::prefix_t::mask() const +{ + if (m_addr.is_v6()) { + boost::asio::ip::address_v6::bytes_type b = + boost::asio::ip::address_v6::any().to_bytes(); + + uint8_t n_bits = mask_width(); + + for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0; + ii < b.max_size(); ii++) { + for (int8_t bit = 7; bit >= 0 && n_bits; bit--) { + b[ii] |= (1 << bit); + n_bits--; + } + if (!n_bits) + break; + } + + return (boost::asio::ip::address_v6(b)); + } else { + uint32_t a; + + a = ~((1 << (32 - mask_width())) - 1); + + return (boost::asio::ip::address_v4(a)); + } +} + +route::prefix_t +route::prefix_t::low() const +{ + prefix_t pfx(*this); + + pfx.m_addr = pfx.m_addr & pfx.mask(); + + return (pfx); +} + +route::prefix_t +route::prefix_t::high() const +{ + prefix_t pfx(*this); + + pfx.m_addr = pfx.m_addr | ~pfx.mask(); + + return (pfx); +} + +/** + * The all Zeros prefix + */ +const route::mprefix_t route::mprefix_t::ZERO; +const route::mprefix_t route::mprefix_t::ZEROv6; + +route::mprefix_t::mprefix_t(const boost::asio::ip::address& gaddr, uint8_t len) + : m_gaddr(gaddr) + , m_saddr() + , m_len(len) +{ +} + +route::mprefix_t::mprefix_t(const boost::asio::ip::address& gaddr) + : m_gaddr(gaddr) + , m_saddr() + , m_len(VOM::mask_width(gaddr)) +{ +} + +route::mprefix_t::mprefix_t(const boost::asio::ip::address& saddr, + const boost::asio::ip::address& gaddr) + : m_gaddr(gaddr) + , m_saddr(saddr) + , m_len(2 * VOM::mask_width(gaddr)) +{ +} + +route::mprefix_t::mprefix_t(const boost::asio::ip::address& saddr, + const boost::asio::ip::address& gaddr, + uint16_t len) + : m_gaddr(gaddr) + , m_saddr(saddr) + , m_len(len) +{ +} + +route::mprefix_t::mprefix_t(const mprefix_t& o) + : m_gaddr(o.m_gaddr) + , m_saddr(o.m_saddr) + , m_len(o.m_len) +{ +} +route::mprefix_t::mprefix_t() + : m_gaddr() + , m_saddr() + , m_len(0) +{ +} + +route::mprefix_t::~mprefix_t() +{ +} + +const boost::asio::ip::address& +route::mprefix_t::grp_address() const +{ + return (m_gaddr); +} + +const boost::asio::ip::address& +route::mprefix_t::src_address() const +{ + return (m_saddr); +} + +uint8_t +route::mprefix_t::mask_width() const +{ + return (m_len); +} + +l3_proto_t +route::mprefix_t::l3_proto() const +{ + if (m_gaddr.is_v6()) { + return (l3_proto_t::IPV6); + } else { + return (l3_proto_t::IPV4); + } + + return (l3_proto_t::IPV4); +} + +route::mprefix_t& +route::mprefix_t::operator=(const route::mprefix_t& o) +{ + m_gaddr = o.m_gaddr; + m_saddr = o.m_saddr; + m_len = o.m_len; + + return (*this); +} + +bool +route::mprefix_t::operator<(const route::mprefix_t& o) const +{ + if (m_len == o.m_len) { + if (m_saddr == o.m_saddr) + return (m_gaddr < o.m_gaddr); + else + return (m_saddr < o.m_saddr); + } else { + return (m_len < o.m_len); + } +} + +bool +route::mprefix_t::operator==(const route::mprefix_t& o) const +{ + return (m_len == o.m_len && m_gaddr == o.m_gaddr && m_saddr == o.m_saddr); +} + +bool +route::mprefix_t::operator!=(const route::mprefix_t& o) const +{ + return (!(*this == o)); +} + +std::string +route::mprefix_t::to_string() const +{ + std::ostringstream s; + + s << "(" << m_saddr.to_string() << "," << m_gaddr.to_string() << "/" + << std::to_string(m_len) << ")"; + + return (s.str()); +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/prefix.hpp b/extras/deprecated/vom/vom/prefix.hpp new file mode 100644 index 00000000000..a6496326fc4 --- /dev/null +++ b/extras/deprecated/vom/vom/prefix.hpp @@ -0,0 +1,414 @@ +/* + * 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_PREFIX_H__ +#define __VOM_PREFIX_H__ + +#include "vom/enum_base.hpp" +#include + +namespace VOM { +/** + * Types belonging to Routing + */ + +/** + * A next-hop protocol describes the protocol of a peer to which packets + * are sent after matching a route. + */ +class nh_proto_t : public enum_base +{ +public: + const static nh_proto_t IPV4; + const static nh_proto_t IPV6; + const static nh_proto_t MPLS; + const static nh_proto_t ETHERNET; + + static const nh_proto_t& from_address(const boost::asio::ip::address& addr); + +private: + /** + * Private constructor taking the value and the string name + */ + nh_proto_t(int v, const std::string& s); +}; + +/** + * An L3 protocol can be used to construct a prefix that is used + * to match packets are part of a route. + */ +class l3_proto_t : public enum_base +{ +public: + const static l3_proto_t IPV4; + const static l3_proto_t IPV6; + const static l3_proto_t MPLS; + + bool is_ipv4() const; + bool is_ipv6() const; + + static const l3_proto_t& from_address(const boost::asio::ip::address& addr); + + const nh_proto_t& to_nh_proto() const; + +private: + /** + * Private constructor taking the value and the string name + */ + l3_proto_t(int v, const std::string& s); +}; + +/** + * Ostream output for l3_proto_t + */ +std::ostream& operator<<(std::ostream& os, const l3_proto_t& l3p); + +/** + * IP DSCP values + */ +class ip_dscp_t : public enum_base +{ +public: + /* unfortunately some of the CSX names are defined in terminos.h + * as macros, hence the longer names */ + const static ip_dscp_t DSCP_CS0; + const static ip_dscp_t DSCP_CS1; + const static ip_dscp_t DSCP_CS2; + const static ip_dscp_t DSCP_CS3; + const static ip_dscp_t DSCP_CS4; + const static ip_dscp_t DSCP_CS5; + const static ip_dscp_t DSCP_CS6; + const static ip_dscp_t DSCP_CS7; + const static ip_dscp_t DSCP_AF11; + const static ip_dscp_t DSCP_AF12; + const static ip_dscp_t DSCP_AF13; + const static ip_dscp_t DSCP_AF21; + const static ip_dscp_t DSCP_AF22; + const static ip_dscp_t DSCP_AF23; + const static ip_dscp_t DSCP_AF31; + const static ip_dscp_t DSCP_AF32; + const static ip_dscp_t DSCP_AF33; + const static ip_dscp_t DSCP_AF41; + const static ip_dscp_t DSCP_AF42; + const static ip_dscp_t DSCP_AF43; + const static ip_dscp_t DSCP_EF; + + /** + * Constructor allows the creation of any DSCP value + */ + ip_dscp_t(int v); + +private: + ip_dscp_t(int v, const std::string& s); +}; + +namespace route { +/** + * type def the table-id + */ +typedef uint32_t table_id_t; + +/** + * The table-id for the default table + */ +const static table_id_t DEFAULT_TABLE = 0; + +/** + * A prefix defintion. Address + length + */ +class prefix_t +{ +public: + /** + * Default Constructor - creates ::/0 + */ + prefix_t(); + /** + * Constructor with address and length + */ + prefix_t(const boost::asio::ip::address& addr, uint8_t len); + /** + * Constructor with just the address, this creates a + * host prefix + */ + prefix_t(const boost::asio::ip::address& addr); + + /** + * Constructor with string and length + */ + prefix_t(const std::string& s, uint8_t len); + + /** + * Copy Constructor + */ + prefix_t(const prefix_t&); + + /** + * Constructor with VPP API prefix representation + */ + prefix_t(uint8_t is_ip6, uint8_t* addr, uint8_t len); + /** + * Destructor + */ + ~prefix_t(); + + /** + * Get the address + */ + const boost::asio::ip::address& address() const; + + /** + * Get the network mask width + */ + uint8_t mask_width() const; + + /** + * Assignement + */ + prefix_t& operator=(const prefix_t&); + + /** + * Less than operator + */ + bool operator<(const prefix_t& o) const; + + /** + * equals operator + */ + bool operator==(const prefix_t& o) const; + + /** + * not equal opartor + */ + bool operator!=(const prefix_t& o) const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * The all Zeros prefix + */ + const static prefix_t ZERO; + + /** + * The all Zeros v6 prefix + */ + const static prefix_t ZEROv6; + + /** + * Convert the prefix into VPP API parameters + */ + void to_vpp(uint8_t* is_ip6, uint8_t* addr, uint8_t* len) const; + + /** + * Return a address representation of the mask, e.g. 255.255.0.0 + */ + boost::asio::ip::address mask() const; + + /** + * get the lowest address in the prefix + */ + prefix_t low() const; + + /** + * Get the highest address in the prefix + */ + prefix_t high() const; + + /** + * Get the L3 protocol + */ + l3_proto_t l3_proto() const; + +private: + /** + * The address + */ + boost::asio::ip::address m_addr; + + /** + * The prefix length + */ + uint8_t m_len; +}; + +/** +* A prefix defintion. Address + length +*/ +class mprefix_t +{ +public: + /** + * Default Constructor - creates ::/0 + */ + mprefix_t(); + /** + * Constructor for (S,G) + */ + mprefix_t(const boost::asio::ip::address& saddr, + const boost::asio::ip::address& gaddr); + /* + * Constructor for (*,G) + */ + mprefix_t(const boost::asio::ip::address& gaddr); + + /* + * Constructor for (*,G/n) + */ + mprefix_t(const boost::asio::ip::address& gaddr, uint8_t len); + + /** + *Constructor for (S,G) + */ + mprefix_t(const boost::asio::ip::address& saddr, + const boost::asio::ip::address& gaddr, + uint16_t len); + + /** + * Copy Constructor + */ + mprefix_t(const mprefix_t&); + + /** + * Destructor + */ + ~mprefix_t(); + + /** + * Get the address + */ + const boost::asio::ip::address& grp_address() const; + const boost::asio::ip::address& src_address() const; + + /** + * Get the network mask width + */ + uint8_t mask_width() const; + + /** + * Assignement + */ + mprefix_t& operator=(const mprefix_t&); + + /** + * Less than operator + */ + bool operator<(const mprefix_t& o) const; + + /** + * equals operator + */ + bool operator==(const mprefix_t& o) const; + + /** + * not equal opartor + */ + bool operator!=(const mprefix_t& o) const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * The all Zeros prefix + */ + const static mprefix_t ZERO; + + /** + * The all Zeros v6 prefix + */ + const static mprefix_t ZEROv6; + + /** + * Get the L3 protocol + */ + l3_proto_t l3_proto() const; + +private: + /** + * The address + */ + boost::asio::ip::address m_gaddr; + boost::asio::ip::address m_saddr; + + /** + * The prefix length + */ + uint8_t m_len; +}; + +}; // namespace route + +boost::asio::ip::address_v4 operator|(const boost::asio::ip::address_v4& addr1, + const boost::asio::ip::address_v4& addr2); + +boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4& addr1, + const boost::asio::ip::address_v4& addr2); + +boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1); + +boost::asio::ip::address_v6 operator|(const boost::asio::ip::address_v6& addr1, + const boost::asio::ip::address_v6& addr2); + +boost::asio::ip::address_v6 operator&(const boost::asio::ip::address_v6& addr1, + const boost::asio::ip::address_v6& addr2); + +boost::asio::ip::address_v6 operator~(const boost::asio::ip::address_v6& addr1); + +boost::asio::ip::address operator|(const boost::asio::ip::address& addr1, + const boost::asio::ip::address& addr2); + +boost::asio::ip::address operator&(const boost::asio::ip::address& addr1, + const boost::asio::ip::address& addr2); + +boost::asio::ip::address operator~(const boost::asio::ip::address& addr1); + +/** + * Ostream printer for prefix_t + */ +std::ostream& operator<<(std::ostream& os, const route::prefix_t& pfx); + +/** + * Convert a boost address into a VPP bytes string + */ +void to_bytes(const boost::asio::ip::address& addr, + uint8_t* is_ip6, + uint8_t* array); +void to_bytes(const boost::asio::ip::address_v4& addr, uint8_t* array); +void to_bytes(const boost::asio::ip::address_v6& addr, uint8_t* array); + +/** + * Get the prefix mask length of a host route from the boost address + */ +uint32_t mask_width(const boost::asio::ip::address& addr); + +/** + * Convert a VPP byte stinrg into a boost addresss + */ +boost::asio::ip::address from_bytes(uint8_t is_ip6, const uint8_t* array); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_map.cpp b/extras/deprecated/vom/vom/qos_map.cpp new file mode 100644 index 00000000000..1f0dcc5a057 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_map.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2019 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/qos_map.hpp" +#include "vom/api_types.hpp" +#include "vom/qos_map_cmds.hpp" +#include "vom/qos_types_api.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace QoS { + +singular_db map::m_db; + +map::event_handler map::m_evh; + +map::map(uint32_t id, const outputs_t& o) + : m_config(false) + , m_id(id) + , m_outputs(o) +{ +} + +map::map(const map& r) + : m_config(r.m_config) + , m_id(r.m_id) + , m_outputs(r.m_outputs) +{ +} + +map::~map() +{ + sweep(); + m_db.release(key(), this); +} + +const map::key_t +map::key() const +{ + return m_id; +} + +const uint32_t +map::id() const +{ + return m_id; +} + +bool +map::operator==(const map& m) const +{ + return (key() == m.key() && m_outputs == m.m_outputs); +} + +void +map::sweep() +{ + if (m_config) { + HW::enqueue(new map_cmds::delete_cmd(m_config, m_id)); + } + HW::write(); +} + +void +map::replay() +{ + if (m_config) { + HW::enqueue(new map_cmds::create_cmd(m_config, m_id, m_outputs)); + } +} + +std::string +map::to_string() const +{ + std::ostringstream s; + s << "qos-map:" << (int)m_id; + + return (s.str()); +} + +void +map::update(const map& m) +{ + m_outputs = m.m_outputs; + + if (rc_t::OK != m_config.rc()) { + HW::enqueue(new map_cmds::create_cmd(m_config, m_id, m_outputs)); + } +} + +std::shared_ptr +map::find_or_add(const map& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +map::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +map::singular() const +{ + return find_or_add(*this); +} + +void +map::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +map::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "qos-map" }, "QoS Map", this); +} + +void +map::event_handler::handle_replay() +{ + m_db.replay(); +} + +static const map::outputs_t +from_api(vapi_type_qos_egress_map_row rows[4]) +{ + map::outputs_t o; + + for (uint32_t ii = 0; ii < 4; ii++) { + std::copy(std::begin(rows[ii].outputs), std::end(rows[ii].outputs), + o[ii].begin()); + } + + return o; +} + +void +map::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& rr : *cmd) { + auto& payload = rr.get_payload(); + + map qr(payload.map.id, from_api(payload.map.rows)); + OM::commit(key, qr); + } +} + +dependency_t +map::event_handler::order() const +{ + return (dependency_t::TABLE); +} + +void +map::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_map.hpp b/extras/deprecated/vom/vom/qos_map.hpp new file mode 100644 index 00000000000..04a14451cd8 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_map.hpp @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2019 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_QOS_MAP_H__ +#define __VOM_QOS_MAP_H__ + +#include + +#include "vom/interface.hpp" +#include "vom/qos_types.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * Types belonging to QoS + */ +namespace QoS { + +/** + * A QoS map determines how value from one source are translated to + * values of another source + */ +class map : public object_base +{ +public: + typedef std::array, 4> outputs_t; + + map(uint32_t id, const outputs_t& o); + map(const map& r); + + ~map(); + + typedef uint32_t key_t; + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * Return the object's ID + */ + const key_t id() const; + + /** + * comparison operator + */ + bool operator==(const map& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const map& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const map& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class VOM::OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the config. The bool representing the + * do/don't configured/unconfigured. + */ + HW::item m_config; + + /** + * unique ID of the MAP. + */ + uint32_t m_id; + + /** + * outputs from the translation + */ + outputs_t m_outputs; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +}; // namesapce QoS + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_map_cmds.cpp b/extras/deprecated/vom/vom/qos_map_cmds.cpp new file mode 100644 index 00000000000..8e1f7f8c015 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_map_cmds.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2019 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/qos_map_cmds.hpp" +#include "vom/qos_types_api.hpp" + +namespace VOM { +namespace QoS { +namespace map_cmds { + +static void +to_api(const map::outputs_t& o, vapi_type_qos_egress_map_row rows[4]) +{ + for (uint32_t ii = 0; ii < 4; ii++) { + std::copy(o[ii].begin(), o[ii].end(), std::begin(rows[ii].outputs)); + } +} + +create_cmd::create_cmd(HW::item& item, + uint32_t id, + const map::outputs_t& o) + : rpc_cmd(item) + , m_id(id) + , m_outputs(o) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return (m_id == other.m_id && m_outputs == other.m_outputs); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.map.id = m_id; + to_api(m_outputs, payload.map.rows); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "qos-map-create: " << m_hw_item.to_string() << " map:" << m_id; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, uint32_t id) + : rpc_cmd(item) + , m_id(id) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_hw_item == other.m_hw_item && m_id == other.m_id); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.map.id = m_id; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "qos-map-delete: " << m_hw_item.to_string() << " map:" << m_id; + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("qos-map-dump"); +} + +}; // namespace map_cmds +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_map_cmds.hpp b/extras/deprecated/vom/vom/qos_map_cmds.hpp new file mode 100644 index 00000000000..937bf7da209 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_map_cmds.hpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2019 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_QOS_MAP_CMDS_H__ +#define __VOM_QOS_MAP_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/qos_map.hpp" + +#include + +namespace VOM { +namespace QoS { +namespace map_cmds { + +/** + * A command class that creates or updates the GBP endpoint + */ +class create_cmd : public rpc_cmd, vapi::Qos_egress_map_update> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, uint32_t id, const map::outputs_t& o); + + /** + * 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; + +private: + uint32_t m_id; + const map::outputs_t& m_outputs; +}; + +/** + * A cmd class that deletes a GBP endpoint + */ +class delete_cmd : public rpc_cmd, vapi::Qos_egress_map_update> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, uint32_t id); + + /** + * 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: + uint32_t m_id; +}; + +/** + * A cmd class that Dumps all the GBP endpoints + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace map_cmds +}; // namespace Qos +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_mark.cpp b/extras/deprecated/vom/vom/qos_mark.cpp new file mode 100644 index 00000000000..33ebe40831e --- /dev/null +++ b/extras/deprecated/vom/vom/qos_mark.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2019 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/qos_mark.hpp" +#include "vom/api_types.hpp" +#include "vom/qos_mark_cmds.hpp" +#include "vom/qos_types_api.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace QoS { + +singular_db mark::m_db; + +mark::event_handler mark::m_evh; + +mark::mark(const interface& itf, const map& m, const source_t& src) + : m_config(false) + , m_itf(itf.singular()) + , m_map(m.singular()) + , m_src(src) +{ +} + +mark::mark(const mark& m) + : m_config(m.m_config) + , m_itf(m.m_itf) + , m_map(m.m_map) + , m_src(m.m_src) +{ +} + +mark::~mark() +{ + sweep(); + m_db.release(key(), this); +} + +const mark::key_t +mark::key() const +{ + return (std::make_pair(m_itf->key(), m_src)); +} + +bool +mark::operator==(const mark& m) const +{ + return (key() == m.key() && m_map->id() == m.m_map->id()); +} + +void +mark::sweep() +{ + if (m_config) { + HW::enqueue(new mark_cmds::delete_cmd(m_config, m_itf->handle(), m_src)); + } + HW::write(); +} + +void +mark::replay() +{ + if (m_config) { + HW::enqueue( + new mark_cmds::create_cmd(m_config, m_itf->handle(), m_map->id(), m_src)); + } +} + +std::string +mark::to_string() const +{ + std::ostringstream s; + s << "qos-mark:[" << m_itf->to_string() << ", map:" << m_map->id() + << ", src:" << m_src.to_string(); + + return (s.str()); +} + +void +mark::update(const mark& r) +{ + if (rc_t::OK != m_config.rc()) { + HW::enqueue( + new mark_cmds::create_cmd(m_config, m_itf->handle(), m_map->id(), m_src)); + } +} + +std::shared_ptr +mark::find_or_add(const mark& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +mark::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +mark::singular() const +{ + return find_or_add(*this); +} + +void +mark::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +mark::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "qos-mark" }, "QoS Mark", this); +} + +void +mark::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +mark::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& rr : *cmd) { + auto& payload = rr.get_payload(); + + std::shared_ptr itf = interface::find(payload.mark.sw_if_index); + std::shared_ptr map = map::find(payload.mark.map_id); + + VOM_LOG(log_level_t::DEBUG) << "data: " << payload.mark.sw_if_index; + + if (itf && map) { + mark qm(*itf, *map, from_api(payload.mark.output_source)); + OM::commit(key, qm); + + VOM_LOG(log_level_t::DEBUG) << "read: " << qm.to_string(); + } else { + VOM_LOG(log_level_t::ERROR) + << "no interface or map:" << payload.mark.sw_if_index << ", " + << payload.mark.map_id; + } + } +} + +dependency_t +mark::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +mark::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_mark.hpp b/extras/deprecated/vom/vom/qos_mark.hpp new file mode 100644 index 00000000000..2ba5a0d9df6 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_mark.hpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2019 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_QOS_MARK_H__ +#define __VOM_QOS_MARK_H__ + +#include + +#include "vom/interface.hpp" +#include "vom/qos_map.hpp" +#include "vom/qos_types.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +namespace QoS { + +/** + * The marking of packets with QoS bits as they egress an interface + */ +class mark : public object_base +{ +public: + mark(const interface& i, const map& m, const source_t& source); + mark(const mark& r); + + ~mark(); + + typedef std::pair key_t; + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const mark& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const mark& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const mark& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class VOM::OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the config. The bool representing the + * do/don't configured/unconfigured. + */ + HW::item m_config; + + /** + * The interface the mark applies to + */ + std::shared_ptr m_itf; + + /** + * The map the marking uses + */ + std::shared_ptr m_map; + + /** + * QoS source to mark from + */ + source_t m_src; + + /** + * A map of all QoS Markers + */ + static singular_db m_db; +}; + +}; // namesapce QoS + +std::ostream& operator<<(std::ostream& os, const QoS::mark::key_t& key); + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_mark_cmds.cpp b/extras/deprecated/vom/vom/qos_mark_cmds.cpp new file mode 100644 index 00000000000..1dd4cc177c5 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_mark_cmds.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019 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/qos_mark_cmds.hpp" +#include "vom/qos_types_api.hpp" + +namespace VOM { +namespace QoS { +namespace mark_cmds { + +create_cmd::create_cmd(HW::item& item, + const handle_t& itf, + uint32_t map_id, + const source_t& s) + : rpc_cmd(item) + , m_itf(itf) + , m_map_id(map_id) + , m_src(s) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_src == other.m_src) && + (m_map_id == other.m_map_id)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.mark.sw_if_index = m_itf.value(); + payload.mark.map_id = m_map_id; + payload.mark.output_source = to_api(m_src); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "qos-mark-create: " << m_hw_item.to_string() << " itf:" << m_itf + << " src:" << m_src.to_string() << " map-id:" << m_map_id; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + const handle_t& itf, + const source_t& s) + : rpc_cmd(item) + , m_itf(itf) + , m_src(s) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_hw_item == other.m_hw_item && m_itf == other.m_itf && + m_src == other.m_src); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.mark.sw_if_index = m_itf.value(); + payload.mark.output_source = to_api(m_src); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "qos-mark-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("qos-mark-dump"); +} + +}; // namespace mark_cmds +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_mark_cmds.hpp b/extras/deprecated/vom/vom/qos_mark_cmds.hpp new file mode 100644 index 00000000000..8e2882d9ab4 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_mark_cmds.hpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019 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_QOS_MARK_CMDS_H__ +#define __VOM_QOS_MARK_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/qos_mark.hpp" + +#include + +namespace VOM { +namespace QoS { +namespace mark_cmds { + +/** + * A command class that creates or updates the GBP endpoint + */ +class create_cmd : public rpc_cmd, vapi::Qos_mark_enable_disable> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + const handle_t& itf, + uint32_t map_id, + const source_t& src); + + /** + * 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; + +private: + handle_t m_itf; + uint32_t m_map_id; + const source_t& m_src; +}; + +/** + * A cmd class that deletes a GBP endpoint + */ +class delete_cmd : public rpc_cmd, vapi::Qos_mark_enable_disable> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, const handle_t& itf, const source_t& src); + + /** + * 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: + const handle_t m_itf; + const source_t& m_src; +}; + +/** + * A cmd class that Dumps all the GBP endpoints + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace mark_cmds +}; // namespace Qos +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_record.cpp b/extras/deprecated/vom/vom/qos_record.cpp new file mode 100644 index 00000000000..3c8ea750145 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_record.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2019 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/qos_record.hpp" +#include "vom/api_types.hpp" +#include "vom/qos_record_cmds.hpp" +#include "vom/qos_types_api.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace QoS { + +singular_db record::m_db; + +record::event_handler record::m_evh; + +record::record(const interface& itf, const source_t& src) + : m_config(false) + , m_itf(itf.singular()) + , m_src(src) +{ +} + +record::record(const record& r) + : m_config(r.m_config) + , m_itf(r.m_itf) + , m_src(r.m_src) +{ +} + +record::~record() +{ + sweep(); + m_db.release(key(), this); +} + +const record::key_t +record::key() const +{ + return (std::make_pair(m_itf->key(), m_src)); +} + +bool +record::operator==(const record& r) const +{ + return (key() == r.key()); +} + +void +record::sweep() +{ + if (m_config) { + HW::enqueue(new record_cmds::delete_cmd(m_config, m_itf->handle(), m_src)); + } + HW::write(); +} + +void +record::replay() +{ + if (m_config) { + HW::enqueue(new record_cmds::create_cmd(m_config, m_itf->handle(), m_src)); + } +} + +std::string +record::to_string() const +{ + std::ostringstream s; + s << "qos-record:[" << m_itf->to_string() << ", src:" << m_src.to_string(); + + return (s.str()); +} + +void +record::update(const record& r) +{ + if (rc_t::OK != m_config.rc()) { + HW::enqueue(new record_cmds::create_cmd(m_config, m_itf->handle(), m_src)); + } +} + +std::shared_ptr +record::find_or_add(const record& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +record::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +record::singular() const +{ + return find_or_add(*this); +} + +void +record::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +record::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "qos-record" }, "QoS Record", this); +} + +void +record::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +record::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& rr : *cmd) { + auto& payload = rr.get_payload(); + + std::shared_ptr itf = + interface::find(payload.record.sw_if_index); + + VOM_LOG(log_level_t::DEBUG) << "data: " << payload.record.sw_if_index; + + if (itf) { + record qr(*itf, from_api(payload.record.input_source)); + OM::commit(key, qr); + + VOM_LOG(log_level_t::DEBUG) << "read: " << qr.to_string(); + } else { + VOM_LOG(log_level_t::ERROR) << "no interface:" + << payload.record.sw_if_index; + } + } +} + +dependency_t +record::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +record::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +}; // namespace QoS + +std::ostream& +operator<<(std::ostream& os, const QoS::record::key_t& key) +{ + os << key.first << "," << key.second; + + return os; +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_record.hpp b/extras/deprecated/vom/vom/qos_record.hpp new file mode 100644 index 00000000000..396b4313643 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_record.hpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2019 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_QOS_RECORD_H__ +#define __VOM_QOS_RECORD_H__ + +#include + +#include "vom/interface.hpp" +#include "vom/qos_types.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * Types belonging to QoS + */ +namespace QoS { + +class record : public object_base +{ +public: + record(const interface& i, const source_t& source); + record(const record& r); + + ~record(); + + typedef std::pair key_t; + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const record& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const record& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const record& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class VOM::OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the config. The bool representing the + * do/don't configured/unconfigured. + */ + HW::item m_config; + + /** + * The interface the endpoint is attached to. + */ + std::shared_ptr m_itf; + + /** + * QoS source to record from + */ + source_t m_src; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +}; // namesapce QoS + +std::ostream& operator<<(std::ostream& os, const QoS::record::key_t& key); + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_record_cmds.cpp b/extras/deprecated/vom/vom/qos_record_cmds.cpp new file mode 100644 index 00000000000..ec5580ee238 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_record_cmds.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2019 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/qos_record_cmds.hpp" +#include "vom/qos_types_api.hpp" + +namespace VOM { +namespace QoS { +namespace record_cmds { + +create_cmd::create_cmd(HW::item& item, + const handle_t& itf, + const source_t& s) + : rpc_cmd(item) + , m_itf(itf) + , m_src(s) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_src == other.m_src)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.record.sw_if_index = m_itf.value(); + payload.record.input_source = to_api(m_src); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "qos-record-create: " << m_hw_item.to_string() << " itf:" << m_itf + << " src:" << m_src.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + const handle_t& itf, + const source_t& s) + : rpc_cmd(item) + , m_itf(itf) + , m_src(s) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_hw_item == other.m_hw_item && m_itf == other.m_itf && + m_src == other.m_src); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.record.sw_if_index = m_itf.value(); + payload.record.input_source = to_api(m_src); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "qos-record-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("qos-record-dump"); +} + +}; // namespace record_cmds +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_record_cmds.hpp b/extras/deprecated/vom/vom/qos_record_cmds.hpp new file mode 100644 index 00000000000..1cffc11eead --- /dev/null +++ b/extras/deprecated/vom/vom/qos_record_cmds.hpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019 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_QOS_RECORD_CMDS_H__ +#define __VOM_QOS_RECORD_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/qos_record.hpp" + +#include + +namespace VOM { +namespace QoS { +namespace record_cmds { + +/** + * A command class that creates or updates the GBP endpoint + */ +class create_cmd + : public rpc_cmd, vapi::Qos_record_enable_disable> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, const handle_t& itf, const source_t& src); + + /** + * 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; + +private: + const handle_t m_itf; + const source_t& m_src; +}; + +/** + * A cmd class that deletes a GBP endpoint + */ +class delete_cmd + : public rpc_cmd, vapi::Qos_record_enable_disable> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, const handle_t& itf, const source_t& src); + + /** + * 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: + const handle_t m_itf; + const source_t& m_src; +}; + +/** + * A cmd class that Dumps all the GBP endpoints + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace record_cmds +}; // namespace Qos +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_store.cpp b/extras/deprecated/vom/vom/qos_store.cpp new file mode 100644 index 00000000000..a55c14b5ecd --- /dev/null +++ b/extras/deprecated/vom/vom/qos_store.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2019 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/qos_store.hpp" +#include "vom/api_types.hpp" +#include "vom/qos_store_cmds.hpp" +#include "vom/qos_types_api.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace QoS { + +singular_db store::m_db; + +store::event_handler store::m_evh; + +store::store(const interface& itf, const source_t& src, bits_t value) + : m_config(false) + , m_itf(itf.singular()) + , m_src(src) + , m_value(value) +{ +} + +store::store(const store& s) + : m_config(s.m_config) + , m_itf(s.m_itf) + , m_src(s.m_src) + , m_value(s.m_value) +{ +} + +store::~store() +{ + sweep(); + m_db.release(key(), this); +} + +const store::key_t +store::key() const +{ + return (std::make_pair(m_itf->key(), m_src)); +} + +bool +store::operator==(const store& r) const +{ + return (key() == r.key()); +} + +void +store::sweep() +{ + if (m_config) { + HW::enqueue(new store_cmds::delete_cmd(m_config, m_itf->handle(), m_src)); + } + HW::write(); +} + +void +store::replay() +{ + if (m_config) { + HW::enqueue( + new store_cmds::create_cmd(m_config, m_itf->handle(), m_src, m_value)); + } +} + +std::string +store::to_string() const +{ + std::ostringstream s; + s << "qos-store:[" << m_itf->to_string() << ", src:" << m_src.to_string() + << ", value:" << static_cast(m_value); + + return (s.str()); +} + +void +store::update(const store& r) +{ + if (rc_t::OK != m_config.rc()) { + HW::enqueue( + new store_cmds::create_cmd(m_config, m_itf->handle(), m_src, m_value)); + } +} + +std::shared_ptr +store::find_or_add(const store& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +store::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +store::singular() const +{ + return find_or_add(*this); +} + +void +store::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +store::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "qos-store" }, "QoS Store", this); +} + +void +store::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +store::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& rr : *cmd) { + auto& payload = rr.get_payload(); + + std::shared_ptr itf = interface::find(payload.store.sw_if_index); + + VOM_LOG(log_level_t::DEBUG) << "data: " << payload.store.sw_if_index; + + if (itf) { + store qr(*itf, from_api(payload.store.input_source), payload.store.value); + OM::commit(key, qr); + + VOM_LOG(log_level_t::DEBUG) << "read: " << qr.to_string(); + } else { + VOM_LOG(log_level_t::ERROR) << "no interface:" + << payload.store.sw_if_index; + } + } +} + +dependency_t +store::event_handler::order() const +{ + return (dependency_t::ENTRY); +} + +void +store::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +}; // namespace QoS + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_store.hpp b/extras/deprecated/vom/vom/qos_store.hpp new file mode 100644 index 00000000000..b2f6c67ce1c --- /dev/null +++ b/extras/deprecated/vom/vom/qos_store.hpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2019 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_QOS_STORE_H__ +#define __VOM_QOS_STORE_H__ + +#include + +#include "vom/interface.hpp" +#include "vom/qos_types.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * Types belonging to QoS + */ +namespace QoS { + +class store : public object_base +{ +public: + store(const interface& i, const source_t& source, bits_t value); + store(const store& r); + + ~store(); + + typedef std::pair key_t; + + /** + * Return the object's key + */ + const key_t key() const; + + /** + * comparison operator + */ + bool operator==(const store& bdae) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find(const key_t& k); + + /** + * Dump all bridge_domain-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const store& obj); + + /** + * Find or add the instnace of the bridge_domain domain in the OM + */ + static std::shared_ptr find_or_add(const store& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class VOM::OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the config. The bool representing the + * do/don't configured/unconfigured. + */ + HW::item m_config; + + /** + * The interface the endpoint is attached to. + */ + std::shared_ptr m_itf; + + /** + * QoS source to store from + */ + source_t m_src; + + /** + * QoS Value to store in the buffer + */ + bits_t m_value; + + /** + * A map of all bridge_domains + */ + static singular_db m_db; +}; + +}; // namesapce QoS + +std::ostream& operator<<(std::ostream& os, const QoS::store::key_t& key); + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_store_cmds.cpp b/extras/deprecated/vom/vom/qos_store_cmds.cpp new file mode 100644 index 00000000000..1d7d18981f1 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_store_cmds.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019 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/qos_store_cmds.hpp" +#include "vom/qos_types_api.hpp" + +namespace VOM { +namespace QoS { +namespace store_cmds { + +create_cmd::create_cmd(HW::item& item, + const handle_t& itf, + const source_t& s, + bits_t value) + : rpc_cmd(item) + , m_itf(itf) + , m_src(s) + , m_value(value) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_itf == other.m_itf) && (m_src == other.m_src) && + (m_value == other.m_value)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.store.sw_if_index = m_itf.value(); + payload.store.input_source = to_api(m_src); + payload.store.value = m_value; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "qos-store-create: " << m_hw_item.to_string() << " itf:" << m_itf + << " src:" << m_src.to_string() << " value:" << static_cast(m_value); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + const handle_t& itf, + const source_t& s) + : rpc_cmd(item) + , m_itf(itf) + , m_src(s) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_hw_item == other.m_hw_item && m_itf == other.m_itf && + m_src == other.m_src); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.store.sw_if_index = m_itf.value(); + payload.store.input_source = to_api(m_src); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "qos-store-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("qos-store-dump"); +} + +}; // namespace store_cmds +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_store_cmds.hpp b/extras/deprecated/vom/vom/qos_store_cmds.hpp new file mode 100644 index 00000000000..29d95de9fb8 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_store_cmds.hpp @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2019 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_QOS_STORE_CMDS_H__ +#define __VOM_QOS_STORE_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/qos_store.hpp" + +#include + +namespace VOM { +namespace QoS { +namespace store_cmds { + +/** + * A command class that creates or updates the GBP endpoint + */ +class create_cmd + : public rpc_cmd, vapi::Qos_store_enable_disable> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, + const handle_t& itf, + const source_t& src, + bits_t value); + + /** + * 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; + +private: + handle_t m_itf; + const source_t& m_src; + bits_t m_value; +}; + +/** + * A cmd class that deletes a GBP endpoint + */ +class delete_cmd + : public rpc_cmd, vapi::Qos_store_enable_disable> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, const handle_t& itf, const source_t& src); + + /** + * 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: + const handle_t m_itf; + const source_t& m_src; +}; + +/** + * A cmd class that Dumps all the GBP endpoints + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; +}; // namespace store_cmds +}; // namespace Qos +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_types.cpp b/extras/deprecated/vom/vom/qos_types.cpp new file mode 100644 index 00000000000..6b43c2237e1 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_types.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 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/qos_types.hpp" + +namespace VOM { +namespace QoS { + +const source_t source_t::EXT(0, "ext"); +const source_t source_t::VLAN(1, "vlan"); +const source_t source_t::MPLS(2, "mpls"); +const source_t source_t::IP(3, "IP"); + +source_t::source_t(int v, const std::string& s) + : enum_base(v, s) +{ +} +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_types.hpp b/extras/deprecated/vom/vom/qos_types.hpp new file mode 100644 index 00000000000..4cdbc416a9f --- /dev/null +++ b/extras/deprecated/vom/vom/qos_types.hpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019 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_QOS_TYPES_H__ +#define __VOM_QOS_TYPES_H__ + +#include "vom/enum_base.hpp" + +namespace VOM { +/** + * Types belonging to QoS + */ +namespace QoS { + +typedef uint8_t bits_t; + +/** + * The Source of the QoS classification (i.e. which header the bits are + * associated with). + */ +class source_t : public enum_base +{ +public: + const static source_t EXT; + const static source_t VLAN; + const static source_t MPLS; + const static source_t IP; + +private: + /** + * Private constructor taking the value and the string name + */ + source_t(int v, const std::string& s); +}; + +}; // namesapce QoS + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/qos_types_api.cpp b/extras/deprecated/vom/vom/qos_types_api.cpp new file mode 100644 index 00000000000..6c16b4b1997 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_types_api.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019 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/qos_types.hpp" + +#include + +DEFINE_VAPI_MSG_IDS_QOS_API_JSON; + +namespace VOM { +namespace QoS { + +const source_t& +from_api(vapi_enum_qos_source e) +{ + switch (e) { + case QOS_API_SOURCE_EXT: + return source_t::EXT; + case QOS_API_SOURCE_VLAN: + return source_t::VLAN; + case QOS_API_SOURCE_IP: + return source_t::IP; + case QOS_API_SOURCE_MPLS: + return source_t::MPLS; + } + return source_t::EXT; +} + +vapi_enum_qos_source +to_api(const source_t& s) +{ + return static_cast((int)s); +} + +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/qos_types_api.hpp b/extras/deprecated/vom/vom/qos_types_api.hpp new file mode 100644 index 00000000000..e8ec9a2bfd3 --- /dev/null +++ b/extras/deprecated/vom/vom/qos_types_api.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019 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/qos_types.hpp" + +#include + +namespace VOM { +namespace QoS { + +const source_t& from_api(vapi_enum_qos_source e); +vapi_enum_qos_source to_api(const source_t& s); + +}; // namespace QoS +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/ra_config.cpp b/extras/deprecated/vom/vom/ra_config.cpp new file mode 100644 index 00000000000..5b11449b192 --- /dev/null +++ b/extras/deprecated/vom/vom/ra_config.cpp @@ -0,0 +1,89 @@ +/* + * 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 + +#include "vom/ra_config.hpp" + +DEFINE_VAPI_MSG_IDS_IP6_ND_API_JSON; + +namespace VOM { + +/** + * Construct a new object matching the desried state + */ +ra_config::ra_config(uint8_t suppress, + uint8_t send_unicast, + uint8_t default_router, + uint32_t max_interval) + : m_suppress(suppress) + , m_managed(0) + , m_other(0) + , m_ll_option(0) + , m_send_unicast(send_unicast) + , m_cease(0) + , m_default_router(default_router) + , m_max_interval(max_interval) + , m_min_interval((max_interval * 3) / 4) + , m_lifetime(600) + , m_initial_count(3) + , m_initial_interval(16) +{} + +void +ra_config::to_vpp(vapi_payload_sw_interface_ip6nd_ra_config& ra_config) const +{ + ra_config.suppress = m_suppress; + ra_config.managed = m_managed; + ra_config.other = m_other; + ra_config.ll_option = m_ll_option; + ra_config.send_unicast = m_send_unicast; + ra_config.cease = m_cease; + ra_config.max_interval = m_max_interval; + ra_config.min_interval = m_min_interval; + ra_config.lifetime = m_lifetime; + ra_config.initial_count = m_initial_count; + ra_config.initial_interval = m_initial_interval; +} + +bool +ra_config::operator==(const ra_config& other) const +{ + return ((m_suppress == other.m_suppress) && + (m_send_unicast == other.m_send_unicast) && + (m_default_router == other.m_default_router) && + (m_max_interval == other.m_max_interval)); +} + +std::string +ra_config::to_string() const +{ + std::ostringstream s; + + s << "ra-config:[" + << " suppress:" << m_suppress << " send-unicast:" << m_send_unicast + << " default-router:" << m_default_router + << " max_interval:" << m_max_interval << "]"; + + return (s.str()); +} +} +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/ra_config.hpp b/extras/deprecated/vom/vom/ra_config.hpp new file mode 100644 index 00000000000..f5b782a72d2 --- /dev/null +++ b/extras/deprecated/vom/vom/ra_config.hpp @@ -0,0 +1,145 @@ +/* + * 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_RA_CONFIG_H__ +#define __VOM_RA_CONFIG_H__ + +#include + +namespace VOM { +/** + * A representation of Router Advertisement configuration + */ +class ra_config +{ +public: + /** + * Construct a new object matching the desried state + */ + ra_config(uint8_t suppress, + uint8_t send_unicast, + uint8_t default_router, + uint32_t max_interval); + + /** + * Copy Constructor + */ + ra_config(const ra_config& o) = default; + + /** + * Destructor + */ + ~ra_config() = default; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Comparison operator - only used for UT + */ + bool operator==(const ra_config& ra_config) const; + + /** + * convert the ra config to VPP API + */ + void to_vpp(vapi_payload_sw_interface_ip6nd_ra_config& ra_config) const; + +private: + /** + * Disables sending ICMPv6 router-advertisement messages. + */ + uint8_t m_suppress; + + /** + * Advertises in ICMPv6 router-advertisement messages to use + * stateful address auto-configuration to obtain address information. + */ + uint8_t m_managed; + + /** + * Indicates in ICMPv6 router-advertisement messages that + * hosts use stateful auto configuration to obtain nonaddress + * related information. + */ + uint8_t m_other; + + /** + * Indicates not to include the optional source link-layer + * address in the ICMPv6 router-advertisement messages. + */ + uint8_t m_ll_option; + + /** + * Use the source address of the router-solicitation message if + * availiable. + */ + uint8_t m_send_unicast; + + /** + * Cease sending ICMPv6 router-advertisement messages. + */ + uint8_t m_cease; + + /** + * .... ? + */ + uint8_t m_default_router; + + /** + * Configures the interval between sending ICMPv6 router-advertisement + * messages. The range for max-interval is from 4 to 200 seconds. + */ + uint32_t m_max_interval; + + /** + * min-interval can not be more than 75% of max-interval. + * If not set, min-interval will be set to 75% of max-interval. + * The range for min-interval is from 3 to 150 seconds. + */ + uint32_t m_min_interval; + + /** + * Advertises the lifetime of a default router in ICMPv6 + * router-advertisement messages. The range is from 0 to 9000 seconds. + * '' must be greater than ''. + * The default value is 600 seconds + */ + uint32_t m_lifetime; + + /** + * Number of initial ICMPv6 router-advertisement messages sent. + * Range for count is 1 - 3 and default is 3. + */ + uint32_t m_initial_count; + + /** + * The interval between each initial messages. + * Range for interval is 1 to 16 seconds, and default is 16 seconds. + */ + uint32_t m_initial_interval; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/ra_prefix.cpp b/extras/deprecated/vom/vom/ra_prefix.cpp new file mode 100644 index 00000000000..2106879c0ba --- /dev/null +++ b/extras/deprecated/vom/vom/ra_prefix.cpp @@ -0,0 +1,87 @@ +/* + * 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 + +#include "vom/api_types.hpp" +#include "vom/ra_prefix.hpp" + +namespace VOM { +ra_prefix::ra_prefix(const route::prefix_t& pfx, + uint8_t use_default, + uint8_t no_advertise, + uint32_t val_lifetime, + uint32_t pref_lifetime) + : m_pfx(pfx) + , m_use_default(use_default) + , m_no_advertise(no_advertise) + , m_off_link(0) + , m_no_autoconfig(0) + , m_no_onlink(0) + , m_val_lifetime(val_lifetime) + , m_pref_lifetime(pref_lifetime) +{ +} + +void +ra_prefix::to_vpp(vapi_payload_sw_interface_ip6nd_ra_prefix& ra_prefix) const +{ + ra_prefix.prefix = to_api(m_pfx); + + ra_prefix.use_default = m_use_default; + ra_prefix.no_advertise = m_no_advertise; + ra_prefix.off_link = m_off_link; + ra_prefix.no_autoconfig = m_no_autoconfig; + ra_prefix.no_onlink = m_no_onlink; + ra_prefix.val_lifetime = m_val_lifetime; + ra_prefix.pref_lifetime = m_pref_lifetime; +} + +bool +ra_prefix::operator==(const ra_prefix& other) const +{ + return ((m_pfx == other.m_pfx) && (m_use_default == other.m_use_default) && + (m_no_advertise == other.m_no_advertise) && + (m_val_lifetime == other.m_val_lifetime) && + (m_pref_lifetime == other.m_pref_lifetime)); +} + +std::string +ra_prefix::to_string() const +{ + std::ostringstream s; + + s << "ra-pfx-config:[" + << " pfx:" << m_pfx.to_string() << " use-default:" << m_use_default + << " no-advertise:" << m_no_advertise << " val-lifetime:" << m_val_lifetime + << " pref-lifetime:" << m_pref_lifetime << "]"; + + return (s.str()); +} + +const route::prefix_t& +ra_prefix::prefix() const +{ + return (m_pfx); +} +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/ra_prefix.hpp b/extras/deprecated/vom/vom/ra_prefix.hpp new file mode 100644 index 00000000000..0be40c403b3 --- /dev/null +++ b/extras/deprecated/vom/vom/ra_prefix.hpp @@ -0,0 +1,134 @@ +/* + * 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_RA_PREFIX_H__ +#define __VOM_RA_PREFIX_H__ + +#include "vom/prefix.hpp" + +#include + +namespace VOM { +/** + * A representation of RA prefix configuration on given interface + */ +class ra_prefix +{ +public: + /** + * Construct a new object matching the desried state + */ + ra_prefix(const route::prefix_t& pfx, + uint8_t use_default, + uint8_t no_advertise, + uint32_t val_lifetime, + uint32_t pref_lifetime); + + /** + * Copy Constructor + */ + ra_prefix(const ra_prefix& o) = default; + + /** + * Destructor + */ + ~ra_prefix() = default; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Return the prefix associated with this ra prefix + */ + const route::prefix_t& prefix() const; + + /** + * Comparison operator - only used for UT + */ + bool operator==(const ra_prefix& ra_prefix) const; + + /** + * Convert the ra prefix configuration to Vpp Api + */ + void to_vpp(vapi_payload_sw_interface_ip6nd_ra_prefix& ra_prefix) const; + +private: + /** + * The prefix to be advertised. + */ + route::prefix_t m_pfx; + + /** + * Revert to default settings. + */ + uint8_t m_use_default; + + /** + * Do not send full router address in prefix advertisement. + * Default is to advertise. + */ + uint8_t m_no_advertise; + + /** + * Prefix is off-link. Default is on-link. + */ + uint8_t m_off_link; + + /** + * Do not use prefix for autoconfiguration. + * Default is autoconfig. + */ + uint8_t m_no_autoconfig; + + /** + * Do not use prefix for onlink determination. + * Default is on-link (this flag is off). + */ + uint8_t m_no_onlink; + + /** + * ' is the length of time in seconds during what + * the prefix is valid for the purpose of on-link determination. + * + * Range is 7203 to 2592000 seconds and default is 2592000 seconds. + * A value of all one bits (0xffffffff) represents infinity (no + * timeout). + */ + uint32_t m_val_lifetime; + + /** + * '' is the prefered-lifetime and is the length of + * time in seconds during what addresses generated from the prefix + * remain preferred. + * + * Range is 0 to 604800 seconds and default is 604800 seconds. + * A value of all one bits (0xffffffff) represents infinity (no + * timeout). + */ + uint32_t m_pref_lifetime; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/route.cpp b/extras/deprecated/vom/vom/route.cpp new file mode 100644 index 00000000000..7f4497dfb2c --- /dev/null +++ b/extras/deprecated/vom/vom/route.cpp @@ -0,0 +1,703 @@ +/* + * 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/route.hpp" +#include "vom/api_types.hpp" +#include "vom/mroute_cmds.hpp" +#include "vom/route_api_types.hpp" +#include "vom/route_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { +namespace route { +ip_route::event_handler ip_route::m_evh; +ip_mroute::event_handler ip_mroute::m_evh; +singular_db ip_route::m_db; +singular_db ip_mroute::m_db; + +const path::special_t path::special_t::STANDARD(0, "standard"); +const path::special_t path::special_t::LOCAL(1, "local"); +const path::special_t path::special_t::DROP(2, "standard"); +const path::special_t path::special_t::UNREACH(3, "unreachable"); +const path::special_t path::special_t::PROHIBIT(4, "prohibit"); + +path::special_t::special_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const path::flags_t path::flags_t::NONE(0, "none"); +const path::flags_t path::flags_t::DVR((1 << 0), "dvr"); + +path::flags_t::flags_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +const itf_flags_t itf_flags_t::NONE(0, "none"); +const itf_flags_t itf_flags_t::ACCEPT((1 << 1), "accept"); +const itf_flags_t itf_flags_t::FORWARD((1 << 2), "forward"); + +itf_flags_t::itf_flags_t(int v, const std::string& s) + : enum_base(v, s) +{ +} + +path::path(special_t special, const nh_proto_t& proto) + : m_type(special) + , m_nh_proto(proto) + , m_flags(flags_t::NONE) + , m_nh() + , m_rd(nullptr) + , m_interface(nullptr) + , m_weight(1) + , m_preference(0) +{ +} + +path::path(const boost::asio::ip::address& nh, + const interface& interface, + uint8_t weight, + uint8_t preference) + : m_type(special_t::STANDARD) + , m_nh_proto(nh_proto_t::from_address(nh)) + , m_flags(flags_t::NONE) + , m_nh(nh) + , m_rd(nullptr) + , m_interface(interface.singular()) + , m_weight(weight) + , m_preference(preference) +{ +} + +path::path(const route_domain& rd, + const boost::asio::ip::address& nh, + uint8_t weight, + uint8_t preference) + : m_type(special_t::STANDARD) + , m_nh_proto(nh_proto_t::from_address(nh)) + , m_flags(flags_t::NONE) + , m_nh(nh) + , m_rd(rd.singular()) + , m_interface(nullptr) + , m_weight(weight) + , m_preference(preference) +{ +} + +path::path(const interface& interface, + const nh_proto_t& proto, + const flags_t& flags, + uint8_t weight, + uint8_t preference) + : m_type(special_t::STANDARD) + , m_nh_proto(proto) + , m_flags(flags) + , m_nh() + , m_rd(nullptr) + , m_interface(interface.singular()) + , m_weight(weight) + , m_preference(preference) +{ +} + +path::path(const path& p) + : m_type(p.m_type) + , m_nh_proto(p.m_nh_proto) + , m_flags(p.m_flags) + , m_nh(p.m_nh) + , m_rd(p.m_rd) + , m_interface(p.m_interface) + , m_weight(p.m_weight) + , m_preference(p.m_preference) +{ +} + +bool +path::operator<(const path& p) const +{ + if (m_nh_proto < p.m_nh_proto) + return true; + if (m_flags < p.m_flags) + return true; + if (m_type < p.m_type) + return true; + if (m_rd && !p.m_rd) + return false; + if (!m_rd && p.m_rd) + return true; + if (m_rd && p.m_rd) { + if (m_rd->table_id() < p.m_rd->table_id()) + return true; + else if (m_rd->table_id() > p.m_rd->table_id()) + return false; + } + if (m_nh < p.m_nh) + return true; + if (m_interface && !p.m_interface) + return false; + if (!m_interface && p.m_interface) + return true; + if (m_interface && p.m_interface) { + if (m_interface->handle() < p.m_interface->handle()) + return true; + if (p.m_interface->handle() < m_interface->handle()) + return false; + } + + return (false); +} + +path::~path() +{ +} + +bool +path::operator==(const path& p) const +{ + bool result = true; + if (m_rd && !p.m_rd) + return false; + if (!m_rd && p.m_rd) + return false; + if (m_rd && p.m_rd) + result &= (*m_rd == *p.m_rd); + if (m_interface && !p.m_interface) + return false; + if (!m_interface && p.m_interface) + return false; + if (m_interface && p.m_interface) + result &= (*m_interface == *p.m_interface); + return (result && (m_type == p.m_type) && (m_nh == p.m_nh) && + (m_nh_proto == p.m_nh_proto) && (m_flags == p.m_flags)); +} + +std::string +path::to_string() const +{ + std::ostringstream s; + + s << "path:[" + << "type:" << m_type.to_string() << " proto:" << m_nh_proto.to_string() + << " flags:" << m_flags.to_string() << " neighbour:" << m_nh.to_string(); + if (m_rd) { + s << " " << m_rd->to_string(); + } + if (m_interface) { + s << " " << m_interface->to_string(); + } + s << " weight:" << static_cast(m_weight) + << " preference:" << static_cast(m_preference) << "]"; + + return (s.str()); +} + +path::special_t +path::type() const +{ + return m_type; +} + +nh_proto_t +path::nh_proto() const +{ + return m_nh_proto; +} + +path::flags_t +path::flags() const +{ + return m_flags; +} + +const boost::asio::ip::address& +path::nh() const +{ + return m_nh; +} + +std::shared_ptr +path::rd() const +{ + return m_rd; +} + +std::shared_ptr +path::itf() const +{ + return m_interface; +} + +uint8_t +path::weight() const +{ + return m_weight; +} + +uint8_t +path::preference() const +{ + return m_preference; +} + +ip_route::ip_route(const prefix_t& prefix, const path& p) + : m_hw(false) + , m_rd(route_domain::get_default()) + , m_prefix(prefix) + , m_paths({ p }) +{ +} + +ip_route::ip_route(const prefix_t& prefix) + : m_hw(false) + , m_rd(route_domain::get_default()) + , m_prefix(prefix) + , m_paths() +{ +} + +ip_route::ip_route(const ip_route& r) + : m_hw(r.m_hw) + , m_rd(r.m_rd) + , m_prefix(r.m_prefix) + , m_paths(r.m_paths) +{ +} + +ip_route::ip_route(const route_domain& rd, const prefix_t& prefix) + : m_hw(false) + , m_rd(rd.singular()) + , m_prefix(prefix) + , m_paths() +{ +} + +ip_route::ip_route(const route_domain& rd, + const prefix_t& prefix, + const path& p) + : m_hw(false) + , m_rd(rd.singular()) + , m_prefix(prefix) + , m_paths({ p }) +{ +} + +ip_route::~ip_route() +{ + sweep(); + + // not in the DB anymore. + m_db.release(key(), this); + m_paths.clear(); +} + +const ip_route::key_t +ip_route::key() const +{ + return (std::make_pair(m_rd->table_id(), m_prefix)); +} + +bool +ip_route::operator==(const ip_route& i) const +{ + return ((key() == i.key()) && (m_paths == i.m_paths)); +} + +void +ip_route::add(const path& path) +{ + m_paths.insert(path); +} + +void +ip_route::remove(const path& path) +{ + m_paths.erase(path); +} + +void +ip_route::sweep() +{ + if (m_hw) { + HW::enqueue( + new ip_route_cmds::delete_cmd(m_hw, m_rd->table_id(), m_prefix)); + } + HW::write(); +} + +void +ip_route::replay() +{ + if (m_hw) { + HW::enqueue( + new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths)); + } +} +std::string +ip_route::to_string() const +{ + std::ostringstream s; + s << "route:[" << m_rd->to_string() << ", " << m_prefix.to_string() << " [" + << m_paths << "]" + << "]"; + + return (s.str()); +} + +void +ip_route::update(const ip_route& r) +{ + m_paths = r.m_paths; + HW::enqueue( + new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths)); +} + +std::shared_ptr +ip_route::find_or_add(const ip_route& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +ip_route::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +ip_route::singular() const +{ + return find_or_add(*this); +} + +void +ip_route::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +ip_route::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "ip-route" }, "ip route configurations", this); +} + +void +ip_route::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +ip_route::event_handler::handle_populate(const client_db::key_t& key) +{ + // for each known route-domain + auto it = route_domain::cbegin(); + + while (it != route_domain::cend()) { + + std::vector l3s = { l3_proto_t::IPV4, l3_proto_t::IPV4 }; + + for (auto l3 : l3s) { + std::shared_ptr cmd = + std::make_shared(it->second.lock()->table_id(), + l3); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr rd = + route_domain::find(payload.route.table_id); + + if (!rd) { + continue; + } + + prefix_t pfx = from_api(payload.route.prefix); + ip_route ip_r(*rd, pfx); + + for (unsigned int i = 0; i < payload.route.n_paths; i++) { + ip_r.add(from_api(payload.route.paths[i])); + } + + VOM_LOG(log_level_t::DEBUG) << "ip-route-dump: " << ip_r.to_string(); + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, ip_r); + } + } + ++it; + } +} + +dependency_t +ip_route::event_handler::order() const +{ + return (dependency_t::TABLE); +} + +void +ip_route::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +ip_mroute::ip_mroute(const mprefix_t& mprefix) + : m_hw(false) + , m_rd(route_domain::get_default()) + , m_mprefix(mprefix) + , m_paths() +{ +} + +ip_mroute::ip_mroute(const ip_mroute& r) + : m_hw(r.m_hw) + , m_rd(r.m_rd) + , m_mprefix(r.m_mprefix) + , m_paths(r.m_paths) +{ +} + +ip_mroute::ip_mroute(const route_domain& rd, const mprefix_t& mprefix) + : m_hw(false) + , m_rd(rd.singular()) + , m_mprefix(mprefix) + , m_paths() +{ +} + +void +ip_mroute::add(const path& path, const itf_flags_t& flag) +{ + m_paths.insert(std::make_pair(path, flag)); +} + +ip_mroute::~ip_mroute() +{ + sweep(); + m_db.release(key(), this); +} + +const ip_mroute::key_t +ip_mroute::key() const +{ + return (std::make_pair(m_rd->table_id(), m_mprefix)); +} + +bool +ip_mroute::operator==(const ip_mroute& i) const +{ + return ((key() == i.key()) && (m_paths == i.m_paths)); +} + +void +ip_mroute::sweep() +{ + if (m_hw) { + for (auto& p : m_paths) + HW::enqueue(new ip_mroute_cmds::delete_cmd(m_hw, m_rd->table_id(), + m_mprefix, p.first, p.second)); + } + HW::write(); +} + +void +ip_mroute::replay() +{ + if (m_hw) { + for (auto& p : m_paths) + HW::enqueue(new ip_mroute_cmds::update_cmd(m_hw, m_rd->table_id(), + m_mprefix, p.first, p.second)); + } +} +std::string +ip_mroute::to_string() const +{ + std::ostringstream s; + s << "route:[" << m_rd->to_string() << ", " << m_mprefix.to_string() << " [" + << m_paths << "]" + << "]"; + + return (s.str()); +} + +void +ip_mroute::update(const ip_mroute& r) +{ + if (rc_t::OK != m_hw.rc()) { + for (auto& p : m_paths) + HW::enqueue(new ip_mroute_cmds::update_cmd(m_hw, m_rd->table_id(), + m_mprefix, p.first, p.second)); + } +} + +std::shared_ptr +ip_mroute::find_or_add(const ip_mroute& temp) +{ + return (m_db.find_or_add(temp.key(), temp)); +} + +std::shared_ptr +ip_mroute::find(const key_t& k) +{ + return (m_db.find(k)); +} + +std::shared_ptr +ip_mroute::singular() const +{ + return find_or_add(*this); +} + +void +ip_mroute::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +ip_mroute::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "ip-mroute" }, + "ip multicast route configurations", this); +} + +void +ip_mroute::event_handler::handle_replay() +{ + m_db.replay(); +} + +void +ip_mroute::event_handler::handle_populate(const client_db::key_t& key) +{ + // for each known route-domain + auto it = route_domain::cbegin(); + + while (it != route_domain::cend()) { + + std::vector l3s = { l3_proto_t::IPV4, l3_proto_t::IPV4 }; + + for (auto l3 : l3s) { + std::shared_ptr cmd = + std::make_shared( + it->second.lock()->table_id(), l3); + + HW::enqueue(cmd); + HW::write(); + + VOM_LOG(log_level_t::DEBUG) << "ip-mroute-dump: "; + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + std::shared_ptr rd = + route_domain::find(payload.route.table_id); + + if (!rd) { + continue; + } + + mprefix_t pfx = from_api(payload.route.prefix); + ip_mroute ip_r(*rd, pfx); + + for (unsigned int i = 0; i < payload.route.n_paths; i++) { + ip_r.add(from_api(payload.route.paths[i].path), + from_api(payload.route.paths[i].itf_flags)); + } + + VOM_LOG(log_level_t::DEBUG) << "ip-mroute-dump: " << ip_r.to_string(); + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, ip_r); + } + } + ++it; + } +} + +dependency_t +ip_mroute::event_handler::order() const +{ + return (dependency_t::TABLE); +} + +void +ip_mroute::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +std::ostream& +operator<<(std::ostream& os, const ip_route::key_t& key) +{ + os << "[" << key.first << ", " << key.second.to_string() << "]"; + + return (os); +} + +std::ostream& +operator<<(std::ostream& os, const ip_mroute::key_t& key) +{ + os << "[" << key.first << ", " << key.second.to_string() << "]"; + + return (os); +} + +std::ostream& +operator<<(std::ostream& os, const path_list_t& key) +{ + os << "["; + for (auto k : key) { + os << k.to_string() << " "; + } + os << "]"; + + return (os); +} + +std::ostream& +operator<<(std::ostream& os, const mpath_list_t& key) +{ + os << "["; + for (auto k : key) { + os << "[" << k.first.to_string() << ", " << k.second.to_string() << "]"; + } + os << "]"; + + return (os); +} + +}; // namespace route +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/route.hpp b/extras/deprecated/vom/vom/route.hpp new file mode 100644 index 00000000000..185bd0a04eb --- /dev/null +++ b/extras/deprecated/vom/vom/route.hpp @@ -0,0 +1,595 @@ +/* + * 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_ROUTE_H__ +#define __VOM_ROUTE_H__ + +#include "vom/interface.hpp" +#include "vom/prefix.hpp" +#include "vom/route_domain.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * Types belonging to Routing + */ +namespace route { +/** + * A path for IP or MPLS routes + */ +class path +{ +public: + /** + * Special path types + */ + class special_t : public enum_base + { + public: + /** + * A standard path type. this includes path types + * that use the next-hop and interface + */ + const static special_t STANDARD; + + /** + * A local/for-us/recieve + */ + const static special_t LOCAL; + + /** + * drop path + */ + const static special_t DROP; + + /** + * a path will return ICMP unreachables + */ + const static special_t UNREACH; + + /** + * a path will return ICMP prohibit + */ + const static special_t PROHIBIT; + + private: + /** + * Private constructor taking the value and the string name + */ + special_t(int v, const std::string& s); + }; + + /** + * Path flags + */ + class flags_t : public enum_base + { + public: + /** + * No flags + */ + const static flags_t NONE; + + /** + * A path that resolves via a DVR next-hop + */ + const static flags_t DVR; + + private: + /** + * Private constructor taking the value and the string name + */ + flags_t(int v, const std::string& s); + }; + + /** + * constructor for special paths + */ + path(special_t special, const nh_proto_t& proto = nh_proto_t::IPV4); + + /** + * Constructor for standard non-recursive paths + */ + path(const boost::asio::ip::address& nh, + const interface& interface, + uint8_t weight = 1, + uint8_t preference = 0); + + /** + * Constructor for standard recursive paths + */ + path(const route_domain& rd, + const boost::asio::ip::address& nh, + uint8_t weight = 1, + uint8_t preference = 0); + + /** + * Constructor for DVR paths or attached paths. + */ + path(const interface& interface, + const nh_proto_t& proto, + const flags_t& flags = flags_t::NONE, + uint8_t weight = 1, + uint8_t preference = 0); + + /** + * Copy Constructor + */ + path(const path& p); + + /** + * Destructor + */ + ~path(); + + /** + * comparison operator + */ + bool operator==(const path& p) const; + + /** + * Less than operator for set insertion + */ + bool operator<(const path& p) const; + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Getters + */ + special_t type() const; + nh_proto_t nh_proto() const; + flags_t flags() const; + const boost::asio::ip::address& nh() const; + std::shared_ptr rd() const; + std::shared_ptr itf() const; + uint8_t weight() const; + uint8_t preference() const; + +private: + /** + * The special path tpye + */ + special_t m_type; + + /** + * The next-hop protocol + */ + nh_proto_t m_nh_proto; + + /** + * Flags for the path + */ + flags_t m_flags; + + /** + * The next-hop + */ + boost::asio::ip::address m_nh; + + /** + * For recursive routes, this is the table in which the + * the next-hop exists. + */ + std::shared_ptr m_rd; + + /** + * The next-hop interface [if present]. + */ + std::shared_ptr m_interface; + + /** + * UCMP weight + */ + uint8_t m_weight; + + /** + * Path preference + */ + uint8_t m_preference; +}; + +class itf_flags_t : public enum_base +{ +public: + const static itf_flags_t NONE; + /** + * Path is accepting multicast traffic + */ + const static itf_flags_t ACCEPT; + + /** + * A local/for-us/recieve + */ + const static itf_flags_t FORWARD; + +private: + /** + * Private constructor taking the value and the string name + */ + itf_flags_t(int v, const std::string& s); +}; + +/** + * A path-list is a set of paths + */ +typedef std::set path_list_t; + +/** + * A mpath-list is a set of paths and interface flags + */ +typedef std::set> mpath_list_t; + +/** + * ostream output for iterator + */ +std::ostream& operator<<(std::ostream& os, const path_list_t& path_list); +std::ostream& operator<<(std::ostream& os, const mpath_list_t& path_list); + +/** + * A IP route + */ +class ip_route : public object_base +{ +public: + /** + * The key for a route + */ + typedef std::pair key_t; + + /** + * Construct a route in the default table + */ + ip_route(const prefix_t& prefix); + + /** + * Construct a route with a path + */ + ip_route(const prefix_t& prefix, const path& p); + + /** + * Copy Construct + */ + ip_route(const ip_route& r); + + /** + * Construct a route in the given route domain + */ + ip_route(const route_domain& rd, const prefix_t& prefix); + + /** + * Construct a route in the given route domain with a path + */ + ip_route(const route_domain& rd, const prefix_t& prefix, const path& p); + + /** + * Destructor + */ + ~ip_route(); + + /** + * Get the route's key + */ + const key_t key() const; + + /** + * Comparison operator + */ + bool operator==(const ip_route& i) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Add a path. + */ + void add(const path& path); + + /** + * remove a path. + */ + void remove(const path& path); + + /** + * Find the instnace of the route domain in the OM + */ + static std::shared_ptr find(const ip_route& temp); + + /** + * Dump all route-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + + /** + * Return the matching 'singular instance' + */ + static std::shared_ptr find(const key_t& k); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Find or add the instnace of the route domain in the OM + */ + static std::shared_ptr find_or_add(const ip_route& temp); + + /* + * It's the OM class that updates the objects in HW + */ + friend class VOM::OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const ip_route& obj); + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the route + */ + HW::item m_hw; + + /** + * The route domain the route is in. + */ + std::shared_ptr m_rd; + + /** + * The prefix to match + */ + prefix_t m_prefix; + + /** + * The set of paths + */ + path_list_t m_paths; + + /** + * A map of all routes + */ + static singular_db m_db; +}; + +/** + * A IP multicast route + */ +class ip_mroute : public object_base +{ +public: + /** + * The key for a route + */ + typedef std::pair key_t; + + /** + * Construct a route in the default table + */ + ip_mroute(const mprefix_t& mprefix); + + /** + * Copy Construct + */ + ip_mroute(const ip_mroute& r); + + /** + * Construct a route in the given route domain + */ + ip_mroute(const route_domain& rd, const mprefix_t& mprefix); + + /** + * Destructor + */ + ~ip_mroute(); + + /** + * Get the route's key + */ + const key_t key() const; + + /** + * Comparison operator + */ + bool operator==(const ip_mroute& i) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Find the instnace of the route domain in the OM + */ + static std::shared_ptr find(const ip_mroute& temp); + + /** + * Dump all route-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Convert to string for debugging + */ + std::string to_string() const; + + /** + * Return the matching 'singular instance' + */ + static std::shared_ptr find(const key_t& k); + + void add(const path& path, const itf_flags_t& flag); + +private: + /** + * 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; + }; + + /** + * event_handler to register with OM + */ + static event_handler m_evh; + + /** + * Find or add the instnace of the route domain in the OM + */ + static std::shared_ptr find_or_add(const ip_mroute& temp); + + /* + * It's the OM class that updates the objects in HW + */ + friend class VOM::OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const ip_mroute& obj); + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the route + */ + HW::item m_hw; + + /** + * The route domain the route is in. + */ + std::shared_ptr m_rd; + + /** + * The mprefix to match + */ + mprefix_t m_mprefix; + + /** + * The set of paths + */ + mpath_list_t m_paths; + + /** + * A map of all routes + */ + static singular_db m_db; +}; + +std::ostream& operator<<(std::ostream& os, const ip_route::key_t& key); +std::ostream& operator<<(std::ostream& os, const ip_mroute::key_t& key); +}; // namespace route +}; // namesapce VPP + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/route_api_types.cpp b/extras/deprecated/vom/vom/route_api_types.cpp new file mode 100644 index 00000000000..1c9519c4053 --- /dev/null +++ b/extras/deprecated/vom/vom/route_api_types.cpp @@ -0,0 +1,190 @@ +/* + * 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 +#include +#include + +namespace VOM { + +const route::itf_flags_t& +from_api(vapi_enum_mfib_itf_flags val) +{ + if (route::itf_flags_t::ACCEPT == val) + return route::itf_flags_t::ACCEPT; + else + return route::itf_flags_t::FORWARD; +} + +vapi_enum_mfib_itf_flags +to_api(const route::itf_flags_t& in) +{ + vapi_enum_mfib_itf_flags out = MFIB_API_ITF_FLAG_NONE; + + if (route::itf_flags_t::ACCEPT & in) + out = static_cast(out | MFIB_API_ITF_FLAG_ACCEPT); + if (route::itf_flags_t::FORWARD & in) + out = + static_cast(out | MFIB_API_ITF_FLAG_FORWARD); + + return (out); +} + +void +to_api(const route::path& p, vapi_type_fib_path& payload) +{ + payload.flags = FIB_API_PATH_FLAG_NONE; + payload.proto = to_api(p.nh_proto()); + payload.sw_if_index = ~0; + + if (route::path::flags_t::DVR & p.flags()) { + payload.type = FIB_API_PATH_TYPE_DVR; + } else if (route::path::special_t::STANDARD == p.type()) { + to_api(p.nh(), payload.nh.address); + + if (p.rd()) { + payload.table_id = p.rd()->table_id(); + } + if (p.itf()) { + payload.sw_if_index = p.itf()->handle().value(); + } + } else if (route::path::special_t::DROP == p.type()) { + payload.type = FIB_API_PATH_TYPE_DROP; + } else if (route::path::special_t::UNREACH == p.type()) { + payload.type = FIB_API_PATH_TYPE_ICMP_UNREACH; + } else if (route::path::special_t::PROHIBIT == p.type()) { + payload.type = FIB_API_PATH_TYPE_ICMP_PROHIBIT; + } else if (route::path::special_t::LOCAL == p.type()) { + payload.type = FIB_API_PATH_TYPE_LOCAL; + } + + payload.weight = p.weight(); + payload.preference = p.preference(); + payload.n_labels = 0; +} + +route::path +from_api(const vapi_type_fib_path& p) +{ + switch (p.type) { + case FIB_API_PATH_TYPE_DVR: { + std::shared_ptr itf = interface::find(p.sw_if_index); + if (!itf) + throw invalid_decode("fib-path deocde no interface:" + + std::to_string(p.sw_if_index)); + + return (route::path(*itf, from_api(p.proto), route::path::flags_t::DVR, + p.weight, p.preference)); + } + case FIB_API_PATH_TYPE_NORMAL: { + boost::asio::ip::address address = from_api(p.nh.address, p.proto); + std::shared_ptr itf = interface::find(p.sw_if_index); + if (itf) { + return (route::path(address, *itf, p.weight, p.preference)); + } else { + std::shared_ptr rd = route_domain::find(p.table_id); + + if (!rd) + throw invalid_decode("fib-path deocde no route-domain:" + + std::to_string(p.table_id)); + + return (route::path(*rd, address, p.weight, p.preference)); + } + } + case FIB_API_PATH_TYPE_LOCAL: + return (route::path(route::path::special_t::LOCAL)); + case FIB_API_PATH_TYPE_DROP: + return (route::path(route::path::special_t::DROP)); + case FIB_API_PATH_TYPE_ICMP_UNREACH: + return (route::path(route::path::special_t::PROHIBIT)); + case FIB_API_PATH_TYPE_ICMP_PROHIBIT: + return (route::path(route::path::special_t::UNREACH)); + + case FIB_API_PATH_TYPE_UDP_ENCAP: + case FIB_API_PATH_TYPE_BIER_IMP: + case FIB_API_PATH_TYPE_SOURCE_LOOKUP: + case FIB_API_PATH_TYPE_INTERFACE_RX: + case FIB_API_PATH_TYPE_CLASSIFY: + // not done yet + break; + } + return (route::path(route::path::special_t::DROP)); +}; + +vapi_enum_ip_dscp +to_api(const ip_dscp_t& d) +{ + return static_cast((int)d); +} +const ip_dscp_t& +from_api(vapi_enum_ip_dscp d) +{ + switch (d) { + case IP_API_DSCP_CS0: + return ip_dscp_t::DSCP_CS0; + case IP_API_DSCP_CS1: + return ip_dscp_t::DSCP_CS1; + case IP_API_DSCP_CS2: + return ip_dscp_t::DSCP_CS2; + case IP_API_DSCP_CS3: + return ip_dscp_t::DSCP_CS3; + case IP_API_DSCP_CS4: + return ip_dscp_t::DSCP_CS4; + case IP_API_DSCP_CS5: + return ip_dscp_t::DSCP_CS5; + case IP_API_DSCP_CS6: + return ip_dscp_t::DSCP_CS6; + case IP_API_DSCP_CS7: + return ip_dscp_t::DSCP_CS7; + case IP_API_DSCP_EF: + return ip_dscp_t::DSCP_EF; + case IP_API_DSCP_AF11: + return ip_dscp_t::DSCP_AF11; + case IP_API_DSCP_AF12: + return ip_dscp_t::DSCP_AF12; + case IP_API_DSCP_AF13: + return ip_dscp_t::DSCP_AF13; + case IP_API_DSCP_AF21: + return ip_dscp_t::DSCP_AF21; + case IP_API_DSCP_AF22: + return ip_dscp_t::DSCP_AF22; + case IP_API_DSCP_AF23: + return ip_dscp_t::DSCP_AF23; + case IP_API_DSCP_AF31: + return ip_dscp_t::DSCP_AF31; + case IP_API_DSCP_AF32: + return ip_dscp_t::DSCP_AF32; + case IP_API_DSCP_AF33: + return ip_dscp_t::DSCP_AF33; + case IP_API_DSCP_AF41: + return ip_dscp_t::DSCP_AF41; + case IP_API_DSCP_AF42: + return ip_dscp_t::DSCP_AF42; + case IP_API_DSCP_AF43: + return ip_dscp_t::DSCP_AF43; + } + + return ip_dscp_t::DSCP_CS0; +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/route_api_types.hpp b/extras/deprecated/vom/vom/route_api_types.hpp new file mode 100644 index 00000000000..4576488fd43 --- /dev/null +++ b/extras/deprecated/vom/vom/route_api_types.hpp @@ -0,0 +1,40 @@ +/* + * 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 + +#include + +namespace VOM { + +vapi_enum_mfib_itf_flags to_api(const route::itf_flags_t& flags); +const route::itf_flags_t& from_api(vapi_enum_mfib_itf_flags flags); + +void to_api(const route::path& p, vapi_type_fib_path& o); + +route::path from_api(const vapi_type_fib_path& p); + +vapi_enum_ip_dscp to_api(const ip_dscp_t& d); +const ip_dscp_t& from_api(vapi_enum_ip_dscp d); + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/route_cmds.cpp b/extras/deprecated/vom/vom/route_cmds.cpp new file mode 100644 index 00000000000..4055b8574df --- /dev/null +++ b/extras/deprecated/vom/vom/route_cmds.cpp @@ -0,0 +1,171 @@ +/* + * 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 + +#include +#include +#include + +namespace VOM { +namespace route { +namespace ip_route_cmds { + +update_cmd::update_cmd(HW::item& item, + table_id_t id, + const prefix_t& prefix, + const path_list_t& pl) + : srpc_cmd(item) + , m_id(id) + , m_prefix(prefix) + , m_pl(pl) +{ +} + +bool +update_cmd::operator==(const update_cmd& other) const +{ + return ((m_prefix == other.m_prefix) && (m_id == other.m_id) && + (m_pl == other.m_pl)); +} + +rc_t +update_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), m_pl.size(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.route.table_id = m_id; + payload.is_add = 1; + payload.is_multipath = 1; + + payload.route.table_id = m_id; + payload.route.prefix = to_api(m_prefix); + + uint32_t ii = 0; + for (auto& p : m_pl) + to_api(p, payload.route.paths[ii++]); + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +update_cmd::to_string() const +{ + std::ostringstream s; + s << "ip-route-create: " << m_hw_item.to_string() << " table-id:" << m_id + << " prefix:" << m_prefix.to_string() << " paths:"; + for (auto p : m_pl) + s << p.to_string() << " "; + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + table_id_t id, + const prefix_t& prefix) + : rpc_cmd(item) + , m_id(id) + , m_prefix(prefix) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return ((m_prefix == other.m_prefix) && (m_id == other.m_id)); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), 0, std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 0; + payload.is_multipath = 0; + + payload.route.table_id = m_id; + payload.route.n_paths = 0; + payload.route.table_id = m_id; + payload.route.prefix = to_api(m_prefix); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return rc_t::OK; +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "ip-route-delete: " << m_hw_item.to_string() << " id:" << m_id + << " prefix:" << m_prefix.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd(route::table_id_t id, const l3_proto_t& proto) + : m_id(id) + , m_proto(proto) +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + + payload.table.table_id = m_id; + payload.table.is_ip6 = m_proto.is_ipv6(); + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("ip-route-v4-dump"); +} + +} // namespace ip_route_cmds +} // namespace route +} // namespace vom + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/route_cmds.hpp b/extras/deprecated/vom/vom/route_cmds.hpp new file mode 100644 index 00000000000..abdba5fa476 --- /dev/null +++ b/extras/deprecated/vom/vom/route_cmds.hpp @@ -0,0 +1,142 @@ +/* + * 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_ROUTE_CMDS_H__ +#define __VOM_ROUTE_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/route.hpp" +#include "vom/srpc_cmd.hpp" + +#include + +namespace VOM { +namespace route { +namespace ip_route_cmds { + +/** + * A command class that creates or updates the route + */ +class update_cmd : public srpc_cmd +{ +public: + /** + * Constructor + */ + update_cmd(HW::item& item, + table_id_t id, + const prefix_t& prefix, + const path_list_t& pl); + + /** + * 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 update_cmd& i) const; + +private: + route::table_id_t m_id; + prefix_t m_prefix; + const path_list_t& m_pl; +}; + +/** + * A cmd class that deletes a route + */ +class delete_cmd : public rpc_cmd, vapi::Ip_route_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, table_id_t id, const prefix_t& prefix); + + /** + * 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: + route::table_id_t m_id; + prefix_t m_prefix; +}; + +/** + * A cmd class that Dumps ip fib routes + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(route::table_id_t id, const l3_proto_t& proto); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; + route::table_id_t m_id; + const l3_proto_t& m_proto; +}; + +}; // namespace ip_route_cmds +}; // namespace route +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/route_domain.cpp b/extras/deprecated/vom/vom/route_domain.cpp new file mode 100644 index 00000000000..5df69f3e62e --- /dev/null +++ b/extras/deprecated/vom/vom/route_domain.cpp @@ -0,0 +1,228 @@ +/* + * 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/route_domain.hpp" +#include "vom/cmd.hpp" +#include "vom/route_domain_cmds.hpp" +#include "vom/singular_db_funcs.hpp" + +namespace VOM { + +route_domain::event_handler route_domain::m_evh; + +/** + * A DB of al the interfaces, key on the name + */ +singular_db route_domain::m_db; + +/** + * Construct a new object matching the desried state + */ +route_domain::route_domain(route::table_id_t id) + : m_hw_v4(true) + , m_hw_v6(true) + , m_table_id(id) +{ +} + +route_domain::route_domain(const route_domain& o) + : m_hw_v4(o.m_hw_v4) + , m_hw_v6(o.m_hw_v6) + , m_table_id(o.m_table_id) +{ +} + +bool +route_domain::operator==(const route_domain& r) const +{ + return (m_table_id == r.m_table_id); +} + +route::table_id_t +route_domain::table_id() const +{ + return (m_table_id); +} + +route_domain::key_t +route_domain::key() const +{ + return (table_id()); +} + +route_domain::const_iterator_t +route_domain::cbegin() +{ + return m_db.begin(); +} + +route_domain::const_iterator_t +route_domain::cend() +{ + return m_db.end(); +} + +void +route_domain::sweep() +{ + if (m_hw_v4) { + HW::enqueue( + new route_domain_cmds::delete_cmd(m_hw_v4, l3_proto_t::IPV4, m_table_id)); + } + if (m_hw_v6) { + HW::enqueue( + new route_domain_cmds::delete_cmd(m_hw_v6, l3_proto_t::IPV6, m_table_id)); + } + HW::write(); +} + +void +route_domain::replay() +{ + if (m_hw_v4) { + HW::enqueue( + new route_domain_cmds::create_cmd(m_hw_v4, l3_proto_t::IPV4, m_table_id)); + } + if (m_hw_v6) { + HW::enqueue( + new route_domain_cmds::create_cmd(m_hw_v6, l3_proto_t::IPV6, m_table_id)); + } +} + +route_domain::~route_domain() +{ + sweep(); + + // not in the DB anymore. + m_db.release(m_table_id, this); +} + +std::string +route_domain::to_string() const +{ + std::ostringstream s; + s << "route-domain:[" + << "table-id:" << m_table_id << " v4:" << m_hw_v4.to_string() + << " v6:" << m_hw_v6.to_string() << "]"; + + return (s.str()); +} + +std::shared_ptr +route_domain::find(const key_t& k) +{ + return (m_db.find(k)); +} + +void +route_domain::update(const route_domain& desired) +{ + /* + * create the table if it is not yet created + */ + if (rc_t::OK != m_hw_v4.rc()) { + HW::enqueue( + new route_domain_cmds::create_cmd(m_hw_v4, l3_proto_t::IPV4, m_table_id)); + } + if (rc_t::OK != m_hw_v6.rc()) { + HW::enqueue( + new route_domain_cmds::create_cmd(m_hw_v6, l3_proto_t::IPV6, m_table_id)); + } +} + +std::shared_ptr +route_domain::get_default() +{ + route_domain rd(route::DEFAULT_TABLE); + + return (find_or_add(rd)); +} + +std::shared_ptr +route_domain::find_or_add(const route_domain& temp) +{ + return (m_db.find_or_add(temp.m_table_id, temp)); +} + +std::shared_ptr +route_domain::singular() const +{ + return find_or_add(*this); +} + +void +route_domain::dump(std::ostream& os) +{ + db_dump(m_db, os); +} + +void +route_domain::event_handler::handle_populate(const client_db::key_t& key) +{ + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + + route_domain rd(payload.table.table_id); + + VOM_LOG(log_level_t::DEBUG) << "ip-table-dump: " << rd.to_string(); + + /* + * Write each of the discovered interfaces into the OM, + * but disable the HW Command q whilst we do, so that no + * commands are sent to VPP + */ + OM::commit(key, rd); + } +} + +route_domain::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "rd", "route-domain" }, "Route Domains", this); +} + +void +route_domain::event_handler::handle_replay() +{ + m_db.replay(); +} + +dependency_t +route_domain::event_handler::order() const +{ + return (dependency_t::TABLE); +} + +void +route_domain::event_handler::show(std::ostream& os) +{ + db_dump(m_db, os); +} + +}; // namespace VOPM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/route_domain.hpp b/extras/deprecated/vom/vom/route_domain.hpp new file mode 100644 index 00000000000..e3e389637d2 --- /dev/null +++ b/extras/deprecated/vom/vom/route_domain.hpp @@ -0,0 +1,200 @@ +/* + * 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_ROUTE_DOMAIN_H__ +#define __VOM_ROUTE_DOMAIN_H__ + +#include "vom/inspect.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/prefix.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A route-domain is a VRF. + * creating a route-domain object will construct both an IPv4 + * and IPv6 table. + */ +class route_domain : public object_base +{ +public: + /** + * The Key for a route-domain + */ + typedef route::table_id_t key_t; + + /** + * The iterator type + */ + typedef singular_db::const_iterator + const_iterator_t; + + static const_iterator_t cbegin(); + static const_iterator_t cend(); + + /** + * Construct a new object matching the desried state + */ + route_domain(route::table_id_t id); + + /** + * Copy Constructor + */ + route_domain(const route_domain& o); + + /** + * Destructor + */ + ~route_domain(); + + /** + * comparison operator - for UT + */ + bool operator==(const route_domain& r) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Debug print function + */ + std::string to_string() const; + + /** + * Get the table ID + */ + route::table_id_t table_id() const; + + /** + * Get the route-domain's key + */ + key_t key() const; + + /** + * Find the instnace of the route domain in the OM + */ + static std::shared_ptr find(const key_t& temp); + + /** + * Dump all route-doamin into the stream provided + */ + static void dump(std::ostream& os); + + /** + * Return the sigular instance for the default table + */ + static std::shared_ptr get_default(); + + /** + * replay the object to create it in hardware + */ + void replay(void); + +private: + /** + * 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; + }; + + /** + * Instance of the event handler to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const route_domain& obj); + + /** + * Find or add the instnace of the route domain in the OM + */ + static std::shared_ptr find_or_add(const route_domain& temp); + + /* + * It's the OM class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * HW configuration for the result of creating the v4 table + */ + HW::item m_hw_v4; + + /** + * HW configuration for the result of creating the v6 table + */ + HW::item m_hw_v6; + + /** + * VPP understands Table-IDs not table names. + * The table IDs for V4 and V6 are the same. + */ + route::table_id_t m_table_id; + + /** + * A map of all interfaces key against the interface's name + */ + static singular_db m_db; +}; +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/route_domain_cmds.cpp b/extras/deprecated/vom/vom/route_domain_cmds.cpp new file mode 100644 index 00000000000..217a2ebfbad --- /dev/null +++ b/extras/deprecated/vom/vom/route_domain_cmds.cpp @@ -0,0 +1,140 @@ +/* + * 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/route_domain_cmds.hpp" + +namespace VOM { +namespace route_domain_cmds { + +create_cmd::create_cmd(HW::item& item, + l3_proto_t proto, + route::table_id_t id) + : rpc_cmd(item) + , m_id(id) + , m_proto(proto) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return (m_id == other.m_id); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.table.table_id = m_id; + payload.table.is_ip6 = m_proto.is_ipv6(); + payload.is_add = 1; + + VAPI_CALL(req.execute()); + + return (wait()); +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "ip-table-create: " << m_hw_item.to_string() << " id:" << m_id + << " af:" << m_proto.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + l3_proto_t proto, + route::table_id_t id) + : rpc_cmd(item) + , m_id(id) + , m_proto(proto) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_id == other.m_id); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.table.table_id = m_id; + payload.table.is_ip6 = m_proto.is_ipv6(); + payload.is_add = 0; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + return (rc_t::OK); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "ip-table-delete: " << m_hw_item.to_string() << " id:" << m_id + << " af:" << m_proto.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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 ("ip-table-dump"); +} + +} // namespace route_domain_cmds +} // namespace VOM + /* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/route_domain_cmds.hpp b/extras/deprecated/vom/vom/route_domain_cmds.hpp new file mode 100644 index 00000000000..d500de88063 --- /dev/null +++ b/extras/deprecated/vom/vom/route_domain_cmds.hpp @@ -0,0 +1,148 @@ +/* + * 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_ROUTE_DOMAIN_CMDS_H__ +#define __VOM_ROUTE_DOMAIN_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/route_domain.hpp" +#include "vom/rpc_cmd.hpp" + +#include + +namespace VOM { +namespace route_domain_cmds { + +/** + * A command class that creates the IP table + */ +class create_cmd : public rpc_cmd, vapi::Ip_table_add_del> +{ +public: + /** + * Constructor + */ + create_cmd(HW::item& item, l3_proto_t proto, route::table_id_t id); + + /** + * 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; + +private: + /** + * table-ID to create + */ + route::table_id_t m_id; + + /** + * L3 protocol of the table + */ + l3_proto_t m_proto; +}; + +/** + * A cmd class that Deletes the IP Table + */ +class delete_cmd : public rpc_cmd, vapi::Ip_table_add_del> +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item, l3_proto_t proto, route::table_id_t id); + + /** + * 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: + /** + * table-ID to create + */ + route::table_id_t m_id; + + /** + * L3 protocol of the table + */ + l3_proto_t m_proto; +}; + +/** + * A cmd class that Dumps IP fib tables + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Constructor + */ + dump_cmd(); + dump_cmd(const dump_cmd& d); + + /** + * 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; + +private: + /** + * HW reutrn code + */ + HW::item item; +}; + +}; // namespace route_domain_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/rpc_cmd.hpp b/extras/deprecated/vom/vom/rpc_cmd.hpp new file mode 100644 index 00000000000..cba540d9318 --- /dev/null +++ b/extras/deprecated/vom/vom/rpc_cmd.hpp @@ -0,0 +1,151 @@ +/* + * 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_RPC_CMD_H__ +#define __VOM_RPC_CMD_H__ + +#include + +#include + +#include "vom/cmd.hpp" +#include "vom/logger.hpp" + +namespace VOM { +/** + * A base class for all RPC commands to VPP. + * RPC commands are one of the sub-set of command types to VPP + * that modify/create state in VPP and thus return an error code. + * Commands are issued in one thread context, but read in another. The + * command has an associated std::promise that is met by the RX thread. + * this allows the sender, which waits on the promise's future, to + * experience a synchronous command. + * + * 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 +class rpc_cmd : public cmd +{ +public: + /** + * convenient typedef + */ + typedef MSG msg_t; + + /** + * Constructor taking the HW item that will be updated by the command + */ + rpc_cmd(HWITEM& item) + : cmd() + , m_hw_item(item) + , m_promise() + { + } + + /** + * Desructor + */ + virtual ~rpc_cmd() {} + + /** + * return the HW item the command updates + */ + HWITEM& item() { return m_hw_item; } + + /** + * return the const HW item the command updates + */ + const HWITEM& item() const { return m_hw_item; } + + /** + * Fulfill the commands promise. Called from the RX thread + */ + void fulfill(const HWITEM& d) { m_promise.set_value(d); } + + /** + * Wait on the commands promise. i.e. block on the completion + * of the command. + */ + rc_t wait() + { + std::future_status status; + std::future result; + + result = m_promise.get_future(); + status = result.wait_for(std::chrono::seconds(5)); + + if (status != std::future_status::ready) { + m_hw_item.set(rc_t::TIMEOUT); + } else { + m_hw_item = result.get(); + } + + return (m_hw_item.rc()); + } + + /** + * Called by the HW Command Q when it is disabled to indicate the + * command can be considered successful without issuing it to HW + */ + virtual void succeeded() + { + m_hw_item.set(rc_t::OK); + VOM_LOG(log_level_t::DEBUG) << to_string(); + } + + /** + * call operator used as a callback by VAPI when the reply is available + */ + 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; + + /* set a temporary value in this callback thread */ + hi.set(rc_t::from_vpp_retval(retval)); + fulfill(hi); + + return (VAPI_OK); + } + + /** + * Retire/cancel a long running command + */ + virtual void retire(connection& con) {} + +protected: + /** + * A reference to an object's HW::item that the command will update + */ + HWITEM& m_hw_item; + + /** + * The promise that implements the synchronous issue + */ + std::promise m_promise; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/singular_db.hpp b/extras/deprecated/vom/vom/singular_db.hpp new file mode 100644 index 00000000000..15ec9c5af59 --- /dev/null +++ b/extras/deprecated/vom/vom/singular_db.hpp @@ -0,0 +1,148 @@ +/* + * 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_INST_DB_H__ +#define __VOM_INST_DB_H__ + +#include +#include +#include + +#include "vom/logger.hpp" + +namespace VOM { +/** + * A Database to store the unique 'singular' instances of a single object + * type. + * The instances are stored as weak pointers. So the DB does not own these + * objects, they are owned by object in the client_db. + */ +template +class singular_db +{ +public: + /** + * Constructor + */ + singular_db() {} + + /** + * Iterator + */ + typedef + typename std::map>::const_iterator const_iterator; + + /** + * Get iterator to the beginning of the DB + */ + const_iterator begin() const { return m_map.cbegin(); } + + /** + * Get iterator to the beginning of the DB + */ + const_iterator end() const { return m_map.cend(); } + + /** + * Find or add the object to the store. + * The object passed is deisred state. A new instance will be copy + * constructed from it. This function is templatised on the object type + * passed, which may be drrived from, the object type stored. this + * prevents slicing during the make_shared construction. + */ + template + std::shared_ptr find_or_add(const KEY& key, const DERIVED& obj) + { + auto search = m_map.find(key); + + if (search == m_map.end()) { + std::shared_ptr sp = std::make_shared(obj); + + m_map[key] = sp; + + VOM_LOG(log_level_t::DEBUG) << *sp; + return (sp); + } + + return (search->second.lock()); + } + + /** + * Find the object to the store. + */ + std::shared_ptr find(const KEY& key) + { + auto search = m_map.find(key); + + if (search == m_map.end()) { + std::shared_ptr sp(NULL); + + return (sp); + } + + return (search->second.lock()); + } + + /** + * Release the object from the DB store, if it's the one we have stored + */ + void release(const KEY& key, const OBJ* obj) + { + auto search = m_map.find(key); + + if (search != m_map.end()) { + if (search->second.expired()) { + m_map.erase(key); + } else { + std::shared_ptr sp = m_map[key].lock(); + + if (sp.get() == obj) { + m_map.erase(key); + } + } + } + } + + /** + * Find the object to the store. + */ + void add(const KEY& key, std::shared_ptr sp) { m_map[key] = sp; } + + /** + * Populate VPP from current state, on VPP restart + */ + void replay() + { + for (auto entry : m_map) { + entry.second.lock()->replay(); + } + } + +private: + /** + * the map of objects against their key + */ + std::map> m_map; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/singular_db_funcs.hpp b/extras/deprecated/vom/vom/singular_db_funcs.hpp new file mode 100644 index 00000000000..8d32fb58945 --- /dev/null +++ b/extras/deprecated/vom/vom/singular_db_funcs.hpp @@ -0,0 +1,52 @@ +/* + * 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_INST_DB_FUNCS_H__ +#define __VOM_INST_DB_FUNCS_H__ + +#include + +#include "singular_db.hpp" + +/** + * A set of helper function to iterate over objects in the DB. + * These functions are delcared not as DB member functions so that + * the template instatiation of the DB does not require the definitions + * of the functions used to be declared. + */ +namespace VOM { +/** + * Print each of the objects in the DB into the stream provided + */ +template +void +db_dump(const DB& db, std::ostream& os) +{ + for (const auto entry : db) { + os << "key: " << entry.first << std::endl; + os << " " << entry.second.lock()->to_string() << std::endl; + } +} +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/srpc_cmd.hpp b/extras/deprecated/vom/vom/srpc_cmd.hpp new file mode 100644 index 00000000000..258abbf6e15 --- /dev/null +++ b/extras/deprecated/vom/vom/srpc_cmd.hpp @@ -0,0 +1,74 @@ +/* + * 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_SRPC_CMD_H__ +#define __VOM_SRPC_CMD_H__ + +#include "vom/hw.hpp" +#include "vom/rpc_cmd.hpp" + +namespace VOM { +template +class srpc_cmd : public rpc_cmd, MSG> +{ +public: + /** + * convenient typedef + */ + typedef MSG msg_t; + + /** + * Constructor taking the HW item that will be updated by the command + */ + srpc_cmd(HW::item& item) + : rpc_cmd, MSG>(item) + { + } + + /** + * Desructor + */ + virtual ~srpc_cmd() {} + + virtual vapi_error_e operator()(MSG& reply) + { + int stats_index = reply.get_response().get_payload().stats_index; + int retval = reply.get_response().get_payload().retval; + + VOM_LOG(log_level_t::DEBUG) << this->to_string() << " " << retval; + + rc_t rc = rc_t::from_vpp_retval(retval); + handle_t handle = handle_t::INVALID; + + if (rc_t::OK == rc) { + handle = stats_index; + } + + this->fulfill(HW::item(handle, rc)); + + return (VAPI_OK); + } +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/stat_client.cpp b/extras/deprecated/vom/vom/stat_client.cpp new file mode 100644 index 00000000000..ca7bc6e2381 --- /dev/null +++ b/extras/deprecated/vom/vom/stat_client.cpp @@ -0,0 +1,247 @@ +/* + * 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/stat_client.hpp" + +namespace VOM { + +stat_client::stat_data_t::stat_data_t(const stat_segment_data_t& stat_seg_data) + : m_name(stat_seg_data.name) + , m_type(stat_seg_data.type) +{ + switch (m_type) { + case STAT_DIR_TYPE_SCALAR_INDEX: + m_scalar_value = stat_seg_data.scalar_value; + break; + case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE: + m_simple_counter_vec = stat_seg_data.simple_counter_vec; + break; + case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED: + m_combined_counter_vec = stat_seg_data.combined_counter_vec; + break; + case STAT_DIR_TYPE_ERROR_INDEX: + m_error_vec = stat_seg_data.error_vector; + break; + case STAT_DIR_TYPE_NAME_VECTOR: + break; + case STAT_DIR_TYPE_ILLEGAL: + break; + case STAT_DIR_TYPE_EMPTY: + break; + } +} + +const std::string& +stat_client::stat_data_t::name() const +{ + return m_name; +} + +const stat_directory_type_t& +stat_client::stat_data_t::type() const +{ + return m_type; +} + +double +stat_client::stat_data_t::get_stat_segment_scalar_data() const +{ + return m_scalar_value; +} + +uint64_t* +stat_client::stat_data_t::get_stat_segment_error_data() const +{ + return m_error_vec; +} + +uint64_t** +stat_client::stat_data_t::get_stat_segment_simple_counter_data() const +{ + return m_simple_counter_vec; +} + +vlib_counter_t** +stat_client::stat_data_t::get_stat_segment_combined_counter_data() const +{ + return m_combined_counter_vec; +} + +stat_client::stat_client(std::string& socket_name) + : m_socket_name(socket_name) + , m_patterns() + , m_stat_connect(false) + , m_counter_vec() + , m_stat_seg_data(nullptr) + , m_stat_data() +{ + m_patterns.push_back("/if"); +} + +stat_client::stat_client(std::vector& pattern) + : m_socket_name("/run/vpp/stats.sock") + , m_patterns(pattern) + , m_stat_connect(false) + , m_counter_vec() + , m_stat_seg_data(nullptr) + , m_stat_data() +{} + +stat_client::stat_client(std::string socket_name, + std::vector patterns) + : m_socket_name(socket_name) + , m_patterns(patterns) + , m_stat_connect(false) + , m_counter_vec() + , m_stat_seg_data(nullptr) + , m_stat_data() +{} + +stat_client::stat_client() + : m_socket_name("/run/vpp/stats.sock") + , m_patterns() + , m_stat_connect(false) + , m_counter_vec() + , m_stat_seg_data(nullptr) + , m_stat_data() +{ + m_patterns.push_back("/if"); +} + +stat_client::~stat_client() +{ + stat_segment_vec_free(m_counter_vec); + data_free(); + if (m_stat_connect) + stat_segment_disconnect(); +} + +stat_client::stat_client(const stat_client& o) + : m_socket_name(o.m_socket_name) + , m_patterns(o.m_patterns) +{} + +int +stat_client::connect() +{ + if (stat_segment_connect(m_socket_name.c_str()) == 0) { + m_stat_connect = true; + ls(); + } + return m_stat_connect; +} + +void +stat_client::disconnect() +{ + if (m_stat_connect) + stat_segment_disconnect(); + m_stat_connect = false; +} + +int +stat_client::vec_len(void* vec) +{ + return stat_segment_vec_len(vec); +} + +void +stat_client::vec_free(void* vec) +{ + stat_segment_vec_free(vec); +} + +void +stat_client::ls() +{ + uint8_t** string_vec = { 0 }; + for (auto& pattern : m_patterns) { + string_vec = stat_segment_string_vector(string_vec, pattern.c_str()); + } + m_counter_vec = stat_segment_ls(string_vec); + stat_segment_vec_free(string_vec); +} + +const stat_client::stat_data_vec_t& +stat_client::dump() +{ + stat_segment_data_free(m_stat_seg_data); + m_stat_seg_data = NULL; + if (m_stat_data.size()) { + m_stat_data.clear(); + } + if (m_stat_connect) { + m_stat_seg_data = stat_segment_dump(m_counter_vec); + if (!m_stat_seg_data) { + ls(); + return m_stat_data; + } + for (int i = 0; i < stat_segment_vec_len(m_stat_seg_data); i++) { + stat_data_t sd(m_stat_seg_data[i]); + m_stat_data.push_back(sd); + } + } + return m_stat_data; +} + +const stat_client::stat_data_vec_t& +stat_client::dump_entry(uint32_t index) +{ + stat_segment_data_free(m_stat_seg_data); + m_stat_seg_data = NULL; + if (m_stat_data.size()) { + m_stat_data.clear(); + } + if (m_stat_connect) { + m_stat_seg_data = stat_segment_dump_entry(index); + if (!m_stat_seg_data) { + ls(); + return m_stat_data; + } + for (int i = 0; i < stat_segment_vec_len(m_stat_seg_data); i++) { + stat_data_t sd(m_stat_seg_data[i]); + m_stat_data.push_back(sd); + } + } + return m_stat_data; +} + +void +stat_client::data_free() +{ + stat_segment_data_free(m_stat_seg_data); +} + +double +stat_client::heartbeat() +{ + return stat_segment_heartbeat(); +} + +std::string +stat_client::index_to_name(uint32_t index) +{ + return stat_segment_index_to_name(index); +} + +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/stat_client.hpp b/extras/deprecated/vom/vom/stat_client.hpp new file mode 100644 index 00000000000..355b90caf7b --- /dev/null +++ b/extras/deprecated/vom/vom/stat_client.hpp @@ -0,0 +1,209 @@ +/* + * 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_STAT_CLIENT_H__ +#define __VOM_STAT_CLIENT_H__ + +#include +#include +#include + +extern "C" { +#include +} + +namespace VOM { + +/** + * A representation of a stat client in VPP + */ +class stat_client +{ +public: + /** + * stat data representation + */ + struct stat_data_t + { + /** + * stat data custom constructor + */ + stat_data_t(const stat_segment_data_t& stat_seg_data); + + /** + * get name of stat + */ + const std::string& name() const; + + /** + * get type of stat + */ + const stat_directory_type_t& type() const; + + /** + * Get pointer to actual data + */ + double get_stat_segment_scalar_data() const; + uint64_t* get_stat_segment_error_data() const; + uint64_t** get_stat_segment_simple_counter_data() const; + vlib_counter_t** get_stat_segment_combined_counter_data() const; + + private: + /** + * name of stat data + */ + const std::string m_name; + + /** + * type of stat data + */ + const stat_directory_type_t m_type; + + /** + * union of pointers to actual stat data + */ + union + { + double m_scalar_value; + counter_t* m_error_vec; + counter_t** m_simple_counter_vec; + vlib_counter_t** m_combined_counter_vec; + }; + }; + + /** + * vector of stat_data_t + */ + typedef std::vector stat_data_vec_t; + + /** + * Stat Client constructor with custom socket name + */ + stat_client(std::string& socket_name); + + /** + * Stat Client constructor with custom vector of patterns + */ + stat_client(std::vector& pattern); + + /** + * Stat Client constructor with custom socket name and vector of patterns + */ + stat_client(std::string socket_name, std::vector patterns); + + /** + * Stat Client constructor + */ + stat_client(); + + /** + * Stat Client destructor + */ + ~stat_client(); + + /** + * Stat Client copy constructor + */ + stat_client(const stat_client& o); + + /** + * Connect to stat segment + */ + int connect(); + + /** + * Disconnect to stat segment + */ + void disconnect(); + + /** + * dump all the stats for given pattern + */ + const stat_data_vec_t& dump(); + + /** + * dump stats for given index in stat directory + */ + const stat_data_vec_t& dump_entry(uint32_t index); + + /** + * Get vector length of VPP style vector + */ + int vec_len(void* vec); + + double heartbeat(); + + /** + * get index to name of stat + */ + std::string index_to_name(uint32_t index); + +private: + /** + * Free VPP style vector + */ + void vec_free(void* vec); + + /** + * Free stat segment data + */ + void data_free(); + + /** + * ls on the stat directory using given pattern + */ + void ls(); + + /** + * socket name + */ + std::string m_socket_name; + + /** + * vector of patterns for stats + */ + std::vector m_patterns; + + /** + * connection bit + */ + bool m_stat_connect; + + /** + * Pointer to VPP style vector of stat indexes + */ + uint32_t* m_counter_vec; + + /** + * Pointer to stat segment + */ + stat_segment_data_t* m_stat_seg_data; + + /** + * Vector of stat data + */ + stat_data_vec_t m_stat_data; +}; +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/stat_reader.cpp b/extras/deprecated/vom/vom/stat_reader.cpp new file mode 100644 index 00000000000..34ac6053688 --- /dev/null +++ b/extras/deprecated/vom/vom/stat_reader.cpp @@ -0,0 +1,139 @@ +/* + * 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/stat_reader.hpp" +#include "vom/interface.hpp" + +namespace VOM { + +stat_reader::stat_indexes_t stat_reader::m_stat_itf_indexes; + +stat_reader::stat_reader() + : m_client() +{} + +stat_reader::stat_reader(stat_client sc) + : m_client(sc) +{} + +stat_reader::~stat_reader() {} + +int +stat_reader::connect() +{ + return m_client.connect(); +} + +void +stat_reader::disconnect() +{ + m_client.disconnect(); +} + +void +stat_reader::registers(const interface& intf) +{ + m_stat_itf_indexes.insert(intf.handle_i().value()); +} + +void +stat_reader::unregisters(const interface& intf) +{ + m_stat_itf_indexes.erase(intf.handle_i().value()); +} + +void +stat_reader::read() +{ + std::set> itfs_w_stats; + const stat_client::stat_data_vec_t& sd = m_client.dump(); + + for (auto& sde : sd) { + std::string name; + + if (sde.name().empty()) + continue; + + name = sde.name(); + + if (name.find("/if") != std::string::npos) + name.erase(0, 4); + + switch (sde.type()) { + case STAT_DIR_TYPE_ERROR_INDEX: + case STAT_DIR_TYPE_SCALAR_INDEX: + case STAT_DIR_TYPE_NAME_VECTOR: + case STAT_DIR_TYPE_ILLEGAL: + case STAT_DIR_TYPE_EMPTY: + break; + + case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE: { + uint64_t** data; + + data = sde.get_stat_segment_simple_counter_data(); + + for (auto& i : m_stat_itf_indexes) { + counter_t count; + + for (int k = 0; k < m_client.vec_len(data); k++) { + count.packets += data[k][i]; + } + + std::shared_ptr itf = interface::find(i); + if (itf) { + itf->set(count, name); + itfs_w_stats.insert(itf); + } + } + break; + } + + case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED: { + vlib_counter_t** data; + + data = sde.get_stat_segment_combined_counter_data(); + + for (auto& i : m_stat_itf_indexes) { + counter_t count; + + for (int k = 0; k < m_client.vec_len(data); k++) { + count.packets += data[k][i].packets; + count.bytes += data[k][i].bytes; + } + + std::shared_ptr itf = interface::find(i); + if (itf) { + itf->set(count, name); + itfs_w_stats.insert(itf); + } + } + break; + } + } + } + for (auto itf : itfs_w_stats) { + itf->publish_stats(); + } +} + +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/stat_reader.hpp b/extras/deprecated/vom/vom/stat_reader.hpp new file mode 100644 index 00000000000..3deeb439c7b --- /dev/null +++ b/extras/deprecated/vom/vom/stat_reader.hpp @@ -0,0 +1,103 @@ +/* + * 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_STAT_READER_H__ +#define __VOM_STAT_READER_H__ + +#include "vom/stat_client.hpp" +#include + +namespace VOM { + +class interface; + +/** + * Stat reader: single interface to get stats + */ +class stat_reader +{ +public: + /** + * Default Constructor + */ + stat_reader(); + + /** + * Constructor + */ + stat_reader(stat_client sc); + + /** + * Destructor + */ + ~stat_reader(); + + /** + * connection to stat object + */ + virtual int connect(); + + /** + * disconnect to stat object + */ + virtual void disconnect(); + + /** + * read stats for registered objects from stat_segment + * and set those stats to respective objects + */ + virtual void read(); + +private: + /** + * friend to interface class to call stat_register and + * stat_unregister methods + */ + friend class interface; + + /** + * Register objects to get stats for + */ + static void registers(const interface& itf); + + /** + * Unregister objects + */ + static void unregisters(const interface& itf); + + /** + * typedef of stat_indexes + */ + typedef std::set stat_indexes_t; + + /** + * stat_client object + */ + stat_client m_client; + + /** + * static pointer to set of registered interfaces + */ + static stat_indexes_t m_stat_itf_indexes; +}; +}; +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ +#endif diff --git a/extras/deprecated/vom/vom/sub_interface.cpp b/extras/deprecated/vom/vom/sub_interface.cpp new file mode 100644 index 00000000000..3d6912cdcb0 --- /dev/null +++ b/extras/deprecated/vom/vom/sub_interface.cpp @@ -0,0 +1,114 @@ +/* + * 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/sub_interface.hpp" +#include "vom/sub_interface_cmds.hpp" + +namespace VOM { +/** + * Construct a new object matching the desried state + */ +sub_interface::sub_interface(const interface& parent, + admin_state_t state, + vlan_id_t vlan) + : interface(mk_name(parent, vlan), parent.type(), state) + , m_parent(parent.singular()) + , m_vlan(vlan) +{ +} + +/** + * Construct a new object matching the desried state + */ +sub_interface::sub_interface(const interface& parent, + admin_state_t state, + const route_domain& rd, + vlan_id_t vlan) + : interface(mk_name(parent, vlan), parent.type(), state, rd) + , m_parent(parent.singular()) + , m_vlan(vlan) +{ +} + +sub_interface::~sub_interface() +{ + sweep(); + release(); +} + +sub_interface::sub_interface(const sub_interface& o) + : interface(o) + , m_parent(o.m_parent) + , m_vlan(o.m_vlan) +{ +} + +bool +sub_interface::operator==(const sub_interface& s) const +{ + return (interface::operator==(s) && (m_parent->key() == s.m_parent->key()) && + (m_vlan == s.m_vlan)); +} + +std::string +sub_interface::mk_name(const interface& parent, vlan_id_t vlan) +{ + return (parent.name() + "." + std::to_string(vlan)); +} + +std::queue& +sub_interface::mk_create_cmd(std::queue& q) +{ + q.push(new sub_interface_cmds::create_cmd(m_hdl, name(), m_parent->handle(), + m_vlan)); + + return (q); +} + +std::queue& +sub_interface::mk_delete_cmd(std::queue& q) +{ + q.push(new sub_interface_cmds::delete_cmd(m_hdl)); + + return (q); +} + +std::shared_ptr +sub_interface::singular() const +{ + return std::dynamic_pointer_cast(singular_i()); +} + +std::shared_ptr +sub_interface::singular_i() const +{ + return m_db.find_or_add(key(), *this); +} + +std::shared_ptr +sub_interface::find(const key_t& k) +{ + return std::dynamic_pointer_cast(m_db.find(k)); +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/sub_interface.hpp b/extras/deprecated/vom/vom/sub_interface.hpp new file mode 100644 index 00000000000..2a24b531ed6 --- /dev/null +++ b/extras/deprecated/vom/vom/sub_interface.hpp @@ -0,0 +1,110 @@ +/* + * 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_SUB_INTERFACE_H__ +#define __VOM_SUB_INTERFACE_H__ + +#include "vom/interface.hpp" + +namespace VOM { +/** + * A Sub-interface. e.g. a VLAN sub-interface on an Ethernet interface + */ +class sub_interface : public interface +{ + /* + * Typedef for VLAN ID + */ + typedef uint16_t vlan_id_t; + +public: + /** + * Construct a new object matching the desried state + */ + sub_interface(const interface& parent, admin_state_t state, vlan_id_t vlan); + + sub_interface(const interface& parent, + admin_state_t state, + const route_domain& rd, + vlan_id_t vlan); + + /** + * Destructor + */ + ~sub_interface(); + /** + * Copy Constructor + */ + sub_interface(const sub_interface& o); + + /** + * comparison operator - for UT + */ + bool operator==(const sub_interface& s) const; + + /** + * Return the matching 'singular instance' of the sub-interface + */ + std::shared_ptr singular() const; + + /** + * Find a subinterface from its key + */ + static std::shared_ptr find(const key_t& k); + +private: + /** + * Return the matching 'instance' of the sub-interface + * over-ride from the base class + */ + std::shared_ptr singular_i() const; + + /** + * Virtual functions to construct an interface create commands. + */ + virtual std::queue& mk_create_cmd(std::queue& cmds); + + /** + * Virtual functions to construct an interface delete commands. + */ + virtual std::queue& mk_delete_cmd(std::queue& cmds); + + /** + * From the name of the parent and the vlan, + * construct the sub-interface's name + */ + static std::string mk_name(const interface& parent, vlan_id_t vlan); + + /** + * Refernece conter lock on the parent + */ + const std::shared_ptr m_parent; + + /** + * VLAN ID + */ + vlan_id_t m_vlan; +}; +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/sub_interface_cmds.cpp b/extras/deprecated/vom/vom/sub_interface_cmds.cpp new file mode 100644 index 00000000000..d317303d938 --- /dev/null +++ b/extras/deprecated/vom/vom/sub_interface_cmds.cpp @@ -0,0 +1,115 @@ +/* + * 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/sub_interface_cmds.hpp" +#include "vom/cmd.hpp" + +#include + +namespace VOM { +namespace sub_interface_cmds { + +create_cmd::create_cmd(HW::item& item, + const std::string& name, + const handle_t& parent, + uint16_t vlan) + : interface::create_cmd(item, name) + , m_parent(parent) + , m_vlan(vlan) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return ((m_name == other.m_name) && (m_parent == other.m_parent) && + (m_vlan == other.m_vlan)); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_parent.value(); + payload.vlan_id = m_vlan; + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) { + insert_interface(); + } + + return rc_t::OK; +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "sub-itf-create: " << m_hw_item.to_string() << " parent:" << m_parent + << " vlan:" << m_vlan; + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item) + : interface::delete_cmd(item) +{ +} + +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)); + + auto& payload = req.get_request().get_payload(); + payload.sw_if_index = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return (rc_t::OK); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + + s << "sub-itf-delete: " << m_hw_item.to_string(); + + return (s.str()); +} +} // namespace sub_interface_cmds +} // namespace VOM + /* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/sub_interface_cmds.hpp b/extras/deprecated/vom/vom/sub_interface_cmds.hpp new file mode 100644 index 00000000000..40a2baac879 --- /dev/null +++ b/extras/deprecated/vom/vom/sub_interface_cmds.hpp @@ -0,0 +1,108 @@ +/* + * 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_SUB_INTERFACE_CMDS_H__ +#define __VOM_SUB_INTERFACE_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" +#include "vom/sub_interface.hpp" + +#include + +namespace VOM { +namespace sub_interface_cmds { + +/** + * A functor class that creates an interface + */ +class create_cmd : public interface::create_cmd +{ +public: + /** + * Cstrunctor taking the reference to the parent + * and the sub-interface's VLAN + */ + create_cmd(HW::item& item, + const std::string& name, + const handle_t& parent, + uint16_t vlan); + + /** + * 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; + +private: + /** + * Refernece to the parents handle + */ + const handle_t& m_parent; + + /** + * The VLAN of the sub-interface + */ + uint16_t m_vlan; +}; + +/** + * A cmd class that Delete an interface + */ +class delete_cmd : public interface::delete_cmd +{ +public: + /** + * Constructor + */ + delete_cmd(HW::item& item); + + /** + * 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; +}; + +}; // namespace sub_interface_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/tap_interface.cpp b/extras/deprecated/vom/vom/tap_interface.cpp new file mode 100644 index 00000000000..a1f3f2bfc16 --- /dev/null +++ b/extras/deprecated/vom/vom/tap_interface.cpp @@ -0,0 +1,126 @@ +/* + * 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/tap_interface.hpp" +#include "vom/tap_interface_cmds.hpp" + +#include + +namespace VOM { +tap_interface::event_handler tap_interface::m_evh; + +/** + * Construct a new object matching the desried state + */ +tap_interface::tap_interface(const std::string& name, + const admin_state_t& state, + const route::prefix_t& prefix) + : interface(name, type_t::TAPV2, state) + , m_prefix(prefix) + , m_l2_address(l2_address_t::ZERO) +{ +} + +tap_interface::tap_interface(const std::string& name, + const admin_state_t& state, + const route::prefix_t& prefix, + const l2_address_t& l2_address) + : interface(name, type_t::TAPV2, state) + , m_prefix(prefix) + , m_l2_address(l2_address) +{ +} + +tap_interface::~tap_interface() +{ + sweep(); + release(); +} + +tap_interface::tap_interface(const tap_interface& o) + : interface(o) + , m_prefix(o.m_prefix) + , m_l2_address(o.m_l2_address) +{ +} + +std::queue& +tap_interface::mk_create_cmd(std::queue& q) +{ + q.push(new tap_interface_cmds::tapv2_create_cmd(m_hdl, name(), m_prefix, + m_l2_address)); + + return (q); +} + +std::queue& +tap_interface::mk_delete_cmd(std::queue& q) +{ + q.push(new tap_interface_cmds::tapv2_delete_cmd(m_hdl)); + + return (q); +} + +std::shared_ptr +tap_interface::singular() const +{ + return std::dynamic_pointer_cast(singular_i()); +} + +std::shared_ptr +tap_interface::singular_i() const +{ + return m_db.find_or_add(name(), *this); +} + +void +tap_interface::event_handler::handle_populate(const client_db::key_t& key) +{ + // It will be polulate by interface handler +} + +tap_interface::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "tap" }, "tap_interfaces", this); +} + +void +tap_interface::event_handler::handle_replay() +{ + // It will be replayed by interface handler +} + +dependency_t +tap_interface::event_handler::order() const +{ + return (dependency_t::INTERFACE); +} + +void +tap_interface::event_handler::show(std::ostream& os) +{ + // dumped by the interface handler +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/tap_interface.hpp b/extras/deprecated/vom/vom/tap_interface.hpp new file mode 100644 index 00000000000..b167810bc42 --- /dev/null +++ b/extras/deprecated/vom/vom/tap_interface.hpp @@ -0,0 +1,118 @@ +/* + * 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_TAP_INTERFACE_H__ +#define __VOM_TAP_INTERFACE_H__ + +#include "vom/interface.hpp" + +namespace VOM { +/** + * A tap-interface. e.g. a tap interface + */ +class tap_interface : public interface +{ +public: + tap_interface(const std::string& name, + const admin_state_t& state, + const route::prefix_t& prefix); + + tap_interface(const std::string& name, + const admin_state_t& state, + const route::prefix_t& prefix, + const l2_address_t& l2_address); + + ~tap_interface(); + tap_interface(const tap_interface& o); + + /** + * Return the matching 'singular instance' of the TAP interface + */ + std::shared_ptr singular() const; + +private: + /** + * 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; + + /** + * host Ip Prefix + */ + route::prefix_t m_prefix; + + /** + * host mac address + */ + l2_address_t m_l2_address; + + /** + * Return the matching 'instance' of the sub-interface + * over-ride from the base class + */ + std::shared_ptr singular_i() const; + + /** + * Virtual functions to construct an interface create commands. + */ + virtual std::queue& mk_create_cmd(std::queue& cmds); + + /** + * Virtual functions to construct an interface delete commands. + */ + virtual std::queue& mk_delete_cmd(std::queue& cmds); + + /* + * It's the OM class that call singular() + */ + friend class OM; +}; +} + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/tap_interface_cmds.cpp b/extras/deprecated/vom/vom/tap_interface_cmds.cpp new file mode 100644 index 00000000000..b809c1384f9 --- /dev/null +++ b/extras/deprecated/vom/vom/tap_interface_cmds.cpp @@ -0,0 +1,158 @@ +/* + * 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/tap_interface_cmds.hpp" + +#include + +DEFINE_VAPI_MSG_IDS_TAPV2_API_JSON; + +namespace VOM { +namespace tap_interface_cmds { +/* + * TAPV2 + */ +tapv2_create_cmd::tapv2_create_cmd(HW::item& item, + const std::string& name, + const route::prefix_t& prefix, + const l2_address_t& l2_address) + : interface::create_cmd(item, name) + , m_prefix(prefix) + , m_l2_address(l2_address) +{} + +rc_t +tapv2_create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + memset(payload.host_if_name, 0, sizeof(payload.host_if_name)); + memcpy(payload.host_if_name, + m_name.c_str(), + std::min(m_name.length(), sizeof(payload.host_if_name))); + payload.host_if_name_set = 1; + + if (m_prefix != route::prefix_t::ZERO) { + if (m_prefix.address().is_v6()) { + m_prefix.to_vpp((uint8_t*)&payload.host_ip6_prefix_set, + payload.host_ip6_prefix.address, + &payload.host_ip6_prefix.len); + } else { + m_prefix.to_vpp((uint8_t*)&payload.host_ip4_prefix_set, + payload.host_ip4_prefix.address, + &payload.host_ip4_prefix.len); + payload.host_ip4_prefix_set = 1; + } + } + + if (m_l2_address != l2_address_t::ZERO) { + m_l2_address.to_bytes(payload.host_mac_addr, 6); + payload.host_mac_addr_set = 1; + } + + payload.id = 0xffffffff; + payload.use_random_mac = 1; + payload.tx_ring_sz = 1024; + payload.rx_ring_sz = 1024; + + VAPI_CALL(req.execute()); + + wait(); + + if (m_hw_item.rc() == rc_t::OK) { + insert_interface(); + } + + return rc_t::OK; +} + +std::string +tapv2_create_cmd::to_string() const +{ + std::ostringstream s; + s << "tapv2-intf-create: " << m_hw_item.to_string() + << " ip-prefix:" << m_prefix.to_string(); + + return (s.str()); +} + +tapv2_delete_cmd::tapv2_delete_cmd(HW::item& item) + : interface::delete_cmd(item) +{} + +rc_t +tapv2_delete_cmd::issue(connection& con) +{ + + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.sw_if_index = m_hw_item.data().value(); + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return rc_t::OK; +} +std::string +tapv2_delete_cmd::to_string() const +{ + std::ostringstream s; + s << "tapv2-itf-delete: " << m_hw_item.to_string(); + + return (s.str()); +} + +tapv2_dump_cmd::tapv2_dump_cmd() {} + +bool +tapv2_dump_cmd::operator==(const tapv2_dump_cmd& other) const +{ + return (true); +} + +rc_t +tapv2_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 +tapv2_dump_cmd::to_string() const +{ + return ("tapv2-itf-dump"); +} + +} // namespace tap_interface_cmds +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/tap_interface_cmds.hpp b/extras/deprecated/vom/vom/tap_interface_cmds.hpp new file mode 100644 index 00000000000..386dafaa648 --- /dev/null +++ b/extras/deprecated/vom/vom/tap_interface_cmds.hpp @@ -0,0 +1,102 @@ +/* + * 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_TAP_INTERFACE_CMDS_H__ +#define __VOM_TAP_INTERFACE_CMDS_H__ + +#include "vom/interface.hpp" +#include "vom/tap_interface.hpp" +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" + +#include +#include + +namespace VOM { +namespace tap_interface_cmds { + +/** + * A functor class that creates an interface + */ +class tapv2_create_cmd : public interface::create_cmd +{ +public: + tapv2_create_cmd(HW::item& item, + const std::string& name, + const route::prefix_t& prefix, + const l2_address_t& l2_address); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + +private: + const route::prefix_t& m_prefix; + const l2_address_t& m_l2_address; +}; + +/** + * A functor class that deletes a Tap interface + */ +class tapv2_delete_cmd : public interface::delete_cmd +{ +public: + tapv2_delete_cmd(HW::item& item); + + /** + * Issue the command to VPP/HW + */ + rc_t issue(connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; +}; + +/** + * A cmd class that Dumps all the Vpp Interfaces + */ +class tapv2_dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + tapv2_dump_cmd(); + + /** + * 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 tapv2_dump_cmd& i) const; +}; + +}; // namespace tap_interface_cmds +}; // namespace VOM + +#endif diff --git a/extras/deprecated/vom/vom/test_stats.cpp b/extras/deprecated/vom/vom/test_stats.cpp new file mode 100644 index 00000000000..6235dd44e3f --- /dev/null +++ b/extras/deprecated/vom/vom/test_stats.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include + +class listener : public VOM::interface::stat_listener +{ +public: + listener() {} + ~listener() {} + void handle_interface_stat(const VOM::interface& itf) + { + std::cout << itf.name() << " " << itf.get_stats(); + } +}; + +/** + * Run VPP on another terminal before running vom_stats_test + */ +int main() +{ + uint8_t i = 5; + listener *listen = new listener(); + + VOM::HW::init(new VOM::HW::cmd_q()); + VOM::OM::init(); + + while (VOM::HW::connect() != true) + ; + + VOM::tap_interface itf("tap0", VOM::interface::admin_state_t::UP, VOM::route::prefix_t::ZERO); + VOM::OM::write("__TAP__", itf); + + std::shared_ptr intf = itf.singular(); + + + VOM::tap_interface itf1("tap1", VOM::interface::admin_state_t::UP, VOM::route::prefix_t::ZERO); + VOM::OM::write("__TAP__", itf1); + + std::shared_ptr intf1 = itf1.singular(); + + VOM::tap_interface itf2("tap2", VOM::interface::admin_state_t::UP, VOM::route::prefix_t::ZERO); + VOM::OM::write("__TAP__", itf2); + + std::shared_ptr intf2 = itf2.singular(); + + if (VOM::handle_t::INVALID == intf->handle() || VOM::handle_t::INVALID == intf1->handle() + || VOM::handle_t::INVALID == intf2->handle()) + { + std::cout << "Interface index is INVALID" << std::endl; + VOM::HW::disconnect(); + + return 0; + } + else + { + std::cout << "Interface #1 index is " << intf->handle().value() << std::endl; + std::cout << "Interface #2 index is " << intf1->handle().value() << std::endl; + std::cout << "Interface #3 index is " << intf2->handle().value() << std::endl; + } + + intf->enable_stats(listen); + intf1->enable_stats(listen); + intf2->enable_stats(listen); + + while (i--) + { + sleep(3); + std::cout << "stats # " << std::to_string(i) << std::endl; + VOM::HW::read_stats(); + + if (i == 2) + intf->disable_stats(); + + } + + intf1->disable_stats(); + intf2->disable_stats(); + + intf.reset(); + intf1.reset(); + intf2.reset(); + + VOM::OM::remove("__TAP__"); + + delete listen; + sleep(2); + VOM::HW::disconnect(); + + return 0; +} diff --git a/extras/deprecated/vom/vom/types.cpp b/extras/deprecated/vom/vom/types.cpp new file mode 100644 index 00000000000..fe86fc6ee2e --- /dev/null +++ b/extras/deprecated/vom/vom/types.cpp @@ -0,0 +1,342 @@ +/* + * 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 +#include +#include +#include + +#include + +#include "vom/types.hpp" + +namespace VOM { + +rc_t::rc_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +const rc_t& +rc_t::from_vpp_retval(int32_t rv) +{ + if (0 == rv) { + return (rc_t::OK); + } + if (-68 == rv) { + // sub interface already exists + return (rc_t::OK); + } + if (-79 == rv) { + // interface already exists + return (rc_t::OK); + } + + return (rc_t::INVALID); +} + +const rc_t rc_t::UNSET(0, "un-set"); +const rc_t rc_t::NOOP(1, "no-op"); +const rc_t rc_t::OK(2, "ok"); +const rc_t rc_t::INVALID(3, "invalid"); +const rc_t rc_t::TIMEOUT(4, "timeout"); + +const handle_t handle_t::INVALID(~0); + +handle_t::handle_t(int value) + : m_value(value) +{ +} + +handle_t::handle_t() + : m_value(~0) +{ +} + +std::string +handle_t::to_string() const +{ + return (std::to_string(m_value)); +} + +bool +handle_t::operator==(const handle_t& other) const +{ + return (m_value == other.m_value); +} + +bool +handle_t::operator!=(const handle_t& other) const +{ + return (!(*this == other)); +} + +bool +handle_t::operator<(const handle_t& other) const +{ + return (m_value < other.m_value); +} + +uint32_t +handle_t::value() const +{ + return (m_value); +} + +void +handle_t::reset() +{ + m_value = ~0; +} + +std::ostream& +operator<<(std::ostream& os, const handle_t& h) +{ + os << h.value(); + + return (os); +} + +mac_address_t::mac_address_t(const uint8_t b[6]) +{ + std::copy(b, b + 6, std::begin(bytes)); +} + +mac_address_t::mac_address_t(std::initializer_list i) +{ + std::copy(i.begin(), i.end(), std::begin(bytes)); +} + +mac_address_t::mac_address_t(const std::string& str) +{ + std::vector parts; + + boost::split(parts, str, boost::is_any_of(":")); + + size_t n_bytes = std::min(bytes.size(), parts.size()); + + for (uint32_t ii = 0; ii < n_bytes; ii++) { + bytes[ii] = std::stoul(parts[ii], nullptr, 16); + } +} + +const mac_address_t mac_address_t::ONE({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }); + +const mac_address_t mac_address_t::ZERO({ 0x0 }); + +void +mac_address_t::to_bytes(uint8_t* array, uint8_t len) const +{ + for (int i = 0; i < 6 && i < len; i++) { + array[i] = bytes[i]; + } +} + +std::string +mac_address_t::to_string() const +{ + std::ostringstream s; + bool first = true; + + s.fill('0'); + s << std::hex; + for (auto byte : bytes) { + if (first) + first = false; + else + s << ":"; + s << std::setw(2) << static_cast(byte); + } + + return (s.str()); +} + +bool +mac_address_t::operator==(const mac_address_t& mac) const +{ + return (bytes == mac.bytes); +} +bool +mac_address_t::operator<(const mac_address_t& m) const +{ + return (bytes < m.bytes); +} + +std::ostream& +operator<<(std::ostream& os, const mac_address_t& mac) +{ + os << mac.to_string(); + + return (os); +} + +l2_address_t::l2_address_t(const uint8_t b[8], uint8_t n_bytes) + : bytes(n_bytes) +{ + std::copy_n(b, n_bytes, std::begin(bytes)); +} + +l2_address_t::l2_address_t(std::initializer_list i) + : bytes(i) +{ +} + +l2_address_t::l2_address_t(const mac_address_t& mac) + : bytes(6) +{ + std::copy(begin(mac.bytes), std::end(mac.bytes), std::begin(bytes)); +} + +const l2_address_t l2_address_t::ONE({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff }); + +const l2_address_t l2_address_t::ZERO({ 0x0 }); + +void +l2_address_t::to_bytes(uint8_t* array, uint8_t len) const +{ + for (uint8_t i = 0; i < bytes.size() && i < len; i++) { + array[i] = bytes[i]; + } +} + +mac_address_t +l2_address_t::to_mac() const +{ + mac_address_t mac({}); + + std::copy_n(bytes.begin(), mac.bytes.size(), mac.bytes.begin()); + + return (mac); +} + +std::string +l2_address_t::to_string() const +{ + std::ostringstream s; + bool first = true; + + s.fill('0'); + s << std::hex; + for (auto byte : bytes) { + if (first) + first = false; + else + s << ":"; + s << std::setw(2) << static_cast(byte); + } + + return (s.str()); +} + +bool +l2_address_t::operator==(const l2_address_t& l2) const +{ + return (bytes == l2.bytes); +} + +bool +l2_address_t::operator!=(const l2_address_t& l2) const +{ + return (bytes != l2.bytes); +} + +std::ostream& +operator<<(std::ostream& os, const l2_address_t& l2) +{ + os << l2.to_string(); + + return (os); +} + +const direction_t direction_t::INPUT(1, "input"); +const direction_t direction_t::OUTPUT(0, "output"); + +direction_t::direction_t(int v, const std::string s) + : enum_base(v, s) +{ +} +std::ostream& +operator<<(std::ostream& os, const direction_t& dir) +{ + os << dir.to_string(); + return os; +} + +const ethertype_t ethertype_t::ARP(0x0806, "arp"); +const ethertype_t ethertype_t::FCOE(0x8906, "fcoe"); +const ethertype_t ethertype_t::IPV4(0x0800, "ipv4"); +const ethertype_t ethertype_t::IPV6(0x86DD, "ipv6"); +const ethertype_t ethertype_t::MAC_SECURITY(0x88E5, "mac-security"); +const ethertype_t ethertype_t::MPLS_UNICAST(0x8847, "mpls-unicast"); +const ethertype_t ethertype_t::TRILL(0x22F3, "trill"); +const ethertype_t ethertype_t::UNSPECIFIED(0x0, "unspecified"); + +ethertype_t::ethertype_t(int v, const std::string s) + : enum_base(v, s) +{ +} + +std::ostream& +operator<<(std::ostream& os, const ethertype_t& ether) +{ + os << ether.to_string(); + return os; +} + +const ethertype_t& +ethertype_t::from_numeric_val(uint16_t numeric) +{ + if (0x0806 == numeric) { + return (ethertype_t::ARP); + } + if (0x8906 == numeric) { + return (ethertype_t::FCOE); + } + if (0x0800 == numeric) { + return (ethertype_t::IPV4); + } + if (0x86DD == numeric) { + return (ethertype_t::IPV6); + } + if (0x88E5 == numeric) { + return (ethertype_t::MAC_SECURITY); + } + if (0x8847 == numeric) { + return (ethertype_t::MPLS_UNICAST); + } + if (0x22F3 == numeric) { + return (ethertype_t::TRILL); + } + + return (ethertype_t::UNSPECIFIED); +} + +std::ostream& +operator<<(std::ostream& os, const counter_t& c) +{ + os << "[packets: " << c.packets << " bytes:" << c.bytes << "]"; + return os; +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/types.hpp b/extras/deprecated/vom/vom/types.hpp new file mode 100644 index 00000000000..d04528b0555 --- /dev/null +++ b/extras/deprecated/vom/vom/types.hpp @@ -0,0 +1,426 @@ +/* + * 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_TYPES_H__ +#define __VOM_TYPES_H__ + +#include +#include + +#include + +#include "vom/enum_base.hpp" + +/** + * Convenince wrapper macro for error handling in VAPI sends + */ +#define VAPI_CALL(_stmt) \ + { \ + vapi_error_e _rv; \ + do { \ + _rv = (_stmt); \ + } while (VAPI_OK != _rv); \ + } + +namespace VOM { +/** + * There needs to be a strict order in which object types are read from VPP + * (at boot time) and replayed to VPP (if VPP restarts). That ordering is + * defined in this enum types + */ +enum class dependency_t +{ + /** + * Global Configuration has no dependency + */ + GLOBAL = 0, + + /** + * interfaces are the root of the dependency graph + */ + INTERFACE, + + /** + * virtual interfaces - those that depend on some real interface + */ + VIRTUAL_INTERFACE, + + /** + * Tables in which entries are added, e.g bridge/route-domains + */ + TABLE, + + /** + * virtual tables - tables with a dependency on another table + */ + VIRTUAL_TABLE, + + /** + * ACLs + */ + ACL, + + /** + * Then L2/objects that bind to interfaces, BD, ACLS, etc + */ + BINDING, + + /** + * Entries in Tables + */ + ENTRY, +}; + +/** + * Error codes that VPP will return during a HW write + */ +struct rc_t : public enum_base +{ + /** + * Destructor + */ + ~rc_t() = default; + + /** + * The value un-set + */ + const static rc_t UNSET; + + /** + * The HW write/update action was/has not been attempted + */ + const static rc_t NOOP; + + /** + * The HW write was successfull + */ + const static rc_t OK; + + /** + * HW write reported invalid input + */ + const static rc_t INVALID; + + /** + * HW write timedout - VPP did not respond within a timely manner + */ + const static rc_t TIMEOUT; + + /** + * Get the rc_t from the VPP API value + */ + static const rc_t& from_vpp_retval(int32_t rv); + +private: + /** + * Constructor + */ + rc_t(int v, const std::string s); +}; + +/** + * Feature Directions + */ +struct direction_t : public enum_base +{ + /** + * Constructor + */ + direction_t(int v, const std::string s); + + /** + * Destructor + */ + ~direction_t() = default; + + /** + * Permit Direction + */ + const static direction_t INPUT; + + /** + * Deny Direction + */ + const static direction_t OUTPUT; +}; + +/** + * Output ostream for direction_t + */ +std::ostream& operator<<(std::ostream& os, const direction_t& dir); + +/** + * Feature Ethertype + */ +struct ethertype_t : public enum_base +{ + /** + * Constructor + */ + ethertype_t(int v, const std::string s); + + /** + * Destructor + */ + ~ethertype_t() = default; + + /** + * Ethertype Arp + */ + const static ethertype_t ARP; + + /** + * Ethertype FCoE + */ + const static ethertype_t FCOE; + + /** + * Ethertype IPv4 + */ + const static ethertype_t IPV4; + + /** + * Ethertype Ipv6 + */ + const static ethertype_t IPV6; + + /** + * Ethertype MAC Security + */ + const static ethertype_t MAC_SECURITY; + + /** + * Ethertype MPLS unicast + */ + const static ethertype_t MPLS_UNICAST; + + /** + * Ethertype TRILL + */ + const static ethertype_t TRILL; + + /** + * Ethertype Unspecified + */ + const static ethertype_t UNSPECIFIED; + + /** + * Get the ethertype from the numeric value + */ + static const ethertype_t& from_numeric_val(uint16_t numeric); +}; + +/** + * Output ostream for ethertype_t + */ +std::ostream& operator<<(std::ostream& os, const ethertype_t& eth); + +/** + * A type declaration of an interface handle in VPP + */ +struct handle_t +{ + /** + * Constructor + */ + handle_t(int value); + + /** + * Constructor + */ + handle_t(); + + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + + /** + * Comparison operator + */ + bool operator==(const handle_t& other) const; + + /** + * Comparison operator + */ + bool operator!=(const handle_t& other) const; + + /** + * less than operator + */ + bool operator<(const handle_t& other) const; + + /** + * A value of an interface handle_t that means the itf does not exist + */ + const static handle_t INVALID; + + /** + * get the value of the handle + */ + uint32_t value() const; + + /** + * reset the value of the handle to ~0 + */ + void reset(); + +private: + /** + * VPP's handle value + */ + uint32_t m_value; +}; + +/** + * ostream print of a handle_t + */ +std::ostream& operator<<(std::ostream& os, const handle_t& h); + +/** + * Type def of a Ethernet address + */ +struct mac_address_t +{ + mac_address_t(const uint8_t bytes[6]); + mac_address_t(const std::string& str); + mac_address_t(std::initializer_list bytes); + /** + * Convert to byte array + */ + void to_bytes(uint8_t* array, uint8_t len) const; + + /** + * An all 1's MAC address + */ + const static mac_address_t ONE; + + /** + * An all 0's MAC address + */ + const static mac_address_t ZERO; + + /** + * Comparison operator + */ + bool operator==(const mac_address_t& m) const; + + /** + * less than operator + */ + bool operator<(const mac_address_t& m) const; + + /** + * String conversion + */ + std::string to_string() const; + + /** + * Underlying bytes array + */ + std::array bytes; +}; + +/** + * Type def of a L2 address as read from VPP + */ +struct l2_address_t +{ + l2_address_t(const uint8_t bytes[8], uint8_t n_bytes); + l2_address_t(std::initializer_list bytes); + l2_address_t(const mac_address_t& mac); + + /** + * Convert to byte array + */ + void to_bytes(uint8_t* array, uint8_t len) const; + + /** + * An all 1's L2 address + */ + const static l2_address_t ONE; + + /** + * An all 0's L2 address + */ + const static l2_address_t ZERO; + + /** + * Comparison operator + */ + bool operator==(const l2_address_t& m) const; + + /** + * Comparison operator + */ + bool operator!=(const l2_address_t& m) const; + + /** + * String conversion + */ + std::string to_string() const; + + /** + * MAC address conversion + */ + mac_address_t to_mac() const; + + /** + * Underlying bytes array - filled from least to most significant + */ + std::vector bytes; +}; + +struct counter_t +{ + counter_t() + : packets(0) + , bytes(0) + { + } + counter_t(const counter_t& c) + : packets(c.packets) + , bytes(c.bytes) + { + } + uint64_t packets; + uint64_t bytes; +}; + +/** + * Ostream operator for a MAC address + */ +std::ostream& operator<<(std::ostream& os, const mac_address_t& mac); + +/** + * Ostream operator for a MAC address + */ +std::ostream& operator<<(std::ostream& os, const l2_address_t& l2); + +/** + * Ostream operator for a MAC address + */ +std::ostream& operator<<(std::ostream& os, const counter_t& c); +}; + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/vxlan_gbp_tunnel_cmds.cpp b/extras/deprecated/vom/vom/vxlan_gbp_tunnel_cmds.cpp new file mode 100644 index 00000000000..ba9cdb039ac --- /dev/null +++ b/extras/deprecated/vom/vom/vxlan_gbp_tunnel_cmds.cpp @@ -0,0 +1,166 @@ +/* + * 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/vxlan_gbp_tunnel_cmds.hpp" +#include "vom/api_types.hpp" + +DEFINE_VAPI_MSG_IDS_VXLAN_GBP_API_JSON; + +namespace VOM { +namespace vxlan_gbp_tunnel_cmds { + +create_cmd::create_cmd(HW::item& item, + const std::string& name, + const vxlan_tunnel::endpoint_t& ep, + bool is_l2, + handle_t mcast_itf) + : interface::create_cmd(item, name) + , m_ep(ep) + , m_is_l2(is_l2) + , m_mcast_itf(mcast_itf) +{ +} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return (m_ep == other.m_ep); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + + payload.is_add = 1; + + to_api(m_ep.src, payload.tunnel.src); + to_api(m_ep.dst, payload.tunnel.dst); + payload.tunnel.mcast_sw_if_index = m_mcast_itf.value(); + payload.tunnel.encap_table_id = 0; + payload.tunnel.vni = m_ep.vni; + payload.tunnel.instance = ~0; + payload.tunnel.mode = + (m_is_l2 ? VXLAN_GBP_API_TUNNEL_MODE_L2 : VXLAN_GBP_API_TUNNEL_MODE_L3); + + VAPI_CALL(req.execute()); + + wait(); + + if (rc_t::OK == m_hw_item.rc()) { + insert_interface(); + } + + return rc_t::OK; +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "vxlan-gbp-tunnel-create: " << m_hw_item.to_string() << " " + << m_ep.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + const vxlan_tunnel::endpoint_t& ep) + : interface::delete_cmd(item) + , m_ep(ep) +{ +} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_ep == other.m_ep); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto payload = req.get_request().get_payload(); + + payload.is_add = 0; + + to_api(m_ep.src, payload.tunnel.src); + to_api(m_ep.dst, payload.tunnel.dst); + payload.tunnel.mcast_sw_if_index = ~0; + payload.tunnel.encap_table_id = 0; + payload.tunnel.vni = m_ep.vni; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return (rc_t::OK); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "vxlan-gbp-tunnel-delete: " << m_hw_item.to_string() << m_ep.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() +{ +} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("vxlan-gbp-tunnel-dump"); +} +} // namespace vxlan_tunnel_cmds +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/vxlan_gbp_tunnel_cmds.hpp b/extras/deprecated/vom/vom/vxlan_gbp_tunnel_cmds.hpp new file mode 100644 index 00000000000..cac2564b59c --- /dev/null +++ b/extras/deprecated/vom/vom/vxlan_gbp_tunnel_cmds.hpp @@ -0,0 +1,138 @@ +/* + * 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_VXLAN_GBP_TUNNEL_CMDS_H__ +#define __VOM_VXLAN_GBP_TUNNEL_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" +#include "vom/vxlan_tunnel.hpp" + +#include + +namespace VOM { +namespace vxlan_gbp_tunnel_cmds { + +/** + * A Command class that creates an VXLAN tunnel + */ +class create_cmd : public interface::create_cmd +{ +public: + /** + * Create command constructor taking HW item to update and the + * endpoint values + */ + create_cmd(HW::item& item, + const std::string& name, + const vxlan_tunnel::endpoint_t& ep, + bool is_l2, + handle_t mcast_itf); + + /** + * 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; + +private: + /** + * Enpoint values of the tunnel to be created + */ + const vxlan_tunnel::endpoint_t m_ep; + bool m_is_l2; + handle_t m_mcast_itf; +}; + +/** + * A functor class that creates an VXLAN tunnel + */ +class delete_cmd : public interface::delete_cmd +{ +public: + /** + * delete command constructor taking HW item to update and the + * endpoint values + */ + delete_cmd(HW::item& item, const vxlan_tunnel::endpoint_t& ep); + + /** + * 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: + /** + * Enpoint values of the tunnel to be deleted + */ + const vxlan_tunnel::endpoint_t m_ep; +}; + +/** + * A cmd class that Dumps all the Vpp interfaces + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + dump_cmd(); + + /** + * 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 vxlan_tunnel_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/vxlan_tunnel.cpp b/extras/deprecated/vom/vom/vxlan_tunnel.cpp new file mode 100644 index 00000000000..5da0c99987f --- /dev/null +++ b/extras/deprecated/vom/vom/vxlan_tunnel.cpp @@ -0,0 +1,359 @@ +/* + * 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/vxlan_tunnel.hpp" +#include "vom/api_types.hpp" +#include "vom/interface_cmds.hpp" +#include "vom/logger.hpp" +#include "vom/singular_db_funcs.hpp" +#include "vom/vxlan_gbp_tunnel_cmds.hpp" +#include "vom/vxlan_tunnel_cmds.hpp" + +namespace VOM { +const std::string VXLAN_TUNNEL_NAME = "vxlan-tunnel-itf"; + +vxlan_tunnel::event_handler vxlan_tunnel::m_evh; + +const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::STANDARD(0, "standard"); +const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::GBP_L2(1, "GBP-L2"); +const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::GBP_L3(2, "GBP-L3"); +const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::GPE(3, "GPE"); + +vxlan_tunnel::mode_t::mode_t(int v, const std::string s) + : enum_base(v, s) +{} + +vxlan_tunnel::endpoint_t::endpoint_t(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + uint32_t vni) + : src(src) + , dst(dst) + , vni(vni) +{} + +vxlan_tunnel::endpoint_t::endpoint_t() + : src() + , dst() + , vni(0) +{} + +bool +vxlan_tunnel::endpoint_t::operator==(const endpoint_t& other) const +{ + return ((src == other.src) && (dst == other.dst) && (vni == other.vni)); +} + +std::string +vxlan_tunnel::endpoint_t::to_string() const +{ + std::ostringstream s; + + s << "ep:[" + << "src:" << src.to_string() << " dst:" << dst.to_string() << " vni:" << vni + << "]"; + + return (s.str()); +} + +std::string +vxlan_tunnel::mk_name(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + const mode_t& mode, + uint32_t vni) +{ + std::ostringstream s; + + s << VXLAN_TUNNEL_NAME << "-" << mode.to_string() << "-" << src << "-" << dst + << ":" << vni; + + return (s.str()); +} + +vxlan_tunnel::vxlan_tunnel(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + uint32_t vni, + const mode_t& mode) + : interface(mk_name(src, dst, mode, vni), + interface::type_t::VXLAN, + interface::admin_state_t::UP) + , m_tep(src, dst, vni) + , m_mode(mode) + , m_mcast_itf() + , m_rd() + , m_table_id(route::DEFAULT_TABLE) +{} + +vxlan_tunnel::vxlan_tunnel(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + uint32_t vni, + const interface& mcast_itf, + const mode_t& mode) + : interface(mk_name(src, dst, mode, vni), + interface::type_t::VXLAN, + interface::admin_state_t::UP) + , m_tep(src, dst, vni) + , m_mode(mode) + , m_mcast_itf(mcast_itf.singular()) + , m_rd() + , m_table_id(route::DEFAULT_TABLE) +{} + +vxlan_tunnel::vxlan_tunnel(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + uint32_t vni, + const route_domain& rd, + const mode_t& mode) + : interface(mk_name(src, dst, mode, vni), + interface::type_t::VXLAN, + interface::admin_state_t::UP) + , m_tep(src, dst, vni) + , m_mode(mode) + , m_mcast_itf() + , m_rd(rd.singular()) + , m_table_id(m_rd->table_id()) +{} + +vxlan_tunnel::vxlan_tunnel(const vxlan_tunnel& o) + : interface(o) + , m_tep(o.m_tep) + , m_mode(o.m_mode) + , m_mcast_itf(o.m_mcast_itf) + , m_rd(o.m_rd) + , m_table_id(o.m_table_id) +{} + +bool +vxlan_tunnel::operator==(const vxlan_tunnel& other) const +{ + return ((m_tep == other.m_tep) && (m_mode == other.m_mode) && + (m_mcast_itf == other.m_mcast_itf)); +} + +const handle_t& +vxlan_tunnel::handle() const +{ + return (m_hdl.data()); +} + +std::shared_ptr +vxlan_tunnel::find(const interface::key_t& k) +{ + return std::dynamic_pointer_cast(m_db.find(k)); +} + +void +vxlan_tunnel::sweep() +{ + if (m_hdl) { + if (mode_t::STANDARD == m_mode) + HW::enqueue(new vxlan_tunnel_cmds::delete_cmd(m_hdl, m_tep)); + else if (mode_t::GBP_L2 == m_mode || mode_t::GBP_L3 == m_mode) + HW::enqueue(new vxlan_gbp_tunnel_cmds::delete_cmd(m_hdl, m_tep)); + } + HW::write(); +} + +void +vxlan_tunnel::replay() +{ + if (m_hdl) { + if (mode_t::STANDARD == m_mode) + HW::enqueue(new vxlan_tunnel_cmds::create_cmd( + m_hdl, + name(), + m_tep, + (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); + else if (mode_t::GBP_L2 == m_mode) + HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd( + m_hdl, + name(), + m_tep, + true, + (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); + else if (mode_t::GBP_L3 == m_mode) + HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd( + m_hdl, + name(), + m_tep, + false, + (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); + } + if (m_rd && (m_rd->table_id() != route::DEFAULT_TABLE)) { + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); + } +} + +vxlan_tunnel::~vxlan_tunnel() +{ + sweep(); + release(); +} + +std::string +vxlan_tunnel::to_string() const +{ + std::ostringstream s; + s << "vxlan-tunnel: " << m_hdl.to_string() << " " << m_mode.to_string() << " " + << m_tep.to_string(); + if (m_mcast_itf) + s << " " << m_mcast_itf->to_string(); + + return (s.str()); +} + +void +vxlan_tunnel::update(const vxlan_tunnel& desired) +{ + /* + * the desired state is always that the interface should be created + */ + if (rc_t::OK != m_hdl.rc()) { + if (mode_t::STANDARD == m_mode) + HW::enqueue(new vxlan_tunnel_cmds::create_cmd( + m_hdl, + name(), + m_tep, + (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); + else if (mode_t::GBP_L2 == m_mode) + HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd( + m_hdl, + name(), + m_tep, + true, + (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); + else if (mode_t::GBP_L3 == m_mode) + HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd( + m_hdl, + name(), + m_tep, + false, + (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); + } + if (!m_table_id && m_rd) { + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); + HW::enqueue( + new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); + } +} + +std::shared_ptr +vxlan_tunnel::singular() const +{ + return std::dynamic_pointer_cast(singular_i()); +} + +std::shared_ptr +vxlan_tunnel::singular_i() const +{ + return m_db.find_or_add(key(), *this); +} + +void +vxlan_tunnel::event_handler::handle_populate(const client_db::key_t& key) +{ + /* + * dump VPP current states + */ + { + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + handle_t hdl(payload.sw_if_index); + boost::asio::ip::address src = + from_bytes(payload.src_address.af, (uint8_t*)&payload.src_address.un); + boost::asio::ip::address dst = + from_bytes(payload.dst_address.af, (uint8_t*)&payload.dst_address.un); + + std::shared_ptr vt = + vxlan_tunnel(src, dst, payload.vni).singular(); + vt->set(hdl); + + VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string(); + + OM::commit(key, *vt); + } + } + { + std::shared_ptr cmd = + std::make_shared(); + + HW::enqueue(cmd); + HW::write(); + + for (auto& record : *cmd) { + auto& payload = record.get_payload(); + handle_t hdl(payload.tunnel.sw_if_index); + boost::asio::ip::address src = from_api(payload.tunnel.src); + boost::asio::ip::address dst = from_api(payload.tunnel.dst); + + std::shared_ptr vt = + vxlan_tunnel(src, + dst, + payload.tunnel.vni, + (payload.tunnel.mode == VXLAN_GBP_API_TUNNEL_MODE_L2 + ? mode_t::GBP_L2 + : mode_t::GBP_L3)) + .singular(); + vt->set(hdl); + + VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string(); + + OM::commit(key, *vt); + } + } +} + +vxlan_tunnel::event_handler::event_handler() +{ + OM::register_listener(this); + inspect::register_handler({ "vxlan" }, "VXLAN Tunnels", this); +} + +void +vxlan_tunnel::event_handler::handle_replay() +{ + // replay is handled from the interface DB +} + +dependency_t +vxlan_tunnel::event_handler::order() const +{ + return (dependency_t::VIRTUAL_INTERFACE); +} + +void +vxlan_tunnel::event_handler::show(std::ostream& os) +{ + // dumped by the interface handler +} + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/vxlan_tunnel.hpp b/extras/deprecated/vom/vom/vxlan_tunnel.hpp new file mode 100644 index 00000000000..aa5d210c13b --- /dev/null +++ b/extras/deprecated/vom/vom/vxlan_tunnel.hpp @@ -0,0 +1,269 @@ +/* + * 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_VXLAN_TUNNEL_H__ +#define __VOM_VXLAN_TUNNEL_H__ + +#include "vom/hw.hpp" +#include "vom/inspect.hpp" +#include "vom/interface.hpp" +#include "vom/object_base.hpp" +#include "vom/om.hpp" +#include "vom/prefix.hpp" +#include "vom/route_domain.hpp" +#include "vom/singular_db.hpp" + +namespace VOM { +/** + * A representation of a VXLAN Tunnel in VPP + */ +class vxlan_tunnel : public interface +{ +public: + /** + * Combaintion of attributes that are a unique key + * for a VXLAN tunnel + */ + struct endpoint_t + { + /** + * Default constructor + */ + endpoint_t(); + /** + * Constructor taking endpoint values + */ + endpoint_t(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + uint32_t vni); + + /** + * Comparison operator + */ + bool operator==(const endpoint_t& o) const; + + /** + * Debug print function + */ + std::string to_string() const; + + /** + * The src IP address of the endpoint + */ + boost::asio::ip::address src; + + /** + * The destination IP address of the endpoint + */ + boost::asio::ip::address dst; + + /** + * The VNI of the endpoint + */ + uint32_t vni; + }; + + /** + * mode for the tunnel + */ + struct mode_t : public enum_base + { + ~mode_t() = default; + const static mode_t STANDARD; + const static mode_t GBP_L2; + const static mode_t GBP_L3; + const static mode_t GPE; + + private: + mode_t(int v, const std::string s); + mode_t() = default; + }; + + /** + * Construct a new object matching the desried state + */ + vxlan_tunnel(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + uint32_t vni, + const mode_t& mode = mode_t::STANDARD); + vxlan_tunnel(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + uint32_t vni, + const interface& mcast_itf, + const mode_t& mode = mode_t::STANDARD); + vxlan_tunnel(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + uint32_t vni, + const route_domain& rd, + const mode_t& mode = mode_t::STANDARD); + + /* + * Destructor + */ + ~vxlan_tunnel(); + + /** + * Copy constructor + */ + vxlan_tunnel(const vxlan_tunnel& o); + + /** + * comparison operator + */ + bool operator==(const vxlan_tunnel& vx) const; + + /** + * Return the matching 'singular instance' + */ + std::shared_ptr singular() const; + + /** + * Debug rpint function + */ + virtual std::string to_string() const; + + /** + * Return VPP's handle to this object + */ + const handle_t& handle() const; + + /** + * Fond the singular instance of the interface in the DB by key + */ + static std::shared_ptr find(const interface::key_t& k); + +private: + /** + * 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; + }; + + /** + * Event handle to register with OM + */ + static event_handler m_evh; + + /** + * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. + */ + void update(const vxlan_tunnel& obj); + + /** + * Return the matching 'instance' of the sub-interface + * over-ride from the base class + */ + std::shared_ptr singular_i() const; + + /** + * Find the VXLAN tunnel in the OM + */ + static std::shared_ptr find_or_add(const vxlan_tunnel& temp); + + /* + * It's the VPPHW class that updates the objects in HW + */ + friend class OM; + + /** + * It's the singular_db class that calls replay() + */ + friend class singular_db; + + /** + * Sweep/reap the object if still stale + */ + void sweep(void); + + /** + * replay the object to create it in hardware + */ + void replay(void); + + /** + * Tunnel enpoint/key + */ + endpoint_t m_tep; + + /** + * The tunnel mode + */ + mode_t m_mode; + + /** + * The interface on which to send the packets if the destination + * is multicast + */ + std::shared_ptr m_mcast_itf; + + /** + * The RD an L3 interface is bound to + */ + std::shared_ptr m_rd; + + /** + * HW state of the VPP table mapping + */ + HW::item m_table_id; + + /** + * Construct a unique name for the tunnel + */ + static std::string mk_name(const boost::asio::ip::address& src, + const boost::asio::ip::address& dst, + const mode_t& mode, + uint32_t vni); +}; + +/** + * Ostream output for a tunnel endpoint + */ +std::ostream& operator<<(std::ostream& os, const vxlan_tunnel::endpoint_t& ep); + +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/deprecated/vom/vom/vxlan_tunnel_cmds.cpp b/extras/deprecated/vom/vom/vxlan_tunnel_cmds.cpp new file mode 100644 index 00000000000..4fd0315f814 --- /dev/null +++ b/extras/deprecated/vom/vom/vxlan_tunnel_cmds.cpp @@ -0,0 +1,162 @@ +/* + * 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/vxlan_tunnel_cmds.hpp" + +DEFINE_VAPI_MSG_IDS_VXLAN_API_JSON; + +namespace VOM { +namespace vxlan_tunnel_cmds { + +create_cmd::create_cmd(HW::item& item, + const std::string& name, + const vxlan_tunnel::endpoint_t& ep, + handle_t mcast_itf) + : interface::create_cmd(item, name) + , m_ep(ep) + , m_mcast_itf(mcast_itf) +{} + +bool +create_cmd::operator==(const create_cmd& other) const +{ + return (m_ep == other.m_ep); +} + +rc_t +create_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto& payload = req.get_request().get_payload(); + payload.is_add = 1; + to_bytes(m_ep.src, + (uint8_t*)&payload.src_address.af, + (uint8_t*)&payload.src_address.un); + to_bytes(m_ep.dst, + (uint8_t*)&payload.dst_address.af, + (uint8_t*)&payload.dst_address.un); + payload.mcast_sw_if_index = m_mcast_itf.value(); + payload.encap_vrf_id = 0; + payload.decap_next_index = ~0; + payload.vni = m_ep.vni; + + VAPI_CALL(req.execute()); + + wait(); + + if (rc_t::OK == m_hw_item.rc()) { + insert_interface(); + } + + return rc_t::OK; +} + +std::string +create_cmd::to_string() const +{ + std::ostringstream s; + s << "vxlan-tunnel-create: " << m_hw_item.to_string() << " " + << m_ep.to_string(); + + return (s.str()); +} + +delete_cmd::delete_cmd(HW::item& item, + const vxlan_tunnel::endpoint_t& ep) + : interface::delete_cmd(item) + , m_ep(ep) +{} + +bool +delete_cmd::operator==(const delete_cmd& other) const +{ + return (m_ep == other.m_ep); +} + +rc_t +delete_cmd::issue(connection& con) +{ + msg_t req(con.ctx(), std::ref(*this)); + + auto payload = req.get_request().get_payload(); + payload.is_add = 0; + to_bytes(m_ep.src, + (uint8_t*)&payload.src_address.af, + (uint8_t*)&payload.src_address.un); + to_bytes(m_ep.dst, + (uint8_t*)&payload.dst_address.af, + (uint8_t*)&payload.dst_address.un); + payload.mcast_sw_if_index = ~0; + payload.encap_vrf_id = 0; + payload.decap_next_index = ~0; + payload.vni = m_ep.vni; + + VAPI_CALL(req.execute()); + + wait(); + m_hw_item.set(rc_t::NOOP); + + remove_interface(); + return (rc_t::OK); +} + +std::string +delete_cmd::to_string() const +{ + std::ostringstream s; + s << "vxlan-tunnel-delete: " << m_hw_item.to_string() << m_ep.to_string(); + + return (s.str()); +} + +dump_cmd::dump_cmd() {} + +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))); + + auto& payload = m_dump->get_request().get_payload(); + payload.sw_if_index = ~0; + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +dump_cmd::to_string() const +{ + return ("Vpp-vxlan_tunnels-Dump"); +} +} // namespace vxlan_tunnel_cmds +} // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ diff --git a/extras/deprecated/vom/vom/vxlan_tunnel_cmds.hpp b/extras/deprecated/vom/vom/vxlan_tunnel_cmds.hpp new file mode 100644 index 00000000000..9c321d101fc --- /dev/null +++ b/extras/deprecated/vom/vom/vxlan_tunnel_cmds.hpp @@ -0,0 +1,137 @@ +/* + * 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_VXLAN_TUNNEL_CMDS_H__ +#define __VOM_VXLAN_TUNNEL_CMDS_H__ + +#include "vom/dump_cmd.hpp" +#include "vom/rpc_cmd.hpp" +#include "vom/vxlan_tunnel.hpp" + +#include +#include + +namespace VOM { +namespace vxlan_tunnel_cmds { + +/** + * A Command class that creates an VXLAN tunnel + */ +class create_cmd : public interface::create_cmd +{ +public: + /** + * Create command constructor taking HW item to update and the + * endpoint values + */ + create_cmd(HW::item& item, + const std::string& name, + const vxlan_tunnel::endpoint_t& ep, + handle_t mcast_itf); + + /** + * 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; + +private: + /** + * Enpoint values of the tunnel to be created + */ + const vxlan_tunnel::endpoint_t m_ep; + handle_t m_mcast_itf; +}; + +/** + * A functor class that creates an VXLAN tunnel + */ +class delete_cmd : public interface::delete_cmd +{ +public: + /** + * delete command constructor taking HW item to update and the + * endpoint values + */ + delete_cmd(HW::item& item, const vxlan_tunnel::endpoint_t& ep); + + /** + * 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: + /** + * Enpoint values of the tunnel to be deleted + */ + const vxlan_tunnel::endpoint_t m_ep; +}; + +/** + * A cmd class that Dumps all the Vpp interfaces + */ +class dump_cmd : public VOM::dump_cmd +{ +public: + /** + * Default Constructor + */ + dump_cmd(); + + /** + * 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 vxlan_tunnel_cmds +}; // namespace VOM + +/* + * fd.io coding-style-patch-verification: OFF + * + * Local Variables: + * eval: (c-set-style "mozilla") + * End: + */ + +#endif diff --git a/extras/rpm/vpp.spec b/extras/rpm/vpp.spec index 1bb78af8cf7..f04eecc5c24 100644 --- a/extras/rpm/vpp.spec +++ b/extras/rpm/vpp.spec @@ -264,7 +264,7 @@ install -m 0644 $MODULES \ # # devel # -for dir in %{_mu_build_dir}/%{_vpp_install_dir}/{vom,vpp}/include/ +for dir in %{_mu_build_dir}/%{_vpp_install_dir}/vpp/include/ do for subdir in $(cd ${dir} && find . -type d -print) do diff --git a/extras/vom/CMakeLists.txt b/extras/vom/CMakeLists.txt deleted file mode 100644 index 4947235717e..00000000000 --- a/extras/vom/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -# 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. - -cmake_minimum_required(VERSION 3.5 FATAL_ERROR) - -project(vom) - -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) - -unset (VOM_LIB_VERSION) -execute_process( - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND bash -c "git describe | cut -f1 -d- | cut -dv -f2" - OUTPUT_VARIABLE VOM_LIB_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE -) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib) -set(CMAKE_INSTALL_MESSAGE NEVER) - -find_package(VPP) -find_package(Threads REQUIRED) -find_package(Boost OPTIONAL_COMPONENTS system filesystem) - -add_subdirectory(vom) -add_subdirectory(cmake) - -add_vpp_packaging( - NAME "vom" - VENDOR "fd.io" - DESCRIPTION "VPP Object Model" -) diff --git a/extras/vom/cmake/CMakeLists.txt b/extras/vom/cmake/CMakeLists.txt deleted file mode 100644 index dff24a99180..00000000000 --- a/extras/vom/cmake/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# 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. - -install( - FILES - VOMConfig.cmake - - DESTINATION - lib/cmake/vom - - COMPONENT vom -) diff --git a/extras/vom/cmake/FindCheck.cmake b/extras/vom/cmake/FindCheck.cmake deleted file mode 100644 index e5f399c5449..00000000000 --- a/extras/vom/cmake/FindCheck.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# 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. - -######################################## -# -# Find the Libcheck library and includes -# This module sets: -# CHECK_FOUND: True if Libcheck was found -# CHECK_LIBRARY: The Libcheck library -# CHECK_INCLUDE_DIR: The Libcheck include dir -# - -set(CHECK_SEARCH_PATH_LIST - ${CHECK_HOME} - $ENV{CHECK_HOME} - /usr/local - /opt - /usr -) - -find_path(CHECK_INCLUDE_DIR check.h - HINTS ${CHECK_SEARCH_PATH_LIST} - PATH_SUFFIXES include - DOC "Find the check includes" -) - -find_library(CHECK_LIBRARY NAMES check - HINTS ${CHECK_SEARCH_PATH_LIST} - PATH_SUFFIXES lib - DOC "Find the check libraries" -) - -execute_process( - COMMAND grep "CHECK_MICRO_VERSION" ${CHECK_INCLUDE_DIR}/check.h - COMMAND grep -Eo [0-9]+ - OUTPUT_VARIABLE CHECK_MICRO_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE -) - -execute_process( - COMMAND grep "CHECK_MINOR_VERSION" ${CHECK_INCLUDE_DIR}/check.h - COMMAND grep -Eo [0-9]+ - OUTPUT_VARIABLE CHECK_MINOR_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE -) - -execute_process( - COMMAND grep "CHECK_MAJOR_VERSION" ${CHECK_INCLUDE_DIR}/check.h - COMMAND grep -Eo [0-9]+ - OUTPUT_VARIABLE CHECK_MAJOR_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE -) - -set(CHECK_VERSION "${CHECK_MAJOR_VERSION}.${CHECK_MINOR_VERSION}.${CHECK_MICRO_VERSION}") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - Check - REQUIRED_VARS CHECK_LIBRARY CHECK_INCLUDE_DIR - VERSION_VAR CHECK_VERSION -) \ No newline at end of file diff --git a/extras/vom/cmake/FindSubunit.cmake b/extras/vom/cmake/FindSubunit.cmake deleted file mode 100644 index 121cb5f10e2..00000000000 --- a/extras/vom/cmake/FindSubunit.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# 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. - -######################################## -# -# Find the Libsubunit library and includes -# This module sets: -# SUBUNIT_FOUND: True if Libsubunit was found -# SUBUNIT_LIBRARY: The Libsubunit library -# SUBUNIT_INCLUDE_DIR: The Libsubunit include dir -# - -set(SUBUNIT_SEARCH_PATH_LIST - ${SUBUNIT_HOME} - $ENV{SUBUNIT_HOME} - /usr/local - /opt - /usr -) - -find_path(SUBUNIT_INCLUDE_DIR - NAMES child.h - HINTS ${SUBUNIT_SEARCH_PATH_LIST} - PATH_SUFFIXES include subunit -) - -find_library(SUBUNIT_LIBRARY - NAMES subunit - PATH_SUFFIXES lib - HINTS ${SUBUNIT_SEARCH_PATH_LIST} -) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - Subunit - REQUIRED_VARS SUBUNIT_LIBRARY SUBUNIT_INCLUDE_DIR -) \ No newline at end of file diff --git a/extras/vom/cmake/VOMConfig.cmake b/extras/vom/cmake/VOMConfig.cmake deleted file mode 100644 index a2ea6b60491..00000000000 --- a/extras/vom/cmake/VOMConfig.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# 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. - -get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) - -find_path(VOM_INCLUDE_DIR PATH_SUFFIXES NAMES vom/om.hpp) - -if(VOM_INCLUDE_DIR) - include_directories (${VOM_INCLUDE_DIR}) -else() - message(FATAL_ERROR "VOM headers, libraries and/or tools not found") -endif() - -set(VPP_EXTERNAL_PROJECT 1) - -include(CheckCCompilerFlag) diff --git a/extras/vom/vom/.clang-format b/extras/vom/vom/.clang-format deleted file mode 100644 index b83102010d0..00000000000 --- a/extras/vom/vom/.clang-format +++ /dev/null @@ -1,4 +0,0 @@ - -BasedOnStyle: mozilla -AlwaysBreakAfterReturnType: TopLevelDefinitions -BinPackParameters: false diff --git a/extras/vom/vom/CMakeLists.txt b/extras/vom/vom/CMakeLists.txt deleted file mode 100644 index 92a4348dba4..00000000000 --- a/extras/vom/vom/CMakeLists.txt +++ /dev/null @@ -1,323 +0,0 @@ -# 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. - -unset (VPPAPICLIENT_LIB) -unset (VAPICLIENT_LIB) -unset (ACL_FILE) -unset (NAT_FILE) -unset (L2E_FILE) -unset (GBP_FILE) -unset (IGMP_FILE) -unset (VOM_SOURCES) -unset (VOM_HEADERS) - -find_library(VPPAPICLIENT_LIB NAMES vppapiclient REQUIRED) -find_path(VPPAPICLIENT_INCLUDE_DIR NAMES vpp-api/client/vppapiclient.h) -find_library(VAPICLIENT_LIB NAMES vapiclient REQUIRED) -find_path(VAPICLIENT_INCLUDE_DIR NAMES vapi/vapi.hpp) - - -if(NOT VPPAPICLIENT_INCLUDE_DIR OR NOT VPPAPICLIENT_LIB) - message(FATAL_ERROR "Cannot find vppapiclient library and/or headers") -endif() -if(NOT VAPICLIENT_INCLUDE_DIR OR NOT VAPICLIENT_LIB) - message(FATAL_ERROR "Cannot find vapiclient library and/or headers") -endif() - -include_directories(${VPPAPICLIENT_INCLUDE_DIR}) -include_directories(${VAPICLIENT_INCLUDE_DIR}) -include_directories(${CMAKE_SOURCE_DIR}) - -find_file(ACL_FILE NAMES acl.api.vapi.hpp PATH_SUFFIXES vapi) -find_file(NAT_FILE NAMES nat.api.vapi.hpp PATH_SUFFIXES vapi) -find_file(L2E_FILE NAMES l2e.api.vapi.hpp PATH_SUFFIXES vapi) -find_file(GBP_FILE NAMES gbp.api.vapi.hpp PATH_SUFFIXES vapi) -find_file(IGMP_FILE NAMES igmp.api.vapi.hpp PATH_SUFFIXES vapi) - -if(ACL_FILE) - list(APPEND VOM_SOURCES - acl_binding_cmds.cpp - acl_binding.cpp - acl_ethertype_cmds.cpp - acl_ethertype.cpp - acl_l2_list.cpp - acl_l2_rule.cpp - acl_l3_list.cpp - acl_l3_rule.cpp - acl_list_cmds.cpp - acl_types.cpp - ) -endif() - -if(NAT_FILE) - list(APPEND VOM_SOURCES - nat_static.cpp - nat_static_cmds.cpp - nat_binding.cpp - nat_binding_cmds.cpp - ) -endif() - -if (L2E_FILE) - list(APPEND VOM_SOURCES - l2_emulation_cmds.cpp - l2_emulation.cpp - ) -endif() - -if(GBP_FILE) - list(APPEND VOM_SOURCES - gbp_contract_cmds.cpp - gbp_contract.cpp - gbp_bridge_domain_cmds.cpp - gbp_bridge_domain.cpp - gbp_endpoint_cmds.cpp - gbp_endpoint.cpp - gbp_endpoint_group_cmds.cpp - gbp_endpoint_group.cpp - gbp_ext_itf.cpp - gbp_ext_itf_cmds.cpp - gbp_recirc_cmds.cpp - gbp_recirc.cpp - gbp_route_domain_cmds.cpp - gbp_route_domain.cpp - gbp_rule.cpp - gbp_subnet_cmds.cpp - gbp_subnet.cpp - gbp_types.hpp - gbp_vxlan.cpp - gbp_vxlan_cmds.cpp - ) -endif() - -if (IGMP_FILE) - list(APPEND VOM_SOURCES - igmp_binding_cmds.cpp - igmp_binding.cpp - igmp_listen_cmds.cpp - igmp_listen.cpp - ) -endif() - -list(APPEND VOM_SOURCES - types.cpp - api_types.cpp - arp_proxy_binding_cmds.cpp - arp_proxy_binding.cpp - arp_proxy_config_cmds.cpp - arp_proxy_config.cpp - bond_group_binding_cmds.cpp - bond_group_binding.cpp - bond_interface_cmds.cpp - bond_interface.cpp - bond_member.cpp - bridge_domain_cmds.cpp - bridge_domain.cpp - bridge_domain_arp_entry.cpp - bridge_domain_arp_entry_cmds.cpp - bridge_domain_entry_cmds.cpp - bridge_domain_entry.cpp - client_db.cpp - cmd.cpp - connection.cpp - dhcp_client_cmds.cpp - dhcp_client.cpp - hw_cmds.cpp - hw.cpp - inspect.cpp - interface_cmds.cpp - interface.cpp - interface_factory.cpp - interface_ip6_nd_cmds.cpp - interface_span_cmds.cpp - interface_span.cpp - interface_types.cpp - ip_punt_redirect_cmds.cpp - ip_punt_redirect.cpp - ip_unnumbered_cmds.cpp - ip_unnumbered.cpp - l2_binding_cmds.cpp - l2_binding.cpp - l2_vtr.cpp - l2_vtr_cmds.cpp - l2_xconnect_cmds.cpp - l2_xconnect.cpp - l3_binding_cmds.cpp - l3_binding.cpp - lldp_binding_cmds.cpp - lldp_binding.cpp - lldp_global_cmds.cpp - lldp_global.cpp - logger.cpp - neighbour.cpp - neighbour_cmds.cpp - object_base.cpp - mroute_cmds.cpp - om.cpp - pipe.cpp - pipe_cmds.cpp - prefix.cpp - qos_map.cpp - qos_map_cmds.cpp - qos_mark.cpp - qos_mark_cmds.cpp - qos_record.cpp - qos_record_cmds.cpp - qos_store.cpp - qos_store_cmds.cpp - qos_types.cpp - qos_types_api.cpp - ra_config.cpp - ra_prefix.cpp - route.cpp - route_api_types.cpp - route_cmds.cpp - route_domain.cpp - route_domain_cmds.cpp - stat_client.cpp - stat_reader.cpp - sub_interface_cmds.cpp - sub_interface.cpp - tap_interface.cpp - tap_interface_cmds.cpp - vxlan_gbp_tunnel_cmds.cpp - vxlan_tunnel_cmds.cpp - vxlan_tunnel.cpp -) - -if(ACL_FILE) - list(APPEND VOM_HEADERS - acl_binding.hpp - acl_ethertype.hpp - acl_l2_rule.hpp - acl_l3_rule.hpp - acl_l3_list.hpp - acl_l2_list.hpp - acl_types.hpp - ) -endif() - -if(NAT_FILE) - list(APPEND VOM_HEADERS - nat_static.hpp - nat_binding.hpp - ) -endif() - -if(L2E_FILE) - list(APPEND VOM_HEADERS - l2_emulation.hpp - ) -endif() - -if(GBP_FILE) - list(APPEND VOM_HEADERS - gbp_contract.hpp - gbp_bridge_domain.hpp - gbp_endpoint.hpp - gbp_endpoint_group.hpp - gbp_ext_itf.hpp - gbp_recirc.hpp - gbp_route_domain.hpp - gbp_rule.hpp - gbp_subnet.hpp - gbp_types.hpp - gbp_vxlan.hpp - ) -endif() - -if(IGMP_FILE) - list(APPEND VOM_HEADERS - igmp_binding.hpp - igmp_listen.hpp - ) -endif() - -list(APPEND VOM_HEADERS - arp_proxy_binding.hpp - arp_proxy_config.hpp - bond_group_binding.hpp - bond_interface.hpp - bond_member.hpp - bridge_domain.hpp - bridge_domain_arp_entry.hpp - bridge_domain_entry.hpp - client_db.hpp - cmd.hpp - connection.hpp - dhcp_client.hpp - dump_cmd.hpp - enum_base.hpp - event_cmd.hpp - hw.hpp - inspect.hpp - interface.hpp - interface_cmds.hpp - interface_ip6_nd.hpp - interface_span.hpp - ip_punt_redirect.hpp - ip_unnumbered.hpp - l2_binding.hpp - l2_vtr.hpp - l2_xconnect.hpp - l3_binding.hpp - lldp_binding.hpp - lldp_global.hpp - logger.hpp - neighbour.hpp - object_base.hpp - om.hpp - pipe.hpp - prefix.hpp - qos_map.hpp - qos_mark.hpp - qos_record.hpp - qos_store.hpp - qos_types.hpp - ra_config.hpp - ra_prefix.hpp - route.hpp - route_domain.hpp - rpc_cmd.hpp - singular_db.hpp - singular_db_funcs.hpp - stat_client.hpp - stat_reader.hpp - sub_interface.hpp - tap_interface.hpp - types.hpp - api_types.hpp - vxlan_tunnel.hpp -) - -add_definitions(-Wall -Werror -std=gnu++11 -g) -add_library(vom SHARED ${VOM_SOURCES}) -if (VOM_LIB_VERSION) - set_target_properties(vom PROPERTIES SOVERSION ${VOM_LIB_VERSION}) -endif() -target_link_libraries(vom ${VPPAPICLIENT_LIB} ${VAPICLIENT_LIB} Threads::Threads - ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} m rt) -install(TARGETS vom DESTINATION lib COMPONENT vom) -install(FILES ${VOM_HEADERS} DESTINATION include/vom COMPONENT vom) - -if (Boost_FOUND) - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - add_definitions(-stdlib=libstdc++) - endif() - add_executable(vom_stats_test test_stats.cpp) - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - target_link_libraries(vom_stats_test vom stdc++) - else() - target_link_libraries(vom_stats_test vom) - endif() -endif() diff --git a/extras/vom/vom/acl_binding.cpp b/extras/vom/vom/acl_binding.cpp deleted file mode 100644 index d57ed7741e5..00000000000 --- a/extras/vom/vom/acl_binding.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * 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/acl_binding.hpp" -#include "vom/acl_binding_cmds.hpp" - -namespace VOM { -namespace ACL { -template <> -dependency_t -l2_binding::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -template <> -l2_binding::event_handler::event_handler() -{ - /* hack to get this function instantiated */ - order(); - - OM::register_listener(this); - inspect::register_handler({ "l2-acl-binding" }, "L2 ACL bindings", this); -} - -template <> -void -l2_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - /* hack to get this function instantiated */ - order(); - - /* - * dump VPP Bridge domains - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = interface::find(payload.sw_if_index); - - if (itf) { - for (int ii = 0; ii < payload.count; ii++) { - std::shared_ptr acl = l2_list::find(payload.acls[ii]); - - if (acl) { - l2_binding binding(direction_t::INPUT, *itf, *acl); - OM::commit(key, binding); - } else { - VOM_LOG(log_level_t::ERROR) << "no ACL id:" << payload.acls[ii]; - } - } - } else { - VOM_LOG(log_level_t::ERROR) << "no interface:" << payload.sw_if_index; - } - } -} - -template <> -dependency_t -l3_binding::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -template <> -l3_binding::event_handler::event_handler() -{ - /* hack to get this function instantiated */ - order(); - - OM::register_listener(this); - inspect::register_handler({ "l3-acl-binding" }, "L3 ACL bindings", this); -} - -template <> -void -l3_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - /* hack to get this function instantiated */ - order(); - - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = interface::find(payload.sw_if_index); - uint8_t n_input = payload.n_input; - - if (itf) { - for (int ii = 0; ii < payload.count; ii++) { - std::shared_ptr acl = l3_list::find(payload.acls[ii]); - - if (acl) { - if (n_input) { - l3_binding binding(direction_t::INPUT, *itf, *acl); - n_input--; - OM::commit(key, binding); - } else { - l3_binding binding(direction_t::OUTPUT, *itf, *acl); - OM::commit(key, binding); - } - } else { - VOM_LOG(log_level_t::ERROR) << "no ACL id:" << payload.acls[ii]; - } - } - } else { - VOM_LOG(log_level_t::ERROR) << "no interface:" << payload.sw_if_index; - } - } -} - -template <> -void -l3_binding::update(const binding& obj) -{ - if (!m_binding) { - HW::enqueue(new binding_cmds::l3_bind_cmd( - m_binding, m_direction, m_itf->handle(), m_acl->handle())); - } - HW::write(); -} - -template <> -void -l3_binding::sweep(void) -{ - if (m_binding) { - HW::enqueue(new binding_cmds::l3_unbind_cmd( - m_binding, m_direction, m_itf->handle(), m_acl->handle())); - } - HW::write(); -} - -template <> -void -l3_binding::replay(void) -{ - if (m_binding) { - HW::enqueue(new binding_cmds::l3_bind_cmd( - m_binding, m_direction, m_itf->handle(), m_acl->handle())); - } -} - -template <> -void -l2_binding::update(const binding& obj) -{ - if (!m_binding) { - HW::enqueue(new binding_cmds::l2_bind_cmd( - m_binding, m_direction, m_itf->handle(), m_acl->handle())); - } - HW::write(); -} - -template <> -void -l2_binding::sweep(void) -{ - if (m_binding) { - HW::enqueue(new binding_cmds::l2_unbind_cmd( - m_binding, m_direction, m_itf->handle(), m_acl->handle())); - } - HW::write(); -} - -template <> -void -l2_binding::replay(void) -{ - if (m_binding) { - HW::enqueue(new binding_cmds::l2_bind_cmd( - m_binding, m_direction, m_itf->handle(), m_acl->handle())); - } -} -}; - -std::ostream& -operator<<(std::ostream& os, - const std::pair& key) -{ - os << "[" << key.first.to_string() << " " << key.second << "]"; - - return (os); -} -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_binding.hpp b/extras/vom/vom/acl_binding.hpp deleted file mode 100644 index 2c9923b8266..00000000000 --- a/extras/vom/vom/acl_binding.hpp +++ /dev/null @@ -1,245 +0,0 @@ -/* - * 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_ACL_BINDING_H__ -#define __VOM_ACL_BINDING_H__ - -#include - -#include "vom/acl_l2_list.hpp" -#include "vom/acl_l3_list.hpp" -#include "vom/acl_types.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace ACL { -/** - * A binding between an ACL and an interface. - * A representation of the application of the ACL to the interface. - */ -template -class binding : public object_base -{ -public: - /** - * The key for a binding is the direction and the interface - */ - typedef std::pair key_t; - - /** - * Construct a new object matching the desried state - */ - binding(const direction_t& direction, const interface& itf, const LIST& acl) - : m_direction(direction) - , m_itf(itf.singular()) - , m_acl(acl.singular()) - , m_binding(false) - { - m_evh.order(); - } - - /** - * Copy Constructor - */ - binding(const binding& o) - : m_direction(o.m_direction) - , m_itf(o.m_itf) - , m_acl(o.m_acl) - , m_binding(o.m_binding) - { - } - - /** - * Destructor - */ - ~binding() - { - sweep(); - m_db.release(std::make_pair(m_direction, m_itf->key()), this); - } - - /** - * Return the 'singular instance' of the L2 config that matches this - * object - */ - std::shared_ptr singular() const { return find_or_add(*this); } - - /** - * convert to string format for debug purposes - */ - std::string to_string() const - { - std::ostringstream s; - s << "acl-binding:[" << m_direction.to_string() << " " << m_itf->to_string() - << " " << m_acl->to_string() << " " << m_binding.to_string() << "]"; - - return (s.str()); - } - - /** - * Dump all bindings into the stream provided - */ - static void dump(std::ostream& os) { m_db.dump(os); } - - static dependency_t order() { return m_evh.order(); } - -private: - /** - * 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() { m_db.replay(); } - - /** - * Show the object in the Singular DB - */ - void show(std::ostream& os) { db_dump(m_db, os); } - - /** - * Get the sortable Id of the listener - */ - dependency_t order() const; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const binding& obj); - - /** - * Find or Add the instance in the DB - */ - static std::shared_ptr find_or_add(const binding& temp) - { - return (m_db.find_or_add( - std::make_pair(temp.m_direction, temp.m_itf->key()), temp)); - } - - /* - * It's the OM class that calls singular() - */ - friend class VOM::OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * Replay the objects state to HW - */ - void replay(void); - - /** - * The direction the of the packets on which to apply the ACL - * input or output - */ - const direction_t m_direction; - - /** - * A reference counting pointer the interface that this L3 layer - * represents. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * A reference counting pointer the ACL that this - * interface is bound to. By holding the reference here, we can - * guarantee that this object will outlive the BD. - */ - const std::shared_ptr m_acl; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A map of all L2 interfaces key against the interface's handle_t - */ - static singular_db m_db; -}; - -/** - * Typedef the L3 binding type - */ -typedef binding l3_binding; - -/** - * Typedef the L2 binding type - */ -typedef binding l2_binding; - -/** - * Definition of the static Singular DB for ACL bindings - */ -template -singular_db::key_t, ACL::binding> - binding::m_db; - -template -typename ACL::binding::event_handler binding::m_evh; - -namespace { -const static dependency_t __attribute__((unused)) l2o = l2_binding::order(); -const static dependency_t __attribute__((unused)) l3o = l3_binding::order(); -}; -}; - -std::ostream& operator<<(std::ostream& os, - const std::pair& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_binding_cmds.cpp b/extras/vom/vom/acl_binding_cmds.cpp deleted file mode 100644 index 062c1b90c9f..00000000000 --- a/extras/vom/vom/acl_binding_cmds.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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/acl_binding_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_ACL_API_JSON; - -namespace VOM { -namespace ACL { -namespace binding_cmds { -template <> -rc_t -l3_bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.is_add = 1; - payload.is_input = (m_direction == direction_t::INPUT ? 1 : 0); - payload.acl_index = m_acl.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -template <> -std::string -l3_bind_cmd::to_string() const -{ - std::ostringstream s; - s << "l3-acl-bind:[" << m_direction.to_string() - << " itf:" << m_itf.to_string() << " acl:" << m_acl.to_string() << "]"; - - return (s.str()); -} - -template <> -rc_t -l3_unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.is_add = 0; - payload.is_input = (m_direction == direction_t::INPUT ? 1 : 0); - payload.acl_index = m_acl.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -template <> -std::string -l3_unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "l3-acl-unbind:[" << m_direction.to_string() - << " itf:" << m_itf.to_string() << " acl:" << m_acl.to_string() << "]"; - - return (s.str()); -} - -template <> -rc_t -l3_dump_cmd::issue(connection& con) -{ - m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -template <> -std::string -l3_dump_cmd::to_string() const -{ - return ("l3-acl-bind-dump"); -} - -template <> -rc_t -l2_bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.is_add = 1; - payload.acl_index = m_acl.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -template <> -std::string -l2_bind_cmd::to_string() const -{ - std::ostringstream s; - s << "l2-acl-bind:[" << m_direction.to_string() - << " itf:" << m_itf.to_string() << " acl:" << m_acl.to_string() << "]"; - - return (s.str()); -} - -template <> -rc_t -l2_unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.is_add = 0; - payload.acl_index = m_acl.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -template <> -std::string -l2_unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "l2-acl-unbind:[" << m_direction.to_string() - << " itf:" << m_itf.to_string() << " acl:" << m_acl.to_string() << "]"; - - return (s.str()); -} - -template <> -rc_t -l2_dump_cmd::issue(connection& con) -{ - m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -template <> -std::string -l2_dump_cmd::to_string() const -{ - return ("l2-acl-bind-dump"); -} - -}; // namespace binding_cmds -}; // namespace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_binding_cmds.hpp b/extras/vom/vom/acl_binding_cmds.hpp deleted file mode 100644 index 8515b4148ac..00000000000 --- a/extras/vom/vom/acl_binding_cmds.hpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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_ACL_BINDING_CMDS_H__ -#define __VOM_ACL_BINDING_CMDS_H__ - -#include "vom/acl_binding.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace ACL { -namespace binding_cmds { -/** - * A command class that binds the ACL to the interface - */ -template -class bind_cmd : public rpc_cmd, BIND> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, - const direction_t& direction, - const handle_t& itf, - const handle_t& acl) - : rpc_cmd, BIND>(item) - , m_direction(direction) - , m_itf(itf) - , m_acl(acl) - { - } - - /** - * 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 bind_cmd& other) const - { - return ((m_itf == other.m_itf) && (m_acl == m_acl)); - } - -private: - /** - * The direction of the binding - */ - const direction_t m_direction; - - /** - * The interface to bind to - */ - const handle_t m_itf; - - /** - * The ACL to bind - */ - const handle_t m_acl; -}; - -/** - * A command class that binds the ACL to the interface - */ -template -class unbind_cmd : public rpc_cmd, BIND> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, - const direction_t& direction, - const handle_t& itf, - const handle_t& acl) - : rpc_cmd, BIND>(item) - , m_direction(direction) - , m_itf(itf) - , m_acl(acl) - { - } - - /** - * 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 unbind_cmd& other) const - { - return ((m_itf == other.m_itf) && (m_acl == m_acl)); - } - -private: - /** - * The direction of the binding - */ - const direction_t m_direction; - - /** - * The interface to bind to - */ - const handle_t m_itf; - - /** - * The ACL to bind - */ - const handle_t m_acl; -}; - -/** - * A cmd class that Dumps all the ACLs - */ -template -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -/** - * Typedef the L3 ACL binding commands - */ -typedef bind_cmd l3_bind_cmd; -typedef unbind_cmd l3_unbind_cmd; -typedef dump_cmd l3_dump_cmd; - -/** - * Typedef the L2 binding type - */ -typedef bind_cmd l2_bind_cmd; -typedef unbind_cmd l2_unbind_cmd; -typedef dump_cmd l2_dump_cmd; - -}; // namespace binding_cmds -}; // namespace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_ethertype.cpp b/extras/vom/vom/acl_ethertype.cpp deleted file mode 100644 index 81ed7a28a7a..00000000000 --- a/extras/vom/vom/acl_ethertype.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - * 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/acl_ethertype.hpp" -#include "vom/acl_ethertype_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace ACL { - -ethertype_rule_t::ethertype_rule_t(const ethertype_t& eth, - const direction_t& dir) - : m_eth(eth) - , m_dir(dir) -{ -} - -std::string -ethertype_rule_t::to_string() const -{ - std::ostringstream s; - - s << "[" - << "ethertype:" << m_eth.to_string() << " dir:" << m_dir.to_string() - << "],"; - - return (s.str()); -} - -bool -ethertype_rule_t::operator<(const ethertype_rule_t& other) const -{ - return (m_dir > other.m_dir); -} - -bool -ethertype_rule_t::operator==(const ethertype_rule_t& other) const -{ - return (m_dir == other.m_dir && m_eth == other.m_eth); -} - -uint16_t -ethertype_rule_t::getEthertype() const -{ - return m_eth.value(); -} - -const direction_t& -ethertype_rule_t::getDirection() const -{ - return m_dir; -} - -/** - * A DB of all acl ethertype bindings configs - */ -singular_db acl_ethertype::m_db; - -acl_ethertype::event_handler acl_ethertype::m_evh; - -acl_ethertype::acl_ethertype(const interface& itf, - const acl_ethertype::ethertype_rules_t& le) - : m_itf(itf.singular()) - , m_le(le) - , m_binding(true) -{ -} - -acl_ethertype::acl_ethertype(const acl_ethertype& o) - : m_itf(o.m_itf) - , m_le(o.m_le) - , m_binding(o.m_binding) -{ -} - -acl_ethertype::~acl_ethertype() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_itf->key(), this); -} - -void -acl_ethertype::sweep() -{ - if (m_binding) { - HW::enqueue(new acl_ethertype_cmds::unbind_cmd(m_binding, m_itf->handle())); - } - HW::write(); -} - -const acl_ethertype::key_t& -acl_ethertype::key() const -{ - return (m_itf->key()); -} - -bool -acl_ethertype::operator==(const acl_ethertype& other) const -{ - return (m_itf->key() == other.m_itf->key() && m_le == other.m_le); -} - -std::shared_ptr -acl_ethertype::find(const key_t& key) -{ - return (m_db.find(key)); -} - -void -acl_ethertype::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -acl_ethertype::replay() -{ - if (m_binding) { - HW::enqueue( - new acl_ethertype_cmds::bind_cmd(m_binding, m_itf->handle(), m_le)); - } -} - -std::string -acl_ethertype::to_string() const -{ - std::ostringstream s; - s << "Acl-Ethertype:" << m_itf->to_string() << " ethertype-rules:"; - auto it = m_le.cbegin(); - while (it != m_le.cend()) { - s << it->to_string(); - ++it; - } - s << " rules-size:" << m_le.size(); - - return (s.str()); -} - -void -acl_ethertype::update(const acl_ethertype& desired) -{ - /* - * always update the instance with the latest rules - */ - if (!m_binding || desired.m_le != m_le) { - HW::enqueue( - new acl_ethertype_cmds::bind_cmd(m_binding, m_itf->handle(), m_le)); - } - - m_le = desired.m_le; -} - -std::shared_ptr -acl_ethertype::find_or_add(const acl_ethertype& temp) -{ - return (m_db.find_or_add(temp.m_itf->key(), temp)); -} - -std::shared_ptr -acl_ethertype::singular() const -{ - return find_or_add(*this); -} - -acl_ethertype::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "acl-ethertype" }, "ACL Ethertype bindings", - this); -} - -void -acl_ethertype::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -acl_ethertype::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump VPP acl ethertypes - */ - std::shared_ptr cmd = - std::make_shared(~0); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - handle_t hdl(payload.sw_if_index); - std::shared_ptr itf = interface::find(hdl); - uint8_t n_input = payload.n_input; - uint8_t count = payload.count; - ethertype_rules_t ler; - if (itf) { - for (int i = 0; i < count; i++) { - ethertype_t e = ethertype_t::from_numeric_val(payload.whitelist[i]); - if (n_input) { - ethertype_rule_t er(e, direction_t::INPUT); - ler.insert(er); - n_input--; - } else { - ethertype_rule_t er(e, direction_t::OUTPUT); - ler.insert(er); - } - } - if (!ler.empty()) { - acl_ethertype a_e(*itf, ler); - VOM_LOG(log_level_t::DEBUG) << "ethertype dump: " << a_e.to_string(); - OM::commit(key, a_e); - } - } else { - VOM_LOG(log_level_t::ERROR) << "no interface:" << payload.sw_if_index; - } - } -} - -dependency_t -acl_ethertype::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -acl_ethertype::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -}; -}; -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_ethertype.hpp b/extras/vom/vom/acl_ethertype.hpp deleted file mode 100644 index 98d3ce20707..00000000000 --- a/extras/vom/vom/acl_ethertype.hpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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_ACL_ETHERTYPE_H__ -#define __VOM_ACL_ETHERTYPE_H__ - -#include - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -namespace ACL { -/** - * An ACL ethertype list comprises a set of inbound ether types and out bound - * ether types - * to be applied to packets. - * A list is bound to a given interface. - */ - -struct ethertype_rule_t -{ -public: - /** - * Constructor - */ - ethertype_rule_t(const ethertype_t& eth, const direction_t& dir); - - /** - * Destructor - */ - ~ethertype_rule_t() = default; - - /** - * convert to string - */ - std::string to_string() const; - - /** - * comparision operator - */ - bool operator<(const ethertype_rule_t& other) const; - - /** - * comparision operator (for testing) - */ - bool operator==(const ethertype_rule_t& other) const; - - /** - * get the ether value - */ - uint16_t getEthertype(void) const; - - /** - * get the direction - */ - const direction_t& getDirection(void) const; - -private: - /** - * ethertype for this rule - */ - const ethertype_t m_eth; - - /** - * direction in which ethertype will be applied w.r.t. intf - */ - const direction_t m_dir; -}; - -class acl_ethertype : public object_base -{ -public: - /** - * The KEY can be used to uniquely identify the ACL ethertype. - * (other choices for keys, like the summation of the properties - * of the rules, are rather too cumbersome to use - */ - typedef std::string key_t; - - /** - * The ethertype container - */ - typedef std::multiset ethertype_rules_t; - - /** - * Construct a new object matching the desried state - */ - acl_ethertype(const interface& itf, const ethertype_rules_t& le); - - /** - * Copy Constructor - */ - acl_ethertype(const acl_ethertype& o); - - /** - * Destructor - */ - ~acl_ethertype(); - - /** - * Return the binding's key - */ - const key_t& key() const; - - /** - * comparision operator (for testing) - */ - bool operator==(const acl_ethertype& o) const; - - /** - * Return the 'singular' of the acl ethertype that matches this object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all acl ethertype into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Static function to find the acl_ethertype in the model - */ - static std::shared_ptr find(const key_t& key); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enque commands to the VPP command Q for the update - */ - void update(const acl_ethertype& obj); - - /** - * Find or add acl ethertype to the OM - */ - static std::shared_ptr find_or_add(const acl_ethertype& temp); - - /* - * It's the OM class that calls singular() - */ - friend class VOM::OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer to the interface on which acl ethertype - * resides. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * Inbound and outbound ethers list applied on given interface - */ - ethertype_rules_t m_le; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A map of all acl ethertype keyed against the interface. - */ - static singular_db m_db; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_ethertype_cmds.cpp b/extras/vom/vom/acl_ethertype_cmds.cpp deleted file mode 100644 index 0fa1d6db73e..00000000000 --- a/extras/vom/vom/acl_ethertype_cmds.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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/acl_ethertype_cmds.hpp" - -namespace VOM { -namespace ACL { -namespace acl_ethertype_cmds { - -bind_cmd::bind_cmd(HW::item& item, - const handle_t& itf, - const acl_ethertype::ethertype_rules_t& le) - : rpc_cmd(item) - , m_itf(itf) - , m_le(le) -{ -} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return (m_itf == other.m_itf && m_le == other.m_le); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), m_le.size(), std::ref(*this)); - uint32_t i = 0; - uint8_t n_input = 0; - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.count = m_le.size(); - - auto it = m_le.cbegin(); - while (it != m_le.cend()) { - payload.whitelist[i] = it->getEthertype(); - if (it->getDirection() == direction_t::INPUT) - n_input++; - ++it; - ++i; - } - - payload.n_input = n_input; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "ACL-Ethertype: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string() << " ethertype-rules:"; - auto it = m_le.cbegin(); - while (it != m_le.cend()) { - s << it->to_string(); - ++it; - } - - s << " rules-size:" << m_le.size(); - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{ -} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), 0, std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.count = 0; - - payload.n_input = 0; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "ACL-Ethertype-Unbind: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string(); - return (s.str()); -} - -dump_cmd::dump_cmd(const handle_t& hdl) - : m_itf(hdl) -{ -} - -dump_cmd::dump_cmd(const dump_cmd& d) - : m_itf(d.m_itf) -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("acl-ethertype-dump"); -} -}; // namespace acl_ethertype_cmds -}; // namespace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_ethertype_cmds.hpp b/extras/vom/vom/acl_ethertype_cmds.hpp deleted file mode 100644 index a294a758056..00000000000 --- a/extras/vom/vom/acl_ethertype_cmds.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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_ACL_ETHERTYPE_CMDS_H__ -#define __VOM_ACL_ETHERTYPE_CMDS_H__ - -#include "vom/acl_ethertype.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace ACL { -namespace acl_ethertype_cmds { -/** - * A command class that binds the ethertype list to the interface - */ -class bind_cmd - : public rpc_cmd, vapi::Acl_interface_set_etype_whitelist> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, - const handle_t& itf, - const acl_ethertype::ethertype_rules_t& le); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to bind - */ - const handle_t& m_itf; - - /** - * Ethertype list applied to interface - */ - const acl_ethertype::ethertype_rules_t& m_le; -}; - -/** - * A command class that unbinds the ethertype list to the interface - */ -class unbind_cmd - : public rpc_cmd, vapi::Acl_interface_set_etype_whitelist> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to bind - */ - const handle_t m_itf; -}; - -/** - * A cmd class that Dumps all the acl ethertypes on given interface - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(const handle_t& itf); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * The interface to get the addresses for - */ - const handle_t m_itf; -}; -}; -}; -}; -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_l2_list.cpp b/extras/vom/vom/acl_l2_list.cpp deleted file mode 100644 index 8684c2c4d3a..00000000000 --- a/extras/vom/vom/acl_l2_list.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - * 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/acl_l2_list.hpp" -#include "vom/acl_list_cmds.hpp" -#include "vom/api_types.hpp" -#include "vom/logger.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace ACL { - -/** - * Definition of the static singular_db for ACL Lists - */ -singular_db l2_list::m_db; - -/** - * Definition of the static per-handle DB for ACL Lists - */ -std::map> l2_list::m_hdl_db; - -l2_list::event_handler l2_list::m_evh; - -l2_list::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "l2-acl-list" }, "L2 ACL lists", this); -} - -l2_list::l2_list(const key_t& key) - : m_hdl(handle_t::INVALID) - , m_key(key) -{} - -l2_list::l2_list(const handle_t& hdl, const key_t& key) - : m_hdl(hdl) - , m_key(key) -{} - -l2_list::l2_list(const key_t& key, const rules_t& rules) - : m_hdl(handle_t::INVALID) - , m_key(key) - , m_rules(rules) -{} - -l2_list::l2_list(const l2_list& o) - : m_hdl(o.m_hdl) - , m_key(o.m_key) - , m_rules(o.m_rules) -{} - -l2_list::~l2_list() -{ - sweep(); - m_db.release(m_key, this); -} - -std::shared_ptr -l2_list::singular() const -{ - return find_or_add(*this); -} - -/** - * Dump all ACLs into the stream provided - */ -void -l2_list::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -/** - * convert to string format for debug purposes - */ -std::string -l2_list::to_string() const -{ - std::ostringstream s; - s << "acl-list:[" << m_key << " " << m_hdl.to_string() << " rules:["; - - for (auto rule : m_rules) { - s << rule.to_string() << " "; - } - - s << "]]"; - - return (s.str()); -} - -void -l2_list::insert(const l2_rule& rule) -{ - m_rules.insert(rule); -} - -void -l2_list::remove(const l2_rule& rule) -{ - m_rules.erase(rule); -} - -const handle_t& -l2_list::handle() const -{ - return (singular()->handle_i()); -} - -std::shared_ptr -l2_list::find(const handle_t& handle) -{ - return (m_hdl_db[handle].lock()); -} - -std::shared_ptr -l2_list::find(const key_t& key) -{ - return (m_db.find(key)); -} - -std::shared_ptr -l2_list::find_or_add(const l2_list& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -const handle_t& -l2_list::handle_i() const -{ - return (m_hdl.data()); -} - -void -l2_list::add(const key_t& key, const HW::item& item) -{ - std::shared_ptr sp = find(key); - - if (sp && item) { - m_hdl_db[item.data()] = sp; - } -} - -void -l2_list::remove(const HW::item& item) -{ - m_hdl_db.erase(item.data()); -} - -const l2_list::key_t& -l2_list::key() const -{ - return m_key; -} - -const l2_list::rules_t& -l2_list::rules() const -{ - return m_rules; -} - -bool -l2_list::operator==(const l2_list& l) const -{ - return (key() == l.key() && rules() == l.rules()); -} - -void -l2_list::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump L2 ACLs - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - const handle_t hdl(payload.acl_index); - l2_list acl(hdl, std::string(reinterpret_cast(payload.tag))); - - for (unsigned int ii = 0; ii < payload.count; ii++) { - const route::prefix_t pfx = from_api(payload.r[ii].src_prefix); - l2_rule rule(ii, - action_t::from_int(payload.r[ii].is_permit), - pfx, - { payload.r[ii].src_mac }, - { payload.r[ii].src_mac_mask }); - - acl.insert(rule); - } - VOM_LOG(log_level_t::DEBUG) << "dump: " << acl.to_string(); - - /* - * Write each of the discovered ACLs into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, acl); - } -} - -void -l2_list::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -dependency_t -l2_list::event_handler::order() const -{ - return (dependency_t::ACL); -} - -void -l2_list::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -l2_list::update(const l2_list& obj) -{ - /* - * always update the instance with the latest rule set - */ - if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) { - HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules)); - } - /* - * We don't, can't, read the priority from VPP, - * so the is equals check above does not include the priorty. - * but we save it now. - */ - m_rules = obj.m_rules; -} - -void -l2_list::sweep(void) -{ - if (m_hdl) { - HW::enqueue(new list_cmds::l2_delete_cmd(m_hdl)); - } - HW::write(); -} - -void -l2_list::replay(void) -{ - if (m_hdl) { - m_hdl.data().reset(); - HW::enqueue(new list_cmds::l2_update_cmd(m_hdl, m_key, m_rules)); - } -} - -}; // namespace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_l2_list.hpp b/extras/vom/vom/acl_l2_list.hpp deleted file mode 100644 index 82cfd072fe7..00000000000 --- a/extras/vom/vom/acl_l2_list.hpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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_ACL_L2_LIST_H__ -#define __VOM_ACL_L2_LIST_H__ - -#include - -#include "vom/acl_l2_rule.hpp" -#include "vom/acl_types.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -namespace ACL { -/** - * An L2 ACL list comprises a set of match actions rules to be applied to - * packets. - * A list is bound to a given interface. - */ -class l2_list : public object_base -{ -public: - /** - * The KEY can be used to uniquely identify the ACL. - * (other choices for keys, like the summation of the properties - * of the rules, are rather too cumbersome to use - */ - typedef std::string key_t; - - /** - * The rule container type - */ - typedef std::multiset rules_t; - - /** - * Construct a new object matching the desried state - */ - l2_list(const key_t& key); - - l2_list(const handle_t& hdl, const key_t& key); - - l2_list(const key_t& key, const rules_t& rules); - - /** - * Copy Constructor - */ - l2_list(const l2_list& o); - - /** - * Destructor - */ - ~l2_list(); - - /** - * Return the 'sigular instance' of the ACL that matches this object - */ - std::shared_ptr singular() const; - - /** - * Dump all ACLs into the stream provided - */ - static void dump(std::ostream& os); - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Insert priority sorted a rule into the list - */ - void insert(const l2_rule& rule); - - /** - * Remove a rule from the list - */ - void remove(const l2_rule& rule); - - /** - * Return the VPP assign handle - */ - const handle_t& handle() const; - - static std::shared_ptr find(const handle_t& handle); - - static std::shared_ptr find(const key_t& key); - static void add(const key_t& key, const HW::item& item); - - static void remove(const HW::item& item); - - const key_t& key() const; - - const rules_t& rules() const; - - /** - * Comparison operator - for UT - */ - bool operator==(const l2_list& l) const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enqueue commands to the VPP command Q for the update - */ - void update(const l2_list& obj); - - /** - * HW assigned handle - */ - HW::item m_hdl; - - /** - * Find or add the sigular instance in the DB - */ - static std::shared_ptr find_or_add(const l2_list& temp); - - /** - * return the acl-list's handle in the singular instance - */ - const handle_t& handle_i() const; - - /* - * It's the VOM::OM class that updates call update - */ - friend class VOM::OM; - - /** - * It's the VOM::singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * Replay the objects state to HW - */ - void replay(void); - - /** - * A map of all ACL's against the client's key - */ - static singular_db m_db; - - /** - * A map of all ACLs keyed against VPP's handle - */ - static std::map> m_hdl_db; - - /** - * The Key is a user defined identifer for this ACL - */ - const key_t m_key; - - /** - * A sorted list of the rules - */ - rules_t m_rules; -}; - -}; // namesace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_l2_rule.cpp b/extras/vom/vom/acl_l2_rule.cpp deleted file mode 100644 index 2b12e68c184..00000000000 --- a/extras/vom/vom/acl_l2_rule.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 - -#include "vom/acl_l2_rule.hpp" - -namespace VOM { -namespace ACL { - -l2_rule::l2_rule(uint32_t priority, - const action_t& action, - const route::prefix_t& ip, - const mac_address_t& mac, - const mac_address_t& mac_mask) - : m_priority(priority) - , m_action(action) - , m_src_ip(ip) - , m_mac(mac) - , m_mac_mask(mac_mask) -{ -} - -bool -l2_rule::operator<(const l2_rule& other) const -{ - return (other.m_priority < m_priority); -} - -bool -l2_rule::operator==(const l2_rule& rule) const -{ - return ((m_action == rule.m_action) && (m_src_ip == rule.m_src_ip) && - (m_mac == rule.m_mac) && (m_mac_mask == rule.m_mac_mask)); -} - -std::string -l2_rule::to_string() const -{ - std::ostringstream s; - - s << "L2-rule:[" - << "priority:" << m_priority << " action:" << m_action.to_string() - << " ip:" << m_src_ip.to_string() << " mac:" << m_mac - << " mac-mask:" << m_mac_mask << "]"; - - return (s.str()); -} - -uint32_t -l2_rule::priority() const -{ - return m_priority; -} - -const action_t& -l2_rule::action() const -{ - return m_action; -} - -const route::prefix_t& -l2_rule::src_ip() const -{ - return m_src_ip; -} - -const mac_address_t& -l2_rule::mac() const -{ - return m_mac; -} - -const mac_address_t& -l2_rule::mac_mask() const -{ - return m_mac_mask; -} -} -} -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_l2_rule.hpp b/extras/vom/vom/acl_l2_rule.hpp deleted file mode 100644 index 8c094aef5f4..00000000000 --- a/extras/vom/vom/acl_l2_rule.hpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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_L2_ACL_RULE_H__ -#define __VOM_L2_ACL_RULE_H__ - -#include "vom/acl_types.hpp" -#include "vom/prefix.hpp" - -namespace VOM { -namespace ACL { -/** - * An ACL rule is the building block of an ACL. An ACL, which is - * the object applied to an interface, is comprised of an ordersed - * sequence of ACL rules. - * This class is a wrapper around the VAPI generated struct and exports - * an API with better types. - */ -class l2_rule -{ -public: - /** - * Construct a new object matching the desried state - */ - l2_rule(uint32_t priority, - const action_t& action, - const route::prefix_t& ip, - const mac_address_t& mac, - const mac_address_t& mac_mask); - - /** - * Copy Constructor - */ - l2_rule(const l2_rule& o) = default; - - /** - * Destructor - */ - ~l2_rule() = default; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * less-than operator - */ - bool operator<(const l2_rule& rule) const; - - /** - * comparison operator (for testing) - */ - bool operator==(const l2_rule& rule) const; - - /** - * Getters - */ - uint32_t priority() const; - const action_t& action() const; - const route::prefix_t& src_ip() const; - const mac_address_t& mac() const; - const mac_address_t& mac_mask() const; - -private: - /** - * Priority. Used to sort the rules in a list in the order - * in which they are applied - */ - uint32_t m_priority; - - /** - * Action on match - */ - action_t m_action; - - /** - * Source Prefix - */ - route::prefix_t m_src_ip; - - /** - * Source Mac - */ - mac_address_t m_mac; - - /** - * Source MAC mask - */ - mac_address_t m_mac_mask; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_l3_list.cpp b/extras/vom/vom/acl_l3_list.cpp deleted file mode 100644 index cfa9cfee948..00000000000 --- a/extras/vom/vom/acl_l3_list.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * 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/acl_l3_list.hpp" -#include "vom/acl_list_cmds.hpp" -#include "vom/api_types.hpp" -#include "vom/logger.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace ACL { - -/** - * Definition of the static singular_db for ACL Lists - */ -singular_db l3_list::m_db; - -/** - * Definition of the static per-handle DB for ACL Lists - */ -std::map> l3_list::m_hdl_db; - -l3_list::event_handler l3_list::m_evh; - -l3_list::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "l3-acl-list" }, "L3 ACL lists", this); -} - -l3_list::l3_list(const key_t& key) - : m_hdl(handle_t::INVALID) - , m_key(key) -{} - -l3_list::l3_list(const handle_t& hdl, const key_t& key) - : m_hdl(hdl) - , m_key(key) -{} - -l3_list::l3_list(const key_t& key, const rules_t& rules) - : m_hdl(handle_t::INVALID) - , m_key(key) - , m_rules(rules) -{} - -l3_list::l3_list(const l3_list& o) - : m_hdl(o.m_hdl) - , m_key(o.m_key) - , m_rules(o.m_rules) -{} - -l3_list::~l3_list() -{ - sweep(); - m_db.release(m_key, this); -} - -std::shared_ptr -l3_list::singular() const -{ - return find_or_add(*this); -} - -/** - * Dump all ACLs into the stream provided - */ -void -l3_list::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -/** - * convert to string format for debug purposes - */ -std::string -l3_list::to_string() const -{ - std::ostringstream s; - s << "acl-list:[" << m_key << " " << m_hdl.to_string() << " rules:["; - - for (auto rule : m_rules) { - s << rule.to_string() << " "; - } - - s << "]]"; - - return (s.str()); -} - -void -l3_list::insert(const l3_rule& rule) -{ - m_rules.insert(rule); -} - -void -l3_list::remove(const l3_rule& rule) -{ - m_rules.erase(rule); -} - -const handle_t& -l3_list::handle() const -{ - return (singular()->handle_i()); -} - -std::shared_ptr -l3_list::find(const handle_t& handle) -{ - return (m_hdl_db[handle].lock()); -} - -std::shared_ptr -l3_list::find(const key_t& key) -{ - return (m_db.find(key)); -} - -std::shared_ptr -l3_list::find_or_add(const l3_list& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -const handle_t& -l3_list::handle_i() const -{ - return (m_hdl.data()); -} - -void -l3_list::add(const key_t& key, const HW::item& item) -{ - std::shared_ptr sp = find(key); - - if (sp && item) { - m_hdl_db[item.data()] = sp; - } -} - -void -l3_list::remove(const HW::item& item) -{ - m_hdl_db.erase(item.data()); -} - -const l3_list::key_t& -l3_list::key() const -{ - return m_key; -} - -const l3_list::rules_t& -l3_list::rules() const -{ - return m_rules; -} - -bool -l3_list::operator==(const l3_list& l) const -{ - return (key() == l.key() && rules() == l.rules()); -} - -void -l3_list::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump L3 ACLs Bridge domains - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - const handle_t hdl(payload.acl_index); - l3_list acl(hdl, std::string(reinterpret_cast(payload.tag))); - - for (unsigned int ii = 0; ii < payload.count; ii++) { - const route::prefix_t src = from_api(payload.r[ii].src_prefix); - const route::prefix_t dst = from_api(payload.r[ii].dst_prefix); - l3_rule rule(ii, action_t::from_int(payload.r[ii].is_permit), src, dst); - - rule.set_proto(payload.r[ii].proto); - rule.set_src_from_port(payload.r[ii].srcport_or_icmptype_first); - rule.set_src_to_port(payload.r[ii].srcport_or_icmptype_last); - rule.set_dst_from_port(payload.r[ii].dstport_or_icmpcode_first); - rule.set_dst_to_port(payload.r[ii].dstport_or_icmpcode_last); - rule.set_tcp_flags_mask(payload.r[ii].tcp_flags_mask); - rule.set_tcp_flags_value(payload.r[ii].tcp_flags_value); - - acl.insert(rule); - } - VOM_LOG(log_level_t::DEBUG) << "dump: " << acl.to_string(); - - /* - * Write each of the discovered ACLs into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, acl); - } -} - -void -l3_list::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -dependency_t -l3_list::event_handler::order() const -{ - return (dependency_t::ACL); -} - -void -l3_list::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -l3_list::update(const l3_list& obj) -{ - /* - * always update the instance with the latest rule set - */ - if (rc_t::OK != m_hdl.rc() || obj.m_rules != m_rules) { - HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules)); - } - /* - * We don't, can't, read the priority from VPP, - * so the is equals check above does not include the priorty. - * but we save it now. - */ - m_rules = obj.m_rules; -} - -/** - * Sweep/reap the object if still stale - */ -void -l3_list::sweep(void) -{ - if (m_hdl) { - HW::enqueue(new list_cmds::l3_delete_cmd(m_hdl)); - } - HW::write(); -} - -/** - * Replay the objects state to HW - */ -void -l3_list::replay(void) -{ - if (m_hdl) { - m_hdl.data().reset(); - HW::enqueue(new list_cmds::l3_update_cmd(m_hdl, m_key, m_rules)); - } -} - -}; // namespace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_l3_list.hpp b/extras/vom/vom/acl_l3_list.hpp deleted file mode 100644 index 092bbe37dc0..00000000000 --- a/extras/vom/vom/acl_l3_list.hpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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_ACL_L3_LIST_H__ -#define __VOM_ACL_L3_LIST_H__ - -#include - -#include "vom/acl_l3_rule.hpp" -#include "vom/acl_types.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -namespace ACL { -/** - * An L3 ACL list comprises a set of match actions rules to be applied to - * packets. - * A list is bound to a given interface. - */ -class l3_list : public object_base -{ -public: - /** - * The KEY can be used to uniquely identify the ACL. - * (other choices for keys, like the summation of the properties - * of the rules, are rather too cumbersome to use - */ - typedef std::string key_t; - - /** - * The rule container type - */ - typedef std::multiset rules_t; - - /** - * Construct a new object matching the desried state - */ - l3_list(const key_t& key); - - l3_list(const handle_t& hdl, const key_t& key); - - l3_list(const key_t& key, const rules_t& rules); - - /** - * Copy Constructor - */ - l3_list(const l3_list& o); - - /** - * Destructor - */ - ~l3_list(); - - /** - * Return the 'sigular instance' of the ACL that matches this object - */ - std::shared_ptr singular() const; - - /** - * Dump all ACLs into the stream provided - */ - static void dump(std::ostream& os); - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Insert priority sorted a rule into the list - */ - void insert(const l3_rule& rule); - - /** - * Remove a rule from the list - */ - void remove(const l3_rule& rule); - - /** - * Return the VPP assign handle - */ - const handle_t& handle() const; - - static std::shared_ptr find(const handle_t& handle); - - static std::shared_ptr find(const key_t& key); - static void add(const key_t& key, const HW::item& item); - - static void remove(const HW::item& item); - - const key_t& key() const; - - const rules_t& rules() const; - - /** - * Comparison operator - for UT - */ - bool operator==(const l3_list& l) const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enqueue commands to the VPP command Q for the update - */ - void update(const l3_list& obj); - - /** - * HW assigned handle - */ - HW::item m_hdl; - - /** - * Find or add the sigular instance in the DB - */ - static std::shared_ptr find_or_add(const l3_list& temp); - - /** - * return the acl-list's handle in the singular instance - */ - const handle_t& handle_i() const; - - /* - * It's the VOM::OM class that updates call update - */ - friend class VOM::OM; - - /** - * It's the VOM::singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * Replay the objects state to HW - */ - void replay(void); - - /** - * A map of all ACL's against the client's key - */ - static singular_db m_db; - - /** - * A map of all ACLs keyed against VPP's handle - */ - static std::map> m_hdl_db; - - /** - * The Key is a user defined identifer for this ACL - */ - const key_t m_key; - - /** - * A sorted list of the rules - */ - rules_t m_rules; -}; - -}; // namesace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_l3_rule.cpp b/extras/vom/vom/acl_l3_rule.cpp deleted file mode 100644 index 417dc5f2eb7..00000000000 --- a/extras/vom/vom/acl_l3_rule.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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 - -#include "vom/acl_l3_rule.hpp" - -namespace VOM { -namespace ACL { -l3_rule::l3_rule(uint32_t priority, - const action_t& action, - const route::prefix_t& src, - const route::prefix_t& dst, - uint8_t proto, - uint16_t srcport_or_icmptype_first, - uint16_t srcport_or_icmptype_last, - uint16_t dstport_or_icmpcode_first, - uint16_t dstport_or_icmpcode_last, - uint8_t tcp_flags_mask, - uint8_t tcp_flags_value) - : m_priority(priority) - , m_action(action) - , m_src(src) - , m_dst(dst) - , m_proto(proto) - , m_srcport_or_icmptype_first(srcport_or_icmptype_first) - , m_srcport_or_icmptype_last(srcport_or_icmptype_last) - , m_dstport_or_icmpcode_first(dstport_or_icmpcode_first) - , m_dstport_or_icmpcode_last(dstport_or_icmpcode_last) - , m_tcp_flags_mask(tcp_flags_mask) - , m_tcp_flags_value(tcp_flags_value) -{ -} - -bool -l3_rule::operator<(const l3_rule& other) const -{ - return (other.m_priority < m_priority); -} - -bool -l3_rule::operator==(const l3_rule& rule) const -{ - return ((m_action == rule.m_action) && (m_src == rule.m_src) && - (m_dst == rule.m_dst) && (m_proto == rule.m_proto) && - (m_srcport_or_icmptype_first == rule.m_srcport_or_icmptype_first) && - (m_srcport_or_icmptype_last == rule.m_srcport_or_icmptype_last) && - (m_dstport_or_icmpcode_first == rule.m_dstport_or_icmpcode_first) && - (m_dstport_or_icmpcode_last == rule.m_dstport_or_icmpcode_last) && - (m_tcp_flags_mask == rule.m_tcp_flags_mask) && - (m_tcp_flags_value == rule.m_tcp_flags_value)); -} - -std::string -l3_rule::to_string() const -{ - std::ostringstream s; - - s << "L3-rule:[" - << "priority:" << m_priority << " action:" << m_action.to_string() - << " src:" << m_src.to_string() << " dst:" << m_dst.to_string() - << " proto:" << std::to_string(m_proto) - << " srcportfrom:" << m_srcport_or_icmptype_first - << " srcportto: " << m_srcport_or_icmptype_last - << " dstportfrom:" << m_dstport_or_icmpcode_first - << " dstportto:" << m_dstport_or_icmpcode_last - << " tcpflagmask:" << std::to_string(m_tcp_flags_mask) - << " tcpflagvalue:" << std::to_string(m_tcp_flags_value) << "]"; - - return (s.str()); -} - -void -l3_rule::set_src_ip(route::prefix_t src) -{ - m_src = src; -} - -void -l3_rule::set_dst_ip(route::prefix_t dst) -{ - m_dst = dst; -} - -void -l3_rule::set_proto(uint8_t proto) -{ - m_proto = proto; -} -void -l3_rule::set_src_from_port(uint16_t srcport_or_icmptype_first) -{ - m_srcport_or_icmptype_first = srcport_or_icmptype_first; -} - -void -l3_rule::set_src_to_port(uint16_t srcport_or_icmptype_last) -{ - m_srcport_or_icmptype_last = srcport_or_icmptype_last; -} - -void -l3_rule::set_dst_from_port(uint16_t dstport_or_icmpcode_first) -{ - m_dstport_or_icmpcode_first = dstport_or_icmpcode_first; -} - -void -l3_rule::set_dst_to_port(uint16_t dstport_or_icmpcode_last) -{ - m_dstport_or_icmpcode_last = dstport_or_icmpcode_last; -} - -void -l3_rule::set_tcp_flags_mask(uint8_t tcp_flags_mask) -{ - m_tcp_flags_mask = tcp_flags_mask; -} - -void -l3_rule::set_tcp_flags_value(uint8_t tcp_flags_value) -{ - m_tcp_flags_value = tcp_flags_value; -} - -const route::prefix_t& -l3_rule::src() const -{ - return m_src; -} - -uint32_t -l3_rule::priority() const -{ - return m_priority; -} - -const action_t& -l3_rule::action() const -{ - return m_action; -} - -const route::prefix_t& -l3_rule::dst() const -{ - return m_dst; -} - -uint8_t -l3_rule::proto() const -{ - return m_proto; -} - -uint16_t -l3_rule::srcport_or_icmptype_first() const -{ - return m_srcport_or_icmptype_first; -} - -uint16_t -l3_rule::srcport_or_icmptype_last() const -{ - return m_srcport_or_icmptype_last; -} - -uint16_t -l3_rule::dstport_or_icmpcode_first() const -{ - return m_dstport_or_icmpcode_first; -} - -uint16_t -l3_rule::dstport_or_icmpcode_last() const -{ - return m_dstport_or_icmpcode_last; -} - -uint8_t -l3_rule::tcp_flags_mask() const -{ - return m_tcp_flags_mask; -} - -uint8_t -l3_rule::tcp_flags_value() const -{ - return m_tcp_flags_value; -} - -}; // namespace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_l3_rule.hpp b/extras/vom/vom/acl_l3_rule.hpp deleted file mode 100644 index c1f1ceea5a1..00000000000 --- a/extras/vom/vom/acl_l3_rule.hpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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_L3_ACL_RULE_H__ -#define __VOM_L3_ACL_RULE_H__ - -#include "vom/acl_types.hpp" -#include "vom/prefix.hpp" - -namespace VOM { -namespace ACL { -/** - * An ACL rule is the building block of an ACL. An ACL, which is - * the object applied to an interface, is comprised of an ordersed - * sequence of ACL rules. - * This class is a wrapper around the VAPI generated struct and exports - * an API with better types. - */ -class l3_rule -{ -public: - /** - * Construct a new object matching the desried state - */ - l3_rule(uint32_t priority, - const action_t& action, - const route::prefix_t& src, - const route::prefix_t& dst, - uint8_t proto = 0, - uint16_t srcport_or_icmptype_first = 0, - uint16_t srcport_or_icmptype_last = 0, - uint16_t dstport_or_icmpcode_first = 0, - uint16_t dstport_or_icmpcode_last = 0, - uint8_t tcp_flags_mask = 0, - uint8_t tcp_flags_value = 0); - - /** - * Copy Constructor - */ - l3_rule(const l3_rule& o) = default; - - /** - * Destructor - */ - ~l3_rule() = default; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * less-than operator - */ - bool operator<(const l3_rule& rule) const; - - /** - * comparison operator (for testing) - */ - bool operator==(const l3_rule& rule) const; - - /** - * Set Src Ip Address - */ - void set_src_ip(route::prefix_t src); - - /** - * Set Dst Ip Address - */ - void set_dst_ip(route::prefix_t dst); - - /** - *Set proto - */ - void set_proto(uint8_t proto); - - /** - * Set Src port or ICMP Type first - */ - void set_src_from_port(uint16_t srcport_or_icmptype_first); - - /** - * Set Src port or ICMP Type last - */ - void set_src_to_port(uint16_t srcport_or_icmptype_last); - - /** - * Set Dst port or ICMP code first - */ - void set_dst_from_port(uint16_t dstport_or_icmpcode_first); - - /** - * Set Dst port or ICMP code last - */ - void set_dst_to_port(uint16_t dstport_or_icmpcode_last); - - /** - * Set TCP flags mask - */ - void set_tcp_flags_mask(uint8_t tcp_flags_mask); - - /** - * Set TCP flags value - */ - void set_tcp_flags_value(uint8_t tcp_flags_value); - - /** - * Getters - */ - const route::prefix_t& src() const; - uint32_t priority() const; - const action_t& action() const; - const route::prefix_t& dst() const; - uint8_t proto() const; - uint16_t srcport_or_icmptype_first() const; - uint16_t srcport_or_icmptype_last() const; - uint16_t dstport_or_icmpcode_first() const; - uint16_t dstport_or_icmpcode_last() const; - uint8_t tcp_flags_mask() const; - uint8_t tcp_flags_value() const; - -private: - /** - * Priority. Used to sort the rules in a list in the order - * in which they are applied - */ - uint32_t m_priority; - - /** - * Action on match - */ - action_t m_action; - - /** - * Source Prefix - */ - route::prefix_t m_src; - - /** - * Destination Prefix - */ - route::prefix_t m_dst; - - /** - * L4 protocol. IANA number. 1 = ICMP, 58 = ICMPv6, 6 = TCP, 17 = - * UDP. - * 0 => ignore L4 and ignore the ports/tcpflags when matching. - */ - uint8_t m_proto; - - /** - * If the L4 protocol is TCP or UDP, the below - * hold ranges of ports, else if the L4 is ICMP/ICMPv6 - * they hold ranges of ICMP(v6) types/codes. - * - * Ranges are inclusive, i.e. to match "any" TCP/UDP port, - * use first=0,last=65535. For ICMP(v6), - * use first=0,last=255. - */ - uint16_t m_srcport_or_icmptype_first; - uint16_t m_srcport_or_icmptype_last; - uint16_t m_dstport_or_icmpcode_first; - uint16_t m_dstport_or_icmpcode_last; - - /* - * for proto = 6, this matches if the - * TCP flags in the packet, ANDed with tcp_flags_mask, - * is equal to tcp_flags_value. - */ - uint8_t m_tcp_flags_mask; - uint8_t m_tcp_flags_value; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_list_cmds.cpp b/extras/vom/vom/acl_list_cmds.cpp deleted file mode 100644 index a589e1f2542..00000000000 --- a/extras/vom/vom/acl_list_cmds.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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/acl_list_cmds.hpp" -#include "vom/api_types.hpp" - -namespace VOM { -namespace ACL { -namespace list_cmds { -/* - * Jumping through hoops to not expose the VAPI types publically - */ -static void -to_vpp(const l2_rule& rule, vapi_type_macip_acl_rule& payload) -{ - payload.is_permit = (vapi_enum_acl_action)rule.action().value(); - rule.src_ip().to_vpp((uint8_t*)&payload.src_prefix.address.af, - (uint8_t*)&payload.src_prefix.address.un, - &payload.src_prefix.len); - rule.mac().to_bytes(payload.src_mac, 6); - rule.mac_mask().to_bytes(payload.src_mac_mask, 6); -} - -static void -to_vpp(const l3_rule& rule, vapi_type_acl_rule& payload) -{ - payload.is_permit = (vapi_enum_acl_action)rule.action().value(); - payload.src_prefix = to_api(rule.src()); - payload.dst_prefix = to_api(rule.dst()); - - payload.proto = (vapi_enum_ip_proto)rule.proto(); - payload.srcport_or_icmptype_first = rule.srcport_or_icmptype_first(); - payload.srcport_or_icmptype_last = rule.srcport_or_icmptype_last(); - payload.dstport_or_icmpcode_first = rule.dstport_or_icmpcode_first(); - payload.dstport_or_icmpcode_last = rule.dstport_or_icmpcode_last(); - - payload.tcp_flags_mask = rule.tcp_flags_mask(); - payload.tcp_flags_value = rule.tcp_flags_value(); -} - -template<> -rc_t -l3_update_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), m_rules.size(), std::ref(*this)); - uint32_t ii = 0; - - auto& payload = req.get_request().get_payload(); - payload.acl_index = m_hw_item.data().value(); - payload.count = m_rules.size(); - memset(payload.tag, 0, sizeof(payload.tag)); - memcpy( - payload.tag, m_key.c_str(), std::min(m_key.length(), sizeof(payload.tag))); - - auto it = m_rules.cbegin(); - - while (it != m_rules.cend()) { - to_vpp(*it, payload.r[ii]); - ++it; - ++ii; - } - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) - insert_acl(); - - return rc_t::OK; -} - -template<> -rc_t -l3_delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.acl_index = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_acl(); - - return rc_t::OK; -} - -template<> -rc_t -l3_dump_cmd::issue(connection& con) -{ - m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); - - auto& payload = m_dump->get_request().get_payload(); - payload.acl_index = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -template<> -rc_t -l2_update_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), m_rules.size(), std::ref(*this)); - uint32_t ii = 0; - - auto& payload = req.get_request().get_payload(); - // payload.acl_index = m_hw_item.data().value(); - payload.count = m_rules.size(); - memset(payload.tag, 0, sizeof(payload.tag)); - memcpy( - payload.tag, m_key.c_str(), std::min(m_key.length(), sizeof(payload.tag))); - - auto it = m_rules.cbegin(); - - while (it != m_rules.cend()) { - to_vpp(*it, payload.r[ii]); - ++it; - ++ii; - } - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) - insert_acl(); - - return rc_t::OK; -} - -template<> -rc_t -l2_delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.acl_index = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_acl(); - - return rc_t::OK; -} - -template<> -rc_t -l2_dump_cmd::issue(connection& con) -{ - m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); - - auto& payload = m_dump->get_request().get_payload(); - payload.acl_index = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -}; // namespace list_cmds -}; // namespace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_list_cmds.hpp b/extras/vom/vom/acl_list_cmds.hpp deleted file mode 100644 index 252dec7175d..00000000000 --- a/extras/vom/vom/acl_list_cmds.hpp +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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_ACL_LIST_CMDS_H__ -#define __VOM_ACL_LIST_CMDS_H__ - -#include "vom/acl_l2_list.hpp" -#include "vom/acl_l3_list.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace ACL { -namespace list_cmds { -/** - * A command class that Create the list - */ -template -class update_cmd : public rpc_cmd, UPDATE> -{ -public: - typedef typename LIST::rules_t cmd_rules_t; - typedef typename LIST::key_t cmd_key_t; - - /** - * Constructor - */ - update_cmd(HW::item& item, - const cmd_key_t& key, - const cmd_rules_t& rules) - : rpc_cmd, UPDATE>(item) - , m_key(key) - , m_rules(rules) - { - } - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - - /** - * convert to string format for debug purposes - */ - std::string to_string() const - { - std::ostringstream s; - s << "ACL-list-update:[ " << this->item().to_string() << " rule-list:["; - for (auto rule : m_rules) { - s << " " << rule.to_string(); - } - s << "]]"; - - return (s.str()); - } - - /** - * Comparison operator - only used for UT - */ - bool operator==(const update_cmd& other) const - { - return ((m_key == other.m_key) && (m_rules == other.m_rules)); - } - - void succeeded() - { - rpc_cmd, UPDATE>::succeeded(); - LIST::add(m_key, this->item()); - } - - /** - * A callback function for handling ACL creates - */ - virtual vapi_error_e operator()(UPDATE& reply) - { - int acl_index = reply.get_response().get_payload().acl_index; - int retval = reply.get_response().get_payload().retval; - - VOM_LOG(log_level_t::DEBUG) << this->to_string() << " retval:" << retval - << " acl_index:" << acl_index; - - rc_t rc = rc_t::from_vpp_retval(retval); - handle_t handle(acl_index); - - HW::item res(handle, rc); - - this->fulfill(res); - - return (VAPI_OK); - } - -private: - /** - * add the created acl to the DB - */ - void insert_acl() { LIST::add(m_key, this->item()); } - - /** - * The key. - */ - const cmd_key_t& m_key; - - /** - * The rules - */ - const cmd_rules_t& m_rules; -}; - -/** - * A cmd class that Deletes an ACL - */ -template -class delete_cmd : public rpc_cmd, DELETE> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item) - : rpc_cmd, DELETE>(item) - { - } - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con) { return (rc_t::INVALID); } - - /** - * convert to string format for debug purposes - */ - std::string to_string() const - { - std::ostringstream s; - s << "ACL-list-delete: " << this->item().to_string(); - - return (s.str()); - } - - /** - * Comparison operator - only used for UT - */ - bool operator==(const delete_cmd& other) const - { - return (this->item().data() == other.item().data()); - } - -private: - /** - * remove the acl from the DB - */ - void remove_acl() { LIST::remove(this->item()); } -}; - -/** - * A cmd class that Dumps all the ACLs - */ -template -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * 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 { return ("acl-list-dump"); } - - /** - * Comparison operator - only used for UT - */ - bool operator==(const dump_cmd& i) const { return true; } -}; - -/** - * Typedef the L3 ACL commands - */ -typedef update_cmd l3_update_cmd; -typedef delete_cmd l3_delete_cmd; -typedef dump_cmd l3_dump_cmd; - -/** - * Typedef the L2 ACL commands - */ -typedef update_cmd l2_update_cmd; -typedef delete_cmd l2_delete_cmd; -typedef dump_cmd l2_dump_cmd; - -}; // namespace list_cmds -}; // namespace ACL -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/acl_types.cpp b/extras/vom/vom/acl_types.cpp deleted file mode 100644 index b2c0c7f0b9d..00000000000 --- a/extras/vom/vom/acl_types.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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/acl_types.hpp" - -namespace VOM { -namespace ACL { -const action_t action_t::PERMITANDREFLEX(2, "permitandreflex"); -const action_t action_t::PERMIT(1, "permit"); -const action_t action_t::DENY(0, "deny"); - -action_t::action_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -const action_t& -action_t::from_int(uint8_t i) -{ - if (i == 2) - return action_t::PERMITANDREFLEX; - else if (i) - return action_t::PERMIT; - - return action_t::DENY; -} - -const action_t& -action_t::from_bool(bool b, uint8_t c) -{ - if (b) { - if (c) - return action_t::PERMITANDREFLEX; - return action_t::PERMIT; - } - return action_t::DENY; -} -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/acl_types.hpp b/extras/vom/vom/acl_types.hpp deleted file mode 100644 index cf5bee3e478..00000000000 --- a/extras/vom/vom/acl_types.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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_ACL_TYPES_H__ -#define __VOM_ACL_TYPES_H__ - -#include "vom/types.hpp" - -namespace VOM { -namespace ACL { -/** - * ACL Actions - */ -struct action_t : public enum_base -{ - /** - * Permit and Reflexive - */ - const static action_t PERMITANDREFLEX; - - /** - * Permit Action - */ - const static action_t PERMIT; - - /** - * Deny Action - */ - const static action_t DENY; - - /** - * Get the enum type from a VPP integer value - */ - static const action_t& from_int(uint8_t i); - - /** - *Get the enum type from a bool value and optional uint8_t value - *which implements the connection tracking .... - */ - static const action_t& from_bool(bool b, uint8_t c); - -private: - action_t(int v, const std::string s); -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/api_types.cpp b/extras/vom/vom/api_types.cpp deleted file mode 100644 index 5eea7654eee..00000000000 --- a/extras/vom/vom/api_types.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* - * 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 - -namespace VOM { - -vapi_enum_ip_neighbor_flags -to_api(const neighbour::flags_t& f) -{ - vapi_enum_ip_neighbor_flags out = IP_API_NEIGHBOR_FLAG_NONE; - - if (f & neighbour::flags_t::STATIC) - out = static_cast(out | - IP_API_NEIGHBOR_FLAG_STATIC); - if (f & neighbour::flags_t::NO_FIB_ENTRY) - out = static_cast( - out | IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY); - - return (out); -} - -const neighbour::flags_t -from_api(vapi_enum_ip_neighbor_flags f) -{ - neighbour::flags_t out = neighbour::flags_t::NONE; - - if (f & IP_API_NEIGHBOR_FLAG_STATIC) - out |= neighbour::flags_t::STATIC; - if (f & IP_API_NEIGHBOR_FLAG_NO_FIB_ENTRY) - out |= neighbour::flags_t::NO_FIB_ENTRY; - - return out; -} - -invalid_decode::invalid_decode(const std::string reason) - : reason(reason) -{} - -void -to_api(const boost::asio::ip::address_v4& a, vapi_type_ip4_address& v) -{ - std::copy_n(std::begin(a.to_bytes()), a.to_bytes().size(), v); -} -void -to_api(const boost::asio::ip::address_v6& a, vapi_type_ip6_address& v) -{ - std::copy_n(std::begin(a.to_bytes()), a.to_bytes().size(), v); -} - -void -to_api(const ip_address_t& a, vapi_type_address& v) -{ - if (a.is_v4()) { - v.af = ADDRESS_IP4; - memcpy(v.un.ip4, a.to_v4().to_bytes().data(), 4); - } else { - v.af = ADDRESS_IP6; - memcpy(v.un.ip6, a.to_v6().to_bytes().data(), 16); - } -} - -void -to_api(const ip_address_t& a, - vapi_union_address_union& u, - vapi_enum_address_family& af) -{ - if (a.is_v4()) { - af = ADDRESS_IP4; - memcpy(u.ip4, a.to_v4().to_bytes().data(), 4); - } else { - af = ADDRESS_IP6; - memcpy(u.ip6, a.to_v6().to_bytes().data(), 16); - } -} - -void -to_api(const ip_address_t& a, vapi_union_address_union& u) -{ - if (a.is_v4()) { - memcpy(u.ip4, a.to_v4().to_bytes().data(), 4); - } else { - memcpy(u.ip6, a.to_v6().to_bytes().data(), 16); - } -} - -boost::asio::ip::address_v6 -from_api(const vapi_type_ip6_address& v) -{ - std::array a; - std::copy(v, v + 16, std::begin(a)); - boost::asio::ip::address_v6 v6(a); - - return v6; -} - -boost::asio::ip::address_v4 -from_api(const vapi_type_ip4_address& v) -{ - std::array a; - std::copy(v, v + 4, std::begin(a)); - boost::asio::ip::address_v4 v4(a); - - return v4; -} - -ip_address_t -from_api(const vapi_type_address& v) -{ - boost::asio::ip::address addr; - - if (ADDRESS_IP6 == v.af) { - std::array a; - std::copy(v.un.ip6, v.un.ip6 + 16, std::begin(a)); - boost::asio::ip::address_v6 v6(a); - addr = v6; - } else { - std::array a; - std::copy(v.un.ip6, v.un.ip6 + 4, std::begin(a)); - boost::asio::ip::address_v4 v4(a); - addr = v4; - } - - return addr; -} - -ip_address_t -from_api(const vapi_union_address_union& u, vapi_enum_fib_path_nh_proto proto) -{ - boost::asio::ip::address addr; - - if (FIB_API_PATH_NH_PROTO_IP6 == proto) { - std::array a; - std::copy(u.ip6, u.ip6 + 16, std::begin(a)); - boost::asio::ip::address_v6 v6(a); - addr = v6; - } else if (FIB_API_PATH_NH_PROTO_IP4 == proto) { - std::array a; - std::copy(u.ip6, u.ip6 + 4, std::begin(a)); - boost::asio::ip::address_v4 v4(a); - addr = v4; - } - - return addr; -} - -ip_address_t -from_api(const vapi_union_address_union& u, vapi_enum_address_family af) -{ - boost::asio::ip::address addr; - - if (ADDRESS_IP6 == af) { - std::array a; - std::copy(u.ip6, u.ip6 + 16, std::begin(a)); - boost::asio::ip::address_v6 v6(a); - addr = v6; - } else { - std::array a; - std::copy(u.ip6, u.ip6 + 4, std::begin(a)); - boost::asio::ip::address_v4 v4(a); - addr = v4; - } - - return addr; -} - -void -to_api(const mac_address_t& a, vapi_type_mac_address& v) -{ - std::copy(std::begin(a.bytes), std::end(a.bytes), v); -} - -mac_address_t -from_api(const vapi_type_mac_address& v) -{ - return mac_address_t(v); -} - -route::prefix_t -from_api(const vapi_type_prefix& v) -{ - return route::prefix_t(from_api(v.address), v.len); -} - -vapi_type_prefix -to_api(const route::prefix_t& p) -{ - vapi_type_prefix v; - to_api(p.address(), v.address); - v.len = p.mask_width(); - return v; -} - -route::mprefix_t -from_api(const vapi_type_mprefix& v) -{ - return route::mprefix_t(from_api(v.src_address, v.af), - from_api(v.grp_address, v.af), - v.grp_address_length); -} - -vapi_type_mprefix -to_api(const route::mprefix_t& p) -{ - vapi_enum_address_family af; - vapi_type_mprefix v; - to_api(p.grp_address(), v.grp_address, af); - to_api(p.src_address(), v.src_address, af); - v.grp_address_length = p.mask_width(); - v.af = af; - return v; -} - -vapi_enum_fib_path_nh_proto -to_api(const nh_proto_t& p) -{ - if (p == nh_proto_t::IPV4) { - return FIB_API_PATH_NH_PROTO_IP4; - } else if (p == nh_proto_t::IPV6) { - return FIB_API_PATH_NH_PROTO_IP6; - } else if (p == nh_proto_t::ETHERNET) { - return FIB_API_PATH_NH_PROTO_ETHERNET; - } else if (p == nh_proto_t::MPLS) { - return FIB_API_PATH_NH_PROTO_MPLS; - } - - return FIB_API_PATH_NH_PROTO_IP4; -} - -vapi_enum_address_family -to_api(const l3_proto_t p) -{ - if (p == l3_proto_t::IPV6) { - return ADDRESS_IP6; - } - return ADDRESS_IP4; -} - -const nh_proto_t& -from_api(vapi_enum_fib_path_nh_proto p) -{ - switch (p) { - case FIB_API_PATH_NH_PROTO_IP4: - return nh_proto_t::IPV4; - case FIB_API_PATH_NH_PROTO_IP6: - return nh_proto_t::IPV6; - case FIB_API_PATH_NH_PROTO_ETHERNET: - return nh_proto_t::ETHERNET; - case FIB_API_PATH_NH_PROTO_MPLS: - return nh_proto_t::MPLS; - case FIB_API_PATH_NH_PROTO_BIER: - break; - } - - return nh_proto_t::IPV4; -} - -}; // VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/api_types.hpp b/extras/vom/vom/api_types.hpp deleted file mode 100644 index 8d898f4c880..00000000000 --- a/extras/vom/vom/api_types.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include -#include - -namespace VOM { - -struct invalid_decode -{ - invalid_decode(const std::string reason); - const std::string reason; -}; - -typedef boost::asio::ip::address ip_address_t; - -vapi_enum_ip_neighbor_flags to_api(const neighbour::flags_t& f); -const neighbour::flags_t from_api(vapi_enum_ip_neighbor_flags f); - -void to_api(const ip_address_t& a, vapi_type_address& v); -void to_api(const boost::asio::ip::address_v4& a, vapi_type_ip4_address& v); -void to_api(const boost::asio::ip::address_v6& a, vapi_type_ip6_address& v); -void to_api(const boost::asio::ip::address& a, - vapi_union_address_union& u, - vapi_enum_address_family& af); -void to_api(const boost::asio::ip::address& a, vapi_union_address_union& u); -vapi_enum_address_family to_api(const l3_proto_t p); - -boost::asio::ip::address_v4 from_api(const vapi_type_ip4_address& v); -boost::asio::ip::address_v6 from_api(const vapi_type_ip6_address& v); -ip_address_t from_api(const vapi_type_address& v); -ip_address_t from_api(const vapi_union_address_union& u, - vapi_enum_address_family af); -ip_address_t from_api(const vapi_union_address_union& u, - vapi_enum_fib_path_nh_proto proto); - -void to_api(const mac_address_t& a, vapi_type_mac_address& m); - -mac_address_t from_api(const vapi_type_mac_address& v); - -route::prefix_t from_api(const vapi_type_prefix&); -route::mprefix_t from_api(const vapi_type_mprefix&); - -vapi_type_prefix to_api(const route::prefix_t&); -vapi_type_mprefix to_api(const route::mprefix_t&); - -vapi_enum_fib_path_nh_proto to_api(const nh_proto_t&); -const nh_proto_t& from_api(vapi_enum_fib_path_nh_proto); - -}; // VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/arp_proxy_binding.cpp b/extras/vom/vom/arp_proxy_binding.cpp deleted file mode 100644 index bbae9f683eb..00000000000 --- a/extras/vom/vom/arp_proxy_binding.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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/arp_proxy_binding.hpp" -#include "vom/arp_proxy_binding_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -/** - * A DB of all ARP proxy bindings configs - */ -singular_db arp_proxy_binding::m_db; - -arp_proxy_binding::event_handler arp_proxy_binding::m_evh; - -arp_proxy_binding::arp_proxy_binding(const interface& itf) - : m_itf(itf.singular()) - , m_binding(true) -{ -} - -arp_proxy_binding::arp_proxy_binding(const arp_proxy_binding& o) - : m_itf(o.m_itf) - , m_binding(o.m_binding) -{ -} - -arp_proxy_binding::~arp_proxy_binding() -{ - sweep(); - m_db.release(m_itf->key(), this); -} - -void -arp_proxy_binding::sweep() -{ - if (m_binding) { - HW::enqueue( - new arp_proxy_binding_cmds::unbind_cmd(m_binding, m_itf->handle())); - } - HW::write(); -} - -void -arp_proxy_binding::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -arp_proxy_binding::replay() -{ - if (m_binding) { - HW::enqueue( - new arp_proxy_binding_cmds::bind_cmd(m_binding, m_itf->handle())); - } -} - -std::string -arp_proxy_binding::to_string() const -{ - std::ostringstream s; - s << "ArpProxy-binding: " << m_itf->to_string(); - - return (s.str()); -} - -void -arp_proxy_binding::update(const arp_proxy_binding& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (!m_binding) { - HW::enqueue( - new arp_proxy_binding_cmds::bind_cmd(m_binding, m_itf->handle())); - } -} - -std::shared_ptr -arp_proxy_binding::find_or_add(const arp_proxy_binding& temp) -{ - return (m_db.find_or_add(temp.m_itf->key(), temp)); -} - -std::shared_ptr -arp_proxy_binding::singular() const -{ - return find_or_add(*this); -} - -arp_proxy_binding::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "arp-proxy-binding" }, "ARP proxy bindings", - this); -} - -void -arp_proxy_binding::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -arp_proxy_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = interface::find(payload.sw_if_index); - - if (itf) { - arp_proxy_binding ab(*itf); - OM::commit(key, ab); - } else { - VOM_LOG(log_level_t::ERROR) << "arp-proxy-binding dump:" - << " itf:" << payload.sw_if_index; - } - } -} - -dependency_t -arp_proxy_binding::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -arp_proxy_binding::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/arp_proxy_binding.hpp b/extras/vom/vom/arp_proxy_binding.hpp deleted file mode 100644 index 284cf7371fa..00000000000 --- a/extras/vom/vom/arp_proxy_binding.hpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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_ARP_PROXY_BINDING_H__ -#define __VOM_ARP_PROXY_BINDING_H__ - -#include "vom/arp_proxy_config.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of LLDP client configuration on an interface - */ -class arp_proxy_binding : public object_base -{ -public: - /** - * Construct a new object matching the desried state - */ - arp_proxy_binding(const interface& itf); - - /** - * Copy Constructor - */ - arp_proxy_binding(const arp_proxy_binding& o); - - /** - * Destructor - */ - ~arp_proxy_binding(); - - /** - * Return the 'singular' of the LLDP binding that matches this object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all LLDP bindings into the stream provided - */ - static void dump(std::ostream& os); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const arp_proxy_binding& obj); - - /** - * Find or add LLDP binding to the OM - */ - static std::shared_ptr find_or_add( - const arp_proxy_binding& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer to the interface on which LLDP config - * resides. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A map of all ArpProxy bindings keyed against the interface. - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/arp_proxy_binding_cmds.cpp b/extras/vom/vom/arp_proxy_binding_cmds.cpp deleted file mode 100644 index acad2d5f6ac..00000000000 --- a/extras/vom/vom/arp_proxy_binding_cmds.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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/arp_proxy_binding_cmds.hpp" - -namespace VOM { -namespace arp_proxy_binding_cmds { - -bind_cmd::bind_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.enable = 1; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "ARP-proxy-bind: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string(); - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.enable = 0; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "ARP-proxy-unbind: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string(); - - return (s.str()); -} - -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 ("ARP-proxy-binding-dump"); -} - -}; // namespace arp_proxy_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/arp_proxy_binding_cmds.hpp b/extras/vom/vom/arp_proxy_binding_cmds.hpp deleted file mode 100644 index 976466b4236..00000000000 --- a/extras/vom/vom/arp_proxy_binding_cmds.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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_ARP_PROXY_BINDING_CMDS_H__ -#define __VOM_ARP_PROXY_BINDING_CMDS_H__ - -#include "vom/arp_proxy_binding.hpp" -#include "vom/dump_cmd.hpp" - -#include - -namespace VOM { -namespace arp_proxy_binding_cmds { -/** - * A command class that binds the LLDP config to the interface - */ -class bind_cmd - : public rpc_cmd, vapi::Proxy_arp_intfc_enable_disable> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to bind - */ - const handle_t& m_itf; -}; - -/** - * A cmd class that Unbinds ArpProxy Config from an interface - */ -class unbind_cmd - : public rpc_cmd, vapi::Proxy_arp_intfc_enable_disable> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to unbind - */ - const handle_t& m_itf; -}; - -/** - * A cmd class that Dumps all the Proxy ARP configs - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // namespace cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/arp_proxy_config.cpp b/extras/vom/vom/arp_proxy_config.cpp deleted file mode 100644 index e21fd4a97b2..00000000000 --- a/extras/vom/vom/arp_proxy_config.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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/arp_proxy_config.hpp" -#include "vom/api_types.hpp" -#include "vom/arp_proxy_config_cmds.hpp" -#include "vom/prefix.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -singular_db arp_proxy_config::m_db; - -arp_proxy_config::event_handler arp_proxy_config::m_evh; - -arp_proxy_config::arp_proxy_config(const boost::asio::ip::address_v4& low, - const boost::asio::ip::address_v4& high) - : m_low(low) - , m_high(high) - , m_config(true) -{ -} - -arp_proxy_config::arp_proxy_config(const arp_proxy_config& o) - : m_low(o.m_low) - , m_high(o.m_high) - , m_config(o.m_config) -{ -} - -arp_proxy_config::~arp_proxy_config() -{ - sweep(); - - // not in the DB anymore. - m_db.release(std::make_pair(m_low, m_high), this); -} - -void -arp_proxy_config::sweep() -{ - if (m_config) { - HW::enqueue( - new arp_proxy_config_cmds::unconfig_cmd(m_config, m_low, m_high)); - } - HW::write(); -} - -void -arp_proxy_config::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -arp_proxy_config::replay() -{ - if (m_config) { - HW::enqueue(new arp_proxy_config_cmds::config_cmd(m_config, m_low, m_high)); - } -} - -std::string -arp_proxy_config::to_string() const -{ - std::ostringstream s; - s << "ARP-proxy:" - << " low:" << m_low.to_string() << " high:" << m_high.to_string(); - - return (s.str()); -} - -void -arp_proxy_config::update(const arp_proxy_config& desired) -{ - if (!m_config) { - HW::enqueue(new arp_proxy_config_cmds::config_cmd(m_config, m_low, m_high)); - } -} - -std::shared_ptr -arp_proxy_config::find_or_add(const arp_proxy_config& temp) -{ - return (m_db.find_or_add(std::make_pair(temp.m_low, temp.m_high), temp)); -} - -std::shared_ptr -arp_proxy_config::singular() const -{ - return find_or_add(*this); -} - -arp_proxy_config::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "arp-proxy-config" }, "ARP Proxy configurations", - this); -} - -void -arp_proxy_config::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -arp_proxy_config::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - boost::asio::ip::address lo = from_api(payload.proxy.low); - boost::asio::ip::address hi = from_api(payload.proxy.hi); - - arp_proxy_config ap(lo.to_v4(), hi.to_v4()); - OM::commit(key, ap); - } -} - -dependency_t -arp_proxy_config::event_handler::order() const -{ - return (dependency_t::GLOBAL); -} - -void -arp_proxy_config::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const arp_proxy_config::key_t& key) -{ - os << "[" << key.first << ", " << key.second << "]"; - - return (os); -} -} -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/arp_proxy_config.hpp b/extras/vom/vom/arp_proxy_config.hpp deleted file mode 100644 index 3a50633de4d..00000000000 --- a/extras/vom/vom/arp_proxy_config.hpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * 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_ARP_PROXY_CONFIG_H__ -#define __VOM_ARP_PROXY_CONFIG_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of LLDP client configuration on an interface - */ -class arp_proxy_config : public object_base -{ -public: - /** - * Key type - */ - typedef std::pair - key_t; - - /** - * Construct a new object matching the desried state - */ - arp_proxy_config(const boost::asio::ip::address_v4& low, - const boost::asio::ip::address_v4& high); - - /** - * Copy Constructor - */ - arp_proxy_config(const arp_proxy_config& o); - - /** - * Destructor - */ - ~arp_proxy_config(); - - /** - * Return the 'singular' of the LLDP config that matches this object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all LLDP configs into the stream provided - */ - static void dump(std::ostream& os); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const arp_proxy_config& obj); - - /** - * Find or add LLDP config to the OM - */ - static std::shared_ptr find_or_add( - const arp_proxy_config& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Address range - */ - const boost::asio::ip::address_v4 m_low; - const boost::asio::ip::address_v4 m_high; - - /** - * A map of all ArpProxy configs keyed against the interface. - */ - static singular_db m_db; - - /** - * HW configuration for the config. The bool representing the - * do/don't configured/unconfigured. - */ - HW::item m_config; -}; - -std::ostream& operator<<(std::ostream& os, const arp_proxy_config::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/arp_proxy_config_cmds.cpp b/extras/vom/vom/arp_proxy_config_cmds.cpp deleted file mode 100644 index a203830a62c..00000000000 --- a/extras/vom/vom/arp_proxy_config_cmds.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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/arp_proxy_config_cmds.hpp" -#include "vom/api_types.hpp" - -DEFINE_VAPI_MSG_IDS_ARP_API_JSON; - -namespace VOM { -namespace arp_proxy_config_cmds { - -config_cmd::config_cmd(HW::item& item, - const boost::asio::ip::address_v4& low, - const boost::asio::ip::address_v4& high) - : rpc_cmd(item) - , m_low(low) - , m_high(high) -{} - -bool -config_cmd::operator==(const config_cmd& o) const -{ - return ((m_low == o.m_low) && (m_high == o.m_high)); -} - -rc_t -config_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - - to_api(m_low, payload.proxy.low); - to_api(m_high, payload.proxy.hi); - - VAPI_CALL(req.execute()); - - wait(); - - return (rc_t::OK); -} - -std::string -config_cmd::to_string() const -{ - std::ostringstream s; - s << "ARP-proxy-config: " << m_hw_item.to_string() - << " low:" << m_low.to_string() << " high:" << m_high.to_string(); - - return (s.str()); -} - -unconfig_cmd::unconfig_cmd(HW::item& item, - const boost::asio::ip::address_v4& low, - const boost::asio::ip::address_v4& high) - : rpc_cmd(item) - , m_low(low) - , m_high(high) -{} - -bool -unconfig_cmd::operator==(const unconfig_cmd& o) const -{ - return ((m_low == o.m_low) && (m_high == o.m_high)); -} - -rc_t -unconfig_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - - to_api(m_low, payload.proxy.low); - to_api(m_high, payload.proxy.hi); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return (rc_t::OK); -} - -std::string -unconfig_cmd::to_string() const -{ - std::ostringstream s; - s << "ARP-proxy-unconfig: " << m_hw_item.to_string() - << " low:" << m_low.to_string() << " high:" << m_high.to_string(); - - return (s.str()); -} - -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 ("ARP-proxy-dump"); -} - -}; // namesapce cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/arp_proxy_config_cmds.hpp b/extras/vom/vom/arp_proxy_config_cmds.hpp deleted file mode 100644 index ae95251f13e..00000000000 --- a/extras/vom/vom/arp_proxy_config_cmds.hpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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_ARP_PROXY_CONFIG_CMDS_H__ -#define __VOM_ARP_PROXY_CONFIG_CMDS_H__ - -#include "vom/arp_proxy_config.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace arp_proxy_config_cmds { -/** - * A command class that adds the ARP Proxy config - */ -class config_cmd : public rpc_cmd, vapi::Proxy_arp_add_del> -{ -public: - /** - * Constructor - */ - config_cmd(HW::item& item, - const boost::asio::ip::address_v4& lo, - const boost::asio::ip::address_v4& high); - - /** - * 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 config_cmd& i) const; - -private: - /** - * Address range - */ - const boost::asio::ip::address_v4 m_low; - const boost::asio::ip::address_v4 m_high; -}; - -/** - * A cmd class that Unconfigs ArpProxy Config from an interface - */ -class unconfig_cmd : public rpc_cmd, vapi::Proxy_arp_add_del> -{ -public: - /** - * Constructor - */ - unconfig_cmd(HW::item& item, - const boost::asio::ip::address_v4& lo, - const boost::asio::ip::address_v4& hig); - - /** - * 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 unconfig_cmd& i) const; - -private: - /** - * Address range - */ - const boost::asio::ip::address_v4 m_low; - const boost::asio::ip::address_v4 m_high; -}; - -/** - * A cmd class that Dumps all the Proxy ARP configs - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // namespace cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bond_group_binding.cpp b/extras/vom/vom/bond_group_binding.cpp deleted file mode 100644 index e5d4f3891b5..00000000000 --- a/extras/vom/vom/bond_group_binding.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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/bond_group_binding.hpp" -#include "vom/bond_group_binding_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -/** - * A DB of all bond interface binding - */ -singular_db - bond_group_binding::m_db; - -bond_group_binding::event_handler bond_group_binding::m_evh; - -bond_group_binding::bond_group_binding(const bond_interface& itf, - const enslaved_itf_t& itfs) - : m_itf(itf.singular()) - , m_mem_itfs(itfs) - , m_binding(false) -{ -} - -bond_group_binding::bond_group_binding(const bond_group_binding& o) - : m_itf(o.m_itf) - , m_mem_itfs(o.m_mem_itfs) - , m_binding(o.m_binding) -{ -} - -bond_group_binding::~bond_group_binding() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -const bond_group_binding::key_t -bond_group_binding::key() const -{ - return (m_itf->key() + "-binding"); -} - -void -bond_group_binding::sweep() -{ - - auto it = m_mem_itfs.cbegin(); - while (it != m_mem_itfs.cend()) { - if (m_binding) { - HW::enqueue( - new bond_group_binding_cmds::unbind_cmd(m_binding, it->hdl())); - } - HW::write(); - ++it; - } -} - -void -bond_group_binding::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -bond_group_binding::replay() -{ - auto it = m_mem_itfs.cbegin(); - while (it != m_mem_itfs.cend()) { - if (m_binding) { - HW::enqueue( - new bond_group_binding_cmds::bind_cmd(m_binding, m_itf->handle(), *it)); - } - HW::write(); - ++it; - } -} - -std::string -bond_group_binding::to_string() const -{ - auto it = m_mem_itfs.cbegin(); - std::ostringstream s; - s << "bond-interface-binding: " << m_itf->to_string() << " slave-itfs: ["; - while (it != m_mem_itfs.cend()) { - s << " " << it->to_string(); - ++it; - } - s << "]"; - return (s.str()); -} - -void -bond_group_binding::update(const bond_group_binding& desired) -{ - /* - * the desired state is always that the interface should be created - */ - auto it = m_mem_itfs.cbegin(); - while (it != m_mem_itfs.cend()) { - if (!m_binding) { - HW::enqueue( - new bond_group_binding_cmds::bind_cmd(m_binding, m_itf->handle(), *it)); - } - ++it; - } -} - -std::shared_ptr -bond_group_binding::find_or_add(const bond_group_binding& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -bond_group_binding::singular() const -{ - return find_or_add(*this); -} - -bond_group_binding::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "bond-intf-binding" }, "Bond interface binding", - this); -} - -void -bond_group_binding::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -bond_group_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * handle it in interface class - */ -} - -dependency_t -bond_group_binding::event_handler::order() const -{ - /* - * We want enslaved interfaces bind to bond after interface - * but before anything else. - */ - return (dependency_t::VIRTUAL_INTERFACE); -} - -void -bond_group_binding::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bond_group_binding.hpp b/extras/vom/vom/bond_group_binding.hpp deleted file mode 100644 index bfac4881a44..00000000000 --- a/extras/vom/vom/bond_group_binding.hpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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_BOND_GROUP_BINDING_H__ -#define __VOM_BOND_GROUP_BINDING_H__ - -#include - -#include "vom/bond_interface.hpp" -#include "vom/bond_member.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of bond interface binding - */ -class bond_group_binding : public object_base -{ -public: - /** - * The KEY can be used to uniquely identify the Bond Binding. - * (other choices for keys, like the summation of the properties - * of the rules, are rather too cumbersome to use - */ - typedef std::string key_t; - - /** - * The container type for enslaved itfs - */ - typedef std::set enslaved_itf_t; - - /** - * Construct a new object matching the desried state - */ - bond_group_binding(const bond_interface& itf, const enslaved_itf_t& mem); - - /** - * Copy Constructor - */ - bond_group_binding(const bond_group_binding& o); - - /** - * Destructor - */ - ~bond_group_binding(); - - /** - * Return the 'singular' of the bond interface binding that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * get the key to this object - */ - const key_t key() const; - - /** - * Dump all bond interface bindings into the stream provided - */ - static void dump(std::ostream& os); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enqueue command to the VPP command Q for the update - */ - void update(const bond_group_binding& obj); - - /** - * Find or add bond interface binding to the OM - */ - static std::shared_ptr find_or_add( - const bond_group_binding& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer to the bond interface. - * By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - std::shared_ptr m_itf; - - /** - * A list of member interfaces. - */ - const enslaved_itf_t m_mem_itfs; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A map of all bond interface bindings keyed against the interface + - * "binding". - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bond_group_binding_cmds.cpp b/extras/vom/vom/bond_group_binding_cmds.cpp deleted file mode 100644 index b257f776373..00000000000 --- a/extras/vom/vom/bond_group_binding_cmds.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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/bond_group_binding_cmds.hpp" - -namespace VOM { -namespace bond_group_binding_cmds { - -bind_cmd::bind_cmd(HW::item& item, - const handle_t& bond_itf, - const bond_member& itf) - : rpc_cmd(item) - , m_bond_itf(bond_itf) - , m_itf(itf) -{ -} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return ((m_bond_itf == other.m_bond_itf) && (m_itf == other.m_itf)); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - m_itf.to_vpp(payload); - payload.bond_sw_if_index = m_bond_itf.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "bond-itf-bind: " << m_hw_item.to_string() - << " bond-itf:" << m_bond_itf.to_string() - << " slave-itf:" << m_itf.hdl().to_string(); - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{ -} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "bond-itf-unbind: " << m_hw_item.to_string() - << " slave-itf:" << m_itf.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd(const handle_t& hdl) - : m_itf(hdl) -{ -} - -dump_cmd::dump_cmd(const dump_cmd& d) - : m_itf(d.m_itf) -{ -} - -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))); - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("bond-slave-itfs-dump"); -} - -}; // namespace bond_group_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bond_group_binding_cmds.hpp b/extras/vom/vom/bond_group_binding_cmds.hpp deleted file mode 100644 index 3d9bfeedc61..00000000000 --- a/extras/vom/vom/bond_group_binding_cmds.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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_BOND_GROUP_BINDING_CMDS_H__ -#define __VOM_BOND_GROUP_BINDING_CMDS_H__ - -#include "vom/bond_group_binding.hpp" -#include "vom/dump_cmd.hpp" - -#include - -namespace VOM { -namespace bond_group_binding_cmds { -/** - * A command class that binds the slave interface to the bond interface - */ -class bind_cmd : public rpc_cmd, vapi::Bond_enslave> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, - const handle_t& bond_itf, - const bond_member& itf); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * sw_if_index of bond interface - */ - const handle_t m_bond_itf; - - /** - * member interface of bond group - */ - const bond_member m_itf; -}; - -/** - * A cmd class that detach slave from a bond interface - */ -class unbind_cmd : public rpc_cmd, vapi::Bond_detach_slave> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * slave interface of bond group - */ - const handle_t m_itf; -}; - -/** - * A cmd class that Dumps slave itfs - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Default Constructor - */ - dump_cmd(const handle_t& itf); - dump_cmd(const dump_cmd& d); - /** - * 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; - -private: - /** - * The interface to get the addresses for - */ - const handle_t m_itf; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bond_interface.cpp b/extras/vom/vom/bond_interface.cpp deleted file mode 100644 index 32a00ad7f43..00000000000 --- a/extras/vom/vom/bond_interface.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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/bond_interface.hpp" -#include "vom/bond_group_binding.hpp" -#include "vom/bond_group_binding_cmds.hpp" -#include "vom/bond_interface_cmds.hpp" - -namespace VOM { -/** - * Construct a new object matching the desried state - */ -bond_interface::bond_interface(const std::string& name, - admin_state_t state, - mode_t mode, - lb_t lb) - : interface(name, type_t::BOND, state) - , m_l2_address(l2_address_t::ZERO) - , m_mode(mode) - , m_lb(lb) -{ -} - -bond_interface::bond_interface(const std::string& name, - admin_state_t state, - const l2_address_t& l2_address, - mode_t mode, - lb_t lb) - : interface(name, type_t::BOND, state) - , m_l2_address(l2_address) - , m_mode(mode) - , m_lb(lb) -{ -} - -bond_interface::~bond_interface() -{ - sweep(); - release(); -} - -bond_interface::bond_interface(const bond_interface& o) - : interface(o) - , m_l2_address(o.m_l2_address) - , m_mode(o.m_mode) - , m_lb(o.m_lb) -{ -} - -std::shared_ptr -bond_interface::find(const handle_t& hdl) -{ - return std::dynamic_pointer_cast(interface::find(hdl)); -} - -void -bond_interface::set(bond_interface::mode_t mode) -{ - m_mode = mode; -} - -void -bond_interface::set(bond_interface::lb_t lb) -{ - m_lb = lb; -} - -std::string -bond_interface::to_string() const -{ - std::ostringstream s; - - s << this->interface::to_string() << " mode:" << m_mode.to_string() - << " lb:" << m_lb.to_string(); - - return (s.str()); -} - -std::queue& -bond_interface::mk_create_cmd(std::queue& q) -{ - q.push(new bond_interface_cmds::create_cmd(m_hdl, name(), m_mode, m_lb, - m_l2_address)); - - return (q); -} - -std::queue& -bond_interface::mk_delete_cmd(std::queue& q) -{ - q.push(new bond_interface_cmds::delete_cmd(m_hdl)); - - return (q); -} - -std::shared_ptr -bond_interface::singular() const -{ - return std::dynamic_pointer_cast(singular_i()); -} - -std::shared_ptr -bond_interface::singular_i() const -{ - return m_db.find_or_add(name(), *this); -} - -void -bond_interface::set(handle_t& handle) -{ - this->interface::set(handle); -} - -const bond_interface::mode_t bond_interface::mode_t::ROUND_ROBIN(1, - "round-robin"); -const bond_interface::mode_t bond_interface::mode_t::ACTIVE_BACKUP( - 2, - "active-backup"); -const bond_interface::mode_t bond_interface::mode_t::XOR(3, "xor"); -const bond_interface::mode_t bond_interface::mode_t::BROADCAST(4, "broadcast"); -const bond_interface::mode_t bond_interface::mode_t::LACP(5, "lacp"); -const bond_interface::mode_t bond_interface::mode_t::UNSPECIFIED(0, - "unspecified"); - -const bond_interface::mode_t -bond_interface::mode_t::from_numeric_val(uint8_t numeric) -{ - if (1 == numeric) { - return (bond_interface::mode_t::ROUND_ROBIN); - } - if (2 == numeric) { - return (bond_interface::mode_t::ACTIVE_BACKUP); - } - if (3 == numeric) { - return (bond_interface::mode_t::XOR); - } - if (4 == numeric) { - return (bond_interface::mode_t::BROADCAST); - } - if (5 == numeric) { - return (bond_interface::mode_t::LACP); - } - - return (bond_interface::mode_t::UNSPECIFIED); -} - -bond_interface::mode_t::mode_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const bond_interface::lb_t bond_interface::lb_t::L2(0, "l2"); -const bond_interface::lb_t bond_interface::lb_t::L34(1, "l34"); -const bond_interface::lb_t bond_interface::lb_t::L23(2, "l23"); -const bond_interface::lb_t bond_interface::lb_t::UNSPECIFIED(~0, "unspecified"); - -const bond_interface::lb_t -bond_interface::lb_t::from_numeric_val(uint8_t numeric) -{ - if (0 == numeric) { - return (bond_interface::lb_t::L2); - } - if (1 == numeric) { - return (bond_interface::lb_t::L34); - } - if (2 == numeric) { - return (bond_interface::lb_t::L23); - } - - return (bond_interface::lb_t::UNSPECIFIED); -} - -bond_interface::lb_t::lb_t(int v, const std::string& s) - : enum_base(v, s) -{ -} -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bond_interface.hpp b/extras/vom/vom/bond_interface.hpp deleted file mode 100644 index 74bc08bbbba..00000000000 --- a/extras/vom/vom/bond_interface.hpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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_BOND_INTERFACE_H__ -#define __VOM_BOND_INTERFACE_H__ - -#include "vom/interface.hpp" - -namespace VOM { -/** - * A bond-interface. e.g. a bond interface - */ -class bond_interface : public interface -{ -public: - /** - * A bond interface mode - */ - struct mode_t : enum_base - { - /** - * Round-Robin bond interface mode - */ - const static mode_t ROUND_ROBIN; - /** - * Active-backup bond interface mode - */ - const static mode_t ACTIVE_BACKUP; - /** - * XOR bond interface mode - */ - const static mode_t XOR; - /** - * Broadcast bond interface mode - */ - const static mode_t BROADCAST; - /** - * LACP bond interface mode - */ - const static mode_t LACP; - /** - * Unspecified bond interface mode - */ - const static mode_t UNSPECIFIED; - - /** - * Convert VPP's value of the bond to a mode - */ - static const mode_t from_numeric_val(uint8_t v); - - private: - /** - * Private constructor taking the value and the string name - */ - mode_t(int v, const std::string& s); - }; - - /** - * A bond interface load balance - */ - struct lb_t : enum_base - { - /** - * L2 bond interface lb - */ - const static lb_t L2; - /** - * L34 bond interface lb - */ - const static lb_t L34; - /** - * L23 bond interface lb - */ - const static lb_t L23; - /** - * Unspecified bond interface lb - */ - const static lb_t UNSPECIFIED; - - /** - * Convert VPP's value of the bond to a lb - */ - static const lb_t from_numeric_val(uint8_t v); - - private: - /** - * Private constructor taking the value and the string name - */ - lb_t(int v, const std::string& s); - }; - - bond_interface(const std::string& name, - admin_state_t state, - mode_t mode, - lb_t lb = lb_t::UNSPECIFIED); - - bond_interface(const std::string& name, - admin_state_t state, - const l2_address_t& l2_address, - mode_t mode, - lb_t lb = lb_t::UNSPECIFIED); - - ~bond_interface(); - bond_interface(const bond_interface& o); - - /** - * The the singular instance of the bond interface in the DB by handle - */ - static std::shared_ptr find(const handle_t& hdl); - - /** - * Return the matching 'singular instance' of the BOND interface - */ - std::shared_ptr singular() const; - - /** - * set the mode - */ - void set(mode_t mode); - - /** - * set the lb - */ - void set(lb_t lb); - - /** - * convert to string - */ - virtual std::string to_string() const; - -protected: - /** - * set the handle - */ - void set(handle_t& handle); - friend class interface_factory; - -private: - /** - * l2 address on bond interface - */ - l2_address_t m_l2_address; - - /** - * mode on bond interface - */ - mode_t m_mode; - - /** - * lb mode on bond interface - */ - lb_t m_lb; - - /** - * Return the matching 'instance' of the sub-interface - * over-ride from the base class - */ - std::shared_ptr singular_i() const; - - /** - * Virtual functions to construct an interface create commands. - */ - virtual std::queue& mk_create_cmd(std::queue& cmds); - - /** - * Virtual functions to construct an interface delete commands. - */ - virtual std::queue& mk_delete_cmd(std::queue& cmds); - - /* - * It's the OM class that call singular() - */ - friend class OM; -}; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bond_interface_cmds.cpp b/extras/vom/vom/bond_interface_cmds.cpp deleted file mode 100644 index b5b459a0d42..00000000000 --- a/extras/vom/vom/bond_interface_cmds.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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/bond_interface_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_BOND_API_JSON; - -namespace VOM { -namespace bond_interface_cmds { -create_cmd::create_cmd(HW::item& item, - const std::string& name, - const bond_interface::mode_t& mode, - const bond_interface::lb_t& lb, - const l2_address_t& l2_address) - : interface::create_cmd(item, name) - , m_mode(mode) - , m_lb(lb) - , m_l2_address(l2_address) -{ -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - if (m_l2_address != l2_address_t::ZERO) { - m_l2_address.to_bytes(payload.mac_address, 6); - payload.use_custom_mac = 1; - } - - payload.mode = (vapi_enum_bond_mode)m_mode.value(); - if ((m_mode == bond_interface::mode_t::XOR || - m_mode == bond_interface::mode_t::LACP) && - m_lb != bond_interface::lb_t::UNSPECIFIED) - payload.lb = (vapi_enum_bond_lb_algo)m_lb.value(); - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) { - insert_interface(); - } - - return rc_t::OK; -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "bond-intf-create: " << m_hw_item.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item) - : interface::delete_cmd(item) -{ -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - remove_interface(); - - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "bond-itf-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("bond-itf-dump"); -} -} // namespace bond_interface_cmds -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bond_interface_cmds.hpp b/extras/vom/vom/bond_interface_cmds.hpp deleted file mode 100644 index 06a8ac15009..00000000000 --- a/extras/vom/vom/bond_interface_cmds.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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_BOND_INTERFACE_CMDS_H__ -#define __VOM_BOND_INTERFACE_CMDS_H__ - -#include "vom/bond_interface.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/interface.hpp" -#include "vom/rpc_cmd.hpp" - -#include -#include - -namespace VOM { -namespace bond_interface_cmds { - -/** - * A functor class that creates an interface - */ -class create_cmd : public interface::create_cmd -{ -public: - create_cmd(HW::item& item, - const std::string& name, - const bond_interface::mode_t& mode, - const bond_interface::lb_t& lb, - const l2_address_t& l2_address); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - -private: - const bond_interface::mode_t m_mode; - const bond_interface::lb_t m_lb; - const l2_address_t m_l2_address; -}; - -/** - * A functor class that deletes a Tap interface - */ -class delete_cmd : public interface::delete_cmd -{ -public: - delete_cmd(HW::item& item); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; -}; - -/** - * A cmd class that Dumps all the Vpp Interfaces - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Default Constructor - */ - dump_cmd(); - - /** - * 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 bond_interface_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ -#endif diff --git a/extras/vom/vom/bond_member.cpp b/extras/vom/vom/bond_member.cpp deleted file mode 100644 index f1a27b3d1c6..00000000000 --- a/extras/vom/vom/bond_member.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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/bond_member.hpp" - -namespace VOM { -/** - * Construct a new object matching the desried state - */ -bond_member::bond_member(const interface& itf, mode_t mode, rate_t rate) - : m_itf(itf.singular()) - , m_mode(mode) - , m_rate(rate) -{ -} - -bond_member::~bond_member() -{ -} - -bond_member::bond_member(const bond_member& o) - : m_itf(o.m_itf) - , m_mode(o.m_mode) - , m_rate(o.m_rate) -{ -} - -void -bond_member::to_vpp(vapi_payload_bond_enslave& bond_enslave) const -{ - bond_enslave.sw_if_index = m_itf->handle().value(); - bond_enslave.is_passive = (m_mode == mode_t::PASSIVE) ? 1 : 0; - bond_enslave.is_long_timeout = (m_rate == rate_t::SLOW) ? 1 : 0; -} - -std::string -bond_member::to_string() const -{ - std::ostringstream s; - - s << m_itf->to_string() << " mode:" << m_mode.to_string() - << " rate:" << m_rate.to_string(); - - return (s.str()); -} - -bool -bond_member::operator<(const bond_member& itf) const -{ - return (m_itf->handle() < itf.m_itf->handle()); -} - -void -bond_member::set(mode_t mode) -{ - m_mode = mode; -} - -void -bond_member::set(rate_t rate) -{ - m_rate = rate; -} - -const handle_t -bond_member::hdl(void) const -{ - return m_itf->handle(); -} - -bool -bond_member::operator==(const bond_member& b) const -{ - return ((m_itf == b.m_itf) && (m_mode == b.m_mode) && (m_rate == b.m_rate)); -} - -const bond_member::mode_t bond_member::mode_t::ACTIVE(0, "active"); -const bond_member::mode_t bond_member::mode_t::PASSIVE(1, "passive"); - -const bond_member::mode_t -bond_member::mode_t::from_numeric_val(uint8_t numeric) -{ - if (0 == numeric) - return (bond_member::mode_t::ACTIVE); - - return (bond_member::mode_t::PASSIVE); -} - -bond_member::mode_t::mode_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const bond_member::rate_t bond_member::rate_t::FAST(0, "fast"); -const bond_member::rate_t bond_member::rate_t::SLOW(1, "slow"); - -const bond_member::rate_t -bond_member::rate_t::from_numeric_val(uint8_t numeric) -{ - if (0 == numeric) - return (bond_member::rate_t::FAST); - - return (bond_member::rate_t::SLOW); -} - -bond_member::rate_t::rate_t(int v, const std::string& s) - : enum_base(v, s) -{ -} -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bond_member.hpp b/extras/vom/vom/bond_member.hpp deleted file mode 100644 index 066933b74d7..00000000000 --- a/extras/vom/vom/bond_member.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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_BOND_MEMBER_H__ -#define __VOM_BOND_MEMBER_H__ - -#include "vom/interface.hpp" -#include - -namespace VOM { -/** - * A bond-member. e.g. a bond_member interface - */ -class bond_member -{ -public: - /** - * A member interface mode - */ - struct mode_t : enum_base - { - /** - * Active member interface mode - */ - const static mode_t ACTIVE; - /** - * Passive member interface mode - */ - const static mode_t PASSIVE; - - /** - * Convert VPP's value of the bond to a mode - */ - static const mode_t from_numeric_val(uint8_t v); - - private: - /** - * Private constructor taking the value and the string name - */ - mode_t(int v, const std::string& s); - }; - - /** - * A member interface rate - */ - struct rate_t : enum_base - { - /** - * Fast member interface rate - */ - const static rate_t FAST; - /** - * SLOW member interface rate - */ - const static rate_t SLOW; - - /** - * Convert VPP's value of the bond to a mode - */ - static const rate_t from_numeric_val(uint8_t v); - - private: - /** - * Private constructor taking the value and the string name - */ - rate_t(int v, const std::string& s); - }; - - bond_member(const interface& itf, mode_t mode, rate_t rate); - - ~bond_member(); - bond_member(const bond_member& o); - - /** - * convert to VPP - */ - void to_vpp(vapi_payload_bond_enslave& bond_enslave) const; - - /** - * set the mode - */ - void set(mode_t mode); - - /** - * set the rate - */ - void set(rate_t rate); - - /** - * convert to string - */ - std::string to_string(void) const; - - /** - * less-than operator - */ - bool operator<(const bond_member& mem_itf) const; - - /** - * Get the interface handle - */ - const handle_t hdl(void) const; - - /** - * equality operator - */ - bool operator==(const bond_member& i) const; - -private: - /** - * Refernece conter lock on the parent - */ - const std::shared_ptr m_itf; - - /** - * passive vs active member - */ - mode_t m_mode; - - /** - * slow 90sec. vs. fast 3sec timeout - */ - rate_t m_rate; -}; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bridge_domain.cpp b/extras/vom/vom/bridge_domain.cpp deleted file mode 100644 index e86fc26b268..00000000000 --- a/extras/vom/vom/bridge_domain.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/* - * 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/bridge_domain.hpp" -#include "vom/bridge_domain_cmds.hpp" -#include "vom/interface.hpp" -#include "vom/l2_binding.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -const bridge_domain::learning_mode_t bridge_domain::learning_mode_t::ON(1, - "on"); -const bridge_domain::learning_mode_t bridge_domain::learning_mode_t::OFF(0, - "off"); - -bridge_domain::learning_mode_t::learning_mode_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const bridge_domain::flood_mode_t bridge_domain::flood_mode_t::ON(1, "on"); -const bridge_domain::flood_mode_t bridge_domain::flood_mode_t::OFF(0, "off"); - -bridge_domain::flood_mode_t::flood_mode_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const bridge_domain::uu_flood_mode_t bridge_domain::uu_flood_mode_t::ON(1, - "on"); -const bridge_domain::uu_flood_mode_t bridge_domain::uu_flood_mode_t::OFF(0, - "off"); - -bridge_domain::uu_flood_mode_t::uu_flood_mode_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const bridge_domain::mac_age_mode_t bridge_domain::mac_age_mode_t::ON(1, "on"); -const bridge_domain::mac_age_mode_t bridge_domain::mac_age_mode_t::OFF(0, - "off"); - -bridge_domain::mac_age_mode_t::mac_age_mode_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const bridge_domain::arp_term_mode_t bridge_domain::arp_term_mode_t::ON(1, - "on"); -const bridge_domain::arp_term_mode_t bridge_domain::arp_term_mode_t::OFF(0, - "off"); - -bridge_domain::arp_term_mode_t::arp_term_mode_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const bridge_domain::arp_ufwd_mode_t bridge_domain::arp_ufwd_mode_t::ON(1, - "on"); -const bridge_domain::arp_ufwd_mode_t bridge_domain::arp_ufwd_mode_t::OFF(0, - "off"); - -bridge_domain::arp_ufwd_mode_t::arp_ufwd_mode_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -/** - * A DB of al the interfaces, key on the name - */ -singular_db bridge_domain::m_db; - -bridge_domain::event_handler bridge_domain::m_evh; - -/** - * Construct a new object matching the desried state - */ -bridge_domain::bridge_domain(uint32_t id, - const learning_mode_t& lmode, - const arp_term_mode_t& amode, - const arp_ufwd_mode_t& aumode, - const flood_mode_t& fmode, - const uu_flood_mode_t& uufmode, - const mac_age_mode_t& mmode) - : m_id(id) - , m_learning_mode(lmode) - , m_arp_term_mode(amode) - , m_arp_ufwd_mode(aumode) - , m_flood_mode(fmode) - , m_uu_flood_mode(uufmode) - , m_mac_age_mode(mmode) -{ -} - -bridge_domain::bridge_domain(const bridge_domain& o) - : m_id(o.m_id) - , m_learning_mode(o.m_learning_mode) - , m_arp_term_mode(o.m_arp_term_mode) - , m_arp_ufwd_mode(o.m_arp_ufwd_mode) - , m_flood_mode(o.m_flood_mode) - , m_uu_flood_mode(o.m_uu_flood_mode) - , m_mac_age_mode(o.m_mac_age_mode) -{ -} - -const bridge_domain::key_t& -bridge_domain::key() const -{ - return (m_id.data()); -} - -uint32_t -bridge_domain::id() const -{ - return (m_id.data()); -} - -bool -bridge_domain::operator==(const bridge_domain& b) const -{ - return ((m_learning_mode == b.m_learning_mode) && - (m_flood_mode == b.m_flood_mode) && - (m_uu_flood_mode == b.m_uu_flood_mode) && - (m_mac_age_mode == b.m_mac_age_mode) && - (m_arp_term_mode == b.m_arp_term_mode) && - (m_arp_ufwd_mode == b.m_arp_ufwd_mode) && id() == b.id()); -} - -void -bridge_domain::sweep() -{ - if (rc_t::OK == m_id.rc()) { - HW::enqueue(new bridge_domain_cmds::delete_cmd(m_id)); - } - HW::write(); -} - -void -bridge_domain::replay() -{ - if (rc_t::OK == m_id.rc()) { - HW::enqueue(new bridge_domain_cmds::create_cmd( - m_id, m_learning_mode, m_arp_term_mode, m_arp_ufwd_mode, m_flood_mode, - m_uu_flood_mode, m_mac_age_mode)); - } -} - -bridge_domain::~bridge_domain() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_id.data(), this); -} - -std::string -bridge_domain::to_string() const -{ - std::ostringstream s; - s << "bridge-domain:[" << m_id.to_string() - << " learning-mode:" << m_learning_mode.to_string() << "]"; - - return (s.str()); -} - -std::shared_ptr -bridge_domain::find(const key_t& key) -{ - return (m_db.find(key)); -} - -void -bridge_domain::update(const bridge_domain& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (rc_t::OK != m_id.rc()) { - HW::enqueue(new bridge_domain_cmds::create_cmd( - m_id, m_learning_mode, m_arp_term_mode, m_arp_ufwd_mode, m_flood_mode, - m_uu_flood_mode, m_mac_age_mode)); - } -} - -std::shared_ptr -bridge_domain::find_or_add(const bridge_domain& temp) -{ - return (m_db.find_or_add(temp.m_id.data(), temp)); -} - -std::shared_ptr -bridge_domain::singular() const -{ - return find_or_add(*this); -} - -void -bridge_domain::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -bridge_domain::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump VPP Bridge domains - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - bridge_domain bd( - payload.bd_id, - (payload.learn ? learning_mode_t::ON : learning_mode_t::OFF), - (payload.arp_term ? arp_term_mode_t::ON : arp_term_mode_t::OFF), - (payload.arp_ufwd ? arp_ufwd_mode_t::ON : arp_ufwd_mode_t::OFF), - (payload.flood ? flood_mode_t::ON : flood_mode_t::OFF), - (payload.uu_flood ? uu_flood_mode_t::ON : uu_flood_mode_t::OFF), - (payload.mac_age ? mac_age_mode_t::ON : mac_age_mode_t::OFF)); - - VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); - - /* - * Write each of the discovered bridge-domains into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, bd); - - std::shared_ptr uu_fwd_itf = - interface::find(payload.uu_fwd_sw_if_index); - if (uu_fwd_itf) { - l2_binding l2(*uu_fwd_itf, bd, - l2_binding::l2_port_type_t::L2_PORT_TYPE_UU_FWD); - OM::commit(key, l2); - } else { - VOM_LOG(log_level_t::ERROR) << "no uu-fwd interface:" - << payload.uu_fwd_sw_if_index; - } - - /** - * For each interface in the BD construct an l2_binding - */ - for (unsigned int ii = 0; ii < payload.n_sw_ifs; ii++) { - std::shared_ptr itf = - interface::find(payload.sw_if_details[ii].sw_if_index); - if (itf) { - l2_binding l2(*itf, bd); - OM::commit(key, l2); - } else { - VOM_LOG(log_level_t::ERROR) << "no interface:" - << payload.sw_if_details[ii].sw_if_index; - } - } - } -} - -bridge_domain::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "bd", "bridge" }, "Bridge Domains", this); -} - -void -bridge_domain::event_handler::handle_replay() -{ - m_db.replay(); -} - -dependency_t -bridge_domain::event_handler::order() const -{ - return (dependency_t::TABLE); -} - -void -bridge_domain::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bridge_domain.hpp b/extras/vom/vom/bridge_domain.hpp deleted file mode 100644 index 8ece1cc89d1..00000000000 --- a/extras/vom/vom/bridge_domain.hpp +++ /dev/null @@ -1,306 +0,0 @@ -/* - * 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_BRIDGE_DOMAIN_H__ -#define __VOM_BRIDGE_DOMAIN_H__ - -#include "vom/enum_base.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A base class for all object_base in the VPP object_base-Model. - * provides the abstract interface. - */ -class bridge_domain : public object_base -{ -public: - /** - * Key Type for Bridge Domains in the sigular DB - */ - typedef uint32_t key_t; - - /** - * Bridge Domain Learning mode - */ - struct learning_mode_t : enum_base - { - const static learning_mode_t ON; - const static learning_mode_t OFF; - - private: - /** - * Private constructor taking the value and the string name - */ - learning_mode_t(int v, const std::string& s); - }; - - /** - * Bridge Domain ARP termination mode - */ - struct arp_term_mode_t : enum_base - { - const static arp_term_mode_t ON; - const static arp_term_mode_t OFF; - - private: - /** - * Private constructor taking the value and the string name - */ - arp_term_mode_t(int v, const std::string& s); - }; - - /** - * Bridge Domain ARP Unicast Forward mode - */ - struct arp_ufwd_mode_t : enum_base - { - const static arp_ufwd_mode_t ON; - const static arp_ufwd_mode_t OFF; - - private: - /** - * Private constructor taking the value and the string name - */ - arp_ufwd_mode_t(int v, const std::string& s); - }; - - /** - * Bridge Domain MAC aging mode - */ - struct mac_age_mode_t : enum_base - { - const static mac_age_mode_t ON; - const static mac_age_mode_t OFF; - - private: - /** - * Private constructor taking the value and the string name - */ - mac_age_mode_t(int v, const std::string& s); - }; - - /** - * Bridge Domain flood mode - */ - struct flood_mode_t : enum_base - { - const static flood_mode_t ON; - const static flood_mode_t OFF; - - private: - /** - * Private constructor taking the value and the string name - */ - flood_mode_t(int v, const std::string& s); - }; - - /** - * Bridge Domain Unknown Unicast Flood mode - */ - struct uu_flood_mode_t : enum_base - { - const static uu_flood_mode_t ON; - const static uu_flood_mode_t OFF; - - private: - /** - * Private constructor taking the value and the string name - */ - uu_flood_mode_t(int v, const std::string& s); - }; - - /** - * The value of the defaultbridge domain - */ - const static uint32_t DEFAULT_TABLE = 0; - - /** - * Construct a new object matching the desried state - */ - bridge_domain(uint32_t id, - const learning_mode_t& lmode = learning_mode_t::ON, - const arp_term_mode_t& amode = arp_term_mode_t::ON, - const arp_ufwd_mode_t& aumode = arp_ufwd_mode_t::OFF, - const flood_mode_t& fmode = flood_mode_t::ON, - const uu_flood_mode_t& uufmode = uu_flood_mode_t::ON, - const mac_age_mode_t& mmode = mac_age_mode_t::OFF); - - /** - * Copy Constructor - */ - bridge_domain(const bridge_domain& o); - - /** - * Destructor - */ - ~bridge_domain(); - - /** - * Comparison operator - for UT - */ - bool operator==(const bridge_domain& b) const; - - /** - * Return the bridge domain's VPP ID - */ - uint32_t id() const; - - /** - * Return the bridge domain's key - */ - const key_t& key() const; - - /** - * Return the matchin 'singular' instance of the bridge-domain - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string(void) const; - - /** - * Static function to find the bridge_domain in the model - */ - static std::shared_ptr find(const key_t& key); - - /** - * Dump all bridge-doamin into the stream provided - */ - static void dump(std::ostream& os); - -private: - /** - * 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; - }; - - /** - * Instance of the event handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const bridge_domain& obj); - - /** - * Find or add an singular of a Bridge-Domain in the object_base Model - */ - static std::shared_ptr find_or_add(const bridge_domain& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * The ID we assign to this BD and the HW result in VPP - */ - HW::item m_id; - - /** - * The learning mode of the bridge - */ - learning_mode_t m_learning_mode; - - /** - * The ARP termination mode of the bridge - */ - arp_term_mode_t m_arp_term_mode; - - /** - * The ARP Unicast Forward mode of the bridge - */ - arp_ufwd_mode_t m_arp_ufwd_mode; - - /** - * The flood mode of the bridge - */ - flood_mode_t m_flood_mode; - - /** - * The unknown unicast flood mode of the bridge - */ - uu_flood_mode_t m_uu_flood_mode; - - /** - * The MAC aging mode of the bridge - */ - mac_age_mode_t m_mac_age_mode; - - /** - * A map of all interfaces key against the interface's name - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bridge_domain_arp_entry.cpp b/extras/vom/vom/bridge_domain_arp_entry.cpp deleted file mode 100644 index f468e0f977f..00000000000 --- a/extras/vom/vom/bridge_domain_arp_entry.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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/bridge_domain_arp_entry.hpp" -#include "vom/api_types.hpp" -#include "vom/bridge_domain_arp_entry_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -singular_db - bridge_domain_arp_entry::m_db; - -bridge_domain_arp_entry::event_handler bridge_domain_arp_entry::m_evh; - -bridge_domain_arp_entry::bridge_domain_arp_entry( - const bridge_domain& bd, - const boost::asio::ip::address& ip_addr, - const mac_address_t& mac) - : m_hw(false) - , m_bd(bd.singular()) - , m_ip_addr(ip_addr) - , m_mac(mac) -{ -} - -bridge_domain_arp_entry::bridge_domain_arp_entry( - const boost::asio::ip::address& ip_addr, - const mac_address_t& mac) - : m_hw(false) - , m_bd(nullptr) - , m_ip_addr(ip_addr) - , m_mac(mac) -{ - /* - * the route goes in the default table - */ - bridge_domain bd(bridge_domain::DEFAULT_TABLE); - - m_bd = bd.singular(); -} - -bridge_domain_arp_entry::bridge_domain_arp_entry( - const bridge_domain_arp_entry& bde) - : m_hw(bde.m_hw) - , m_bd(bde.m_bd) - , m_ip_addr(bde.m_ip_addr) - , m_mac(bde.m_mac) -{ -} - -bridge_domain_arp_entry::~bridge_domain_arp_entry() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -const bridge_domain_arp_entry::key_t -bridge_domain_arp_entry::key() const -{ - return (std::make_pair(m_bd->key(), m_ip_addr)); -} - -bool -bridge_domain_arp_entry::operator==(const bridge_domain_arp_entry& bdae) const -{ - return ((key() == bdae.key()) && (m_mac == bdae.m_mac)); -} - -void -bridge_domain_arp_entry::sweep() -{ - if (m_hw) { - HW::enqueue(new bridge_domain_arp_entry_cmds::delete_cmd(m_hw, m_bd->id(), - m_mac, m_ip_addr)); - } - HW::write(); -} - -void -bridge_domain_arp_entry::replay() -{ - if (m_hw) { - HW::enqueue(new bridge_domain_arp_entry_cmds::create_cmd(m_hw, m_bd->id(), - m_mac, m_ip_addr)); - } -} - -std::string -bridge_domain_arp_entry::to_string() const -{ - std::ostringstream s; - s << "bridge-domain-arp-entry:[" << m_bd->to_string() << ", " - << m_mac.to_string() << ", " << m_ip_addr.to_string() << "]"; - - return (s.str()); -} - -void -bridge_domain_arp_entry::update(const bridge_domain_arp_entry& r) -{ - /* - * create the table if it is not yet created - */ - if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new bridge_domain_arp_entry_cmds::create_cmd(m_hw, m_bd->id(), - m_mac, m_ip_addr)); - } -} - -std::shared_ptr -bridge_domain_arp_entry::find_or_add(const bridge_domain_arp_entry& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -bridge_domain_arp_entry::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -bridge_domain_arp_entry::singular() const -{ - return find_or_add(*this); -} - -void -bridge_domain_arp_entry::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -bridge_domain_arp_entry::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "bd-arp" }, - "bridge domain ARP termination entries", this); -} - -void -bridge_domain_arp_entry::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -bridge_domain_arp_entry::event_handler::handle_populate( - const client_db::key_t& key) -{ - /* - * dump VPP Bridge domains - */ - std::shared_ptr cmd = - std::make_shared(~0); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr bd = - bridge_domain::find(payload.entry.bd_id); - bridge_domain_arp_entry bd_ae(*bd, from_api(payload.entry.ip), - from_api(payload.entry.mac)); - - VOM_LOG(log_level_t::DEBUG) << "dump: " << bd_ae.to_string(); - - /* - * Write each of the discovered bridge-domain arp entry into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, bd_ae); - } -} - -dependency_t -bridge_domain_arp_entry::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -bridge_domain_arp_entry::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const bridge_domain_arp_entry::key_t& key) -{ - os << "[" << key.first << ", " << key.second << "]"; - - return (os); -} -} -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bridge_domain_arp_entry.hpp b/extras/vom/vom/bridge_domain_arp_entry.hpp deleted file mode 100644 index b4af6a0f62e..00000000000 --- a/extras/vom/vom/bridge_domain_arp_entry.hpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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_BRIDGE_DOMAIN_ARP_ENTRY_H__ -#define __VOM_BRIDGE_DOMAIN_ARP_ENTRY_H__ - -#include "vom/bridge_domain.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" -#include "vom/types.hpp" - -namespace VOM { -/** - * A entry in the ARP termination table of a Bridge Domain - */ -class bridge_domain_arp_entry : public object_base -{ -public: - /** - * The key for a bridge_domain ARP entry; - * the BD, IP address and MAC address - */ - typedef std::pair key_t; - - /** - * Construct a bridge domain ARP Entry in the given bridge domain - */ - bridge_domain_arp_entry(const bridge_domain& bd, - const boost::asio::ip::address& ip_addr, - const mac_address_t& mac); - - /** - * Construct a bridge domain ARP entry in the default table - */ - bridge_domain_arp_entry(const boost::asio::ip::address& ip_addr, - const mac_address_t& mac); - - /** - * Copy Construct - */ - bridge_domain_arp_entry(const bridge_domain_arp_entry& r); - - /** - * Destructor - */ - ~bridge_domain_arp_entry(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const bridge_domain_arp_entry& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const bridge_domain_arp_entry& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add( - const bridge_domain_arp_entry& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the bridge_domain - */ - HW::item m_hw; - - /** - * The bridge_domain domain the bridge_domain is in. - */ - std::shared_ptr m_bd; - - /** - * The IP address - */ - boost::asio::ip::address m_ip_addr; - - /** - * The mac to return - */ - mac_address_t m_mac; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, - const bridge_domain_arp_entry::key_t& key); -}; // namespace - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bridge_domain_arp_entry_cmds.cpp b/extras/vom/vom/bridge_domain_arp_entry_cmds.cpp deleted file mode 100644 index e1a80908271..00000000000 --- a/extras/vom/vom/bridge_domain_arp_entry_cmds.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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/bridge_domain_arp_entry_cmds.hpp" -#include "vom/api_types.hpp" - -namespace VOM { -namespace bridge_domain_arp_entry_cmds { - -create_cmd::create_cmd(HW::item& item, - uint32_t bd, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr) - : rpc_cmd(item) - , m_bd(bd) - , m_mac(mac) - , m_ip_addr(ip_addr) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_mac == other.m_mac) && (m_ip_addr == other.m_ip_addr) && - (m_bd == other.m_bd)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.entry.bd_id = m_bd; - payload.is_add = 1; - to_api(m_mac, payload.entry.mac); - to_api(m_ip_addr, payload.entry.ip); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "bridge-domain-arp-entry-create: " << m_hw_item.to_string() - << " bd:" << m_bd << " mac:" << m_mac.to_string() - << " ip:" << m_ip_addr.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - uint32_t bd, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr) - : rpc_cmd(item) - , m_bd(bd) - , m_mac(mac) - , m_ip_addr(ip_addr) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return ((m_mac == other.m_mac) && (m_ip_addr == other.m_ip_addr) && - (m_bd == other.m_bd)); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.entry.bd_id = m_bd; - payload.is_add = 0; - to_api(m_mac, payload.entry.mac); - to_api(m_ip_addr, payload.entry.ip); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "bridge-domain-arp-entry-delete: " << m_hw_item.to_string() - << " bd:" << m_bd << " mac:" << m_mac.to_string() - << " ip:" << m_ip_addr.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd(uint32_t bd_id) - : m_bd(bd_id) -{ -} - -dump_cmd::dump_cmd(const dump_cmd& d) - : m_bd(d.m_bd) -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.bd_id = m_bd; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("bridge-domain-arp-entry-dump"); -} - -}; // namespace bridge_domain_arp_entry -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bridge_domain_arp_entry_cmds.hpp b/extras/vom/vom/bridge_domain_arp_entry_cmds.hpp deleted file mode 100644 index 490fc4ba738..00000000000 --- a/extras/vom/vom/bridge_domain_arp_entry_cmds.hpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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_BRIDGE_DOMAIN_ARP_ENTRY_CMDS_H__ -#define __VOM_BRIDGE_DOMAIN_ARP_ENTRY_CMDS_H__ - -#include "vom/bridge_domain_arp_entry.hpp" -#include "vom/dump_cmd.hpp" - -#include -#include - -namespace VOM { -namespace bridge_domain_arp_entry_cmds { - -/** -* A command class that creates or updates the bridge domain ARP Entry -*/ -class create_cmd : public rpc_cmd, vapi::Bd_ip_mac_add_del> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - uint32_t id, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr); - - /** - * 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; - -private: - uint32_t m_bd; - mac_address_t m_mac; - boost::asio::ip::address m_ip_addr; -}; - -/** - * A cmd class that deletes a bridge domain ARP entry - */ -class delete_cmd : public rpc_cmd, vapi::Bd_ip_mac_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, - uint32_t id, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr); - - /** - * 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: - uint32_t m_bd; - mac_address_t m_mac; - boost::asio::ip::address m_ip_addr; -}; - -/** - * A cmd class that Dumps all arp termination tables - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(uint32_t bd_id); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; - - /** - * The bd_id to get the arp termination table for - */ - uint32_t m_bd; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bridge_domain_cmds.cpp b/extras/vom/vom/bridge_domain_cmds.cpp deleted file mode 100644 index 1aeafcee44f..00000000000 --- a/extras/vom/vom/bridge_domain_cmds.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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/bridge_domain_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_L2_API_JSON; - -namespace VOM { -namespace bridge_domain_cmds { -create_cmd::create_cmd(HW::item& item, - const bridge_domain::learning_mode_t& lmode, - const bridge_domain::arp_term_mode_t& amode, - const bridge_domain::arp_ufwd_mode_t& aumode, - const bridge_domain::flood_mode_t& fmode, - const bridge_domain::uu_flood_mode_t& uufmode, - const bridge_domain::mac_age_mode_t& mmode) - : rpc_cmd(item) - , m_learning_mode(lmode) - , m_arp_term_mode(amode) - , m_arp_ufwd_mode(aumode) - , m_flood_mode(fmode) - , m_uu_flood_mode(uufmode) - , m_mac_age_mode(mmode) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return (m_hw_item.data() == other.m_hw_item.data()); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.bd_id = m_hw_item.data(); - payload.flood = m_flood_mode.value(); - payload.uu_flood = m_uu_flood_mode.value(); - payload.forward = 1; - payload.learn = m_learning_mode.value(); - payload.arp_term = m_arp_term_mode.value(); - payload.arp_ufwd = m_arp_ufwd_mode.value(); - payload.mac_age = m_mac_age_mode.value(); - payload.is_add = 1; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "bridge-domain-create: " << m_hw_item.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item) - : rpc_cmd(item) -{ -} - -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)); - - auto& payload = req.get_request().get_payload(); - payload.bd_id = m_hw_item.data(); - payload.is_add = 0; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return (rc_t::OK); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "bridge-domain-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.bd_id = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("bridge-domain-dump"); -} -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bridge_domain_cmds.hpp b/extras/vom/vom/bridge_domain_cmds.hpp deleted file mode 100644 index 395b3560d7a..00000000000 --- a/extras/vom/vom/bridge_domain_cmds.hpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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_BRIDGE_DOMAIN_CMDS_H__ -#define __VOM_BRIDGE_DOMAIN_CMDS_H__ - -#include "vom/bridge_domain.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace bridge_domain_cmds { -/** - * A command class that creates an Bridge-Domain - */ -class create_cmd - : public rpc_cmd, vapi::Bridge_domain_add_del> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - const bridge_domain::learning_mode_t& lmode, - const bridge_domain::arp_term_mode_t& amode, - const bridge_domain::arp_ufwd_mode_t& aumode, - const bridge_domain::flood_mode_t& fmode, - const bridge_domain::uu_flood_mode_t& uufmode, - const bridge_domain::mac_age_mode_t& mmode); - - /** - * 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; - -private: - /** - * the learning mode for the bridge - */ - bridge_domain::learning_mode_t m_learning_mode; - /** - * the learning mode for the bridge - */ - bridge_domain::arp_term_mode_t m_arp_term_mode; - /** - * the learning mode for the bridge - */ - bridge_domain::arp_ufwd_mode_t m_arp_ufwd_mode; - /** - * the flood mode for the bridge - */ - bridge_domain::flood_mode_t m_flood_mode; - /** - * the unknown unicast flood mode for the bridge - */ - bridge_domain::uu_flood_mode_t m_uu_flood_mode; - /** - * the flood mode for the bridge - */ - bridge_domain::mac_age_mode_t m_mac_age_mode; -}; - -/** - * A cmd class that Delete an Bridge-Domain - */ -class delete_cmd - : public rpc_cmd, vapi::Bridge_domain_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item); - - /** - * 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; -}; - -/** - * A cmd class that Dumps all the bridge domains - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bridge_domain_entry.cpp b/extras/vom/vom/bridge_domain_entry.cpp deleted file mode 100644 index 241de953771..00000000000 --- a/extras/vom/vom/bridge_domain_entry.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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/bridge_domain_entry.hpp" -#include "vom/bridge_domain_entry_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -singular_db - bridge_domain_entry::m_db; - -bridge_domain_entry::event_handler bridge_domain_entry::m_evh; - -bridge_domain_entry::bridge_domain_entry(const bridge_domain& bd, - const mac_address_t& mac, - const interface& tx_itf) - : m_hw(false) - , m_mac(mac) - , m_bd(bd.singular()) - , m_tx_itf(tx_itf.singular()) -{ -} - -bridge_domain_entry::bridge_domain_entry(const mac_address_t& mac, - const interface& tx_itf) - : m_hw(false) - , m_mac(mac) - , m_bd(nullptr) - , m_tx_itf(tx_itf.singular()) -{ - /* - * the entry goes in the default bridge-domain - */ - bridge_domain bd(bridge_domain::DEFAULT_TABLE); - - m_bd = bd.singular(); -} - -bridge_domain_entry::bridge_domain_entry(const bridge_domain_entry& bde) - : m_hw(bde.m_hw) - , m_mac(bde.m_mac) - , m_bd(bde.m_bd) - , m_tx_itf(bde.m_tx_itf) -{ -} - -const bridge_domain_entry::key_t -bridge_domain_entry::key() const -{ - return (std::make_pair(m_bd->key(), m_mac)); -} - -bool -bridge_domain_entry::operator==(const bridge_domain_entry& bde) const -{ - return ((key() == bde.key()) && (m_tx_itf == bde.m_tx_itf)); -} - -bridge_domain_entry::~bridge_domain_entry() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -void -bridge_domain_entry::sweep() -{ - if (m_hw) { - HW::enqueue(new bridge_domain_entry_cmds::delete_cmd( - m_hw, m_mac, m_bd->id(), interface::type_t::BVI == m_tx_itf->type())); - } - HW::write(); -} - -void -bridge_domain_entry::replay() -{ - if (m_hw) { - HW::enqueue(new bridge_domain_entry_cmds::create_cmd( - m_hw, m_mac, m_bd->id(), m_tx_itf->handle(), - interface::type_t::BVI == m_tx_itf->type())); - } -} -std::string -bridge_domain_entry::to_string() const -{ - std::ostringstream s; - s << "bridge-domain-entry:[" << m_bd->to_string() << ", " << m_mac.to_string() - << ", tx:" << m_tx_itf->name() << "]"; - - return (s.str()); -} - -void -bridge_domain_entry::update(const bridge_domain_entry& r) -{ - /* - * create the table if it is not yet created - */ - if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new bridge_domain_entry_cmds::create_cmd( - m_hw, m_mac, m_bd->id(), m_tx_itf->handle(), - interface::type_t::BVI == m_tx_itf->type())); - } -} - -std::shared_ptr -bridge_domain_entry::find_or_add(const bridge_domain_entry& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -bridge_domain_entry::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -bridge_domain_entry::singular() const -{ - return find_or_add(*this); -} - -void -bridge_domain_entry::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -bridge_domain_entry::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "bd-entry" }, - "bridge domain entry configurations", this); -} - -void -bridge_domain_entry::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -bridge_domain_entry::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = interface::find(payload.sw_if_index); - std::shared_ptr bd = bridge_domain::find(payload.bd_id); - - if (!bd || !itf) { - VOM_LOG(log_level_t::ERROR) << "bridge-domain-entry dump:" - << " itf:" << payload.sw_if_index - << " bd:" << payload.bd_id; - continue; - } - - mac_address_t mac(payload.mac); - bridge_domain_entry bd_e(*bd, mac, *itf); - - VOM_LOG(log_level_t::DEBUG) << "bridge-domain-entry dump:" - << " " << bd->to_string() << " " - << itf->to_string() << " mac:[" - << mac.to_string() << "]"; - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, bd_e); - } -} - -dependency_t -bridge_domain_entry::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -bridge_domain_entry::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const bridge_domain_entry::key_t& key) -{ - os << "[" << key.first << ", " << key.second.to_string() << "]"; - - return (os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bridge_domain_entry.hpp b/extras/vom/vom/bridge_domain_entry.hpp deleted file mode 100644 index 2aef697ebca..00000000000 --- a/extras/vom/vom/bridge_domain_entry.hpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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_BRIDGE_DOMAIN_ENTRY_H__ -#define __VOM_BRIDGE_DOMAIN_ENTRY_H__ - -#include "vom/bridge_domain.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A MAC forwarding entry in the bridge-domain/L2-FIB - */ -class bridge_domain_entry : public object_base -{ -public: - /** - * The key for a bridge_domain - */ - typedef std::pair key_t; - - /** - * Construct a bridge_domain in the given bridge domain - */ - bridge_domain_entry(const bridge_domain& bd, - const mac_address_t& mac, - const interface& tx_itf); - - /** - * Construct a bridge_domain in the default table - */ - bridge_domain_entry(const mac_address_t& mac, const interface& tx_itf); - - /** - * Copy Construct - */ - bridge_domain_entry(const bridge_domain_entry& r); - - /** - * Destructor - */ - ~bridge_domain_entry(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const bridge_domain_entry& be) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const bridge_domain_entry& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add( - const bridge_domain_entry& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the bridge_domain - */ - HW::item m_hw; - - /** - * The mac to match - */ - mac_address_t m_mac; - - /** - * The bridge_domain domain the bridge_domain is in. - */ - std::shared_ptr m_bd; - - /** - * The set of paths - */ - std::shared_ptr m_tx_itf; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, - const bridge_domain_entry::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/bridge_domain_entry_cmds.cpp b/extras/vom/vom/bridge_domain_entry_cmds.cpp deleted file mode 100644 index ffdd02de0d2..00000000000 --- a/extras/vom/vom/bridge_domain_entry_cmds.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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/bridge_domain_entry_cmds.hpp" - -namespace VOM { -namespace bridge_domain_entry_cmds { -create_cmd::create_cmd(HW::item& item, - const mac_address_t& mac, - uint32_t bd, - handle_t tx_itf, - bool is_bvi) - : rpc_cmd(item) - , m_mac(mac) - , m_bd(bd) - , m_tx_itf(tx_itf) - , m_is_bvi(is_bvi) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_mac == other.m_mac) && (m_tx_itf == other.m_tx_itf) && - (m_bd == other.m_bd) && (m_is_bvi == other.m_is_bvi)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.bd_id = m_bd; - payload.is_add = 1; - m_mac.to_bytes(payload.mac, 6); - payload.sw_if_index = m_tx_itf.value(); - payload.bvi_mac = m_is_bvi; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "bridge-domain-entry-create: " << m_hw_item.to_string() << " bd:" << m_bd - << " mac:" << m_mac.to_string() << " tx:" << m_tx_itf - << " bvi:" << m_is_bvi; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - const mac_address_t& mac, - uint32_t bd, - bool is_bvi) - : rpc_cmd(item) - , m_mac(mac) - , m_bd(bd) - , m_is_bvi(is_bvi) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return ((m_mac == other.m_mac) && (m_bd == other.m_bd) && - (m_is_bvi == other.m_is_bvi)); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.bd_id = m_bd; - payload.is_add = 0; - m_mac.to_bytes(payload.mac, 6); - payload.sw_if_index = ~0; - payload.bvi_mac = m_is_bvi; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "bridge-domain-entry-delete: " << m_hw_item.to_string() << " bd:" << m_bd - << " mac:" << m_mac.to_string() << " bvi:" << m_is_bvi; - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.bd_id = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("bridge-domain-entry-dump"); -} -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/bridge_domain_entry_cmds.hpp b/extras/vom/vom/bridge_domain_entry_cmds.hpp deleted file mode 100644 index dfee04f2a0d..00000000000 --- a/extras/vom/vom/bridge_domain_entry_cmds.hpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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_BRIDGE_DOMAIN_ENTRY_CMDS_H__ -#define __VOM_BRIDGE_DOMAIN_ENTRY_CMDS_H__ - -#include "vom/bridge_domain_entry.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace bridge_domain_entry_cmds { - -/** -* A command class that creates or updates the bridge_domain -*/ -class create_cmd : public rpc_cmd, vapi::L2fib_add_del> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - const mac_address_t& mac, - uint32_t id, - handle_t tx_intf, - bool is_bvi); - - /** - * 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; - -private: - mac_address_t m_mac; - uint32_t m_bd; - handle_t m_tx_itf; - bool m_is_bvi; -}; - -/** - * A cmd class that deletes a bridge_domain - */ -class delete_cmd : public rpc_cmd, vapi::L2fib_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, - const mac_address_t& mac, - uint32_t id, - bool is_bvi); - - /** - * 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: - mac_address_t m_mac; - uint32_t m_bd; - bool m_is_bvi; -}; - -/** - * A cmd class that Dumps all the interface spans - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/client_db.cpp b/extras/vom/vom/client_db.cpp deleted file mode 100644 index 41463d1dd74..00000000000 --- a/extras/vom/vom/client_db.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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/client_db.hpp" - -namespace VOM { -object_ref_list& -client_db::find(const client_db::key_t& k) -{ - return (m_objs[k]); -} - -void -client_db::flush(const client_db::key_t& k) -{ - auto found = m_objs.find(k); - - if (found != m_objs.end()) - m_objs.erase(found); -} - -void -client_db::dump(const key_t& key, std::ostream& os) -{ - object_ref_list& orlist = find(key); - - for (auto entry : orlist) { - os << " " << entry.obj()->to_string() << std::endl; - } -} - -void -client_db::dump(std::ostream& os) -{ - for (auto entry : m_objs) { - os << " key:[" << entry.first << "]" << std::endl; - } -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/client_db.hpp b/extras/vom/vom/client_db.hpp deleted file mode 100644 index 34204c1d839..00000000000 --- a/extras/vom/vom/client_db.hpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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_KEY_DB_H__ -#define __VOM_KEY_DB_H__ - -#include -#include - -#include "vom/object_base.hpp" - -namespace VOM { -/** - * A convenitent typedef for set of objects owned. - * A set of shared pointers. This is how the reference counting - * of an object in the model it managed. Once all these shared ptr - * and hence references are gone, the object is deleted and any state - * in VPP is removed. - */ -typedef std::set object_ref_list; - -/** - * A DB storing the objects that each owner/key owns. - * Each object is reference counter by each key that owns it. When - * no more references exist the object is destroyed. - */ -class client_db -{ -public: - /** - * In the opflex world each entity is known by a URI which can be - * converted - * into a string. We use the string type, since it allows us to keep - * this VPP - * specific code independent of opflex types. I might consider making - * this - * a template parameter one day... - */ - typedef const std::string key_t; - - /** - * Find the objects owned by the key - */ - object_ref_list& find(const key_t& k); - - /** - * flush, i.e. un-reference, all objects owned by the key - */ - void flush(const key_t& k); - - /** - * Print each of the object in the DB into the stream provided - */ - void dump(const key_t& key, std::ostream& os); - - /** - * Print each KEY - */ - void dump(std::ostream& os); - -private: - /** - * A map of keys versus the object they reference - */ - std::map m_objs; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/cmd.cpp b/extras/vom/vom/cmd.cpp deleted file mode 100644 index 5623507a63f..00000000000 --- a/extras/vom/vom/cmd.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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/cmd.hpp" - -namespace VOM { -/** - * Free ostream function to print a command - */ -std::ostream& -operator<<(std::ostream& os, const cmd& cmd) -{ - os << cmd.to_string(); - - return (os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/cmd.hpp b/extras/vom/vom/cmd.hpp deleted file mode 100644 index 9c87d31218a..00000000000 --- a/extras/vom/vom/cmd.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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_CMD_H__ -#define __VOM_CMD_H__ - -#include - -#include "vom/types.hpp" - -namespace VOM { -/** - * Forward declaration of the connection class - */ -class connection; - -/** - * A representation of a method call to VPP - */ -class cmd -{ -public: - /** - * Default constructor - */ - cmd() {} - /** - * Virtual destructor - */ - virtual ~cmd() {} - - /** - * Issue the command to VPP/HW - */ - virtual rc_t issue(connection& con) = 0; - - /** - * Retire/cancel a long running command - */ - virtual void retire(connection& con) = 0; - - /** - * Invoked on a Command when the HW queue is disabled to indicate - * that the commnad can be considered successful - */ - virtual void succeeded() = 0; - - /** - * convert to string format for debug purposes - */ - virtual std::string to_string() const = 0; -}; - -/** - * Free ostream function to print a command - */ -std::ostream& operator<<(std::ostream& os, const cmd& cmd); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/connection.cpp b/extras/vom/vom/connection.cpp deleted file mode 100644 index c03ef99c172..00000000000 --- a/extras/vom/vom/connection.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 - -#include "vom/connection.hpp" - -namespace VOM { -connection::connection() - : m_vapi_conn(new vapi::Connection()) - , m_app_name("VOM") -{ -} - -connection::~connection() -{ -} - -void -connection::disconnect() -{ - m_vapi_conn->disconnect(); -} - -int -connection::connect() -{ - vapi_error_e rv; - - rv = m_vapi_conn->connect(m_app_name.c_str(), - NULL, // m_api_prefix.c_str(), - 128, 128); - return rv; -} - -vapi::Connection& -connection::ctx() -{ - return (*m_vapi_conn); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/connection.hpp b/extras/vom/vom/connection.hpp deleted file mode 100644 index 06fe840232d..00000000000 --- a/extras/vom/vom/connection.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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_CONNECTION_H__ -#define __VOM_CONNECTION_H__ - -#include -#include - -/** - * Forward declarations - */ -namespace vapi { -class Connection; -}; - -namespace VOM { -/** - * A representation of the connection to VPP - */ -class connection -{ -public: - /** - * Constructor - */ - connection(); - /** - * Destructor - */ - ~connection(); - - /** - * Blocking [re]connect call - always eventually succeeds, or the - * universe expires. Not much this system can do without one. - */ - int connect(); - - /** - * Blocking disconnect - */ - void disconnect(); - - /** - * Retrun the VAPI context the commands will use - */ - vapi::Connection& ctx(); - -private: - /** - * The VAPI connection context - */ - std::unique_ptr m_vapi_conn; - - /** - * The name of this application - */ - const std::string m_app_name; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/dhcp_client.cpp b/extras/vom/vom/dhcp_client.cpp deleted file mode 100644 index 23911b3df0e..00000000000 --- a/extras/vom/vom/dhcp_client.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - * 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/dhcp_client.hpp" -#include "vom/dhcp_client_cmds.hpp" -#include "vom/route_api_types.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -const dhcp_client::state_t dhcp_client::state_t::DISCOVER(0, "discover"); -const dhcp_client::state_t dhcp_client::state_t::REQUEST(1, "request"); -const dhcp_client::state_t dhcp_client::state_t::BOUND(2, "bound"); - -dhcp_client::state_t::state_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const dhcp_client::state_t& -dhcp_client::state_t::from_vpp(int n) -{ - if (REQUEST == n) - return (REQUEST); - if (BOUND == n) - return (BOUND); - - return (DISCOVER); -} - -singular_db dhcp_client::m_db; -std::weak_ptr dhcp_client::m_s_event_cmd; -dhcp_client::dhcp_client_listener dhcp_client::m_listener; - -dhcp_client::event_handler dhcp_client::m_evh; - -dhcp_client::dhcp_client(const interface& itf, - const std::string& hostname, - bool set_broadcast_flag, - const ip_dscp_t& dscp, - event_listener* ev) - : m_itf(itf.singular()) - , m_hostname(hostname) - , m_client_id(l2_address_t::ZERO) - , m_set_broadcast_flag(set_broadcast_flag) - , m_dscp(dscp) - , m_binding(0) - , m_evl(ev) - , m_event_cmd(get_event_cmd()) -{ -} - -dhcp_client::dhcp_client(const interface& itf, - const std::string& hostname, - const l2_address_t& client_id, - bool set_broadcast_flag, - const ip_dscp_t& dscp, - event_listener* ev) - : m_itf(itf.singular()) - , m_hostname(hostname) - , m_client_id(client_id) - , m_set_broadcast_flag(set_broadcast_flag) - , m_dscp(dscp) - , m_binding(0) - , m_evl(ev) - , m_event_cmd(get_event_cmd()) -{ -} - -dhcp_client::dhcp_client(const dhcp_client& o) - : m_itf(o.m_itf) - , m_hostname(o.m_hostname) - , m_client_id(o.m_client_id) - , m_set_broadcast_flag(o.m_set_broadcast_flag) - , m_dscp(o.m_dscp) - , m_binding(0) - , m_evl(o.m_evl) - , m_event_cmd(o.m_event_cmd) -{ -} - -dhcp_client::~dhcp_client() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_itf->key(), this); -} - -bool -dhcp_client::operator==(const dhcp_client& l) const -{ - return ((key() == l.key()) && (m_hostname == l.m_hostname) && - (m_client_id == l.m_client_id && m_dscp == l.m_dscp)); -} - -const dhcp_client::key_t& -dhcp_client::key() const -{ - return (m_itf->key()); -} - -void -dhcp_client::sweep() -{ - if (m_binding) { - HW::enqueue( - new dhcp_client_cmds::unbind_cmd(m_binding, m_itf->handle(), m_hostname)); - } - HW::write(); -} - -void -dhcp_client::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -dhcp_client::replay() -{ - if (m_binding) { - HW::enqueue(new dhcp_client_cmds::bind_cmd( - m_binding, m_itf->handle(), m_hostname, m_client_id, false, m_dscp)); - } -} - -std::string -dhcp_client::to_string() const -{ - std::ostringstream s; - s << "DHCP-client: " << m_itf->to_string() << " hostname:" << m_hostname - << " client_id:[" << m_client_id << "] " - << "dscp:" << m_dscp.to_string() << " " << m_binding.to_string(); - if (m_lease) - s << " " << m_lease->to_string(); - else - s << " no-lease"; - - return (s.str()); -} - -void -dhcp_client::update(const dhcp_client& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (!m_binding) { - HW::enqueue(new dhcp_client_cmds::bind_cmd( - m_binding, m_itf->handle(), m_hostname, m_client_id, false, m_dscp)); - } - - if (desired.m_lease) - m_lease = desired.m_lease; - if (m_evl != desired.m_evl) { - m_evl = desired.m_evl; - } -} - -const std::shared_ptr -dhcp_client::lease() const -{ - return (m_lease); -} - -void -dhcp_client::lease(std::shared_ptr lease) -{ - m_lease = lease; -} - -std::shared_ptr -dhcp_client::find_or_add(const dhcp_client& temp) -{ - return (m_db.find_or_add(temp.m_itf->key(), temp)); -} - -std::shared_ptr -dhcp_client::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -dhcp_client::singular() const -{ - return find_or_add(*this); -} - -dhcp_client::lease_t::lease_t() - : state(state_t::DISCOVER) - , mac(mac_address_t::ZERO) -{ -} - -dhcp_client::lease_t::lease_t(const state_t& state, - std::shared_ptr itf, - const boost::asio::ip::address& router_address, - const route::prefix_t& host_prefix, - const std::string& hostname, - const mac_address_t& mac) - : state(state) - , itf(itf) - , router_address(router_address) - , host_prefix(host_prefix) - , hostname(hostname) - , mac(mac) -{ -} - -std::string -dhcp_client::lease_t::to_string() const -{ - std::stringstream ss; - - ss << "lease:[" << itf->to_string() << " state: " << state.to_string() - << " host: " << host_prefix.to_string() << " router: " << router_address - << " mac: " << mac.to_string() << "]"; - - return (ss.str()); -} - -dhcp_client::event_listener::event_listener() - : m_status(rc_t::NOOP) -{ -} - -HW::item& -dhcp_client::event_listener::status() -{ - return (m_status); -} - -dhcp_client::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "dhcp" }, "DHCP clients", this); -} - -void -dhcp_client::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -dhcp_client::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = - interface::find(payload.client.sw_if_index); - - if (!itf) { - VOM_LOG(log_level_t::ERROR) << "dhcp-client dump:" - << " itf:" << payload.client.sw_if_index; - continue; - } - - const dhcp_client::state_t& s = - dhcp_client::state_t::from_vpp(payload.lease.state); - route::prefix_t pfx(payload.lease.is_ipv6, - (uint8_t*)&payload.lease.host_address.un, - payload.lease.mask_width); - std::string hostname = - reinterpret_cast(payload.lease.hostname); - l2_address_t l2(payload.client.id + 1); - dhcp_client dc(*itf, hostname, l2, payload.client.set_broadcast_flag, - from_api(payload.client.dscp)); - dc.lease(std::make_shared( - s, itf, from_bytes(0, (uint8_t*)&payload.lease.router_address.un), pfx, - hostname, mac_address_t(payload.lease.host_mac))); - OM::commit(key, dc); - } -} - -dependency_t -dhcp_client::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -dhcp_client::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::shared_ptr -dhcp_client::get_event_cmd() -{ - if (m_s_event_cmd.expired()) { - std::shared_ptr c = - std::make_shared(m_listener); - - m_s_event_cmd = c; - - HW::enqueue(c); - HW::write(); - - return c; - } - - return (m_s_event_cmd.lock()); -} - -void -dhcp_client::handle_dhcp_event(std::shared_ptr lease) -{ - m_lease = lease; - if (m_evl) - m_evl->handle_dhcp_event(m_lease); -} - -void -dhcp_client::dhcp_client_listener::handle_dhcp_event(std::shared_ptr e) -{ - /* - * Find the client the event references - */ - std::shared_ptr client = find(e->itf->key()); - - if (client) { - client->handle_dhcp_event(e); - } -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/dhcp_client.hpp b/extras/vom/vom/dhcp_client.hpp deleted file mode 100644 index 8e8669a96ef..00000000000 --- a/extras/vom/vom/dhcp_client.hpp +++ /dev/null @@ -1,317 +0,0 @@ -/* - * 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_DHCP_CLIENT_H__ -#define __VOM_DHCP_CLIENT_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/prefix.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -namespace dhcp_client_cmds { -class events_cmd; -}; -/** - * A representation of DHCP client on an interface - */ -class dhcp_client : public object_base -{ -public: - /** - * typedef for the DHCP client key type - */ - typedef interface::key_t key_t; - - struct state_t : enum_base - { - const static state_t DISCOVER; - const static state_t REQUEST; - const static state_t BOUND; - - static const state_t& from_vpp(int i); - - private: - /** - * Private constructor taking the value and the string name - */ - state_t(int v, const std::string& s); - }; - - /** - * A DHCP lease data - */ - struct lease_t - { - lease_t(); - lease_t(const state_t& state, - std::shared_ptr itf, - const boost::asio::ip::address& router_address, - const route::prefix_t& host_prefix, - const std::string& hostname, - const mac_address_t& mac); - - std::string to_string() const; - - const state_t& state; - std::shared_ptr itf; - boost::asio::ip::address router_address; - route::prefix_t host_prefix; - std::string hostname; - mac_address_t mac; - }; - - /** - * A class that listens to DHCP Events - */ - class event_listener - { - public: - /** - * Constructor - */ - event_listener(); - - /** - * listener's virtual function invoked when a DHCP event is - * available to read - */ - virtual void handle_dhcp_event(std::shared_ptr e) = 0; - - /** - * Return the HW::item associated with this command - */ - HW::item& status(); - - protected: - /** - * The HW::item associated with this command - */ - HW::item m_status; - }; - - /** - * Construct a new object matching the desried state - */ - dhcp_client(const interface& itf, - const std::string& hostname, - bool set_broadcast_flag = true, - const ip_dscp_t& dscp = ip_dscp_t::DSCP_CS0, - event_listener* ev = nullptr); - - /** - * Construct a new object matching the desried state - */ - dhcp_client(const interface& itf, - const std::string& hostname, - const l2_address_t& client_id, - bool set_broadcast_flag = true, - const ip_dscp_t& dscp = ip_dscp_t::DSCP_CS0, - event_listener* ev = nullptr); - - /** - * Copy Constructor - */ - dhcp_client(const dhcp_client& o); - - /** - * Destructor - */ - ~dhcp_client(); - - /** - * Comparison operator - for UT - */ - bool operator==(const dhcp_client& d) const; - - /** - * Return the object's key - */ - const key_t& key() const; - - /** - * Return the 'singular' of the DHCP client that matches this object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all DHCP clients into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Find a DHCP client from its key - */ - static std::shared_ptr find(const key_t& k); - - /** - * return the current lease data - */ - const std::shared_ptr lease() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const dhcp_client& obj); - - /** - * Find or add DHCP client to the OM - */ - static std::shared_ptr find_or_add(const dhcp_client& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - void lease(std::shared_ptr l); - - /** - * A reference counting pointer to the interface on which DHCP client - * resides. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * The hostname in the DHCP client - */ - const std::string m_hostname; - - /** - * The option-61 client_id in the DHCP client - */ - const l2_address_t m_client_id; - - /** - * Flag to control the setting the of DHCP discover's broadcast flag - */ - const bool m_set_broadcast_flag; - - /** - * DSCP setting for generated IP packets - */ - const ip_dscp_t m_dscp; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A pointer to an event listener for client events - */ - event_listener* m_evl; - - /** - * Current lease state for this client - */ - std::shared_ptr m_lease; - - std::shared_ptr m_event_cmd; - - void handle_dhcp_event(std::shared_ptr e); - - /** - * A map of all Dhcp clients keyed against the interface. - */ - static singular_db m_db; - - static std::weak_ptr m_s_event_cmd; - static std::shared_ptr get_event_cmd(); - - class dhcp_client_listener : public event_listener - { - public: - /** - * listener's virtual function invoked when a DHCP event is - * available to read - */ - void handle_dhcp_event(std::shared_ptr e); - }; - static dhcp_client_listener m_listener; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/dhcp_client_cmds.cpp b/extras/vom/vom/dhcp_client_cmds.cpp deleted file mode 100644 index 3f899a63c01..00000000000 --- a/extras/vom/vom/dhcp_client_cmds.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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/dhcp_client_cmds.hpp" -#include "vom/route_api_types.hpp" - -DEFINE_VAPI_MSG_IDS_DHCP_API_JSON; - -namespace VOM { -namespace dhcp_client_cmds { - -bind_cmd::bind_cmd(HW::item& item, - const handle_t& itf, - const std::string& hostname, - const l2_address_t& client_id, - bool set_broadcast_flag, - const ip_dscp_t& dscp) - : rpc_cmd(item) - , m_itf(itf) - , m_hostname(hostname) - , m_client_id(client_id) - , m_set_broadcast_flag(set_broadcast_flag) - , m_dscp(dscp) -{ -} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_hostname == other.m_hostname)); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.client.sw_if_index = m_itf.value(); - payload.client.pid = getpid(); - payload.client.want_dhcp_event = 1; - payload.client.set_broadcast_flag = m_set_broadcast_flag; - payload.client.dscp = to_api(m_dscp); - - memset(payload.client.hostname, 0, sizeof(payload.client.hostname)); - memcpy(payload.client.hostname, m_hostname.c_str(), - std::min(sizeof(payload.client.hostname), m_hostname.length())); - - memset(payload.client.id, 0, sizeof(payload.client.id)); - payload.client.id[0] = 1; - std::copy_n(begin(m_client_id.bytes), - std::min(sizeof(payload.client.id), m_client_id.bytes.size()), - payload.client.id + 1); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "Dhcp-client-bind: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string() << " hostname:" << m_hostname - << " client_id:[" << m_client_id << "] " - << "dscp:" << m_dscp.to_string(); - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, - const handle_t& itf, - const std::string& hostname) - : rpc_cmd(item) - , m_itf(itf) - , m_hostname(hostname) -{ -} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_hostname == other.m_hostname)); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.client.sw_if_index = m_itf.value(); - payload.client.pid = getpid(); - payload.client.want_dhcp_event = 0; - - memcpy(payload.client.hostname, m_hostname.c_str(), - std::min(sizeof(payload.client.hostname), m_hostname.length())); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "Dhcp-client-unbind: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string() << " hostname:" << m_hostname; - - return (s.str()); -} - -events_cmd::events_cmd(dhcp_client::event_listener& el) - : event_cmd(el.status()) - , m_listener(el) -{ -} - -events_cmd::~events_cmd() -{ - VOM_LOG(log_level_t::INFO) << "DHCP events destroyed"; -} - -bool -events_cmd::operator==(const events_cmd& other) const -{ - return (true); -} - -rc_t -events_cmd::issue(connection& con) -{ - /* - * Set the call back to handle DHCP complete envets. - */ - m_reg.reset(new reg_t(con.ctx(), std::ref(*this))); - - /* - * return in-progress so the command stays in the pending list. - */ - return (rc_t::OK); -} - -void -events_cmd::retire(connection& con) -{ -} - -void -events_cmd::notify() -{ - for (auto& msg : *this) { - auto& payload = msg.get_payload(); - - const dhcp_client::state_t& s = - dhcp_client::state_t::from_vpp(payload.lease.state); - route::prefix_t pfx(payload.lease.is_ipv6, - (uint8_t*)&payload.lease.host_address.un, - payload.lease.mask_width); - std::shared_ptr itf = interface::find(payload.lease.sw_if_index); - - if (itf) { - std::shared_ptr ev = - std::make_shared( - s, itf, from_bytes(0, (uint8_t*)&payload.lease.router_address.un), - pfx, reinterpret_cast(payload.lease.hostname), - mac_address_t(payload.lease.host_mac)); - m_listener.handle_dhcp_event(ev); - - VOM_LOG(log_level_t::INFO) << "DHCP: " << ev->to_string(); - } else { - VOM_LOG(log_level_t::ERROR) << "DHCP: no interface: " - << payload.lease.sw_if_index; - } - } - - flush(); -} - -std::string -events_cmd::to_string() const -{ - return ("dhcp-events"); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("dhcp-client-dump"); -} - -}; // namespace dhcp_client_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/dhcp_client_cmds.hpp b/extras/vom/vom/dhcp_client_cmds.hpp deleted file mode 100644 index 10d4026f4f3..00000000000 --- a/extras/vom/vom/dhcp_client_cmds.hpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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_DHCP_CLIENT_CMDS_H__ -#define __VOM_DHCP_CLIENT_CMDS_H__ - -#include "vom/dhcp_client.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/event_cmd.hpp" - -#include -#include - -namespace VOM { -namespace dhcp_client_cmds { - -/** - * A command class that binds the DHCP config to the interface - */ -class bind_cmd : public rpc_cmd, vapi::Dhcp_client_config> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, - const handle_t& itf, - const std::string& hostname, - const l2_address_t& client_id, - bool set_braodcast_flag, - const ip_dscp_t& dscp); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to bind - */ - const handle_t& m_itf; - - /** - * The DHCP client's hostname - */ - const std::string m_hostname; - - /** - * The DHCP client's ID - */ - const l2_address_t m_client_id; - - /** - * Flag to control the setting the of DHCP discover's broadcast flag - */ - const bool m_set_broadcast_flag; - - /** - * DSCP bits - */ - const ip_dscp_t& m_dscp; -}; - -/** - * A cmd class that Unbinds Dhcp Config from an interface - */ -class unbind_cmd : public rpc_cmd, vapi::Dhcp_client_config> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, - const handle_t& itf, - const std::string& hostname); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to unbind - */ - const handle_t& m_itf; - - /** - * The DHCP client's hostname - */ - const std::string m_hostname; -}; - -/** - * A functor class represents our desire to recieve interface events - */ -class events_cmd : public event_cmd -{ -public: - /** - * Constructor - */ - events_cmd(dhcp_client::event_listener& el); - ~events_cmd(); - - /** - * Issue the command to VPP/HW - subscribe to DHCP events - */ - rc_t issue(connection& con); - - /** - * Retire the command - unsubscribe - */ - void retire(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Comparison operator - only used for UT - */ - bool operator==(const events_cmd& i) const; - - /** - * called in the VAPI RX thread when data is available. - */ - void notify(); - -private: - void succeeded() {} - /** - * The listner of this command - */ - dhcp_client::event_listener& m_listener; -}; - -/** - * A cmd class that Dumps all the DHCP clients - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // namespace dhcp_client_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/dump_cmd.hpp b/extras/vom/vom/dump_cmd.hpp deleted file mode 100644 index 4dad02b911e..00000000000 --- a/extras/vom/vom/dump_cmd.hpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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_DUMP_CMD_H__ -#define __VOM_DUMP_CMD_H__ - -#include - -#include "vom/cmd.hpp" -#include "vom/hw.hpp" - -#include - -namespace VOM { -/** - * A function type def for calculating a message's size - */ -typedef unsigned int (*get_msg_size_t)(void*); - -/** - * A base class for VPP dump commands. - * Dump commands are one of the sub-set of command types to VPP. Here the - * client - * makes a read request on the resource and VPP responds with all the - * records. - * This command is executed synchronously. Once complete the client can - * 'pop' - * the records from the command object - */ -template -class dump_cmd : public cmd -{ -public: - typedef MSG msg_t; - typedef typename MSG::resp_type record_t; - - typedef typename vapi::Result_set::const_iterator - const_iterator; - - /** - * Default Constructor - */ - dump_cmd() - : cmd() - { - } - - /** - * Destructor - */ - virtual ~dump_cmd() {} - - dump_cmd(const dump_cmd& d) = default; - - /** - * Constant iterator to the start of the records retunred during the dump - */ - const_iterator begin() - { - /* - * m_dump is NULL during client UT when the commands are not issued. - */ - if (!m_dump) - return const_iterator(); - return (m_dump->get_result_set().begin()); - } - - /** - * Constant iterator to the end of the records retunred during the dump - */ - const_iterator end() - { - if (!m_dump) - return const_iterator(); - return (m_dump->get_result_set().end()); - } - - /** - * Wait for the issue of the command to complete - */ - rc_t wait() - { - std::future_status status; - std::future result; - - result = m_promise.get_future(); - status = result.wait_for(std::chrono::seconds(5)); - - if (status != std::future_status::ready) { - return (rc_t::TIMEOUT); - } - - return (result.get()); - } - - /** - * Call operator called when the dump is complete - */ - vapi_error_e operator()(MSG& d) - { - m_promise.set_value(rc_t::OK); - - return (VAPI_OK); - } - - /** - * Retire/cancel a long running command - */ - virtual void retire(connection& con) {} - -protected: - /** - * The underlying promise that implements the synchornous nature - * of the command issue - */ - std::promise m_promise; - - /** - * Dump commands should not be issued whilst the HW is disabled - */ - void succeeded() {} - - /** - * The HW::cmd_q is a friend so it can call suceedded. - */ - friend class HW::cmd_q; - - /** - * The VAPI event registration - */ - std::unique_ptr m_dump; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/enum_base.hpp b/extras/vom/vom/enum_base.hpp deleted file mode 100644 index 015410a57c5..00000000000 --- a/extras/vom/vom/enum_base.hpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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_ENUM_H__ -#define __VOM_ENUM_H__ - -#include - -namespace VOM { -/** - * A template base class for all enum types. - * This enum type exists to associate an enum value with a string for - * display/debug purposes. - * Concrete enum types use the CRTP. Derived classes thus inherit this - * base's function, but are not polymorphic. - */ -template -class enum_base -{ -public: - /** - * convert to string format for debug purposes - */ - const std::string& to_string() const { return (m_desc); } - - /** - * Comparison operator - */ - bool operator==(const enum_base& e) const { return (e.m_value == m_value); } - - /** - * Assignment - */ - enum_base& operator=(const enum_base& e) - { - m_value = e.m_value; - m_desc = e.m_desc; - - return (*this); - } - - /** - * bitwise or assignemnt - */ - enum_base& operator|=(const enum_base& e) - { - m_value += e.m_value; - m_desc += ":" + e.m_desc; - - return *this; - } - - /** - * bitwise or - */ - enum_base operator|(const enum_base& e1) const - { - enum_base e = *this; - e |= e1; - return e; - } - - /** - * Comparison operator - */ - bool operator!=(const enum_base& e) const { return (e.m_value != m_value); } - - /** - * integer conversion operator - */ - operator int() const { return (m_value); } - - /** - * Return the value of the enum - same as integer conversion - */ - int value() const { return (m_value); } - -protected: - /** - * Constructor of an enum - takes value and string description - */ - enum_base(int value, const std::string desc) - : m_value(value) - , m_desc(desc) - { - } - - /** - * Constructor - */ - virtual ~enum_base() {} - -private: - /** - * Integer value of the enum - */ - int m_value; - - /** - * String description - */ - std::string m_desc; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/event_cmd.hpp b/extras/vom/vom/event_cmd.hpp deleted file mode 100644 index 1120f75b399..00000000000 --- a/extras/vom/vom/event_cmd.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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_EVENT_CMD_H__ -#define __VOM_EVENT_CMD_H__ - -#include - -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -/** - * An Event command base class. - * Events are one of the sub-set of command type to VPP. - * A client performs a one time 'registration/subsription' to VPP for the - * event in question and then is notified asynchronously when those events - * occur. - * The model here then is that the lifetime of the event command represensts - * the during of the clients subscription. When the command is 'issued' the - * subscription begins, when it is 'retired' the subscription ends. For the - * subscription duration the client will be notified as events are recieved. - * The client can then 'pop' these events from this command object. - */ -template -class event_cmd : public rpc_cmd, WANT> -{ -public: - /** - * Default constructor - */ - event_cmd(HW::item& b) - : rpc_cmd, WANT>(b) - { - } - - /** - * Default destructor - */ - virtual ~event_cmd() {} - - /** - * Typedef for the event type - */ - typedef typename vapi::Event_registration::resp_type event_t; - typedef typename vapi::Event_registration reg_t; - - typedef typename vapi::Result_set::const_iterator - const_iterator; - - const_iterator begin() { return (m_reg->get_result_set().begin()); } - - const_iterator end() { return (m_reg->get_result_set().end()); } - - void lock() { m_mutex.lock(); } - void unlock() { m_mutex.unlock(); } - - /** - * flush/free all the events thus far reeived. - * Call with the lock held! - */ - void flush() { m_reg->get_result_set().free_all_responses(); } - - /** - * Retire the command. This is only appropriate for Event Commands - * As they persist until retired. - */ - virtual void retire(connection& con) = 0; - - vapi_error_e operator()(reg_t& dl) - { - notify(); - - return (VAPI_OK); - } - -protected: - /** - * Notify the command that data from VPP has arrived and been stored. - * The command should now inform its clients/listeners. - */ - virtual void notify() = 0; - - /** - * The VAPI event registration - */ - std::unique_ptr> m_reg; - - /** - * Mutex protection for the events - */ - std::mutex m_mutex; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_bridge_domain.cpp b/extras/vom/vom/gbp_bridge_domain.cpp deleted file mode 100644 index 3e015c379c2..00000000000 --- a/extras/vom/vom/gbp_bridge_domain.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - * 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/gbp_bridge_domain.hpp" -#include "vom/gbp_bridge_domain_cmds.hpp" -#include "vom/interface.hpp" -#include "vom/l2_binding.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::NONE(0, "none"); -const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::DO_NOT_LEARN( - 1, - "do-not-learn"); -const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::UU_FWD_DROP( - 2, - "uu-fwd-drop"); -const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::MCAST_DROP( - 4, - "mcast-drop"); -const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::UCAST_ARP( - 8, - "ucast-arp"); - -gbp_bridge_domain::flags_t::flags_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -/** - * A DB of al the interfaces, key on the name - */ -singular_db gbp_bridge_domain::m_db; - -gbp_bridge_domain::event_handler gbp_bridge_domain::m_evh; - -/** - * Construct a new object matching the desried state - */ -gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, - const gbp_route_domain& rd, - const interface& bvi, - const flags_t& flags) - : m_id(bd.id()) - , m_bd(bd.singular()) - , m_rd(rd.singular()) - , m_bvi(bvi.singular()) - , m_uu_fwd() - , m_bm_flood() - , m_flags(flags) -{ -} - -gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, - const gbp_route_domain& rd, - const interface& bvi, - const interface& uu_fwd, - const interface& bm_flood, - const flags_t& flags) - : m_id(bd.id()) - , m_bd(bd.singular()) - , m_rd(rd.singular()) - , m_bvi(bvi.singular()) - , m_uu_fwd(uu_fwd.singular()) - , m_bm_flood(bm_flood.singular()) - , m_flags(flags) -{ -} - -gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, - const gbp_route_domain& rd, - const std::shared_ptr bvi, - const std::shared_ptr uu_fwd, - const std::shared_ptr bm_flood, - const flags_t& flags) - : m_id(bd.id()) - , m_bd(bd.singular()) - , m_rd(rd.singular()) - , m_bvi(bvi) - , m_uu_fwd(uu_fwd) - , m_bm_flood(bm_flood) - , m_flags(flags) -{ - if (m_bvi) - m_bvi = m_bvi->singular(); - if (m_uu_fwd) - m_uu_fwd = m_uu_fwd->singular(); - if (m_bm_flood) - m_bm_flood = m_bm_flood->singular(); -} - -gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd, - const gbp_route_domain& rd, - const interface& bvi, - const std::shared_ptr uu_fwd, - const std::shared_ptr bm_flood, - const flags_t& flags) - : m_id(bd.id()) - , m_bd(bd.singular()) - , m_rd(rd.singular()) - , m_bvi(bvi.singular()) - , m_uu_fwd(uu_fwd) - , m_bm_flood(bm_flood) - , m_flags(flags) -{ - if (m_uu_fwd) - m_uu_fwd = m_uu_fwd->singular(); - if (m_bm_flood) - m_bm_flood = m_bm_flood->singular(); -} - -gbp_bridge_domain::gbp_bridge_domain(const gbp_bridge_domain& bd) - : m_id(bd.id()) - , m_bd(bd.m_bd) - , m_rd(bd.m_rd) - , m_bvi(bd.m_bvi) - , m_uu_fwd(bd.m_uu_fwd) - , m_bm_flood(bd.m_bm_flood) - , m_flags(bd.m_flags) -{ -} - -const gbp_bridge_domain::key_t -gbp_bridge_domain::key() const -{ - return (m_bd->key()); -} - -uint32_t -gbp_bridge_domain::id() const -{ - return (m_bd->id()); -} - -const std::shared_ptr -gbp_bridge_domain::get_bridge_domain() const -{ - return m_bd; -} - -const std::shared_ptr -gbp_bridge_domain::get_bvi() const -{ - return m_bvi; -} - -bool -gbp_bridge_domain::operator==(const gbp_bridge_domain& b) const -{ - bool equal = true; - - if (m_bvi && b.m_bvi) - equal &= (m_bvi->key() == b.m_bvi->key()); - else if (!m_bvi && !b.m_bvi) - ; - else - equal = false; - - if (m_uu_fwd && b.m_uu_fwd) - equal &= (m_uu_fwd->key() == b.m_uu_fwd->key()); - else if (!m_uu_fwd && !b.m_uu_fwd) - ; - else - equal = false; - - if (m_bm_flood && b.m_bm_flood) - equal &= (m_bm_flood->key() == b.m_bm_flood->key()); - else if (!m_bm_flood && !b.m_bm_flood) - ; - else - equal = false; - - return ((m_bd->key() == b.m_bd->key()) && equal); -} - -void -gbp_bridge_domain::sweep() -{ - if (rc_t::OK == m_id.rc()) { - HW::enqueue(new gbp_bridge_domain_cmds::delete_cmd(m_id)); - } - HW::write(); -} - -void -gbp_bridge_domain::replay() -{ - if (rc_t::OK == m_id.rc()) { - HW::enqueue(new gbp_bridge_domain_cmds::create_cmd( - m_id, m_rd->id(), (m_bvi ? m_bvi->handle() : handle_t::INVALID), - (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID), - (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags)); - } -} - -gbp_bridge_domain::~gbp_bridge_domain() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_id.data(), this); -} - -std::string -gbp_bridge_domain::to_string() const -{ - std::ostringstream s; - s << "gbp-bridge-domain:[" << m_bd->to_string() - << " flags:" << m_flags.to_string(); - - if (m_bvi) - s << " bvi:" << m_bvi->to_string(); - if (m_uu_fwd) - s << " uu-fwd:" << m_uu_fwd->to_string(); - - s << "]"; - - return (s.str()); -} - -std::shared_ptr -gbp_bridge_domain::find(const key_t& key) -{ - return (m_db.find(key)); -} - -void -gbp_bridge_domain::update(const gbp_bridge_domain& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (rc_t::OK != m_id.rc()) { - HW::enqueue(new gbp_bridge_domain_cmds::create_cmd( - m_id, m_rd->id(), (m_bvi ? m_bvi->handle() : handle_t::INVALID), - (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID), - (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags)); - } -} - -std::shared_ptr -gbp_bridge_domain::find_or_add(const gbp_bridge_domain& temp) -{ - return (m_db.find_or_add(temp.m_id.data(), temp)); -} - -std::shared_ptr -gbp_bridge_domain::singular() const -{ - return find_or_add(*this); -} - -void -gbp_bridge_domain::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -gbp_bridge_domain::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump GBP Bridge domains - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr uu_fwd = - interface::find(payload.bd.uu_fwd_sw_if_index); - std::shared_ptr bm_flood = - interface::find(payload.bd.bm_flood_sw_if_index); - std::shared_ptr bvi = - interface::find(payload.bd.bvi_sw_if_index); - std::shared_ptr grd = - gbp_route_domain::find(payload.bd.rd_id); - - flags_t flags = gbp_bridge_domain::flags_t::NONE; - if (payload.bd.flags & GBP_BD_API_FLAG_DO_NOT_LEARN) - flags |= gbp_bridge_domain::flags_t::DO_NOT_LEARN; - if (payload.bd.flags & GBP_BD_API_FLAG_UU_FWD_DROP) - flags |= gbp_bridge_domain::flags_t::UU_FWD_DROP; - if (payload.bd.flags & GBP_BD_API_FLAG_MCAST_DROP) - flags |= gbp_bridge_domain::flags_t::MCAST_DROP; - if (payload.bd.flags & GBP_BD_API_FLAG_UCAST_ARP) - flags |= gbp_bridge_domain::flags_t::UCAST_ARP; - - if (uu_fwd && bm_flood && bvi && grd) { - gbp_bridge_domain bd(payload.bd.bd_id, *grd, bvi, uu_fwd, bm_flood, - flags); - OM::commit(key, bd); - VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); - } else if (bvi) { - gbp_bridge_domain bd(payload.bd.bd_id, *grd, *bvi, flags); - OM::commit(key, bd); - VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string(); - } else { - VOM_LOG(log_level_t::ERROR) - << "no BVI:" << payload.bd.bvi_sw_if_index - << " nor uu-fwd:" << payload.bd.uu_fwd_sw_if_index; - } - } -} - -gbp_bridge_domain::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "gbd", "gbridge" }, "GBP Bridge Domains", this); -} - -void -gbp_bridge_domain::event_handler::handle_replay() -{ - m_db.replay(); -} - -dependency_t -gbp_bridge_domain::event_handler::order() const -{ - /* order after gbp-route-domains */ - return (dependency_t::ACL); -} - -void -gbp_bridge_domain::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_bridge_domain.hpp b/extras/vom/vom/gbp_bridge_domain.hpp deleted file mode 100644 index d397fe5231f..00000000000 --- a/extras/vom/vom/gbp_bridge_domain.hpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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_GBP_BRIDGE_DOMAIN_H__ -#define __VOM_GBP_BRIDGE_DOMAIN_H__ - -#include "vom/bridge_domain.hpp" -#include "vom/gbp_route_domain.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { - -/** - * A entry in the ARP termination table of a Bridge Domain - */ -class gbp_bridge_domain : public object_base -{ -public: - /** - * The key for a bridge_domain is the pair of EPG-IDs - */ - typedef bridge_domain::key_t key_t; - - struct flags_t : enum_base - { - const static flags_t NONE; - const static flags_t DO_NOT_LEARN; - const static flags_t UU_FWD_DROP; - const static flags_t MCAST_DROP; - const static flags_t UCAST_ARP; - - static const flags_t& from_vpp(int i); - - private: - flags_t(int v, const std::string& s); - flags_t(); - }; - - /** - * Construct a GBP bridge_domain - */ - gbp_bridge_domain(const bridge_domain& bd, - const gbp_route_domain& rd, - const interface& bvi, - const flags_t& flags = flags_t::NONE); - gbp_bridge_domain(const bridge_domain& bd, - const gbp_route_domain& rd, - const interface& bvi, - const interface& uu_fwd, - const interface& bm_flood, - const flags_t& flags = flags_t::NONE); - gbp_bridge_domain(const bridge_domain& bd, - const gbp_route_domain& rd, - const std::shared_ptr bvi, - const std::shared_ptr uu_fwd, - const std::shared_ptr bm_flood, - const flags_t& flags = flags_t::NONE); - gbp_bridge_domain(const bridge_domain& bd, - const gbp_route_domain& rd, - const interface& bvi, - const std::shared_ptr uu_fwd, - const std::shared_ptr bm_flood, - const flags_t& flags = flags_t::NONE); - - /** - * Copy Construct - */ - gbp_bridge_domain(const gbp_bridge_domain& r); - - /** - * Destructor - */ - ~gbp_bridge_domain(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * Return the bridge domain's VPP ID - */ - uint32_t id() const; - - /** - * comparison operator - */ - bool operator==(const gbp_bridge_domain& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - - const std::shared_ptr get_bridge_domain() const; - const std::shared_ptr get_bvi() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_bridge_domain& obj); - - /** - * Find or add the instance of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add( - const gbp_bridge_domain& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the endpoint - */ - HW::item m_id; - - std::shared_ptr m_bd; - std::shared_ptr m_rd; - std::shared_ptr m_bvi; - std::shared_ptr m_uu_fwd; - std::shared_ptr m_bm_flood; - flags_t m_flags; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -}; // namespace - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_bridge_domain_cmds.cpp b/extras/vom/vom/gbp_bridge_domain_cmds.cpp deleted file mode 100644 index 05064df6269..00000000000 --- a/extras/vom/vom/gbp_bridge_domain_cmds.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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/gbp_bridge_domain_cmds.hpp" - -namespace VOM { -namespace gbp_bridge_domain_cmds { - -create_cmd::create_cmd(HW::item& item, - u32 rd_id, - const handle_t bvi, - const handle_t uu_fwd, - const handle_t bm_flood, - const gbp_bridge_domain::flags_t& flags) - : rpc_cmd(item) - , m_rd_id(rd_id) - , m_bvi(bvi) - , m_uu_fwd(uu_fwd) - , m_bm_flood(bm_flood) - , m_flags(flags) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_hw_item.data() == other.m_hw_item.data()) && - (m_rd_id == other.m_rd_id) && (m_bvi == other.m_bvi) && - (m_uu_fwd == other.m_uu_fwd) && (m_bm_flood == other.m_bm_flood) && - (m_flags == other.m_flags)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.bd.bd_id = m_hw_item.data(); - payload.bd.rd_id = m_rd_id; - payload.bd.bvi_sw_if_index = m_bvi.value(); - payload.bd.uu_fwd_sw_if_index = m_uu_fwd.value(); - payload.bd.bm_flood_sw_if_index = m_bm_flood.value(); - - vapi_enum_gbp_bridge_domain_flags flags = GBP_BD_API_FLAG_NONE; - if (gbp_bridge_domain::flags_t::DO_NOT_LEARN & m_flags) - flags = static_cast( - flags | GBP_BD_API_FLAG_DO_NOT_LEARN); - if (gbp_bridge_domain::flags_t::UU_FWD_DROP & m_flags) - flags = static_cast( - flags | GBP_BD_API_FLAG_UU_FWD_DROP); - if (gbp_bridge_domain::flags_t::MCAST_DROP & m_flags) - flags = static_cast( - flags | GBP_BD_API_FLAG_MCAST_DROP); - if (gbp_bridge_domain::flags_t::UCAST_ARP & m_flags) - flags = static_cast( - flags | GBP_BD_API_FLAG_UCAST_ARP); - - payload.bd.flags = flags; - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-bridge-domain: " << m_hw_item.to_string() - << " flags:" << m_flags.to_string() << " bvi:" << m_bvi.to_string() - << " uu-fwd:" << m_uu_fwd.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item) - : rpc_cmd(item) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_hw_item.data() == other.m_hw_item.data()); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.bd_id = m_hw_item.data(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-bridge-domain: " << m_hw_item.to_string(); - - return (s.str()); -} - -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 ("gbp-bridge-domain-dump"); -} - -}; // namespace gbp_bridge_domain_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_bridge_domain_cmds.hpp b/extras/vom/vom/gbp_bridge_domain_cmds.hpp deleted file mode 100644 index 6dbe6dcdfed..00000000000 --- a/extras/vom/vom/gbp_bridge_domain_cmds.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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_GBP_BRIDGE_DOMAIN_CMDS_H__ -#define __VOM_GBP_BRIDGE_DOMAIN_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_bridge_domain.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace gbp_bridge_domain_cmds { -/** - * A command class that creates an Bridge-Domain - */ -class create_cmd - : public rpc_cmd, vapi::Gbp_bridge_domain_add> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - u32 rd_id, - const handle_t bvi, - const handle_t uu_fwd, - const handle_t bm_flood, - const gbp_bridge_domain::flags_t& flags); - - /** - * 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; - -private: - u32 m_rd_id; - const handle_t m_bvi; - const handle_t m_uu_fwd; - const handle_t m_bm_flood; - const gbp_bridge_domain::flags_t& m_flags; -}; - -/** - * A cmd class that Delete an Bridge-Domain - */ -class delete_cmd - : public rpc_cmd, vapi::Gbp_bridge_domain_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item); - - /** - * 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; -}; - -/** - * A cmd class that Dumps all the bridge domains - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd() = default; - dump_cmd(const dump_cmd& d) = 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // gbp_bridge_domain_cmds -}; // VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_contract.cpp b/extras/vom/vom/gbp_contract.cpp deleted file mode 100644 index 8fcef02da24..00000000000 --- a/extras/vom/vom/gbp_contract.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * 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/gbp_contract.hpp" -#include "vom/api_types.hpp" -#include "vom/gbp_contract_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -singular_db gbp_contract::m_db; - -gbp_contract::event_handler gbp_contract::m_evh; - -gbp_contract::gbp_contract(scope_t scope, - sclass_t sclass, - sclass_t dclass, - const ACL::l3_list& acl, - const gbp_rules_t& rules, - const ethertype_set_t& allowed_ethertypes) - : m_hw(false) - , m_scope(scope) - , m_sclass(sclass) - , m_dclass(dclass) - , m_acl(acl.singular()) - , m_gbp_rules(rules) - , m_allowed_ethertypes(allowed_ethertypes) -{ -} - -gbp_contract::gbp_contract(const gbp_contract& gbpc) - : m_hw(gbpc.m_hw) - , m_scope(gbpc.m_scope) - , m_sclass(gbpc.m_sclass) - , m_dclass(gbpc.m_dclass) - , m_acl(gbpc.m_acl) - , m_gbp_rules(gbpc.m_gbp_rules) - , m_allowed_ethertypes(gbpc.m_allowed_ethertypes) -{ -} - -gbp_contract::~gbp_contract() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -const gbp_contract::key_t -gbp_contract::key() const -{ - return (std::make_tuple(m_scope, m_sclass, m_dclass)); -} - -bool -gbp_contract::operator==(const gbp_contract& gbpc) const -{ - return ((key() == gbpc.key()) && (m_acl->handle() == gbpc.m_acl->handle())); -} - -void -gbp_contract::sweep() -{ - if (m_hw) { - HW::enqueue( - new gbp_contract_cmds::delete_cmd(m_hw, m_scope, m_sclass, m_dclass)); - } - HW::write(); -} - -void -gbp_contract::replay() -{ - if (m_hw) { - HW::enqueue(new gbp_contract_cmds::create_cmd( - m_hw, m_scope, m_sclass, m_dclass, m_acl->handle(), m_gbp_rules, - m_allowed_ethertypes)); - } -} - -std::string -gbp_contract::to_string() const -{ - std::ostringstream s; - s << "gbp-contract:[{" << m_scope << ", " << m_sclass << ", " << m_dclass - << "}, " << m_acl->to_string(); - if (m_gbp_rules.size()) { - auto it = m_gbp_rules.cbegin(); - while (it != m_gbp_rules.cend()) { - s << it->to_string(); - ++it; - } - } - s << "[ethertype:"; - for (auto e : m_allowed_ethertypes) - s << " " << e; - s << "]]"; - - return (s.str()); -} - -void -gbp_contract::update(const gbp_contract& r) -{ - /* - * create the table if it is not yet created - */ - if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new gbp_contract_cmds::create_cmd( - m_hw, m_scope, m_sclass, m_dclass, m_acl->handle(), m_gbp_rules, - m_allowed_ethertypes)); - } -} - -std::shared_ptr -gbp_contract::find_or_add(const gbp_contract& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -gbp_contract::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -gbp_contract::singular() const -{ - return find_or_add(*this); -} - -void -gbp_contract::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -gbp_contract::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "gbp-contract" }, "GBP Contract", this); -} - -void -gbp_contract::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -gbp_contract::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr acl = - ACL::l3_list::find(payload.contract.acl_index); - - if (acl) { - gbp_contract::gbp_rules_t rules; - - for (uint8_t i = 0; i < payload.contract.n_rules; i++) { - const gbp_rule::action_t action = - gbp_rule::action_t::from_int(payload.contract.rules[i].action); - const gbp_rule::hash_mode_t hm = gbp_rule::hash_mode_t::from_int( - payload.contract.rules[i].nh_set.hash_mode); - gbp_rule::next_hops_t nhs; - for (u8 j = 0; j < payload.contract.rules[i].nh_set.n_nhs; j++) { - gbp_rule::next_hop_t nh( - from_api(payload.contract.rules[i].nh_set.nhs[j].ip), - from_api(payload.contract.rules[i].nh_set.nhs[j].mac), - payload.contract.rules[i].nh_set.nhs[j].bd_id, - payload.contract.rules[i].nh_set.nhs[j].rd_id); - nhs.insert(nh); - } - gbp_rule::next_hop_set_t next_hop_set(hm, nhs); - gbp_rule gr(i, next_hop_set, action); - rules.insert(gr); - } - - ethertype_set_t allowed_ethertypes; - u8 *data, n_et; - u16* et; - - data = (((u8*)&payload.contract.n_ether_types) + - (sizeof(payload.contract.rules[0]) * payload.contract.n_rules)); - n_et = *data; - et = (u16*)(++data); - - for (uint8_t i = 0; i < n_et; i++) { - allowed_ethertypes.insert(ethertype_t::from_numeric_val(et[i])); - } - - gbp_contract gbpc(payload.contract.scope, payload.contract.sclass, - payload.contract.dclass, *acl, rules, - allowed_ethertypes); - OM::commit(key, gbpc); - VOM_LOG(log_level_t::DEBUG) << "read: " << gbpc.to_string(); - } else { - VOM_LOG(log_level_t::ERROR) << " no ACL:" << payload.contract.acl_index; - } - } -} - -dependency_t -gbp_contract::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -gbp_contract::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const gbp_contract::key_t& key) -{ - os << "{ " << std::get<0>(key) << "," << std::get<1>(key) << ", " - << std::get<2>(key) << "}"; - - return (os); -} - -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_contract.hpp b/extras/vom/vom/gbp_contract.hpp deleted file mode 100644 index caf5a3c5a0e..00000000000 --- a/extras/vom/vom/gbp_contract.hpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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_GBP_CONTRACT_H__ -#define __VOM_GBP_CONTRACT_H__ - -#include "vom/acl_l3_list.hpp" -#include "vom/gbp_rule.hpp" -#include "vom/gbp_types.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" -#include "vom/types.hpp" - -namespace VOM { - -/** - * A entry in the ARP termination table of a Bridge Domain - */ -class gbp_contract : public object_base -{ -public: - /** - * set of gbp rules - */ - typedef std::set gbp_rules_t; - - /** - * The key for a contract is the pair of EPG-IDs - */ - typedef std::tuple key_t; - - /** - * A set of allowed ethertypes - */ - typedef std::set ethertype_set_t; - - /** - * Construct a GBP contract - */ - gbp_contract(scope_t scope, - sclass_t sclass, - sclass_t dclass, - const ACL::l3_list& acl, - const gbp_rules_t& gpb_rules, - const ethertype_set_t& allowed_ethertypes); - - /** - * Copy Construct - */ - gbp_contract(const gbp_contract& r); - - /** - * Destructor - */ - ~gbp_contract(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const gbp_contract& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_contract& obj); - - /** - * Find or add the instance of the contract domain in the OM - */ - static std::shared_ptr find_or_add(const gbp_contract& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the endpoint - */ - HW::item m_hw; - - /* - * The scope of the contract - */ - scope_t m_scope; - - /** - * The source EPG ID - */ - sclass_t m_sclass; - - /** - * The destination EPG ID - */ - sclass_t m_dclass; - - /** - * The ACL applied to traffic between the gourps - */ - std::shared_ptr m_acl; - - /** - * The gbp rules applied to traffic between the gourps - */ - gbp_rules_t m_gbp_rules; - - /** - * the set of Ether-types allowed by this contract - */ - ethertype_set_t m_allowed_ethertypes; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, const gbp_contract::key_t& key); -}; // namespace - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_contract_cmds.cpp b/extras/vom/vom/gbp_contract_cmds.cpp deleted file mode 100644 index 1bb06bdaa69..00000000000 --- a/extras/vom/vom/gbp_contract_cmds.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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/gbp_contract_cmds.hpp" -#include "vom/api_types.hpp" - -namespace VOM { -namespace gbp_contract_cmds { - -create_cmd::create_cmd(HW::item& item, - scope_t scope, - sclass_t sclass, - sclass_t dclass, - const handle_t& acl, - const gbp_contract::gbp_rules_t& gbp_rules, - const gbp_contract::ethertype_set_t& allowed_ethertypes) - : rpc_cmd(item) - , m_scope(scope) - , m_sclass(sclass) - , m_dclass(dclass) - , m_acl(acl) - , m_gbp_rules(gbp_rules) - , m_allowed_ethertypes(allowed_ethertypes) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_acl == other.m_acl) && (m_sclass == other.m_sclass) && - (m_scope == other.m_scope) && (m_dclass == other.m_dclass) && - (m_gbp_rules == other.m_gbp_rules) && - (m_allowed_ethertypes == other.m_allowed_ethertypes)); -} - -#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0])) - -rc_t -create_cmd::issue(connection& con) -{ - size_t n_rules = m_gbp_rules.size(); - uint32_t ii = 0; - - msg_t req(con.ctx(), n_rules, std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.contract.acl_index = m_acl.value(); - payload.contract.scope = m_scope; - payload.contract.sclass = m_sclass; - payload.contract.dclass = m_dclass; - payload.contract.n_rules = n_rules; - payload.contract.n_ether_types = m_allowed_ethertypes.size(); - - for (auto tt : m_allowed_ethertypes) { - payload.contract.allowed_ethertypes[ii] = tt.value(); - ii++; - if (ii == ARRAY_LEN(payload.contract.allowed_ethertypes)) - break; - } - - ii = 0; - for (auto rule : m_gbp_rules) { - if (rule.action() == gbp_rule::action_t::REDIRECT) - payload.contract.rules[ii].action = GBP_API_RULE_REDIRECT; - else if (rule.action() == gbp_rule::action_t::PERMIT) - payload.contract.rules[ii].action = GBP_API_RULE_PERMIT; - else - payload.contract.rules[ii].action = GBP_API_RULE_DENY; - - if (rule.nhs().hash_mode() == gbp_rule::hash_mode_t::SYMMETRIC) - payload.contract.rules[ii].nh_set.hash_mode = GBP_API_HASH_MODE_SYMMETRIC; - else if (rule.nhs().hash_mode() == gbp_rule::hash_mode_t::SRC_IP) - payload.contract.rules[ii].nh_set.hash_mode = GBP_API_HASH_MODE_SRC_IP; - else - payload.contract.rules[ii].nh_set.hash_mode = GBP_API_HASH_MODE_DST_IP; - - const gbp_rule::next_hops_t& next_hops = rule.nhs().next_hops(); - uint8_t jj = 0, nh_size = (next_hops.size() > 8) ? 8 : next_hops.size(); - - payload.contract.rules[ii].nh_set.n_nhs = nh_size; - for (auto nh : next_hops) { - to_api(nh.getIp(), payload.contract.rules[ii].nh_set.nhs[jj].ip); - to_api(nh.getMac(), payload.contract.rules[ii].nh_set.nhs[jj].mac); - payload.contract.rules[ii].nh_set.nhs[jj].bd_id = nh.getBdId(); - payload.contract.rules[ii].nh_set.nhs[jj].rd_id = nh.getRdId(); - jj++; - } - ++ii; - } - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-contract-create: " << m_hw_item.to_string() - << " sclass:" << m_sclass << " dclass:" << m_dclass << " acl:" << m_acl; - s << "[ethertype:"; - for (auto e : m_allowed_ethertypes) - s << " " << e; - s << "]"; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - scope_t scope, - sclass_t sclass, - sclass_t dclass) - : rpc_cmd(item) - , m_scope(scope) - , m_sclass(sclass) - , m_dclass(dclass) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return ((m_sclass == other.m_sclass) && (m_dclass == other.m_dclass)); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), 0, std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.contract.acl_index = ~0; - payload.contract.scope = m_scope; - payload.contract.sclass = m_sclass; - payload.contract.dclass = m_dclass; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-contract-delete: " << m_hw_item.to_string() << " scope: " << m_scope - << " sclass:" << m_sclass << " dclass:" << m_dclass; - - return (s.str()); -} - -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 ("gbp-contract-dump"); -} - -}; // namespace gbp_contract_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_contract_cmds.hpp b/extras/vom/vom/gbp_contract_cmds.hpp deleted file mode 100644 index d9fe1d74e37..00000000000 --- a/extras/vom/vom/gbp_contract_cmds.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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_GBP_CONTRACT_CMDS_H__ -#define __VOM_GBP_CONTRACT_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_contract.hpp" - -#include - -namespace VOM { -namespace gbp_contract_cmds { - -/** - * A command class that creates or updates the GBP contract - */ -class create_cmd - : public rpc_cmd, vapi::Gbp_contract_add_del> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - scope_t scope, - sclass_t sclass, - sclass_t dclass, - const handle_t& acl, - const gbp_contract::gbp_rules_t& gbp_rules, - const gbp_contract::ethertype_set_t& allowed_ethertypes); - - /** - * 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; - -private: - const scope_t m_scope; - const sclass_t m_sclass; - const sclass_t m_dclass; - const handle_t m_acl; - const gbp_contract::gbp_rules_t& m_gbp_rules; - const gbp_contract::ethertype_set_t& m_allowed_ethertypes; -}; - -/** - * A cmd class that deletes a GBP contract - */ -class delete_cmd - : public rpc_cmd, vapi::Gbp_contract_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, - scope_t scope, - sclass_t sclass, - sclass_t dclass); - - /** - * 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: - const scope_t m_scope; - const sclass_t m_sclass; - const sclass_t m_dclass; -}; - -/** - * A cmd class that Dumps all the GBP contracts - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace gbp_contract_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_endpoint.cpp b/extras/vom/vom/gbp_endpoint.cpp deleted file mode 100644 index ef406b16565..00000000000 --- a/extras/vom/vom/gbp_endpoint.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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/gbp_endpoint.hpp" -#include "vom/api_types.hpp" -#include "vom/gbp_endpoint_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -singular_db gbp_endpoint::m_db; - -gbp_endpoint::event_handler gbp_endpoint::m_evh; - -const gbp_endpoint::flags_t gbp_endpoint::flags_t::NONE(0, "none"); -const gbp_endpoint::flags_t gbp_endpoint::flags_t::BOUNCE(1, "bounce"); -const gbp_endpoint::flags_t gbp_endpoint::flags_t::LEARNT(2, "learnt"); -const gbp_endpoint::flags_t gbp_endpoint::flags_t::REMOTE(4, "remote"); -const gbp_endpoint::flags_t gbp_endpoint::flags_t::EXTERNAL(8, "external"); - -gbp_endpoint::flags_t::flags_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -gbp_endpoint::gbp_endpoint( - const interface& itf, - const std::vector& ip_addrs, - const mac_address_t& mac, - const gbp_endpoint_group& epg, - const flags_t& flags) - : m_hdl(handle_t::INVALID) - , m_itf(itf.singular()) - , m_ips(ip_addrs) - , m_mac(mac) - , m_epg(epg.singular()) - , m_flags(flags) -{ -} - -gbp_endpoint::gbp_endpoint(const gbp_endpoint& gbpe) - : m_hdl(gbpe.m_hdl) - , m_itf(gbpe.m_itf) - , m_ips(gbpe.m_ips) - , m_mac(gbpe.m_mac) - , m_epg(gbpe.m_epg) - , m_flags(gbpe.m_flags) -{ -} - -gbp_endpoint::~gbp_endpoint() -{ - sweep(); - m_db.release(key(), this); -} - -const gbp_endpoint::key_t -gbp_endpoint::key() const -{ - return (std::make_pair(m_itf->key(), m_mac)); -} - -bool -gbp_endpoint::operator==(const gbp_endpoint& gbpe) const -{ - return ((key() == gbpe.key()) && (m_epg == gbpe.m_epg) && - (m_flags == gbpe.m_flags)); -} - -void -gbp_endpoint::sweep() -{ - if (m_hdl) { - HW::enqueue(new gbp_endpoint_cmds::delete_cmd(m_hdl)); - } - HW::write(); -} - -void -gbp_endpoint::replay() -{ - if (m_hdl) { - HW::enqueue(new gbp_endpoint_cmds::create_cmd( - m_hdl, m_itf->handle(), m_ips, m_mac, m_epg->sclass(), m_flags)); - } -} - -std::string -gbp_endpoint::to_string() const -{ - std::ostringstream s; - s << "gbp-endpoint:[" << m_itf->to_string() << ", ips:["; - - for (auto ip : m_ips) - s << ip.to_string(); - - s << "], " << m_mac.to_string() << ", epg:" << m_epg->to_string() << "]"; - - return (s.str()); -} - -void -gbp_endpoint::update(const gbp_endpoint& r) -{ - if (rc_t::OK != m_hdl.rc()) { - HW::enqueue(new gbp_endpoint_cmds::create_cmd( - m_hdl, m_itf->handle(), m_ips, m_mac, m_epg->sclass(), m_flags)); - } -} - -std::shared_ptr -gbp_endpoint::find_or_add(const gbp_endpoint& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -gbp_endpoint::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -gbp_endpoint::singular() const -{ - return find_or_add(*this); -} - -void -gbp_endpoint::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -gbp_endpoint::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "gbp-endpoint" }, "GBP Endpoints", this); -} - -void -gbp_endpoint::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -gbp_endpoint::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::vector addresses; - - for (uint8_t n = 0; n < payload.endpoint.n_ips; n++) - addresses.push_back(from_api(payload.endpoint.ips[n])); - std::shared_ptr itf = - interface::find(payload.endpoint.sw_if_index); - std::shared_ptr epg = - gbp_endpoint_group::find(payload.endpoint.sclass); - mac_address_t mac = from_api(payload.endpoint.mac); - - VOM_LOG(log_level_t::DEBUG) << "data: " << payload.endpoint.sw_if_index; - - if (itf && epg) { - gbp_endpoint gbpe(*itf, addresses, mac, *epg); - OM::commit(key, gbpe); - - VOM_LOG(log_level_t::DEBUG) << "read: " << gbpe.to_string(); - } else { - VOM_LOG(log_level_t::ERROR) - << "no interface:" << payload.endpoint.sw_if_index - << "or sclass:" << payload.endpoint.sclass; - } - } -} - -dependency_t -gbp_endpoint::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -gbp_endpoint::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const gbp_endpoint::key_t& key) -{ - os << key.first << "," << key.second; - - return os; -} - -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_endpoint.hpp b/extras/vom/vom/gbp_endpoint.hpp deleted file mode 100644 index 8008e3b1c67..00000000000 --- a/extras/vom/vom/gbp_endpoint.hpp +++ /dev/null @@ -1,218 +0,0 @@ -/* - * 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_GBP_ENDPOINT_H__ -#define __VOM_GBP_ENDPOINT_H__ - -#include -#include - -#include "vom/gbp_endpoint_group.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A GBP Enpoint (i.e. a VM) - */ -class gbp_endpoint : public object_base -{ -public: - /** - * Endpoint flags - */ - struct flags_t : enum_base - { - const static flags_t NONE; - const static flags_t BOUNCE; - const static flags_t REMOTE; - const static flags_t LEARNT; - const static flags_t EXTERNAL; - - private: - /** - * Private constructor taking the value and the string name - */ - flags_t(int v, const std::string& s); - }; - - /** - * The key for a GBP endpoint; interface and IP - */ - typedef std::pair key_t; - - /** - * Construct a GBP endpoint - */ - gbp_endpoint(const interface& itf, - const std::vector& ip_addr, - const mac_address_t& mac, - const gbp_endpoint_group& epg, - const flags_t& flags = flags_t::NONE); - - /** - * Copy Construct - */ - gbp_endpoint(const gbp_endpoint& r); - - /** - * Destructor - */ - ~gbp_endpoint(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const gbp_endpoint& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_endpoint& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const gbp_endpoint& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the endpoint - */ - HW::item m_hdl; - - /** - * The interface the endpoint is attached to. - */ - std::shared_ptr m_itf; - - /** - * The IP address of the endpoint - */ - std::vector m_ips; - - /** - * The MAC address of the endpoint - */ - mac_address_t m_mac; - - /** - * The EPG the endpoint is in - */ - std::shared_ptr m_epg; - - /** - * Endpoint flags - */ - flags_t m_flags; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, const gbp_endpoint::key_t& key); -}; // namespace - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_endpoint_cmds.cpp b/extras/vom/vom/gbp_endpoint_cmds.cpp deleted file mode 100644 index f0c55ebc4da..00000000000 --- a/extras/vom/vom/gbp_endpoint_cmds.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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/gbp_endpoint_cmds.hpp" -#include "vom/api_types.hpp" - -DEFINE_VAPI_MSG_IDS_GBP_API_JSON; - -namespace VOM { -namespace gbp_endpoint_cmds { - -static vapi_enum_gbp_endpoint_flags -to_api(const gbp_endpoint::flags_t& in) -{ - vapi_enum_gbp_endpoint_flags out = GBP_API_ENDPOINT_FLAG_NONE; - - if (in & gbp_endpoint::flags_t::REMOTE) - out = (vapi_enum_gbp_endpoint_flags)(out | GBP_API_ENDPOINT_FLAG_REMOTE); - if (in & gbp_endpoint::flags_t::BOUNCE) - out = (vapi_enum_gbp_endpoint_flags)(out | GBP_API_ENDPOINT_FLAG_BOUNCE); - if (in & gbp_endpoint::flags_t::LEARNT) - out = (vapi_enum_gbp_endpoint_flags)(out | GBP_API_ENDPOINT_FLAG_LEARNT); - if (in & gbp_endpoint::flags_t::EXTERNAL) - out = (vapi_enum_gbp_endpoint_flags)(out | GBP_API_ENDPOINT_FLAG_EXTERNAL); - - return (out); -} - -create_cmd::create_cmd(HW::item& item, - const handle_t& itf, - const std::vector& ip_addrs, - const mac_address_t& mac, - sclass_t sclass, - const gbp_endpoint::flags_t& flags) - : rpc_cmd(item) - , m_itf(itf) - , m_ip_addrs(ip_addrs) - , m_mac(mac) - , m_sclass(sclass) - , m_flags(flags) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_ip_addrs == other.m_ip_addrs) && - (m_mac == other.m_mac) && (m_sclass == other.m_sclass) && - (m_flags == other.m_flags)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), m_ip_addrs.size() * sizeof(vapi_type_address), - std::ref(*this)); - uint8_t n; - - auto& payload = req.get_request().get_payload(); - payload.endpoint.sw_if_index = m_itf.value(); - payload.endpoint.sclass = m_sclass; - payload.endpoint.n_ips = m_ip_addrs.size(); - payload.endpoint.flags = to_api(m_flags); - - for (n = 0; n < payload.endpoint.n_ips; n++) { - VOM::to_api(m_ip_addrs[n], payload.endpoint.ips[n]); - } - to_api(m_mac, payload.endpoint.mac); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -vapi_error_e -create_cmd::operator()(vapi::Gbp_endpoint_add& reply) -{ - int handle = reply.get_response().get_payload().handle; - int retval = reply.get_response().get_payload().retval; - - VOM_LOG(log_level_t::DEBUG) << this->to_string() << " " << retval; - - rc_t rc = rc_t::from_vpp_retval(retval); - handle_t hdl = handle_t::INVALID; - - if (rc_t::OK == rc) { - hdl = handle; - } - - this->fulfill(HW::item(hdl, rc)); - - return (VAPI_OK); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-endpoint-create: " << m_hw_item.to_string() << " itf:" << m_itf - << " ips:["; - for (auto ip : m_ip_addrs) - s << ip.to_string(); - - s << "] mac:" << m_mac << " slcass:" << m_sclass - << " flags:" << m_flags.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item) - : rpc_cmd(item) -{ -} - -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)); - - auto& payload = req.get_request().get_payload(); - payload.handle = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-endpoint-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("gbp-endpoint-dump"); -} - -}; // namespace gbp_endpoint_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_endpoint_cmds.hpp b/extras/vom/vom/gbp_endpoint_cmds.hpp deleted file mode 100644 index 4b9036aca00..00000000000 --- a/extras/vom/vom/gbp_endpoint_cmds.hpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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_GBP_ENDPOINT_CMDS_H__ -#define __VOM_GBP_ENDPOINT_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_endpoint.hpp" - -#include - -namespace VOM { -namespace gbp_endpoint_cmds { - -/** - * A command class that creates or updates the GBP endpoint - */ -class create_cmd : public rpc_cmd, vapi::Gbp_endpoint_add> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - const handle_t& itf, - const std::vector& ip_addrs, - const mac_address_t& mac, - sclass_t sclass, - const gbp_endpoint::flags_t& flags); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - virtual vapi_error_e operator()(vapi::Gbp_endpoint_add& reply); - - /** - * Comparison operator - only used for UT - */ - bool operator==(const create_cmd& i) const; - -private: - const handle_t m_itf; - const std::vector m_ip_addrs; - const mac_address_t m_mac; - const sclass_t m_sclass; - const gbp_endpoint::flags_t m_flags; -}; - -/** - * A cmd class that deletes a GBP endpoint - */ -class delete_cmd : public rpc_cmd, vapi::Gbp_endpoint_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item); - - /** - * 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: - const handle_t m_hdl; -}; - -/** - * A cmd class that Dumps all the GBP endpoints - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace gbp_enpoint_cms -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_endpoint_group.cpp b/extras/vom/vom/gbp_endpoint_group.cpp deleted file mode 100644 index abec585c744..00000000000 --- a/extras/vom/vom/gbp_endpoint_group.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* - * 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/gbp_endpoint_group.hpp" -#include "vom/gbp_endpoint_group_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -singular_db - gbp_endpoint_group::m_db; - -gbp_endpoint_group::event_handler gbp_endpoint_group::m_evh; - -gbp_endpoint_group::retention_t::retention_t() - : remote_ep_timeout(0xffffffff) -{ -} -gbp_endpoint_group::retention_t::retention_t(uint32_t remote_ep_timeout_) - : remote_ep_timeout(remote_ep_timeout_) -{ -} - -bool -gbp_endpoint_group::retention_t::operator==(const retention_t& o) const -{ - return (remote_ep_timeout == o.remote_ep_timeout); -} - -std::string -gbp_endpoint_group::retention_t::to_string() const -{ - return std::to_string(remote_ep_timeout); -} - -gbp_endpoint_group::gbp_endpoint_group(vnid_t vnid, - sclass_t sclass, - const interface& itf, - const gbp_route_domain& rd, - const gbp_bridge_domain& bd) - : m_hw(false) - , m_vnid(vnid) - , m_sclass(sclass) - , m_itf(itf.singular()) - , m_rd(rd.singular()) - , m_bd(bd.singular()) - , m_retention() -{ -} - -gbp_endpoint_group::gbp_endpoint_group(vnid_t vnid, - sclass_t sclass, - const gbp_route_domain& rd, - const gbp_bridge_domain& bd) - : m_hw(false) - , m_vnid(vnid) - , m_sclass(sclass) - , m_itf() - , m_rd(rd.singular()) - , m_bd(bd.singular()) - , m_retention() -{ -} - -gbp_endpoint_group::gbp_endpoint_group(sclass_t sclass, - const gbp_route_domain& rd, - const gbp_bridge_domain& bd) - : m_hw(false) - , m_vnid(~0) - , m_sclass(sclass) - , m_itf() - , m_rd(rd.singular()) - , m_bd(bd.singular()) - , m_retention() -{ -} - -gbp_endpoint_group::gbp_endpoint_group(const gbp_endpoint_group& epg) - : m_hw(epg.m_hw) - , m_vnid(epg.m_vnid) - , m_sclass(epg.m_sclass) - , m_itf(epg.m_itf) - , m_rd(epg.m_rd) - , m_bd(epg.m_bd) - , m_retention(epg.m_retention) -{ -} - -gbp_endpoint_group::~gbp_endpoint_group() -{ - sweep(); - m_db.release(key(), this); -} - -const gbp_endpoint_group::key_t -gbp_endpoint_group::key() const -{ - return (m_sclass); -} - -vnid_t -gbp_endpoint_group::vnid() const -{ - return (m_vnid); -} - -void -gbp_endpoint_group::set(const retention_t& retention) -{ - m_retention = retention; -} - -sclass_t -gbp_endpoint_group::sclass() const -{ - return (m_sclass); -} - -bool -gbp_endpoint_group::operator==(const gbp_endpoint_group& gg) const -{ - return (key() == gg.key() && (m_vnid == gg.m_vnid) && - (m_retention == gg.m_retention) && (m_itf == gg.m_itf) && - (m_rd == gg.m_rd) && (m_bd == gg.m_bd)); -} - -void -gbp_endpoint_group::sweep() -{ - if (m_hw) { - HW::enqueue(new gbp_endpoint_group_cmds::delete_cmd(m_hw, m_vnid)); - } - HW::write(); -} - -void -gbp_endpoint_group::replay() -{ - if (m_hw) { - HW::enqueue(new gbp_endpoint_group_cmds::create_cmd( - m_hw, m_vnid, m_sclass, m_bd->id(), m_rd->id(), m_retention, - (m_itf ? m_itf->handle() : handle_t::INVALID))); - } -} - -std::string -gbp_endpoint_group::to_string() const -{ - std::ostringstream s; - s << "gbp-endpoint-group:[" - << "vnid:" << m_vnid << ", sclass:" << m_sclass << ", " - << "retention:[" << m_retention.to_string() << "], " - << (m_itf ? m_itf->to_string() : "NULL") << ", " << m_bd->to_string() - << ", " << m_rd->to_string() << "]"; - - return (s.str()); -} - -void -gbp_endpoint_group::update(const gbp_endpoint_group& r) -{ - if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new gbp_endpoint_group_cmds::create_cmd( - m_hw, m_vnid, m_sclass, m_bd->id(), m_rd->id(), m_retention, - (m_itf ? m_itf->handle() : handle_t::INVALID))); - } -} - -std::shared_ptr -gbp_endpoint_group::find_or_add(const gbp_endpoint_group& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -gbp_endpoint_group::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -gbp_endpoint_group::singular() const -{ - return find_or_add(*this); -} - -void -gbp_endpoint_group::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -const std::shared_ptr -gbp_endpoint_group::get_route_domain() const -{ - return m_rd; -} - -const std::shared_ptr -gbp_endpoint_group::get_bridge_domain() const -{ - return m_bd; -} - -gbp_endpoint_group::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "gbp-endpoint-group" }, "GBP Endpoint_Groups", - this); -} - -void -gbp_endpoint_group::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -gbp_endpoint_group::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = - interface::find(payload.epg.uplink_sw_if_index); - std::shared_ptr rd = - gbp_route_domain::find(payload.epg.rd_id); - std::shared_ptr bd = - gbp_bridge_domain::find(payload.epg.bd_id); - - VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.epg.uplink_sw_if_index - << ", " << payload.epg.rd_id << ", " - << payload.epg.bd_id << "]"; - - if (itf && bd && rd) { - gbp_endpoint_group gbpe(payload.epg.vnid, payload.epg.sclass, *itf, *rd, - *bd); - OM::commit(key, gbpe); - - VOM_LOG(log_level_t::DEBUG) << "read: " << gbpe.to_string(); - } else if (bd && rd) { - gbp_endpoint_group gbpe(payload.epg.sclass, *rd, *bd); - OM::commit(key, gbpe); - - VOM_LOG(log_level_t::DEBUG) << "read: " << gbpe.to_string(); - } else { - VOM_LOG(log_level_t::ERROR) << "no itf:" << payload.epg.uplink_sw_if_index - << " or BD:" << payload.epg.bd_id - << " or RD:" << payload.epg.rd_id; - } - } -} - -dependency_t -gbp_endpoint_group::event_handler::order() const -{ - return (dependency_t::ACL); -} - -void -gbp_endpoint_group::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/gbp_endpoint_group.hpp b/extras/vom/vom/gbp_endpoint_group.hpp deleted file mode 100644 index e15a1885317..00000000000 --- a/extras/vom/vom/gbp_endpoint_group.hpp +++ /dev/null @@ -1,245 +0,0 @@ -/* - * 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_GBP_ENDPOINT_GROUP_H__ -#define __VOM_GBP_ENDPOINT_GROUP_H__ - -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" -#include "vom/types.hpp" - -#include "vom/gbp_bridge_domain.hpp" -#include "vom/gbp_route_domain.hpp" -#include "vom/gbp_types.hpp" - -namespace VOM { - -/** - * A entry in the ARP termination table of a Bridge Domain - */ -class gbp_endpoint_group : public object_base -{ -public: - /** - * Endpoint Retention Policy Settings - */ - struct retention_t - { - retention_t(); - retention_t(uint32_t remote_ep_timeout); - - retention_t(const retention_t&) = default; - retention_t& operator=(const retention_t&) = default; - - bool operator==(const retention_t& o) const; - std::string to_string() const; - - /** - * Remote Endpoint timeout/ageing - */ - uint32_t remote_ep_timeout; - }; - - /** - * The key for a GBP endpoint group is its ID - */ - typedef sclass_t key_t; - - /** - * Construct a GBP endpoint_group - */ - gbp_endpoint_group(vnid_t vnid, - sclass_t sclass, - const interface& itf, - const gbp_route_domain& rd, - const gbp_bridge_domain& bd); - gbp_endpoint_group(vnid_t vnid, - sclass_t sclass, - const gbp_route_domain& rd, - const gbp_bridge_domain& bd); - gbp_endpoint_group(sclass_t sclass, - const gbp_route_domain& rd, - const gbp_bridge_domain& bd); - - /** - * Copy Construct - */ - gbp_endpoint_group(const gbp_endpoint_group& r); - - /** - * Destructor - */ - ~gbp_endpoint_group(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const gbp_endpoint_group& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - - /** - * Get the ID of the EPG - */ - vnid_t vnid() const; - sclass_t sclass() const; - - const std::shared_ptr get_route_domain() const; - const std::shared_ptr get_bridge_domain() const; - - void set(const retention_t& retention); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_endpoint_group& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add( - const gbp_endpoint_group& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the endpoint_group - */ - HW::item m_hw; - - /** - * The EPG ID - */ - vnid_t m_vnid; - - /** - * The SClass on the wire - */ - uint16_t m_sclass; - - /** - * The uplink interface for the endpoint group - */ - std::shared_ptr m_itf; - - /** - * The route-domain the EPG uses - */ - std::shared_ptr m_rd; - - /** - * The bridge-domain the EPG uses - */ - std::shared_ptr m_bd; - - /** - * The Group's EP retention Policy - */ - retention_t m_retention; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -}; // namespace - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_endpoint_group_cmds.cpp b/extras/vom/vom/gbp_endpoint_group_cmds.cpp deleted file mode 100644 index c5618602550..00000000000 --- a/extras/vom/vom/gbp_endpoint_group_cmds.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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/gbp_endpoint_group_cmds.hpp" - -namespace VOM { -namespace gbp_endpoint_group_cmds { - -create_cmd::create_cmd(HW::item& item, - vnid_t vnid, - uint16_t sclass, - uint32_t bd_id, - route::table_id_t rd_id, - const gbp_endpoint_group::retention_t& retention, - const handle_t& itf) - : rpc_cmd(item) - , m_vnid(vnid) - , m_sclass(sclass) - , m_bd_id(bd_id) - , m_rd_id(rd_id) - , m_itf(itf) - , m_retention(retention) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_bd_id == other.m_bd_id) && - (m_rd_id == other.m_rd_id) && (m_vnid == other.m_vnid) && - (m_retention == other.m_retention)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.epg.uplink_sw_if_index = m_itf.value(); - payload.epg.vnid = m_vnid; - payload.epg.sclass = m_sclass; - payload.epg.bd_id = m_bd_id; - payload.epg.rd_id = m_rd_id; - payload.epg.retention.remote_ep_timeout = m_retention.remote_ep_timeout; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-endpoint-group-create: " << m_hw_item.to_string() - << " vnid:" << m_vnid << " bd-id:" << m_bd_id << " rd-id:" << m_rd_id - << " itf:" << m_itf; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, sclass_t sclass) - : rpc_cmd(item) - , m_sclass(sclass) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_sclass == other.m_sclass); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sclass = m_sclass; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-endpoint-group-delete: " << m_hw_item.to_string() - << " sclass:" << m_sclass; - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("gbp-endpoint-group-dump"); -} - -}; // namespace gbp_endpoint_group_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_endpoint_group_cmds.hpp b/extras/vom/vom/gbp_endpoint_group_cmds.hpp deleted file mode 100644 index fa892726bf3..00000000000 --- a/extras/vom/vom/gbp_endpoint_group_cmds.hpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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_GBP_ENDPOINT_GROUP_CMDS_H__ -#define __VOM_GBP_ENDPOINT_GROUP_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_endpoint_group.hpp" - -#include - -namespace VOM { -namespace gbp_endpoint_group_cmds { - -/** -* A command class that creates or updates the GBP endpoint_group -*/ -class create_cmd : public rpc_cmd, vapi::Gbp_endpoint_group_add> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - vnid_t vnid, - uint16_t sclass, - uint32_t bd_id, - route::table_id_t rd_id, - const gbp_endpoint_group::retention_t& retention, - const handle_t& itf); - - /** - * 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; - -private: - const vnid_t m_vnid; - const uint16_t m_sclass; - const uint32_t m_bd_id; - const route::table_id_t m_rd_id; - const handle_t m_itf; - const gbp_endpoint_group::retention_t m_retention; -}; - -/** - * A cmd class that deletes a GBP endpoint_group - */ -class delete_cmd : public rpc_cmd, vapi::Gbp_endpoint_group_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, sclass_t sclass); - - /** - * 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: - const sclass_t m_sclass; -}; - -/** - * A cmd class that Dumps all the GBP endpoint_groups - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace gbp_enpoint_cms -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_ext_itf.cpp b/extras/vom/vom/gbp_ext_itf.cpp deleted file mode 100644 index 91697352cd5..00000000000 --- a/extras/vom/vom/gbp_ext_itf.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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/gbp_ext_itf.hpp" -#include "vom/gbp_ext_itf_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -singular_db gbp_ext_itf::m_db; - -gbp_ext_itf::event_handler gbp_ext_itf::m_evh; - -gbp_ext_itf::gbp_ext_itf(const interface& itf, - const gbp_bridge_domain& gbd, - const gbp_route_domain& grd) - : m_hw(false) - , m_itf(itf.singular()) - , m_bd(gbd.singular()) - , m_rd(grd.singular()) -{ -} - -gbp_ext_itf::gbp_ext_itf(const gbp_ext_itf& gbpe) - : m_hw(gbpe.m_hw) - , m_itf(gbpe.m_itf) - , m_bd(gbpe.m_bd) - , m_rd(gbpe.m_rd) -{ -} - -gbp_ext_itf::~gbp_ext_itf() -{ - sweep(); - m_db.release(key(), this); -} - -const gbp_ext_itf::key_t -gbp_ext_itf::key() const -{ - return (m_itf->key()); -} - -const handle_t& -gbp_ext_itf::handle() const -{ - return m_itf->handle(); -} - -bool -gbp_ext_itf::operator==(const gbp_ext_itf& gei) const -{ - return ((key() == gei.key()) && (m_itf == gei.m_itf) && (m_rd == gei.m_rd) && - (m_bd == gei.m_bd)); -} - -void -gbp_ext_itf::sweep() -{ - if (m_hw) { - HW::enqueue(new gbp_ext_itf_cmds::delete_cmd(m_hw, m_itf->handle())); - } - HW::write(); -} - -void -gbp_ext_itf::replay() -{ - if (m_hw) { - HW::enqueue(new gbp_ext_itf_cmds::create_cmd(m_hw, m_itf->handle(), - m_bd->id(), m_rd->id())); - } -} - -std::string -gbp_ext_itf::to_string() const -{ - std::ostringstream s; - s << "gbp-ext_itf:[" << m_itf->to_string() << ", " << m_bd->to_string() - << ", " << m_rd->to_string() << "]"; - - return (s.str()); -} - -void -gbp_ext_itf::update(const gbp_ext_itf& r) -{ - if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new gbp_ext_itf_cmds::create_cmd(m_hw, m_itf->handle(), - m_bd->id(), m_rd->id())); - } -} - -std::shared_ptr -gbp_ext_itf::find_or_add(const gbp_ext_itf& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -gbp_ext_itf::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -gbp_ext_itf::singular() const -{ - return find_or_add(*this); -} - -void -gbp_ext_itf::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -gbp_ext_itf::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "gbp-ext-itf" }, "GBP External-Itfs", this); -} - -void -gbp_ext_itf::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -gbp_ext_itf::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = - interface::find(payload.ext_itf.sw_if_index); - std::shared_ptr gbd = - gbp_bridge_domain::find(payload.ext_itf.bd_id); - std::shared_ptr grd = - gbp_route_domain::find(payload.ext_itf.rd_id); - - VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.ext_itf.sw_if_index - << ", " << payload.ext_itf.bd_id << ", " - << payload.ext_itf.rd_id << "]"; - - if (itf && gbd && grd) { - gbp_ext_itf ext_itf(*itf, *gbd, *grd); - OM::commit(key, ext_itf); - - VOM_LOG(log_level_t::DEBUG) << "read: " << ext_itf.to_string(); - } else { - VOM_LOG(log_level_t::ERROR) << "no itf:" << payload.ext_itf.sw_if_index - << " or BD:" << payload.ext_itf.bd_id - << " or RD:" << payload.ext_itf.rd_id; - } - } -} - -dependency_t -gbp_ext_itf::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -gbp_ext_itf::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/gbp_ext_itf.hpp b/extras/vom/vom/gbp_ext_itf.hpp deleted file mode 100644 index 20d9b6eff9b..00000000000 --- a/extras/vom/vom/gbp_ext_itf.hpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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_GBP_EXT_ITF_H__ -#define __VOM_GBP_EXT_ITF_H__ - -#include "vom/gbp_bridge_domain.hpp" -#include "vom/gbp_route_domain.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A enternal interface for GBP - */ -class gbp_ext_itf : public object_base -{ -public: - /** - * The key for a GBP ext_itf interface - */ - typedef interface::key_t key_t; - - /** - * Construct a GBP ext_itf - */ - gbp_ext_itf(const interface& itf, - const gbp_bridge_domain& gbd, - const gbp_route_domain& grd); - - /** - * Copy Construct - */ - gbp_ext_itf(const gbp_ext_itf& r); - - /** - * Destructor - */ - ~gbp_ext_itf(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const gbp_ext_itf& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the ext_itf interface in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - - /** - * return the ext_itfulation interface's handle - */ - const handle_t& handle() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_ext_itf& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const gbp_ext_itf& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the ext_itf - */ - HW::item m_hw; - - /** - * The interface the ext_itf is attached to. - */ - std::shared_ptr m_itf; - - /** - * The BD & RD the ext_itf is in - */ - std::shared_ptr m_bd; - std::shared_ptr m_rd; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_ext_itf_cmds.cpp b/extras/vom/vom/gbp_ext_itf_cmds.cpp deleted file mode 100644 index b2090ea0fa5..00000000000 --- a/extras/vom/vom/gbp_ext_itf_cmds.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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/gbp_ext_itf_cmds.hpp" - -namespace VOM { -namespace gbp_ext_itf_cmds { - -create_cmd::create_cmd(HW::item& item, - const handle_t& itf, - uint32_t bd_id, - uint32_t rd_id) - : rpc_cmd(item) - , m_itf(itf) - , m_bd_id(bd_id) - , m_rd_id(rd_id) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_bd_id == other.m_bd_id) && - (m_rd_id == other.m_rd_id)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.ext_itf.sw_if_index = m_itf.value(); - payload.ext_itf.bd_id = m_bd_id; - payload.ext_itf.rd_id = m_rd_id; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-ext_itf-create: " << m_hw_item.to_string() << " itf:" << m_itf - << " bd-id:" << m_bd_id << " rd-id:" << m_rd_id; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.ext_itf.sw_if_index = m_itf.value(); - payload.ext_itf.bd_id = ~0; - payload.ext_itf.rd_id = ~0; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-ext-itf-delete: " << m_hw_item.to_string() << " itf:" << m_itf; - - return (s.str()); -} - -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 ("gbp-ext-itf-dump"); -} - -}; // namespace gbp_ext_itf_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_ext_itf_cmds.hpp b/extras/vom/vom/gbp_ext_itf_cmds.hpp deleted file mode 100644 index 51052b9a360..00000000000 --- a/extras/vom/vom/gbp_ext_itf_cmds.hpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * 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_GBP_EXT_ITF_CMDS_H__ -#define __VOM_GBP_EXT_ITF_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_ext_itf.hpp" - -#include - -namespace VOM { -namespace gbp_ext_itf_cmds { - -/** -* A command class that creates or updates the GBP ext_itf -*/ -class create_cmd : public rpc_cmd, vapi::Gbp_ext_itf_add_del> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - const handle_t& itf, - uint32_t bd_id, - uint32_t rd_id); - - /** - * 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; - -private: - const handle_t m_itf; - const uint32_t m_bd_id; - const uint32_t m_rd_id; -}; - -/** - * A cmd class that deletes a GBP ext_itf - */ -class delete_cmd : public rpc_cmd, vapi::Gbp_ext_itf_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, const handle_t& itf); - - /** - * 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: - const handle_t m_itf; -}; - -/** - * A cmd class that Dumps all the GBP ext_itfs - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace gbp_ext_itf_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_recirc.cpp b/extras/vom/vom/gbp_recirc.cpp deleted file mode 100644 index 19cb2da60e2..00000000000 --- a/extras/vom/vom/gbp_recirc.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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/gbp_recirc.hpp" -#include "vom/gbp_recirc_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -gbp_recirc::type_t::type_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -const gbp_recirc::type_t gbp_recirc::type_t::INTERNAL(0, "internal"); -const gbp_recirc::type_t gbp_recirc::type_t::EXTERNAL(1, "external"); - -singular_db gbp_recirc::m_db; - -gbp_recirc::event_handler gbp_recirc::m_evh; - -gbp_recirc::gbp_recirc(const interface& itf, - const type_t& type, - const gbp_endpoint_group& epg) - : m_hw(false) - , m_itf(itf.singular()) - , m_type(type) - , m_epg(epg.singular()) -{ -} - -gbp_recirc::gbp_recirc(const gbp_recirc& gbpe) - : m_hw(gbpe.m_hw) - , m_itf(gbpe.m_itf) - , m_type(gbpe.m_type) - , m_epg(gbpe.m_epg) -{ -} - -gbp_recirc::~gbp_recirc() -{ - sweep(); - m_db.release(key(), this); -} - -const gbp_recirc::key_t -gbp_recirc::key() const -{ - return (m_itf->key()); -} - -const handle_t& -gbp_recirc::handle() const -{ - return m_itf->handle(); -} - -bool -gbp_recirc::operator==(const gbp_recirc& gbpe) const -{ - return ((key() == gbpe.key()) && (m_type == gbpe.m_type) && - (m_itf == gbpe.m_itf) && (m_epg == gbpe.m_epg)); -} - -void -gbp_recirc::sweep() -{ - if (m_hw) { - HW::enqueue(new gbp_recirc_cmds::delete_cmd(m_hw, m_itf->handle())); - } - HW::write(); -} - -void -gbp_recirc::replay() -{ - if (m_hw) { - HW::enqueue(new gbp_recirc_cmds::create_cmd( - m_hw, m_itf->handle(), (m_type == type_t::EXTERNAL), m_epg->sclass())); - } -} - -std::string -gbp_recirc::to_string() const -{ - std::ostringstream s; - s << "gbp-recirc:[" << m_itf->to_string() << ", type:" << m_type.to_string() - << ", " << m_epg->to_string() << "]"; - - return (s.str()); -} - -void -gbp_recirc::update(const gbp_recirc& r) -{ - if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new gbp_recirc_cmds::create_cmd( - m_hw, m_itf->handle(), (m_type == type_t::EXTERNAL), m_epg->sclass())); - } -} - -std::shared_ptr -gbp_recirc::find_or_add(const gbp_recirc& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -gbp_recirc::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -gbp_recirc::singular() const -{ - return find_or_add(*this); -} - -void -gbp_recirc::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -gbp_recirc::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "gbp-recirc" }, "GBP Recircs", this); -} - -void -gbp_recirc::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -gbp_recirc::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = - interface::find(payload.recirc.sw_if_index); - std::shared_ptr epg = - gbp_endpoint_group::find(payload.recirc.sclass); - - VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.recirc.sw_if_index - << ", " << payload.recirc.sclass << "]"; - - if (itf && epg) { - gbp_recirc recirc( - *itf, (payload.recirc.is_ext ? type_t::EXTERNAL : type_t::INTERNAL), - *epg); - OM::commit(key, recirc); - - VOM_LOG(log_level_t::DEBUG) << "read: " << recirc.to_string(); - } - } -} - -dependency_t -gbp_recirc::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -gbp_recirc::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/gbp_recirc.hpp b/extras/vom/vom/gbp_recirc.hpp deleted file mode 100644 index fee4f6c2502..00000000000 --- a/extras/vom/vom/gbp_recirc.hpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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_GBP_RECIRC_H__ -#define __VOM_GBP_RECIRC_H__ - -#include "vom/gbp_endpoint_group.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A recirculation interface for GBP use pre/post NAT - */ -class gbp_recirc : public object_base -{ -public: - /** - * The key for a GBP recirc interface - */ - typedef interface::key_t key_t; - - struct type_t : public enum_base - { - /** - * Internal recirclation interfaces accept per-NAT translation - * traffic from the external/NAT EPG and inject into the - * private/NAT-inside EPG - */ - const static type_t INTERNAL; - - /** - * External recirculation interfaces accept post-NAT translation - * traffic from the internal EPG and inject into the - * NAT EPG - */ - const static type_t EXTERNAL; - - private: - type_t(int v, const std::string s); - }; - - /** - * Construct a GBP recirc - */ - gbp_recirc(const interface& itf, - const type_t& type, - const gbp_endpoint_group& epg); - - /** - * Copy Construct - */ - gbp_recirc(const gbp_recirc& r); - - /** - * Destructor - */ - ~gbp_recirc(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const gbp_recirc& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the recirc interface in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - - /** - * return the recirculation interface's handle - */ - const handle_t& handle() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_recirc& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const gbp_recirc& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the recirc - */ - HW::item m_hw; - - /** - * The interface the recirc is attached to. - */ - std::shared_ptr m_itf; - - /** - * Is the reicrc for the external (i.e. post-NAT) or internal - */ - type_t m_type; - - /** - * The EPG the recirc is in - */ - std::shared_ptr m_epg; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_recirc_cmds.cpp b/extras/vom/vom/gbp_recirc_cmds.cpp deleted file mode 100644 index 90b931c0ced..00000000000 --- a/extras/vom/vom/gbp_recirc_cmds.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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/gbp_recirc_cmds.hpp" - -namespace VOM { -namespace gbp_recirc_cmds { - -create_cmd::create_cmd(HW::item& item, - const handle_t& itf, - bool is_ext, - sclass_t sclass) - : rpc_cmd(item) - , m_itf(itf) - , m_is_ext(is_ext) - , m_sclass(sclass) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_is_ext == other.m_is_ext) && - (m_sclass == other.m_sclass)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.recirc.sw_if_index = m_itf.value(); - payload.recirc.sclass = m_sclass; - payload.recirc.is_ext = m_is_ext; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-recirc-create: " << m_hw_item.to_string() << " itf:" << m_itf - << " ext:" << m_is_ext << " sclass:" << m_sclass; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.recirc.sw_if_index = m_itf.value(); - payload.recirc.sclass = ~0; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-recirc-delete: " << m_hw_item.to_string() << " itf:" << m_itf; - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("gbp-recirc-dump"); -} - -}; // namespace gbp_recirc_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_recirc_cmds.hpp b/extras/vom/vom/gbp_recirc_cmds.hpp deleted file mode 100644 index 9d95bf16195..00000000000 --- a/extras/vom/vom/gbp_recirc_cmds.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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_GBP_RECIRC_CMDS_H__ -#define __VOM_GBP_RECIRC_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_recirc.hpp" - -#include - -namespace VOM { -namespace gbp_recirc_cmds { - -/** -* A command class that creates or updates the GBP recirc -*/ -class create_cmd : public rpc_cmd, vapi::Gbp_recirc_add_del> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - const handle_t& itf, - bool is_ext, - sclass_t sclass); - - /** - * 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; - -private: - const handle_t m_itf; - bool m_is_ext; - const sclass_t m_sclass; -}; - -/** - * A cmd class that deletes a GBP recirc - */ -class delete_cmd : public rpc_cmd, vapi::Gbp_recirc_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, const handle_t& itf); - - /** - * 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: - const handle_t m_itf; -}; - -/** - * A cmd class that Dumps all the GBP recircs - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace gbp_enpoint_cms -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_route_domain.cpp b/extras/vom/vom/gbp_route_domain.cpp deleted file mode 100644 index 54b51cf88a3..00000000000 --- a/extras/vom/vom/gbp_route_domain.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 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/gbp_route_domain.hpp" -#include "vom/gbp_route_domain_cmds.hpp" -#include "vom/interface.hpp" -#include "vom/l2_binding.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -/** - * A DB of al the interfaces, key on the name - */ -singular_db gbp_route_domain::m_db; - -gbp_route_domain::event_handler gbp_route_domain::m_evh; - -/** - * Construct a new object matching the desried state - */ -gbp_route_domain::gbp_route_domain(const gbp_route_domain& rd) - : m_id(rd.id()) - , m_rd(rd.m_rd) - , m_scope(rd.m_scope) - , m_ip4_uu_fwd(rd.m_ip4_uu_fwd) - , m_ip6_uu_fwd(rd.m_ip6_uu_fwd) -{ -} - -gbp_route_domain::gbp_route_domain(const route_domain& rd, - scope_t scope, - const interface& ip4_uu_fwd, - const interface& ip6_uu_fwd) - : m_id(rd.table_id()) - , m_rd(rd.singular()) - , m_scope(scope) - , m_ip4_uu_fwd(ip4_uu_fwd.singular()) - , m_ip6_uu_fwd(ip6_uu_fwd.singular()) -{ -} - -gbp_route_domain::gbp_route_domain(const route_domain& rd, - scope_t scope, - const std::shared_ptr ip4_uu_fwd, - const std::shared_ptr ip6_uu_fwd) - : m_id(rd.table_id()) - , m_rd(rd.singular()) - , m_scope(scope) - , m_ip4_uu_fwd(ip4_uu_fwd) - , m_ip6_uu_fwd(ip6_uu_fwd) -{ - if (m_ip4_uu_fwd) - m_ip4_uu_fwd = m_ip4_uu_fwd->singular(); - if (m_ip6_uu_fwd) - m_ip6_uu_fwd = m_ip6_uu_fwd->singular(); -} - -gbp_route_domain::gbp_route_domain(const route_domain& rd, scope_t scope) - : m_id(rd.table_id()) - , m_rd(rd.singular()) - , m_scope(scope) - , m_ip4_uu_fwd() - , m_ip6_uu_fwd() -{ -} - -const gbp_route_domain::key_t -gbp_route_domain::key() const -{ - return (m_rd->key()); -} - -route::table_id_t -gbp_route_domain::id() const -{ - return (m_rd->table_id()); -} - -const std::shared_ptr -gbp_route_domain::get_route_domain() const -{ - return m_rd; -} - -const std::shared_ptr -gbp_route_domain::get_ip4_uu_fwd() const -{ - return m_ip4_uu_fwd; -} - -const std::shared_ptr -gbp_route_domain::get_ip6_uu_fwd() const -{ - return m_ip6_uu_fwd; -} - -bool -gbp_route_domain::operator==(const gbp_route_domain& b) const -{ - bool equal = true; - - if (m_ip4_uu_fwd && b.m_ip4_uu_fwd) - equal &= (m_ip4_uu_fwd->key() == b.m_ip4_uu_fwd->key()); - else if (!m_ip4_uu_fwd && !b.m_ip4_uu_fwd) - ; - else - equal = false; - - if (m_ip6_uu_fwd && b.m_ip6_uu_fwd) - equal &= (m_ip6_uu_fwd->key() == b.m_ip6_uu_fwd->key()); - else if (!m_ip6_uu_fwd && !b.m_ip6_uu_fwd) - ; - else - equal = false; - - return ((m_rd->key() == b.m_rd->key()) && m_scope == b.m_scope && equal); -} - -void -gbp_route_domain::sweep() -{ - if (rc_t::OK == m_id.rc()) { - HW::enqueue(new gbp_route_domain_cmds::delete_cmd(m_id)); - } - HW::write(); -} - -void -gbp_route_domain::replay() -{ - if (rc_t::OK == m_id.rc()) { - if (m_ip4_uu_fwd && m_ip6_uu_fwd) - HW::enqueue(new gbp_route_domain_cmds::create_cmd( - m_id, m_scope, m_ip4_uu_fwd->handle(), m_ip6_uu_fwd->handle())); - else - HW::enqueue(new gbp_route_domain_cmds::create_cmd( - m_id, m_scope, handle_t::INVALID, handle_t::INVALID)); - } -} - -gbp_route_domain::~gbp_route_domain() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_id.data(), this); -} - -std::string -gbp_route_domain::to_string() const -{ - std::ostringstream s; - s << "gbp-route-domain:[" << m_rd->to_string() << "scope:" << m_scope; - - if (m_ip4_uu_fwd) - s << " v4-uu:[" << m_ip4_uu_fwd->to_string() << "]"; - if (m_ip6_uu_fwd) - s << " v6-uu:[" << m_ip6_uu_fwd->to_string() << "]"; - - s << "]"; - - return (s.str()); -} - -std::shared_ptr -gbp_route_domain::find(const key_t& key) -{ - return (m_db.find(key)); -} - -void -gbp_route_domain::update(const gbp_route_domain& desired) -{ - if (rc_t::OK != m_id.rc()) { - if (m_ip4_uu_fwd && m_ip6_uu_fwd) - HW::enqueue(new gbp_route_domain_cmds::create_cmd( - m_id, m_scope, m_ip4_uu_fwd->handle(), m_ip6_uu_fwd->handle())); - else - HW::enqueue(new gbp_route_domain_cmds::create_cmd( - m_id, m_scope, handle_t::INVALID, handle_t::INVALID)); - } -} - -std::shared_ptr -gbp_route_domain::find_or_add(const gbp_route_domain& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -gbp_route_domain::singular() const -{ - return find_or_add(*this); -} - -void -gbp_route_domain::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -gbp_route_domain::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump VPP Route domains - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr ip6_uu_fwd = - interface::find(payload.rd.ip6_uu_sw_if_index); - std::shared_ptr ip4_uu_fwd = - interface::find(payload.rd.ip4_uu_sw_if_index); - - if (ip6_uu_fwd && ip4_uu_fwd) { - gbp_route_domain rd(payload.rd.rd_id, payload.rd.scope, *ip4_uu_fwd, - *ip6_uu_fwd); - OM::commit(key, rd); - VOM_LOG(log_level_t::DEBUG) << "dump: " << rd.to_string(); - } else { - gbp_route_domain rd(payload.rd.rd_id, payload.rd.scope); - OM::commit(key, rd); - VOM_LOG(log_level_t::DEBUG) << "dump: " << rd.to_string(); - } - } -} - -gbp_route_domain::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "grd", "groute" }, "GBP Route Domains", this); -} - -void -gbp_route_domain::event_handler::handle_replay() -{ - m_db.replay(); -} - -dependency_t -gbp_route_domain::event_handler::order() const -{ - return (dependency_t::VIRTUAL_TABLE); -} - -void -gbp_route_domain::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_route_domain.hpp b/extras/vom/vom/gbp_route_domain.hpp deleted file mode 100644 index dd096738297..00000000000 --- a/extras/vom/vom/gbp_route_domain.hpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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_GBP_ROUTE_DOMAIN_H__ -#define __VOM_GBP_ROUTE_DOMAIN_H__ - -#include "vom/gbp_types.hpp" -#include "vom/interface.hpp" -#include "vom/route_domain.hpp" -#include "vom/singular_db.hpp" -#include "vom/types.hpp" - -namespace VOM { - -/** - * A entry in the ARP termination table of a Route Domain - */ -class gbp_route_domain : public object_base -{ -public: - /** - * The key for a route_domain is the pair of EPG-IDs - */ - typedef route_domain::key_t key_t; - - /** - * Construct a GBP route_domain - */ - gbp_route_domain(const route_domain& rd, scope_t scope); - - gbp_route_domain(const route_domain& rd, - scope_t scope, - const interface& ip4_uu_fwd, - const interface& ip6_uu_fwd); - gbp_route_domain(const route_domain& rd, - scope_t scope, - const std::shared_ptr ip4_uu_fwd, - const std::shared_ptr ip6_uu_fwd); - - /** - * Copy Construct - */ - gbp_route_domain(const gbp_route_domain& r); - - /** - * Destructor - */ - ~gbp_route_domain(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * Return the route domain's VPP ID - */ - route::table_id_t id() const; - - /** - * comparison operator - */ - bool operator==(const gbp_route_domain& rdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the route_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all route_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - - /** - * Accessors for children - */ - const std::shared_ptr get_route_domain() const; - const std::shared_ptr get_ip4_uu_fwd() const; - const std::shared_ptr get_ip6_uu_fwd() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_route_domain& obj); - - /** - * Find or add the instance of the route_domain domain in the OM - */ - static std::shared_ptr find_or_add( - const gbp_route_domain& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the endpoint - */ - HW::item m_id; - - std::shared_ptr m_rd; - scope_t m_scope; - std::shared_ptr m_ip4_uu_fwd; - std::shared_ptr m_ip6_uu_fwd; - - /** - * A map of all route_domains - */ - static singular_db m_db; -}; - -}; // namespace - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_route_domain_cmds.cpp b/extras/vom/vom/gbp_route_domain_cmds.cpp deleted file mode 100644 index 90e81f338e3..00000000000 --- a/extras/vom/vom/gbp_route_domain_cmds.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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/gbp_route_domain_cmds.hpp" - -namespace VOM { -namespace gbp_route_domain_cmds { - -create_cmd::create_cmd(HW::item& item, - scope_t scope, - const handle_t ip4_uu_fwd, - const handle_t ip6_uu_fwd) - : rpc_cmd(item) - , m_scope(scope) - , m_ip4_uu_fwd(ip4_uu_fwd) - , m_ip6_uu_fwd(ip6_uu_fwd) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_hw_item.data() == other.m_hw_item.data()) && - (m_scope == other.m_scope) && (m_ip4_uu_fwd == other.m_ip4_uu_fwd) && - (m_ip6_uu_fwd == other.m_ip6_uu_fwd)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.rd.rd_id = m_hw_item.data(); - payload.rd.scope = m_scope; - payload.rd.ip4_table_id = m_hw_item.data(); - payload.rd.ip6_table_id = m_hw_item.data(); - payload.rd.ip4_uu_sw_if_index = m_ip4_uu_fwd.value(); - payload.rd.ip6_uu_sw_if_index = m_ip6_uu_fwd.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-route-domain: " << m_hw_item.to_string() << " scope:" << m_scope - << " ip4-uu-fwd:" << m_ip4_uu_fwd.to_string() - << " ip6-uu-fwd:" << m_ip6_uu_fwd.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item) - : rpc_cmd(item) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_hw_item.data() == other.m_hw_item.data()); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.rd_id = m_hw_item.data(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-route-domain: " << m_hw_item.to_string(); - - return (s.str()); -} - -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 ("gbp-route-domain-dump"); -} - -}; // namespace gbp_route_domain_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_route_domain_cmds.hpp b/extras/vom/vom/gbp_route_domain_cmds.hpp deleted file mode 100644 index 6ef9fcd3ce9..00000000000 --- a/extras/vom/vom/gbp_route_domain_cmds.hpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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_GBP_ROUTE_DOMAIN_CMDS_H__ -#define __VOM_GBP_ROUTE_DOMAIN_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_route_domain.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace gbp_route_domain_cmds { -/** - * A command class that creates an Route-Domain - */ -class create_cmd - : public rpc_cmd, vapi::Gbp_route_domain_add> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - scope_t scope, - const handle_t ip4_uu_fwd, - const handle_t ip6_uu_fwd); - - /** - * 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; - -private: - const scope_t m_scope; - const handle_t m_ip4_uu_fwd; - const handle_t m_ip6_uu_fwd; -}; - -/** - * A cmd class that Delete an Route-Domain - */ -class delete_cmd - : public rpc_cmd, vapi::Gbp_route_domain_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item); - - /** - * 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; -}; - -/** - * A cmd class that Dumps all the route domains - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd() = default; - dump_cmd(const dump_cmd& d) = 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // gbp_route_domain_cmds -}; // VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_rule.cpp b/extras/vom/vom/gbp_rule.cpp deleted file mode 100644 index 48c59b14c2b..00000000000 --- a/extras/vom/vom/gbp_rule.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* - * 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 - -#include "vom/gbp_rule.hpp" - -namespace VOM { -gbp_rule::next_hop_t::next_hop_t(const boost::asio::ip::address& ip, - const mac_address_t& mac, - uint32_t bd_id, - uint32_t rd_id) - : m_ip(ip) - , m_mac(mac) - , m_bd_id(bd_id) - , m_rd_id(rd_id) -{ -} - -std::string -gbp_rule::next_hop_t::to_string() const -{ - std::ostringstream s; - - s << "[" - << "ip:" << m_ip << " mac:" << m_mac.to_string() << " bd:" << m_bd_id - << " rd:" << m_rd_id << "]"; - - return (s.str()); -} - -bool -gbp_rule::next_hop_t::operator<(const gbp_rule::next_hop_t& nh) const -{ - return (nh.m_ip < m_ip); -} - -bool -gbp_rule::next_hop_t::operator==(const gbp_rule::next_hop_t& nh) const -{ - return ((m_ip == nh.m_ip) && (m_mac == nh.m_mac) && (m_bd_id == nh.m_bd_id) && - (m_rd_id == nh.m_rd_id)); -} - -const boost::asio::ip::address& -gbp_rule::next_hop_t::getIp() const -{ - return m_ip; -} - -const mac_address_t& -gbp_rule::next_hop_t::getMac() const -{ - return m_mac; -} - -const uint32_t -gbp_rule::next_hop_t::getBdId() const -{ - return m_bd_id; -} - -const uint32_t -gbp_rule::next_hop_t::getRdId() const -{ - return m_rd_id; -} - -const gbp_rule::hash_mode_t gbp_rule::hash_mode_t::SRC_IP(1, "src-ip"); -const gbp_rule::hash_mode_t gbp_rule::hash_mode_t::DST_IP(0, "dst-ip"); -const gbp_rule::hash_mode_t gbp_rule::hash_mode_t::SYMMETRIC(2, "symmetric"); - -gbp_rule::hash_mode_t::hash_mode_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -const gbp_rule::hash_mode_t& -gbp_rule::hash_mode_t::from_int(vapi_enum_gbp_hash_mode i) -{ - if (i == GBP_API_HASH_MODE_SYMMETRIC) - return gbp_rule::hash_mode_t::SYMMETRIC; - else if (i == GBP_API_HASH_MODE_SRC_IP) - return gbp_rule::hash_mode_t::SRC_IP; - - return gbp_rule::hash_mode_t::DST_IP; -} - -gbp_rule::next_hop_set_t::next_hop_set_t(const gbp_rule::hash_mode_t& hm, - gbp_rule::next_hops_t& nhs) - : m_hm(hm) - , m_nhs(nhs) -{ -} - -gbp_rule::next_hop_set_t::next_hop_set_t(const hash_mode_t& hm) - : m_hm(hm) - , m_nhs() -{ -} - -std::string -gbp_rule::next_hop_set_t::to_string() const -{ - std::ostringstream s; - - s << "hash-mode:" << m_hm.to_string() << " next-hops:["; - auto it = m_nhs.cbegin(); - while (it != m_nhs.cend()) { - s << " " << it->to_string(); - ++it; - } - s << " ] next-hop-size:" << m_nhs.size(); - - return (s.str()); -} - -bool -gbp_rule::next_hop_set_t::operator==(const next_hop_set_t& nhs) const -{ - return ((m_hm == nhs.m_hm) && (m_nhs == nhs.m_nhs)); -} - -const gbp_rule::hash_mode_t& -gbp_rule::next_hop_set_t::hash_mode() const -{ - return m_hm; -} - -const gbp_rule::next_hops_t& -gbp_rule::next_hop_set_t::next_hops() const -{ - return m_nhs; -} - -const gbp_rule::action_t gbp_rule::action_t::REDIRECT(2, "redirect"); -const gbp_rule::action_t gbp_rule::action_t::PERMIT(1, "permit"); -const gbp_rule::action_t gbp_rule::action_t::DENY(0, "deny"); - -gbp_rule::action_t::action_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -const gbp_rule::action_t& -gbp_rule::action_t::from_int(vapi_enum_gbp_rule_action i) -{ - if (i == GBP_API_RULE_REDIRECT) - return gbp_rule::action_t::REDIRECT; - else if (i == GBP_API_RULE_PERMIT) - return gbp_rule::action_t::PERMIT; - - return gbp_rule::action_t::DENY; -} - -gbp_rule::gbp_rule(uint32_t priority, - const gbp_rule::next_hop_set_t& nhs, - const gbp_rule::action_t& a) - : m_priority(priority) - , m_nhs(nhs) - , m_action(a) -{ -} - -gbp_rule::gbp_rule(uint32_t priority, const gbp_rule::action_t& a) - : m_priority(priority) - , m_nhs() - , m_action(a) -{ -} - -bool -gbp_rule::operator<(const gbp_rule& other) const -{ - return (other.m_priority < m_priority); -} - -bool -gbp_rule::operator==(const gbp_rule& rule) const -{ - return ((m_action == rule.m_action) && (m_nhs == rule.m_nhs) && - (m_priority == rule.m_priority)); -} - -std::string -gbp_rule::to_string() const -{ - std::ostringstream s; - - s << "gbp-rule:[" - << "priority:" << m_priority << " action:" << m_action.to_string() - << " next-hop-set:[" << m_nhs.to_string() << "]]"; - - return (s.str()); -} - -const gbp_rule::action_t& -gbp_rule::action() const -{ - return m_action; -} - -const gbp_rule::next_hop_set_t& -gbp_rule::nhs() const -{ - return m_nhs; -} -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_rule.hpp b/extras/vom/vom/gbp_rule.hpp deleted file mode 100644 index 04301da79e9..00000000000 --- a/extras/vom/vom/gbp_rule.hpp +++ /dev/null @@ -1,282 +0,0 @@ -/* - * 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_GBP_RULE_H__ -#define __VOM_GBP_RULE_H__ - -#include - -#include "vom/types.hpp" -#include -namespace VOM { -class gbp_rule -{ -public: - /** - * Representation of next hop - */ - struct next_hop_t - { - /** - * Constructor for next_hop_t - */ - next_hop_t(const boost::asio::ip::address& ip, - const mac_address_t& mac, - uint32_t bd_id, - uint32_t rd_id); - - /** - * default destructor - */ - ~next_hop_t() = default; - - /** - * convert to string - */ - std::string to_string() const; - - /** - * less-than operator - */ - bool operator<(const next_hop_t& nh) const; - - /** - * comparison operator (for testing) - */ - bool operator==(const next_hop_t& nh) const; - - /** - * get the IP address - */ - const boost::asio::ip::address& getIp(void) const; - - /** - * get the mac address - */ - const mac_address_t& getMac(void) const; - - /** - * get the bridge domain Id - */ - const uint32_t getBdId(void) const; - - /** - * get the route domain Id - */ - const uint32_t getRdId(void) const; - - private: - /** - * IP address for next hop - */ - const boost::asio::ip::address m_ip; - - /** - * mac address for interface lookup - */ - const mac_address_t m_mac; - - /** - * bridge domain in which redirected endpoints exist - */ - const uint32_t m_bd_id; - - /** - * route domain in which redirected endpoints exist - */ - const uint32_t m_rd_id; - }; - - /** - * hash mode enum - */ - struct hash_mode_t : public enum_base - { - /** - * Flow Hash is calculated based on SRC IP - * in case of load balancing - */ - const static hash_mode_t SRC_IP; - - /** - * Flow hash is calculated based on DST IP - */ - const static hash_mode_t DST_IP; - - /** - * Flow hash is calculated based on SRC IP, - * DST IP and Protocol. SRC IP and DST IP - * addresses are sorted before hash such that - * a same hash is generated in both directions. - */ - const static hash_mode_t SYMMETRIC; - - /** - * create the hash mode from int value - */ - static const hash_mode_t& from_int(vapi_enum_gbp_hash_mode i); - - private: - hash_mode_t(int v, const std::string s); - }; - - /** - * unordered set of next hops - */ - typedef std::set next_hops_t; - - /** - * Representation of set of next hops and - * associated hash mode profile - */ - struct next_hop_set_t - { - /** - * Constructor for next_hop_set_t - */ - next_hop_set_t(const hash_mode_t& hm, next_hops_t& nhs); - next_hop_set_t(const hash_mode_t& hm = hash_mode_t::SYMMETRIC); - - /** - * Destructor for next_hop_set_t - */ - ~next_hop_set_t() = default; - - /** - * convert to string - */ - std::string to_string() const; - - /** - * Comparison operator - */ - bool operator==(const next_hop_set_t& nhs) const; - - /** - * get the hash mode - */ - const hash_mode_t& hash_mode(void) const; - - /** - * get the set of next hops - */ - const next_hops_t& next_hops(void) const; - - private: - /** - * hash mode for this rule - */ - const hash_mode_t m_hm; - - /** - * set of next hops - */ - const next_hops_t m_nhs; - }; - - /** - * ACL rule action enum - */ - struct action_t : public enum_base - { - /** - * Permit action - */ - const static action_t PERMIT; - - /** - * Deny action - */ - const static action_t DENY; - - /** - * Redirect action - */ - const static action_t REDIRECT; - - /** - * create the action from int value - */ - static const action_t& from_int(vapi_enum_gbp_rule_action i); - - private: - action_t(int v, const std::string s); - }; - - /** - * Construct a new object matching the desried state - */ - gbp_rule(uint32_t priority, const next_hop_set_t& nhs, const action_t& a); - gbp_rule(uint32_t priority, const action_t& a); - - /** - * Copy Constructor - */ - gbp_rule(const gbp_rule& o) = default; - - /** - * Destructor - */ - ~gbp_rule() = default; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * less-than operator - */ - bool operator<(const gbp_rule& rule) const; - - /** - * comparison operator (for testing) - */ - bool operator==(const gbp_rule& rule) const; - - /** - * Getters - */ - const next_hop_set_t& nhs() const; - const action_t& action() const; - -private: - /** - * Priority. Used to sort the rules in a list in the order - * in which they are applied - */ - uint32_t m_priority; - - /** - * set of next hops along with hash mode profile - */ - const next_hop_set_t m_nhs; - - /** - * Action on match - */ - const action_t m_action; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_subnet.cpp b/extras/vom/vom/gbp_subnet.cpp deleted file mode 100644 index bc897f125db..00000000000 --- a/extras/vom/vom/gbp_subnet.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* - * 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/gbp_subnet.hpp" -#include "vom/api_types.hpp" -#include "vom/gbp_subnet_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -gbp_subnet::type_t::type_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -const gbp_subnet::type_t gbp_subnet::type_t::STITCHED_INTERNAL( - 0, - "stitched-internal"); -const gbp_subnet::type_t gbp_subnet::type_t::STITCHED_EXTERNAL( - 1, - "stitched-external"); -const gbp_subnet::type_t gbp_subnet::type_t::TRANSPORT(2, "transport"); -const gbp_subnet::type_t gbp_subnet::type_t::L3_OUT(3, "l3-out"); -const gbp_subnet::type_t gbp_subnet::type_t::ANON_L3_OUT(4, "anon-l3-out"); - -singular_db gbp_subnet::m_db; - -gbp_subnet::event_handler gbp_subnet::m_evh; - -gbp_subnet::gbp_subnet(const gbp_route_domain& rd, - const route::prefix_t& prefix, - const type_t& type) - : m_hw(false) - , m_rd(rd.singular()) - , m_prefix(prefix) - , m_type(type) - , m_recirc(nullptr) - , m_epg(nullptr) - , m_sclass(~0) -{ -} - -gbp_subnet::gbp_subnet(const gbp_route_domain& rd, - const route::prefix_t& prefix, - const gbp_recirc& recirc, - const gbp_endpoint_group& epg) - : m_hw(false) - , m_rd(rd.singular()) - , m_prefix(prefix) - , m_type(type_t::STITCHED_EXTERNAL) - , m_recirc(recirc.singular()) - , m_epg(epg.singular()) - , m_sclass(~0) -{ -} - -gbp_subnet::gbp_subnet(const gbp_route_domain& rd, - const route::prefix_t& prefix, - sclass_t sclass, - const type_t& type) - : m_hw(false) - , m_rd(rd.singular()) - , m_prefix(prefix) - , m_type(type) - , m_recirc(nullptr) - , m_epg() - , m_sclass(sclass) -{ -} - -gbp_subnet::gbp_subnet(const gbp_subnet& o) - : m_hw(o.m_hw) - , m_rd(o.m_rd) - , m_prefix(o.m_prefix) - , m_type(o.m_type) - , m_recirc(o.m_recirc) - , m_epg(o.m_epg) - , m_sclass(o.m_sclass) -{ -} - -gbp_subnet::~gbp_subnet() -{ - sweep(); - m_db.release(key(), this); -} - -const gbp_subnet::key_t -gbp_subnet::key() const -{ - return (std::make_pair(m_rd->key(), m_prefix)); -} - -bool -gbp_subnet::operator==(const gbp_subnet& gs) const -{ - return ((key() == gs.key()) && (m_type == gs.m_type) && - (m_recirc == gs.m_recirc) && (m_epg == gs.m_epg) && - (m_sclass == gs.m_sclass)); -} - -void -gbp_subnet::sweep() -{ - if (m_hw) { - HW::enqueue(new gbp_subnet_cmds::delete_cmd(m_hw, m_rd->id(), m_prefix)); - } - HW::write(); -} - -void -gbp_subnet::replay() -{ - if (m_hw) { - HW::enqueue(new gbp_subnet_cmds::create_cmd( - m_hw, m_rd->id(), m_prefix, m_type, - (m_recirc ? m_recirc->handle() : handle_t::INVALID), - (m_epg ? m_epg->sclass() : m_sclass))); - } -} - -std::string -gbp_subnet::to_string() const -{ - std::ostringstream s; - s << "gbp-subnet:[" << m_type.to_string() << ", " << m_rd->to_string() << ":" - << m_prefix.to_string(); - if (m_recirc) - s << ", " << m_recirc->to_string(); - if (m_epg) - s << ", " << m_epg->to_string(); - - s << "]"; - - return (s.str()); -} - -void -gbp_subnet::update(const gbp_subnet& r) -{ - if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new gbp_subnet_cmds::create_cmd( - m_hw, m_rd->id(), m_prefix, m_type, - (m_recirc ? m_recirc->handle() : handle_t::INVALID), - (m_epg ? m_epg->sclass() : m_sclass))); - } else { - if (m_type != r.m_type) { - m_epg = r.m_epg; - m_recirc = r.m_recirc; - m_type = r.m_type; - - HW::enqueue(new gbp_subnet_cmds::create_cmd( - m_hw, m_rd->id(), m_prefix, m_type, - (m_recirc ? m_recirc->handle() : handle_t::INVALID), - (m_epg ? m_epg->sclass() : m_sclass))); - } - } -} - -std::shared_ptr -gbp_subnet::find_or_add(const gbp_subnet& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -gbp_subnet::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -gbp_subnet::singular() const -{ - return find_or_add(*this); -} - -void -gbp_subnet::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -gbp_subnet::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "gbp-subnet" }, "GBP Subnets", this); -} - -void -gbp_subnet::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -gbp_subnet::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - route::prefix_t pfx = from_api(payload.subnet.prefix); - std::shared_ptr rd = - gbp_route_domain::find(payload.subnet.rd_id); - - if (rd) { - switch (payload.subnet.type) { - case GBP_API_SUBNET_TRANSPORT: { - gbp_subnet gs(*rd, pfx, type_t::TRANSPORT); - OM::commit(key, gs); - VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); - break; - } - case GBP_API_SUBNET_STITCHED_INTERNAL: { - gbp_subnet gs(*rd, pfx, type_t::STITCHED_INTERNAL); - OM::commit(key, gs); - VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); - break; - } - case GBP_API_SUBNET_L3_OUT: { - gbp_subnet gs(*rd, pfx, payload.subnet.sclass); - OM::commit(key, gs); - VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); - break; - } - case GBP_API_SUBNET_ANON_L3_OUT: { - gbp_subnet gs(*rd, pfx, payload.subnet.sclass, type_t::ANON_L3_OUT); - OM::commit(key, gs); - VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); - break; - } - case GBP_API_SUBNET_STITCHED_EXTERNAL: { - std::shared_ptr itf = - interface::find(payload.subnet.sw_if_index); - std::shared_ptr epg = - gbp_endpoint_group::find(payload.subnet.sclass); - - if (itf && epg) { - std::shared_ptr recirc = gbp_recirc::find(itf->key()); - - if (recirc) { - gbp_subnet gs(*rd, pfx, *recirc, *epg); - OM::commit(key, gs); - VOM_LOG(log_level_t::DEBUG) << "read: " << gs.to_string(); - } - } - } - } - } - } -} - -dependency_t -gbp_subnet::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -gbp_subnet::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const gbp_subnet::key_t& key) -{ - os << "[" << key.first << ", " << key.second << "]"; - - return os; -} - -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_subnet.hpp b/extras/vom/vom/gbp_subnet.hpp deleted file mode 100644 index 3ae8439e83c..00000000000 --- a/extras/vom/vom/gbp_subnet.hpp +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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_GBP_SUBNET_H__ -#define __VOM_GBP_SUBNET_H__ - -#include - -#include "vom/gbp_endpoint_group.hpp" -#include "vom/gbp_recirc.hpp" -#include "vom/gbp_route_domain.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A GBP Enpoint (i.e. a VM) - */ -class gbp_subnet : public object_base -{ -public: - /** - * The key for a GBP subnet; table and prefix - */ - typedef std::pair key_t; - - struct type_t : public enum_base - { - /** - * Internal subnet is reachable through the source EPG's - * uplink interface. - */ - const static type_t STITCHED_INTERNAL; - - /** - * External subnet requires NAT translation before egress. - */ - const static type_t STITCHED_EXTERNAL; - - /** - * A transport subnet, sent via the RD's UU-fwd interface - */ - const static type_t TRANSPORT; - - /** - * A L3-out subnet - */ - const static type_t L3_OUT; - - /** - * An anonymous L3-out subnet - */ - const static type_t ANON_L3_OUT; - - private: - type_t(int v, const std::string s); - }; - - /** - * Construct an internal GBP subnet - */ - gbp_subnet(const gbp_route_domain& rd, - const route::prefix_t& prefix, - const type_t& type); - - /** - * Construct an stitched external GBP subnet - */ - gbp_subnet(const gbp_route_domain& rd, - const route::prefix_t& prefix, - const gbp_recirc& recirc, - const gbp_endpoint_group& epg); - - /** - * Construct an l3-out GBP subnet - */ - gbp_subnet(const gbp_route_domain& rd, - const route::prefix_t& prefix, - sclass_t sclass, - const type_t& type = type_t::L3_OUT); - - /** - * Copy Construct - */ - gbp_subnet(const gbp_subnet& r); - - /** - * Destructor - */ - ~gbp_subnet(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const gbp_subnet& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_subnet& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const gbp_subnet& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the subnet - */ - HW::item m_hw; - - /** - * the route domain the prefix is in - */ - const std::shared_ptr m_rd; - - /** - * prefix to match - */ - const route::prefix_t m_prefix; - - /* - * Subnet type - */ - type_t m_type; - - /** - * The interface the prefix is reachable through - */ - std::shared_ptr m_recirc; - - /** - * The EPG the subnet is in - */ - std::shared_ptr m_epg; - - /** - * Sclass for l3-out subnets - */ - sclass_t m_sclass; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, const gbp_subnet::key_t& key); - -}; // namespace - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_subnet_cmds.cpp b/extras/vom/vom/gbp_subnet_cmds.cpp deleted file mode 100644 index 94152ffe369..00000000000 --- a/extras/vom/vom/gbp_subnet_cmds.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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/gbp_subnet_cmds.hpp" -#include "vom/api_types.hpp" - -namespace VOM { -namespace gbp_subnet_cmds { - -create_cmd::create_cmd(HW::item& item, - route::table_id_t rd, - const route::prefix_t& prefix, - const gbp_subnet::type_t& type, - const handle_t& itf, - sclass_t sclass) - : rpc_cmd(item) - , m_rd(rd) - , m_prefix(prefix) - , m_type(type) - , m_itf(itf) - , m_sclass(sclass) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_rd == other.m_rd) && - (m_prefix == other.m_prefix) && (m_type == other.m_type) && - (m_itf == other.m_itf) && (m_sclass == other.m_sclass)); -} - -static vapi_enum_gbp_subnet_type -gbp_subnet_type_to_api(const gbp_subnet::type_t& type) -{ - if (gbp_subnet::type_t::STITCHED_INTERNAL == type) - return (GBP_API_SUBNET_STITCHED_INTERNAL); - if (gbp_subnet::type_t::STITCHED_EXTERNAL == type) - return (GBP_API_SUBNET_STITCHED_EXTERNAL); - if (gbp_subnet::type_t::TRANSPORT == type) - return (GBP_API_SUBNET_TRANSPORT); - if (gbp_subnet::type_t::L3_OUT == type) - return (GBP_API_SUBNET_L3_OUT); - - return (GBP_API_SUBNET_STITCHED_INTERNAL); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.subnet.type = gbp_subnet_type_to_api(m_type); - payload.subnet.rd_id = m_rd; - payload.subnet.sw_if_index = m_itf.value(); - payload.subnet.sclass = m_sclass; - payload.subnet.prefix = to_api(m_prefix); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-subnet-create: " << m_hw_item.to_string() << "type:" << m_type - << ", " << m_rd << ":" << m_prefix.to_string() << " itf:" << m_itf - << " sclass:" << m_sclass; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - route::table_id_t rd, - const route::prefix_t& prefix) - : rpc_cmd(item) - , m_rd(rd) - , m_prefix(prefix) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return ((m_rd == other.m_rd) && (m_prefix == other.m_prefix)); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.subnet.rd_id = m_rd; - payload.subnet.prefix = to_api(m_prefix); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-subnet-delete: " << m_hw_item.to_string() << ", " << m_rd << ":" - << m_prefix.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("gbp-subnet-dump"); -} - -}; // namespace gbp_subnet_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_subnet_cmds.hpp b/extras/vom/vom/gbp_subnet_cmds.hpp deleted file mode 100644 index b78699e5bf5..00000000000 --- a/extras/vom/vom/gbp_subnet_cmds.hpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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_GBP_SUBNET_CMDS_H__ -#define __VOM_GBP_SUBNET_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_subnet.hpp" - -#include - -namespace VOM { -namespace gbp_subnet_cmds { - -/** - * A command class that creates or updates the GBP subnet - */ -class create_cmd : public rpc_cmd, vapi::Gbp_subnet_add_del> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - route::table_id_t rd, - const route::prefix_t& prefix, - const gbp_subnet::type_t& type, - const handle_t& itf, - sclass_t sclass); - - /** - * 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; - -private: - const route::table_id_t m_rd; - const route::prefix_t m_prefix; - const gbp_subnet::type_t& m_type; - const handle_t m_itf; - const sclass_t m_sclass; -}; - -/** - * A cmd class that deletes a GBP subnet - */ -class delete_cmd : public rpc_cmd, vapi::Gbp_subnet_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, - route::table_id_t rd, - const route::prefix_t& prefix); - - /** - * 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: - const route::table_id_t m_rd; - const route::prefix_t m_prefix; -}; - -/** - * A cmd class that Dumps all the GBP subnets - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace gbp_enpoint_cms -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_types.hpp b/extras/vom/vom/gbp_types.hpp deleted file mode 100644 index 5b46e08f513..00000000000 --- a/extras/vom/vom/gbp_types.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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_GBP_TYPES_H__ -#define __VOM_GBP_TYPES_H__ - -#include - -namespace VOM { - -/** - * EPG IDs are 32 bit integers - */ -typedef uint32_t vnid_t; -typedef uint16_t sclass_t; -typedef uint16_t scope_t; - -}; // namespace - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_vxlan.cpp b/extras/vom/vom/gbp_vxlan.cpp deleted file mode 100644 index 76826c2a3d6..00000000000 --- a/extras/vom/vom/gbp_vxlan.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* - * 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/gbp_vxlan.hpp" -#include "vom/api_types.hpp" -#include "vom/gbp_vxlan_cmds.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -const std::string GBP_VXLAN_NAME = "gbp-vxlan"; - -/** - * A DB of al the interfaces, key on the name - */ -singular_db gbp_vxlan::m_db; - -gbp_vxlan::event_handler gbp_vxlan::m_evh; - -gbp_vxlan::gbp_vxlan(uint32_t vni, - const gbp_route_domain& grd, - const boost::asio::ip::address_v4& src) - : interface(mk_name(vni), - interface::type_t::UNKNOWN, - interface::admin_state_t::UP) - , m_vni(vni) - , m_gbd() - , m_grd(grd.singular()) - , m_src(src) -{ -} -gbp_vxlan::gbp_vxlan(uint32_t vni, - const gbp_bridge_domain& gbd, - const boost::asio::ip::address_v4& src) - : interface(mk_name(vni), - interface::type_t::UNKNOWN, - interface::admin_state_t::UP) - , m_vni(vni) - , m_gbd(gbd.singular()) - , m_grd() - , m_src(src) -{ -} - -gbp_vxlan::gbp_vxlan(const gbp_vxlan& vt) - : interface(vt) - , m_vni(vt.m_vni) - , m_gbd(vt.m_gbd) - , m_grd(vt.m_grd) - , m_src(vt.m_src) -{ -} - -std::string -gbp_vxlan::mk_name(uint32_t vni) -{ - std::ostringstream s; - - s << GBP_VXLAN_NAME << "-" << vni; - - return (s.str()); -} - -const gbp_vxlan::key_t -gbp_vxlan::key() const -{ - return (m_vni); -} - -bool -gbp_vxlan::operator==(const gbp_vxlan& vt) const -{ - return (m_vni == vt.m_vni && m_src == vt.m_src); -} - -void -gbp_vxlan::sweep() -{ - if (rc_t::OK == m_hdl) { - HW::enqueue(new gbp_vxlan_cmds::delete_cmd(m_hdl, m_vni)); - } - HW::write(); -} - -void -gbp_vxlan::replay() -{ - if (rc_t::OK == m_hdl) { - if (m_grd) - HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni, - false, m_grd->id())); - else if (m_gbd) - HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni, - true, m_gbd->id())); - } -} - -gbp_vxlan::~gbp_vxlan() -{ - sweep(); - m_db.release(key(), this); -} - -std::string -gbp_vxlan::to_string() const -{ - std::ostringstream s; - s << "gbp-vxlan:[" << m_vni << "]"; - - return (s.str()); -} - -std::shared_ptr -gbp_vxlan::find(const key_t key) -{ - return (m_db.find(key)); -} - -void -gbp_vxlan::update(const gbp_vxlan& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (rc_t::OK != m_hdl) { - if (m_grd) - HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni, - false, m_grd->id())); - else if (m_gbd) - HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni, - true, m_gbd->id())); - } -} - -std::shared_ptr -gbp_vxlan::find_or_add(const gbp_vxlan& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -gbp_vxlan::singular() const -{ - return find_or_add(*this); -} - -std::shared_ptr -gbp_vxlan::singular_i() const -{ - return find_or_add(*this); -} - -void -gbp_vxlan::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -gbp_vxlan::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump VPP Bridge domains - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - boost::asio::ip::address_v4 src = from_api(payload.tunnel.src); - - if (GBP_VXLAN_TUNNEL_MODE_L3 == payload.tunnel.mode) { - auto rd = gbp_route_domain::find(payload.tunnel.bd_rd_id); - - if (rd) { - gbp_vxlan vt(payload.tunnel.vni, *rd, src); - OM::commit(key, vt); - VOM_LOG(log_level_t::DEBUG) << "dump: " << vt.to_string(); - } - } else { - auto bd = gbp_bridge_domain::find(payload.tunnel.bd_rd_id); - - if (bd) { - gbp_vxlan vt(payload.tunnel.vni, *bd, src); - OM::commit(key, vt); - VOM_LOG(log_level_t::DEBUG) << "dump: " << vt.to_string(); - } - } - } -} - -gbp_vxlan::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "gvt", "gbp-vxlan-tunnel" }, "GBP VXLAN Tunnels", - this); -} - -void -gbp_vxlan::event_handler::handle_replay() -{ - m_db.replay(); -} - -dependency_t -gbp_vxlan::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -gbp_vxlan::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_vxlan.hpp b/extras/vom/vom/gbp_vxlan.hpp deleted file mode 100644 index 8aa4b6b6b6e..00000000000 --- a/extras/vom/vom/gbp_vxlan.hpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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_GBP_VXLAN_H__ -#define __VOM_GBP_VXLAN_H__ - -#include "vom/gbp_bridge_domain.hpp" -#include "vom/gbp_route_domain.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of a GBP_VXLAN Tunnel in VPP - */ -class gbp_vxlan : public interface -{ -public: - /** - * The VNI is the key - */ - typedef uint32_t key_t; - - /** - * Construct a new object matching the desried state - */ - gbp_vxlan(uint32_t vni, - const gbp_bridge_domain& gbd, - const boost::asio::ip::address_v4& src); - gbp_vxlan(uint32_t vni, - const gbp_route_domain& grd, - const boost::asio::ip::address_v4& src); - - /* - * Destructor - */ - ~gbp_vxlan(); - - /** - * Copy constructor - */ - gbp_vxlan(const gbp_vxlan& o); - - bool operator==(const gbp_vxlan& vt) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * Debug rpint function - */ - virtual std::string to_string() const; - - /** - * Return VPP's handle to this object - */ - const handle_t& handle() const; - - /** - * Dump all L3Configs into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Find the GBP_VXLAN tunnel in the OM - */ - static std::shared_ptr find(const key_t k); - -private: - /** - * 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; - }; - - /** - * Event handle to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const gbp_vxlan& obj); - - /** - * Return the matching 'instance' of the sub-interface - * over-ride from the base class - */ - std::shared_ptr singular_i() const; - - /** - * Find the GBP_VXLAN tunnel in the OM - */ - static std::shared_ptr find_or_add(const gbp_vxlan& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Tunnel VNI/key - */ - uint32_t m_vni; - std::shared_ptr m_gbd; - std::shared_ptr m_grd; - boost::asio::ip::address_v4 m_src; - - /** - * A map of all VLAN tunnela against thier key - */ - static singular_db m_db; - - /** - * Construct a unique name for the tunnel - */ - static std::string mk_name(uint32_t vni); -}; - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/gbp_vxlan_cmds.cpp b/extras/vom/vom/gbp_vxlan_cmds.cpp deleted file mode 100644 index 86b61c14f06..00000000000 --- a/extras/vom/vom/gbp_vxlan_cmds.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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/gbp_vxlan_cmds.hpp" -#include "vom/api_types.hpp" - -namespace VOM { -namespace gbp_vxlan_cmds { -create_cmd::create_cmd(HW::item& item, - const std::string& name, - const boost::asio::ip::address_v4& src, - uint32_t vni, - bool is_l2, - uint32_t bd_rd) - : interface::create_cmd(item, name) - , m_src(src) - , m_vni(vni) - , m_is_l2(is_l2) - , m_bd_rd(bd_rd) -{ -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.tunnel.vni = m_vni; - payload.tunnel.bd_rd_id = m_bd_rd; - if (m_is_l2) - payload.tunnel.mode = GBP_VXLAN_TUNNEL_MODE_L2; - else - payload.tunnel.mode = GBP_VXLAN_TUNNEL_MODE_L3; - to_api(m_src, payload.tunnel.src); - - VAPI_CALL(req.execute()); - - wait(); - if (m_hw_item.rc() == rc_t::OK) { - insert_interface(); - } - - return (m_hw_item.rc()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-vxlan-create: " << m_hw_item.to_string() << " vni:" << m_vni - << " bd/rd:" << m_bd_rd; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, uint32_t vni) - : interface::delete_cmd(item) - , m_vni(vni) -{ -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.vni = m_vni; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_interface(); - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "gbp-vxlan-delete: " << m_hw_item.to_string() << " vni:" << m_vni; - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("gbp-vxlan-dump"); -} - -} // namespace gbp_vxlan_cmds -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/gbp_vxlan_cmds.hpp b/extras/vom/vom/gbp_vxlan_cmds.hpp deleted file mode 100644 index 642235731bb..00000000000 --- a/extras/vom/vom/gbp_vxlan_cmds.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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_GBP_VXLAN_CMDS_H__ -#define __VOM_GBP_VXLAN_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/gbp_vxlan.hpp" -#include "vom/interface.hpp" - -#include - -namespace VOM { -namespace gbp_vxlan_cmds { -/** - * A command class that creates an Bridge-Domain - */ -class create_cmd : public interface::create_cmd -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - const std::string& name, - const boost::asio::ip::address_v4& src, - uint32_t vni, - bool is_l2, - uint32_t bd_rd); - - /** - * 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; - -private: - boost::asio::ip::address_v4 m_src; - uint32_t m_vni; - bool m_is_l2; - uint32_t m_bd_rd; -}; - -/** - * A cmd class that Delete an Bridge-Domain - */ -class delete_cmd : public interface::delete_cmd -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, uint32_t vni); - - /** - * 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: - uint32_t m_vni; -}; - -/** - * A cmd class that Dumps all the bridge domains - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // gbp_vxlan_cmds -}; // VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/hw.cpp b/extras/vom/vom/hw.cpp deleted file mode 100644 index 54f0aa2c02f..00000000000 --- a/extras/vom/vom/hw.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/* - * 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/hw.hpp" -#include "vom/hw_cmds.hpp" -#include "vom/logger.hpp" -#include "vom/stat_reader.hpp" - -namespace VOM { -HW::cmd_q::cmd_q() - : m_enabled(true) - , m_connected(false) - , m_conn() -{ -} - -HW::cmd_q::~cmd_q() -{ -} - -HW::cmd_q& -HW::cmd_q::operator=(const HW::cmd_q& f) -{ - return (*this); -} - -/** - * Run the connect/dispatch thread. - */ -void -HW::cmd_q::rx_run() -{ - while (m_connected) { - m_conn.ctx().dispatch(); - } -} - -void -HW::cmd_q::enqueue(cmd* c) -{ - std::shared_ptr sp(c); - - m_queue.push_back(sp); -} - -void -HW::cmd_q::enqueue(std::shared_ptr c) -{ - m_queue.push_back(c); -} - -void -HW::cmd_q::enqueue(std::queue& cmds) -{ - while (cmds.size()) { - std::shared_ptr sp(cmds.front()); - - m_queue.push_back(sp); - cmds.pop(); - } -} - -bool -HW::cmd_q::connect() -{ - if (m_connected) - return m_connected; - - if (0 == m_conn.connect()) { - m_connected = true; - m_rx_thread.reset(new std::thread(&HW::cmd_q::rx_run, this)); - } - return (m_connected); -} - -void -HW::cmd_q::disconnect() -{ - - if (!m_connected) - return; - - m_connected = false; - - if (m_rx_thread && m_rx_thread->joinable()) { - m_rx_thread->join(); - } - - m_conn.disconnect(); -} - -void -HW::cmd_q::enable() -{ - m_enabled = true; -} - -void -HW::cmd_q::disable() -{ - m_enabled = false; -} - -rc_t -HW::cmd_q::write() -{ - rc_t rc = rc_t::OK; - - /* - * The queue is enabled, Execute each command in the queue. - * If one execution fails, abort the rest - */ - auto it = m_queue.begin(); - - while (it != m_queue.end()) { - std::shared_ptr c = *it; - - VOM_LOG(log_level_t::DEBUG) << *c; - - if (m_enabled) { - /* - * before we issue the command we must move it to the pending - * store - * ince a async event can be recieved before the command - * completes - */ - rc = c->issue(m_conn); - - if (rc_t::OK == rc) { - /* - * move to the next - */ - } else { - /* - * barf out without issuing the rest - */ - VOM_LOG(log_level_t::ERROR) << "Failed to execute: " << c->to_string(); - break; - } - } else { - /* - * The HW is disabled, so set each command as succeeded - */ - c->succeeded(); - } - - ++it; - } - - /* - * erase all objects in the queue - */ - m_queue.erase(m_queue.begin(), m_queue.end()); - - return (rc); -} - -/* - * The single Command Queue - */ -HW::cmd_q* HW::m_cmdQ; - -/* - * single stat reader - */ -stat_reader* HW::m_statReader; -HW::item HW::m_poll_state; - -/** - * Initialse the connection to VPP - */ -void -HW::init(HW::cmd_q* f) -{ - m_cmdQ = f; - m_statReader = new stat_reader(); -} - -/** - * Initialse the connection to VPP - */ -void -HW::init(HW::cmd_q* f, stat_reader* s) -{ - m_cmdQ = f; - m_statReader = s; -} - -/** - * Initialse the connection to VPP - */ -void -HW::init() -{ - m_cmdQ = new cmd_q(); - m_statReader = new stat_reader(); -} - -void -HW::enqueue(cmd* cmd) -{ - m_cmdQ->enqueue(cmd); -} - -void -HW::enqueue(std::shared_ptr cmd) -{ - m_cmdQ->enqueue(cmd); -} - -void -HW::enqueue(std::queue& cmds) -{ - m_cmdQ->enqueue(cmds); -} - -bool -HW::connect() -{ - return (m_cmdQ->connect() && m_statReader->connect()); -} - -void -HW::disconnect() -{ - m_statReader->disconnect(); - m_cmdQ->disconnect(); -} - -void -HW::enable() -{ - m_cmdQ->enable(); -} - -void -HW::disable() -{ - m_cmdQ->disable(); -} - -rc_t -HW::write() -{ - return (m_cmdQ->write()); -} - -bool -HW::poll() -{ - std::shared_ptr poll(new hw_cmds::poll(m_poll_state)); - - HW::enqueue(poll); - HW::write(); - - return (m_poll_state); -} - -void -HW::read_stats() -{ - m_statReader->read(); -} - -template <> -std::string -HW::item::to_string() const -{ - std::ostringstream os; - - os << "hw-item:[" - << "rc:" << item_rc.to_string() << " data:" << item_data << "]"; - return (os.str()); -} - -template <> -std::string -HW::item::to_string() const -{ - std::ostringstream os; - - os << "hw-item:[" - << "rc:" << item_rc.to_string() << " data:" << item_data << "]"; - return (os.str()); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/hw.hpp b/extras/vom/vom/hw.hpp deleted file mode 100644 index d10a93aa59b..00000000000 --- a/extras/vom/vom/hw.hpp +++ /dev/null @@ -1,396 +0,0 @@ -/* - * 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_HW_H__ -#define __VOM_HW_H__ - -#include -#include -#include -#include -#include -#include - -#include "vom/cmd.hpp" -#include "vom/connection.hpp" -#include "vom/types.hpp" - -namespace VOM { - -class stat_reader; -class cmd; -class HW -{ -public: - /** - * A HW::item is data that is either to be written to or read from - * VPP/HW. - * The item is a pair of the data written/read and the result of that - * operation. - */ - template - class item - { - public: - /** - * Constructor - */ - item(const T& data) - : item_data(data) - , item_rc(rc_t::NOOP) - { - } - /** - * Constructor - */ - item() - : item_data() - , item_rc(rc_t::UNSET) - { - } - - /** - * Constructor - */ - item(rc_t rc) - : item_data() - , item_rc(rc) - { - } - - /** - * Constructor - */ - item(const T& data, rc_t rc) - : item_data(data) - , item_rc(rc) - { - } - - /** - * Destructor - */ - ~item() = default; - - /** - * Comparison operator - */ - bool operator==(const item& i) const - { - return (item_data == i.item_data); - } - - /** - * Copy assignment - */ - item& operator=(const item& other) - { - item_data = other.item_data; - item_rc = other.item_rc; - - return (*this); - } - - /** - * Return the data read/written - */ - T& data() { return (item_data); } - - /** - * Const reference to the data - */ - const T& data() const { return (item_data); } - - /** - * Get the HW return code - */ - rc_t rc() const { return (item_rc); } - - /** - * Set the HW return code - should only be called from the - * family of Command objects - */ - void set(const rc_t& rc) { item_rc = rc; } - - /** - * Return true if the HW item is configred in HW - */ - operator bool() const { return (rc_t::OK == item_rc); } - - /** - * update the item to the desired state. - * return true if a HW update is required - */ - bool update(const item& desired) - { - bool need_hw_update = false; - - /* - * if the deisred set is unset (i.e. defaulted, we've - * no update to make - */ - if (rc_t::UNSET == desired.rc()) { - return (false); - } - /* - * A HW update is needed if thestate is different - * or the state is not yet in HW - */ - need_hw_update = (item_data != desired.data() || rc_t::OK != rc()); - - item_data = desired.data(); - - return (need_hw_update); - } - - /** - * convert to string format for debug purposes - */ - std::string to_string() const - { - std::ostringstream os; - - os << "hw-item:[" - << "rc:" << item_rc.to_string() << " data:" << item_data.to_string() - << "]"; - - return (os.str()); - } - - private: - /** - * The data - */ - T item_data; - - /** - * The result when the item was written - */ - rc_t item_rc; - }; - - /** - * The pipe to VPP into which we write the commands - */ - class cmd_q - { - public: - /** - * Constructor - */ - cmd_q(); - /** - * Destructor - */ - ~cmd_q(); - - /** - * Copy assignement - only used in UT - */ - cmd_q& operator=(const cmd_q& f); - - /** - * Enqueue a command into the Q. - */ - virtual void enqueue(cmd* c); - /** - * Enqueue a command into the Q. - */ - virtual void enqueue(std::shared_ptr c); - - /** - * Enqueue a set of commands - */ - virtual void enqueue(std::queue& c); - - /** - * Write all the commands to HW - */ - virtual rc_t write(); - - /** - * Blocking Connect to VPP - call once at bootup - */ - virtual bool connect(); - - /** - * Disconnect to VPP - */ - virtual void disconnect(); - - /** - * Disable the passing of commands to VPP. Whilst disabled all - * writes will be discarded. Use this during the reset phase. - */ - void disable(); - - /** - * Enable the passing of commands to VPP - undoes the disable. - * The Q is enabled by default. - */ - void enable(); - - private: - /** - * A queue of enqueued commands, ready to be written - */ - std::deque> m_queue; - - /** - * A map of issued, but uncompleted, commands. - * i.e. those that we are waiting, async stylee, - * for VPP to complete - */ - std::map> m_pending; - - /** - * VPP Q poll function - */ - void rx_run(); - - /** - * The thread object running the poll/dispatch/connect thread - */ - std::unique_ptr m_rx_thread; - - /** - * A flag indicating the client has disabled the cmd Q. - */ - bool m_enabled; - - /** - * A flag for the thread to poll to see if the queue is still alive - */ - bool m_connected; - - /** - * The connection to VPP - */ - connection m_conn; - }; - - /** - * Initialise the HW connection to VPP - the UT version passing - * a mock Q. - */ - static void init(cmd_q* f); - - /** - * Initialise the HW connection to VPP - the UT version passing - * a mock Q. - */ - static void init(cmd_q* f, stat_reader* s); - - /** - * Initialise the HW - */ - static void init(); - - /** - * Enqueue A command for execution - */ - static void enqueue(cmd* f); - - /** - * Enqueue A command for execution - */ - static void enqueue(std::shared_ptr c); - - /** - * Enqueue A set of commands for execution - */ - static void enqueue(std::queue& c); - - /** - * Write/Execute all commands hitherto enqueued. - */ - static rc_t write(); - - /** - * Blocking Connect to VPP - */ - static bool connect(); - - /** - * Disconnect to VPP - */ - static void disconnect(); - - /** - * Blocking pool of the HW connection - */ - static bool poll(); - - /** - * read stats from stat segment - */ - static void read_stats(); - -private: - /** - * The command Q toward HW - */ - static cmd_q* m_cmdQ; - - /** - * The stat reader toward HW - */ - static stat_reader* m_statReader; - - /** - * HW::item representing the connection state as determined by polling - */ - static HW::item m_poll_state; - - /** - * Disable the passing of commands to VPP. Whilst disabled all writes - * will be discarded. Use this during the reset phase. - */ - static void disable(); - - /** - * Enable the passing of commands to VPP - undoes the disable. - * The Q is enabled by default. - */ - static void enable(); - - /** - * Only the OM can enable/disable HW - */ - friend class OM; -}; - -/** - * bool Specialisation for HW::item to_string - */ -template <> -std::string HW::item::to_string() const; - -/** - * uint Specialisation for HW::item to_string - */ -template <> -std::string HW::item::to_string() const; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/hw_cmds.cpp b/extras/vom/vom/hw_cmds.cpp deleted file mode 100644 index 429c123e9e9..00000000000 --- a/extras/vom/vom/hw_cmds.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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/hw_cmds.hpp" - -namespace VOM { -namespace hw_cmds { - -poll::poll(HW::item& item) - : rpc_cmd(item) -{ -} - -rc_t -poll::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -poll::to_string() const -{ - std::ostringstream s; - - s << "poll: " << m_hw_item.to_string(); - - return (s.str()); -} -} -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/hw_cmds.hpp b/extras/vom/vom/hw_cmds.hpp deleted file mode 100644 index c10f71e524c..00000000000 --- a/extras/vom/vom/hw_cmds.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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_HW_CMDS_H__ -#define __VOM_HW_CMDS_H__ - -#include -#include - -#include "vom/hw.hpp" -#include "vom/rpc_cmd.hpp" - -namespace VOM { -namespace hw_cmds { -/** -*A command poll the HW for liveness -*/ -class poll : public rpc_cmd, vapi::Control_ping> -{ -public: - /** - * Constructor taking the HW::item to update - */ - poll(HW::item& item); - - /** - * 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 poll& i) const; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/igmp_binding.cpp b/extras/vom/vom/igmp_binding.cpp deleted file mode 100644 index 73e0bd8f02a..00000000000 --- a/extras/vom/vom/igmp_binding.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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/igmp_binding.hpp" -#include "vom/igmp_binding_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -/** - * A DB of all igmp bindings configs - */ -singular_db igmp_binding::m_db; - -igmp_binding::event_handler igmp_binding::m_evh; - -igmp_binding::igmp_binding(const interface& itf) - : m_itf(itf.singular()) - , m_binding(true) -{ -} - -igmp_binding::igmp_binding(const igmp_binding& o) - : m_itf(o.m_itf) - , m_binding(o.m_binding) -{ -} - -igmp_binding::~igmp_binding() -{ - sweep(); - m_db.release(key(), this); -} - -bool -igmp_binding::operator==(const igmp_binding& l) const -{ - return (*m_itf == *l.m_itf); -} - -const igmp_binding::key_t -igmp_binding::key() const -{ - return (m_itf->key()); -} - -void -igmp_binding::sweep() -{ - if (m_binding) { - HW::enqueue(new igmp_binding_cmds::unbind_cmd(m_binding, m_itf->handle())); - } - HW::write(); -} - -void -igmp_binding::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -igmp_binding::replay() -{ - if (m_binding) { - HW::enqueue(new igmp_binding_cmds::bind_cmd(m_binding, m_itf->handle())); - } -} - -std::string -igmp_binding::to_string() const -{ - std::ostringstream s; - s << "igmp-binding: [" << m_itf->to_string() << " mode:host]"; - - return (s.str()); -} - -void -igmp_binding::update(const igmp_binding& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (!m_binding) { - HW::enqueue(new igmp_binding_cmds::bind_cmd(m_binding, m_itf->handle())); - } -} - -std::shared_ptr -igmp_binding::find_or_add(const igmp_binding& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -igmp_binding::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -igmp_binding::singular() const -{ - return find_or_add(*this); -} - -std::shared_ptr -igmp_binding::itf() const -{ - return m_itf; -} - -igmp_binding::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "igmp-binding" }, "IGMP bindings", this); -} - -void -igmp_binding::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -igmp_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - /* done with igmp_dump in igmp_listen */ -} - -dependency_t -igmp_binding::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -igmp_binding::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/igmp_binding.hpp b/extras/vom/vom/igmp_binding.hpp deleted file mode 100644 index 56af8d1117e..00000000000 --- a/extras/vom/vom/igmp_binding.hpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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_IGMP_BINDING_H__ -#define __VOM_IGMP_BINDING_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of IGMP binding on an interface - */ -class igmp_binding : public object_base -{ -public: - /** - * A binding is tied to a given interface, hence its key is - * that of the interface - */ - typedef interface::key_t key_t; - - /** - * Construct a new object matching the desried state - */ - igmp_binding(const interface& itf); - - /** - * Copy Constructor - */ - igmp_binding(const igmp_binding& o); - - /** - * Destructor - */ - ~igmp_binding(); - - /** - * Equal operator - */ - bool operator==(const igmp_binding& l) const; - - /** - * Get the object's key - */ - const key_t key() const; - - /** - * Return the 'singular' of the IGMP binding that matches this object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Return the matching'singular' of the interface - */ - std::shared_ptr itf() const; - - /** - * Dump all IGMP bindings into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Find a listen from its key - */ - static std::shared_ptr find(const key_t& k); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const igmp_binding& obj); - - /** - * Find or add IGMP binding to the OM - */ - static std::shared_ptr find_or_add(const igmp_binding& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer to the interface on which IGMP config - * resides. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A map of all IGMP bindings keyed against the interface. - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/igmp_binding_cmds.cpp b/extras/vom/vom/igmp_binding_cmds.cpp deleted file mode 100644 index 133509e4e75..00000000000 --- a/extras/vom/vom/igmp_binding_cmds.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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/igmp_binding_cmds.hpp" - -namespace VOM { -namespace igmp_binding_cmds { - -bind_cmd::bind_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{ -} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.enable = 1; - payload.mode = 1; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "igmp-bind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string(); - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{ -} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.enable = 0; - payload.mode = 1; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "igmp-unbind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string(); - - return (s.str()); -} - -}; // namespace igmp_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/igmp_binding_cmds.hpp b/extras/vom/vom/igmp_binding_cmds.hpp deleted file mode 100644 index 25a1a67215a..00000000000 --- a/extras/vom/vom/igmp_binding_cmds.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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_IGMP_BINDING_CMDS_H__ -#define __VOM_IGMP_BINDING_CMDS_H__ - -#include "vom/igmp_binding.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace igmp_binding_cmds { -/** - * A command class that binds the IGMP config to the interface - */ -class bind_cmd : public rpc_cmd, vapi::Igmp_enable_disable> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to bind - */ - const handle_t& m_itf; -}; - -/** - * A cmd class that Unbinds IGMP Config from an interface - */ -class unbind_cmd : public rpc_cmd, vapi::Igmp_enable_disable> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to unbind - */ - const handle_t& m_itf; -}; - -}; // namespace cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/igmp_listen.cpp b/extras/vom/vom/igmp_listen.cpp deleted file mode 100644 index 8d321add65d..00000000000 --- a/extras/vom/vom/igmp_listen.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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/igmp_listen.hpp" -#include "vom/igmp_listen_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -singular_db igmp_listen::m_db; - -igmp_listen::event_handler igmp_listen::m_evh; - -/** - * Construct a new object matching the desried state - */ -igmp_listen::igmp_listen(const igmp_binding& igmp_bind, - const boost::asio::ip::address_v4& gaddr, - const igmp_listen::src_addrs_t& saddrs) - : m_igmp_bind(igmp_bind.singular()) - , m_gaddr(gaddr) - , m_saddrs(saddrs) - , m_listen(true, rc_t::NOOP) -{ -} - -igmp_listen::igmp_listen(const igmp_binding& igmp_bind, - const boost::asio::ip::address_v4& gaddr) - : m_igmp_bind(igmp_bind.singular()) - , m_gaddr(gaddr) - , m_saddrs() - , m_listen(true, rc_t::NOOP) -{ -} - -igmp_listen::igmp_listen(const igmp_listen& o) - : m_igmp_bind(o.m_igmp_bind) - , m_gaddr(o.m_gaddr) - , m_saddrs(o.m_saddrs) - , m_listen(o.m_listen) -{ -} - -igmp_listen::~igmp_listen() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -bool -igmp_listen::operator==(const igmp_listen& l) const -{ - return ((m_gaddr == l.m_gaddr) && (*m_igmp_bind == *l.m_igmp_bind) && - (m_saddrs == l.m_saddrs)); -} - -const igmp_listen::key_t -igmp_listen::key() const -{ - return (make_pair(m_igmp_bind->itf()->key(), m_gaddr)); -} - -void -igmp_listen::sweep() -{ - if (m_listen) { - HW::enqueue(new igmp_listen_cmds::unlisten_cmd( - m_listen, m_igmp_bind->itf()->handle(), m_gaddr)); - } - HW::write(); -} - -void -igmp_listen::replay() -{ - if (m_listen) { - HW::enqueue(new igmp_listen_cmds::listen_cmd( - m_listen, m_igmp_bind->itf()->handle(), m_gaddr, m_saddrs)); - } -} - -std::string -igmp_listen::to_string() const -{ - auto addr = m_saddrs.cbegin(); - - std::ostringstream s; - s << "igmp-listen:[" << m_igmp_bind->to_string() << " group:" << m_gaddr - << " src-addrs: ["; - while (addr != m_saddrs.cend()) { - s << " " << *addr; - ++addr; - } - s << " ] " << m_listen.to_string() << "]"; - - return (s.str()); -} - -void -igmp_listen::update(const igmp_listen& desired) -{ - /* - * no updates for the listen. chaning the interface or the group addr is a - * change to the key, hence a new object - */ - if (!m_listen) { - HW::enqueue(new igmp_listen_cmds::listen_cmd( - m_listen, m_igmp_bind->itf()->handle(), m_gaddr, m_saddrs)); - } -} - -std::shared_ptr -igmp_listen::find_or_add(const igmp_listen& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -igmp_listen::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -igmp_listen::singular() const -{ - return find_or_add(*this); -} - -void -igmp_listen::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -igmp_listen::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "igmp-listen" }, "igmp listener", this); -} - -void -igmp_listen::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -igmp_listen::event_handler::handle_populate(const client_db::key_t& key) -{ - /** - * This is done while populating the interfaces - */ -} - -dependency_t -igmp_listen::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -igmp_listen::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/igmp_listen.hpp b/extras/vom/vom/igmp_listen.hpp deleted file mode 100644 index 4f07e759b09..00000000000 --- a/extras/vom/vom/igmp_listen.hpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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_IGMP_LISTEN_H__ -#define __VOM_IGMP_LISTEN_H__ - -#include "vom/hw.hpp" -#include "vom/igmp_binding.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of igmp configuration on an interface - */ -class igmp_listen : public object_base -{ -public: - typedef std::set src_addrs_t; - - /** - * The key type for igmp_listens - */ - typedef std::pair key_t; - - /** - * Construct a new object matching the desried state - */ - igmp_listen(const igmp_binding& igmp_bind, - const boost::asio::ip::address_v4& gaddr, - const src_addrs_t& saddrs); - igmp_listen(const igmp_binding& igmp_bind, - const boost::asio::ip::address_v4& gaddr); - - /** - * Copy Constructor - */ - igmp_listen(const igmp_listen& o); - - /** - * Destructor - */ - ~igmp_listen(); - - /** - * Comparison operator - */ - bool operator==(const igmp_listen& l) const; - - /** - * Get the object's key - */ - const key_t key() const; - - /** - * Return the 'singular instance' of the IGMP that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all igmp_listens into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Find a listen from its key - */ - static std::shared_ptr find(const key_t& k); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const igmp_listen& obj); - - /** - * Find or add the singular instance in the DB - */ - static std::shared_ptr find_or_add(const igmp_listen& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer the igmp_binding that this 'igmp listen' - * represents. By holding the reference here, we can guarantee that - * this object will outlive the igmp_binding - */ - const std::shared_ptr m_igmp_bind; - - /** - * The group address for igmp configuration - */ - const boost::asio::ip::address_v4 m_gaddr; - - /** - * The set of src addresses to listen for - */ - const src_addrs_t m_saddrs; - - /** - * HW configuration for the listen. The bool representing the - * do/don't bind. - */ - HW::item m_listen; - - /** - * A map of all igmp listen keyed against a combination of the interface - * and group addr keys. - */ - static singular_db m_db; -}; - -/** - * Ostream output for the key - */ -std::ostream& operator<<(std::ostream& os, const igmp_listen::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/igmp_listen_cmds.cpp b/extras/vom/vom/igmp_listen_cmds.cpp deleted file mode 100644 index 69e243d9b4a..00000000000 --- a/extras/vom/vom/igmp_listen_cmds.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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/igmp_listen_cmds.hpp" -#include "vom/api_types.hpp" - -DEFINE_VAPI_MSG_IDS_IGMP_API_JSON; - -namespace VOM { -namespace igmp_listen_cmds { -listen_cmd::listen_cmd(HW::item& item, - const handle_t& itf, - const boost::asio::ip::address_v4& gaddr, - const igmp_listen::src_addrs_t& saddrs) - : rpc_cmd(item) - , m_itf(itf) - , m_gaddr(gaddr) - , m_saddrs(saddrs) -{ -} - -bool -listen_cmd::operator==(const listen_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_gaddr == other.m_gaddr) && - (m_saddrs == other.m_saddrs)); -} - -rc_t -listen_cmd::issue(connection& con) -{ - u8 size = m_saddrs.size(); - msg_t req(con.ctx(), sizeof(vapi_type_ip4_address) * size, std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.group.sw_if_index = m_itf.value(); - to_api(m_gaddr, payload.group.gaddr); - - if (0 == size) { - // no sources => (*,G) join - payload.group.filter = EXCLUDE; - payload.group.n_srcs = 0; - } else { - // source => (S,G) join - payload.group.filter = INCLUDE; - u8 i = 0; - - for (auto addr : m_saddrs) { - to_api(addr, payload.group.saddrs[i]); - i++; - } - payload.group.n_srcs = i; - } - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -listen_cmd::to_string() const -{ - auto addr = m_saddrs.cbegin(); - std::ostringstream s; - s << "igmp-listen: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() - << " group:" << m_gaddr << " src-addrs:["; - while (addr != m_saddrs.cend()) { - s << " " << *addr; - addr++; - } - s << " ]"; - return (s.str()); -} - -unlisten_cmd::unlisten_cmd(HW::item& item, - const handle_t& itf, - const boost::asio::ip::address_v4& gaddr) - : rpc_cmd(item) - , m_itf(itf) - , m_gaddr(gaddr) -{ -} - -bool -unlisten_cmd::operator==(const unlisten_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_gaddr == other.m_gaddr)); -} - -rc_t -unlisten_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), 0, std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.group.sw_if_index = m_itf.value(); - payload.group.n_srcs = 0; - payload.group.filter = INCLUDE; - to_api(m_gaddr, payload.group.gaddr); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unlisten_cmd::to_string() const -{ - std::ostringstream s; - s << "igmp-unlisten: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string() << " group:" << m_gaddr; - - return (s.str()); -} - -dump_cmd::dump_cmd(const handle_t& hdl) - : m_itf(hdl) -{ -} - -dump_cmd::dump_cmd(const dump_cmd& d) - : m_itf(d.m_itf) -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("igmp-listen-dump"); -} - -}; // namespace igmp_listen_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/igmp_listen_cmds.hpp b/extras/vom/vom/igmp_listen_cmds.hpp deleted file mode 100644 index 5bfea47914b..00000000000 --- a/extras/vom/vom/igmp_listen_cmds.hpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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_IGMP_LISTEN_CMDS_H__ -#define __VOM_IGMP_LISTEN_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/igmp_listen.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace igmp_listen_cmds { - -/** - * A functor class that binds the igmp group to the interface - */ -class listen_cmd : public rpc_cmd, vapi::Igmp_listen> -{ -public: - /** - * Constructor - */ - listen_cmd(HW::item& item, - const handle_t& itf, - const boost::asio::ip::address_v4& gaddr, - const igmp_listen::src_addrs_t& saddrs); - - /** - * 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 listen_cmd& i) const; - -private: - /** - * Reference to the interface to bind to - */ - const handle_t& m_itf; - - /** - * The igmp group to bind - */ - const boost::asio::ip::address_v4& m_gaddr; - - /** - * The igmp srouce specific addresses to listen them - */ - const igmp_listen::src_addrs_t& m_saddrs; -}; - -/** - * A cmd class that Unbinds igmp group from an interface - */ -class unlisten_cmd : public rpc_cmd, vapi::Igmp_listen> -{ -public: - /** - * Constructor - */ - unlisten_cmd(HW::item& item, - const handle_t& itf, - const boost::asio::ip::address_v4& gaddr); - - /** - * 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 unlisten_cmd& i) const; - -private: - /** - * Reference to the interface to unbind - */ - const handle_t& m_itf; - - /** - * The igmp group to unlisten - */ - const boost::asio::ip::address_v4& m_gaddr; -}; - -/** - * A cmd class that Dumps all the igmp configs - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(const handle_t& itf); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; - - /** - * The interface to get the igmp config for - */ - const handle_t& m_itf; -}; - -}; // namespace igmp_listen_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/inspect.cpp b/extras/vom/vom/inspect.cpp deleted file mode 100644 index 605a921b5ac..00000000000 --- a/extras/vom/vom/inspect.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 -#include -#include - -#include "vom/inspect.hpp" -#include "vom/logger.hpp" -#include "vom/om.hpp" - -namespace VOM { -std::unique_ptr> - inspect::m_cmd_handlers; - -std::unique_ptr, std::string>>> - inspect::m_help_handlers; - -void -inspect::handle_input(const std::string& message, std::ostream& output) -{ - if (message.length()) { - if (message.find("help") != std::string::npos) { - output << "Command Options: " << std::endl; - output << " keys - Show all keys owning objects" - << std::endl; - output << " key:XXX - Show all object referenced by " - "key XXX" - << std::endl; - output << " all - Show All objects" << std::endl; - output << "Individual object_base Types:" << std::endl; - - for (auto h : *m_help_handlers) { - output << " {"; - - for (auto s : h.first) { - output << s << " "; - } - output << "} - \t"; - output << h.second; - output << std::endl; - } - } else if (message.find("keys") != std::string::npos) { - OM::dump(output); - } else if (message.find("key:") != std::string::npos) { - std::vector results; - boost::split(results, message, boost::is_any_of(":\n")); - OM::dump(results[1], output); - } else if (message.find("all") != std::string::npos) { - /* - * get the unique set of handlers, then invoke each - */ - std::set hdlrs; - for (auto h : *m_cmd_handlers) { - hdlrs.insert(h.second); - } - for (auto h : hdlrs) { - h->show(output); - } - } else { - auto it = m_cmd_handlers->find(message); - - if (it != m_cmd_handlers->end()) { - it->second->show(output); - } else { - output << "Unknown Command: " << message << std::endl; - } - } - } -} - -void -inspect::register_handler(const std::vector& cmds, - const std::string& help, - command_handler* handler) -{ - if (!m_cmd_handlers) { - m_cmd_handlers.reset(new std::map); - m_help_handlers.reset( - new std::deque, std::string>>); - } - - for (auto cmd : cmds) { - (*m_cmd_handlers)[cmd] = handler; - } - m_help_handlers->push_front(std::make_pair(cmds, help)); -} -} -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/inspect.hpp b/extras/vom/vom/inspect.hpp deleted file mode 100644 index d5bca3040d2..00000000000 --- a/extras/vom/vom/inspect.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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_INSPECT_H__ -#define __VOM_INSPECT_H__ - -#include -#include -#include -#include -#include -#include - -namespace VOM { -/** - * A means to inspect the state VPP has built, in total, and per-client - */ -class inspect -{ -public: - /** - * Constructor - */ - inspect() = default; - - /** - * Destructor to tidyup socket resources - */ - ~inspect() = default; - - /** - * handle input from the requester - * - * @param input command - * @param output output - */ - void handle_input(const std::string& input, std::ostream& output); - - /** - * inspect command handler Handler - */ - class command_handler - { - public: - command_handler() = default; - virtual ~command_handler() = default; - - /** - * Show each object - */ - virtual void show(std::ostream& os) = 0; - }; - - /** - * Register a command handler for inspection - */ - static void register_handler(const std::vector& cmds, - const std::string& help, - command_handler* ch); - -private: - /** - * command handler list - */ - static std::unique_ptr> - m_cmd_handlers; - /** - * help handler list - */ - static std::unique_ptr< - std::deque, std::string>>> - m_help_handlers; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/interface.cpp b/extras/vom/vom/interface.cpp deleted file mode 100644 index 70035648d06..00000000000 --- a/extras/vom/vom/interface.cpp +++ /dev/null @@ -1,776 +0,0 @@ -/* - * 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/interface.hpp" -#include "vom/api_types.hpp" -#include "vom/bond_group_binding.hpp" -#include "vom/bond_group_binding_cmds.hpp" -#include "vom/bond_interface_cmds.hpp" -#include "vom/interface_cmds.hpp" -#include "vom/interface_factory.hpp" -#include "vom/l3_binding_cmds.hpp" -#include "vom/logger.hpp" -#include "vom/prefix.hpp" -#include "vom/singular_db_funcs.hpp" -#include "vom/stat_reader.hpp" -#include "vom/tap_interface_cmds.hpp" - -namespace VOM { -/** - * A DB of all the interfaces, key on the name - */ -singular_db interface::m_db; - -/** - * A DB of all the interfaces, key on VPP's handle - */ -std::map> interface::m_hdl_db; - -interface::event_handler interface::m_evh; - -/** - * the event enable command. - */ -std::shared_ptr interface::m_events_cmd; - -/** - * Construct a new object matching the desried state - */ -interface::interface(const std::string& name, - interface::type_t itf_type, - interface::admin_state_t itf_state, - const std::string& tag) - : m_hdl(handle_t::INVALID) - , m_name(name) - , m_type(itf_type) - , m_state(itf_state) - , m_table_id(route::DEFAULT_TABLE) - , m_l2_address(l2_address_t::ZERO, rc_t::UNSET) - , m_stats_type(stats_type_t::NORMAL) - , m_stats({}) - , m_listener(nullptr) - , m_oper(oper_state_t::DOWN) - , m_tag(tag) -{ -} - -interface::interface(const std::string& name, - interface::type_t itf_type, - interface::admin_state_t itf_state, - const route_domain& rd, - const std::string& tag) - : m_hdl(handle_t::INVALID) - , m_name(name) - , m_type(itf_type) - , m_rd(rd.singular()) - , m_state(itf_state) - , m_table_id(m_rd->table_id()) - , m_l2_address(l2_address_t::ZERO, rc_t::UNSET) - , m_stats_type(stats_type_t::NORMAL) - , m_stats({}) - , m_listener(nullptr) - , m_oper(oper_state_t::DOWN) - , m_tag(tag) -{ -} - -interface::interface(const interface& o) - : m_hdl(o.m_hdl) - , m_name(o.m_name) - , m_type(o.m_type) - , m_rd(o.m_rd) - , m_state(o.m_state) - , m_table_id(o.m_table_id) - , m_l2_address(o.m_l2_address) - , m_stats_type(o.m_stats_type) - , m_stats(o.m_stats) - , m_listener(o.m_listener) - , m_oper(o.m_oper) - , m_tag(o.m_tag) -{ -} - -bool -interface::operator==(const interface& i) const -{ - return ((key() == i.key()) && - (m_l2_address.data() == i.m_l2_address.data()) && - (m_state == i.m_state) && (m_rd == i.m_rd) && (m_type == i.m_type) && - (m_oper == i.m_oper)); -} - -interface::event_listener::event_listener() - : m_status(rc_t::NOOP) -{ -} - -HW::item& -interface::event_listener::status() -{ - return (m_status); -} - -interface::stat_listener::stat_listener() - : m_status(rc_t::NOOP) -{ -} - -HW::item& -interface::stat_listener::status() -{ - return (m_status); -} - -/** - * Return the interface type - */ -const interface::type_t& -interface::type() const -{ - return (m_type); -} - -const handle_t& -interface::handle() const -{ - return (singular()->handle_i()); -} - -const handle_t& -interface::handle_i() const -{ - return (m_hdl.data()); -} - -const l2_address_t& -interface::l2_address() const -{ - return (m_l2_address.data()); -} - -const interface::admin_state_t& -interface::admin_state() const -{ - return (m_state.data()); -} - -interface::const_iterator_t -interface::cbegin() -{ - return m_db.begin(); -} - -interface::const_iterator_t -interface::cend() -{ - return m_db.end(); -} - -void -interface::sweep() -{ - if (m_table_id && (m_table_id.data() != route::DEFAULT_TABLE)) { - m_table_id.data() = route::DEFAULT_TABLE; - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); - } - - if (m_listener) { - disable_stats_i(); - } - - // If the interface is up, bring it down - if (m_state && interface::admin_state_t::UP == m_state.data()) { - m_state.data() = interface::admin_state_t::DOWN; - HW::enqueue(new interface_cmds::state_change_cmd(m_state, m_hdl)); - } - - if (m_hdl) { - std::queue cmds; - HW::enqueue(mk_delete_cmd(cmds)); - } - HW::write(); -} - -void -interface::replay() -{ - if (m_hdl) { - std::queue cmds; - HW::enqueue(mk_create_cmd(cmds)); - } - - if (m_state && interface::admin_state_t::UP == m_state.data()) { - HW::enqueue(new interface_cmds::state_change_cmd(m_state, m_hdl)); - } - - if (m_listener) { - enable_stats(m_listener, m_stats_type.data()); - } - - if (m_table_id && (m_table_id.data() != route::DEFAULT_TABLE)) { - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); - } -} - -interface::~interface() -{ - sweep(); - release(); -} - -void -interface::release() -{ - // not in the DB anymore. - m_db.release(m_name, this); -} - -std::string -interface::to_string() const -{ - std::ostringstream s; - s << "interface:[" << m_name << " type:" << m_type.to_string() - << " hdl:" << m_hdl.to_string() << " l2-address:[" - << m_l2_address.to_string() << "]"; - - if (m_rd) { - s << " rd:" << m_rd->to_string(); - } - - s << " admin-state:" << m_state.to_string() - << " oper-state:" << m_oper.to_string(); - - if (!m_tag.empty()) { - s << " tag:[" << m_tag << "]"; - } - - s << "]"; - - return (s.str()); -} - -const std::string& -interface::name() const -{ - return (m_name); -} - -const interface::key_t& -interface::key() const -{ - return (name()); -} - -std::queue& -interface::mk_create_cmd(std::queue& q) -{ - if (type_t::LOOPBACK == m_type) { - q.push(new interface_cmds::loopback_create_cmd(m_hdl, m_name)); - q.push(new interface_cmds::set_tag(m_hdl, m_name)); - /* - * set the m_tag for pretty-print - */ - m_tag = m_name; - } else if (type_t::BVI == m_type) { - q.push(new interface_cmds::bvi_create_cmd(m_hdl, m_name)); - q.push(new interface_cmds::set_tag(m_hdl, m_name)); - m_tag = m_name; - } else if (type_t::AFPACKET == m_type) { - q.push(new interface_cmds::af_packet_create_cmd(m_hdl, m_name)); - if (!m_tag.empty()) - q.push(new interface_cmds::set_tag(m_hdl, m_tag)); - } else if (type_t::TAPV2 == m_type) { - if (!m_tag.empty()) - q.push(new interface_cmds::set_tag(m_hdl, m_tag)); - } else if (type_t::VHOST == m_type) { - q.push(new interface_cmds::vhost_create_cmd(m_hdl, m_name, m_tag)); - } else { - m_hdl.set(rc_t::OK); - } - - return (q); -} - -std::queue& -interface::mk_delete_cmd(std::queue& q) -{ - if (type_t::LOOPBACK == m_type) { - q.push(new interface_cmds::loopback_delete_cmd(m_hdl)); - } else if (type_t::BVI == m_type) { - q.push(new interface_cmds::bvi_delete_cmd(m_hdl)); - } else if (type_t::AFPACKET == m_type) { - q.push(new interface_cmds::af_packet_delete_cmd(m_hdl, m_name)); - } else if (type_t::VHOST == m_type) { - q.push(new interface_cmds::vhost_delete_cmd(m_hdl, m_name)); - } - - return (q); -} - -void -interface::update(const interface& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (rc_t::OK != m_hdl.rc()) { - std::queue cmds; - HW::enqueue(mk_create_cmd(cmds)); - /* - * interface create now, so we can barf early if it fails - */ - HW::write(); - } - - /* - * If the interface is not created do other commands should be issued - */ - if (rc_t::OK != m_hdl.rc()) - return; - - /* - * change the interface state to that which is deisred - */ - if (m_state.update(desired.m_state)) { - HW::enqueue(new interface_cmds::state_change_cmd(m_state, m_hdl)); - } - - /* - * change the interface state to that which is deisred - */ - if (m_l2_address.update(desired.m_l2_address)) { - HW::enqueue(new interface_cmds::set_mac_cmd(m_l2_address, m_hdl)); - } - - /* - * If the interface is mapped into a route domain, set VPP's - * table ID - */ - if (m_rd != desired.m_rd) { - /* - * changing route domains. need to remove all L3 bindings, swap the table - * then reapply the bindings. - */ - auto it = l3_binding::cbegin(); - - while (it != l3_binding::cend()) { - if (it->second.lock()->itf().key() == key()) - it->second.lock()->sweep(); - ++it; - } - m_rd = desired.m_rd; - m_table_id.update(m_rd ? m_rd->table_id() : route::DEFAULT_TABLE); - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); - HW::write(); - - it = l3_binding::cbegin(); - while (it != l3_binding::cend()) { - if (it->second.lock()->itf().key() == key()) - it->second.lock()->replay(); //(*it->second.lock()); - ++it; - } - } else if (!m_table_id && m_rd) { - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); - } -} - -void -interface::set(const admin_state_t& state) -{ - m_state = state; -} - -void -interface::set(const l2_address_t& addr) -{ - m_l2_address = { addr, rc_t::NOOP }; -} - -void -interface::set(const handle_t& hdl) -{ - m_hdl = hdl; -} - -void -interface::set(const oper_state_t& state) -{ - m_oper = state; -} - -void -interface::set(const std::string& tag) -{ - m_tag = tag; -} - -void -interface::set(const counter_t& count, const std::string& stat_type) -{ - if ("rx" == stat_type) - m_stats.m_rx = count; - else if ("tx" == stat_type) - m_stats.m_tx = count; - else if ("drops" == stat_type) - m_stats.m_drop = count; - else if ("rx-unicast" == stat_type) - m_stats.m_rx_unicast = count; - else if ("tx-unicast" == stat_type) - m_stats.m_tx_unicast = count; - else if ("rx-multicast" == stat_type) - m_stats.m_rx_multicast = count; - else if ("tx-multicast" == stat_type) - m_stats.m_tx_multicast = count; - else if ("rx-broadcast" == stat_type) - m_stats.m_rx_broadcast = count; - else if ("tx-broadcast" == stat_type) - m_stats.m_rx_broadcast = count; -} - -const interface::stats_t& -interface::get_stats(void) const -{ - return m_stats; -} - -void -interface::publish_stats() -{ - m_listener->handle_interface_stat(*this); -} - -std::ostream& -operator<<(std::ostream& os, const interface::stats_t& stats) -{ - os << "[" - << "rx " << stats.m_rx << " rx-unicast " << stats.m_rx_unicast - << " rx-multicast " << stats.m_rx_multicast << " rx-broadcast " - << stats.m_rx_broadcast << " tx " << stats.m_tx << " tx-unicast " - << stats.m_tx_unicast << " tx-multicast " << stats.m_tx_multicast - << " tx-broadcast " << stats.m_tx_broadcast << " drops " << stats.m_drop - << "]" << std::endl; - - return (os); -} - -void -interface::enable_stats_i(interface::stat_listener* el, const stats_type_t& st) -{ - if (el != NULL) { - if (stats_type_t::DETAILED == st) { - m_stats_type.set(rc_t::NOOP); - HW::enqueue(new interface_cmds::collect_detail_stats_change_cmd( - m_stats_type, handle_i(), true)); - } - stat_reader::registers(*this); - m_listener = el; - } -} - -void -interface::enable_stats(interface::stat_listener* el, const stats_type_t& st) -{ - singular()->enable_stats_i(el, st); -} - -void -interface::disable_stats_i() -{ - if (m_listener != NULL) { - if (stats_type_t::DETAILED == m_stats_type) { - HW::enqueue(new interface_cmds::collect_detail_stats_change_cmd( - m_stats_type, handle_i(), false)); - } - stat_reader::unregisters(*this); - m_listener = NULL; - } -} - -void -interface::disable_stats() -{ - singular()->disable_stats_i(); -} - -std::shared_ptr -interface::singular_i() const -{ - return (m_db.find_or_add(key(), *this)); -} - -std::shared_ptr -interface::singular() const -{ - return singular_i(); -} - -std::shared_ptr -interface::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -interface::find(const handle_t& handle) -{ - return (m_hdl_db[handle].lock()); -} - -void -interface::add(const key_t& key, const HW::item& item) -{ - std::shared_ptr sp = find(key); - - if (sp && item) { - m_hdl_db[item.data()] = sp; - } -} - -void -interface::remove(const HW::item& item) -{ - m_hdl_db.erase(item.data()); -} - -void -interface::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -interface::enable_events(interface::event_listener& el) -{ - m_events_cmd = std::make_shared(el); - HW::enqueue(m_events_cmd); - HW::write(); -} - -void -interface::disable_events() -{ - m_events_cmd.reset(); -} - -void -interface::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump VPP vhost-user interfaces - */ - std::shared_ptr vcmd = - std::make_shared(); - - HW::enqueue(vcmd); - HW::write(); - - for (auto& vhost_itf_record : *vcmd) { - std::shared_ptr vitf = - interface_factory::new_vhost_user_interface( - vhost_itf_record.get_payload()); - VOM_LOG(log_level_t::DEBUG) << " vhost-dump: " << vitf->to_string(); - OM::commit(key, *vitf); - } - - /* - * dump VPP af-packet interfaces - */ - std::shared_ptr afcmd = - std::make_shared(); - - HW::enqueue(afcmd); - HW::write(); - - for (auto& af_packet_itf_record : *afcmd) { - std::shared_ptr afitf = - interface_factory::new_af_packet_interface( - af_packet_itf_record.get_payload()); - VOM_LOG(log_level_t::DEBUG) << " af_packet-dump: " << afitf->to_string(); - OM::commit(key, *afitf); - } - - /* - * dump VPP tapv2 interfaces - */ - std::shared_ptr tapv2cmd = - std::make_shared(); - - HW::enqueue(tapv2cmd); - HW::write(); - - for (auto& tapv2_record : *tapv2cmd) { - std::shared_ptr tapv2itf = - interface_factory::new_tap_interface(tapv2_record.get_payload()); - VOM_LOG(log_level_t::DEBUG) << "tapv2-dump: " << tapv2itf->to_string(); - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, *tapv2itf); - } - - /* - * dump VPP interfaces - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& itf_record : *cmd) { - auto payload = itf_record.get_payload(); - VOM_LOG(log_level_t::DEBUG) << "dump: [" << payload.sw_if_index - << " name:" << (char*)payload.interface_name - << " tag:" << (char*)payload.tag << "]"; - - std::shared_ptr itf = interface_factory::new_interface(payload); - - if (itf && interface::type_t::LOCAL != itf->type()) { - VOM_LOG(log_level_t::DEBUG) << "dump: " << itf->to_string(); - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, *itf); - - /** - * Get the address configured on the interface - */ - std::shared_ptr dcmd = - std::make_shared( - l3_binding_cmds::dump_v4_cmd(itf->handle())); - - HW::enqueue(dcmd); - HW::write(); - - for (auto& l3_record : *dcmd) { - auto& payload = l3_record.get_payload(); - const route::prefix_t pfx = from_api(payload.prefix); - - VOM_LOG(log_level_t::DEBUG) << "dump: " << pfx.to_string(); - - l3_binding l3(*itf, pfx); - OM::commit(key, l3); - } - } - } - - /* - * dump VPP bond interfaces - */ - std::shared_ptr bcmd = - std::make_shared(); - - HW::enqueue(bcmd); - HW::write(); - - for (auto& bond_itf_record : *bcmd) { - std::shared_ptr bond_itf = - interface_factory::new_bond_interface(bond_itf_record.get_payload()); - - VOM_LOG(log_level_t::DEBUG) << " bond-dump:" << bond_itf->to_string(); - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, *bond_itf); - - std::shared_ptr scmd = - std::make_shared( - bond_group_binding_cmds::dump_cmd(bond_itf->handle())); - - HW::enqueue(scmd); - HW::write(); - - bond_group_binding::enslaved_itf_t enslaved_itfs; - - for (auto& slave_itf_record : *scmd) { - bond_member slave_itf = interface_factory::new_bond_member_interface( - slave_itf_record.get_payload()); - - VOM_LOG(log_level_t::DEBUG) << " slave-dump:" << slave_itf.to_string(); - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - // OM::commit(slave_itf->key(), *slave_itf); - enslaved_itfs.insert(slave_itf); - } - - if (!enslaved_itfs.empty()) { - bond_group_binding bid(*bond_itf, enslaved_itfs); - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, bid); - } - } -} - -interface::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "interface", "intf" }, "interfaces", this); -} - -void -interface::event_handler::handle_replay() -{ - m_db.replay(); -} - -dependency_t -interface::event_handler::order() const -{ - return (dependency_t::INTERFACE); -} - -void -interface::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/interface.hpp b/extras/vom/vom/interface.hpp deleted file mode 100644 index a1098c11329..00000000000 --- a/extras/vom/vom/interface.hpp +++ /dev/null @@ -1,758 +0,0 @@ -/* - * 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_INTERFACE_H__ -#define __VOM_INTERFACE_H__ - -#include "vom/enum_base.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/prefix.hpp" -#include "vom/route_domain.hpp" -#include "vom/rpc_cmd.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * Forward declaration of the stats and events command - */ -namespace interface_cmds { -class events_cmd; -}; -class stat_reader; - -/** - * A representation of an interface in VPP - */ -class interface : public object_base -{ -public: - struct stats_type_t : public enum_base - { - const static stats_type_t DETAILED; - const static stats_type_t NORMAL; - - private: - stats_type_t(int v, const std::string& s); - }; - - /** - * The key for interface's key - */ - typedef std::string key_t; - - /** - * The iterator type - */ - typedef singular_db::const_iterator - const_iterator_t; - - /** - * An interface type - */ - struct type_t : enum_base - { - /** - * Unknown type - */ - const static type_t UNKNOWN; - /** - * A brideged Virtual interface (aka SVI or IRB) - */ - const static type_t BVI; - /** - * VXLAN interface - */ - const static type_t VXLAN; - /** - * Ethernet interface type - */ - const static type_t ETHERNET; - /** - * AF-Packet interface type - */ - const static type_t AFPACKET; - /** - * loopback interface type - */ - const static type_t LOOPBACK; - /** - * Local interface type (specific to VPP) - */ - const static type_t LOCAL; - - /** - * TAPv2 interface type - */ - const static type_t TAPV2; - - /** - * vhost-user interface type - */ - const static type_t VHOST; - - /** - * bond interface type - */ - 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 - */ - static type_t from_string(const std::string& str); - - private: - /** - * Private constructor taking the value and the string name - */ - type_t(int v, const std::string& s); - }; - - /** - * The admin state of the interface - */ - struct admin_state_t : enum_base - { - /** - * Admin DOWN state - */ - const static admin_state_t DOWN; - /** - * Admin UP state - */ - const static admin_state_t UP; - - /** - * Convert VPP's numerical value to enum type - */ - static admin_state_t from_int(uint8_t val); - - private: - /** - * Private constructor taking the value and the string name - */ - admin_state_t(int v, const std::string& s); - }; - - /** - * The oper state of the interface - */ - struct oper_state_t : enum_base - { - /** - * Operational DOWN state - */ - const static oper_state_t DOWN; - /** - * Operational UP state - */ - const static oper_state_t UP; - - /** - * Convert VPP's numerical value to enum type - */ - static oper_state_t from_int(uint8_t val); - - private: - /** - * Private constructor taking the value and the string name - */ - oper_state_t(int v, const std::string& s); - }; - - /** - * stats_t: - */ - struct stats_t - { - counter_t m_rx; - counter_t m_tx; - counter_t m_rx_unicast; - counter_t m_tx_unicast; - counter_t m_rx_multicast; - counter_t m_tx_multicast; - counter_t m_rx_broadcast; - counter_t m_tx_broadcast; - counter_t m_drop; - }; - - /** - * Construct a new object matching the desried state - */ - interface(const std::string& name, - type_t type, - admin_state_t state, - const std::string& tag = ""); - /** - * Construct a new object matching the desried state mapped - * to a specific route_domain - */ - interface(const std::string& name, - type_t type, - admin_state_t state, - const route_domain& rd, - const std::string& tag = ""); - /** - * Destructor - */ - virtual ~interface(); - - /** - * Copy Constructor - */ - interface(const interface& o); - - static const_iterator_t cbegin(); - static const_iterator_t cend(); - - /** - * Return the matching'singular' of the interface - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - virtual std::string to_string(void) const; - - /** - * Return VPP's handle to this object - */ - const handle_t& handle() const; - - /** - * Return the interface type - */ - const type_t& type() const; - - /** - * Return the interface type - */ - const std::string& name() const; - - /** - * Return the interface type - */ - const key_t& key() const; - - /** - * Return the L2 Address - */ - const l2_address_t& l2_address() const; - - /** - * Return the admin state - */ - const admin_state_t& admin_state() const; - - /** - * Set the admin state of the interface - * - * N.B. All set function change only the attibute of the object on whcih - * they act, they do not make changes in VPP - */ - void set(const admin_state_t& state); - - /** - * Set the L2 Address - */ - void set(const l2_address_t& addr); - - /** - * Set the operational state of the interface, as reported by VPP - */ - void set(const oper_state_t& state); - - /** - * Set the tag to the interface - */ - void set(const std::string& tag); - - /** - * Get the interface stats - */ - const stats_t& get_stats(void) const; - - /** - * Comparison operator - only used for UT - */ - virtual bool operator==(const interface& i) const; - - /** - * A base class for interface Create commands - */ - template - class create_cmd : public rpc_cmd, MSG> - { - public: - create_cmd(HW::item& item, const std::string& name) - : rpc_cmd, MSG>(item) - , m_name(name) - { - } - - /** - * Destructor - */ - virtual ~create_cmd() = default; - - /** - * Comparison operator - only used for UT - */ - virtual bool operator==(const create_cmd& o) const - { - return (m_name == o.m_name); - } - - /** - * Indicate the succeeded, when the HW Q is disabled. - */ - void succeeded() - { - rpc_cmd, MSG>::succeeded(); - interface::add(m_name, this->item()); - } - - /** - * add the created interface to the DB - */ - void insert_interface() { interface::add(m_name, this->item()); } - - virtual vapi_error_e operator()(MSG& reply) - { - int sw_if_index = reply.get_response().get_payload().sw_if_index; - int retval = reply.get_response().get_payload().retval; - - VOM_LOG(log_level_t::DEBUG) << this->to_string() << " res:" << retval - << " sw-if-index:" << sw_if_index; - - rc_t rc = rc_t::from_vpp_retval(retval); - handle_t handle = handle_t::INVALID; - - if (rc_t::OK == rc) { - handle = sw_if_index; - } - - this->fulfill(HW::item(handle, rc)); - - return (VAPI_OK); - } - - protected: - /** - * The name of the interface to be created - */ - const std::string& m_name; - }; - - /** - * Base class for intterface Delete commands - */ - template - class delete_cmd : public rpc_cmd, MSG> - { - public: - delete_cmd(HW::item& item, const std::string& name) - : rpc_cmd, MSG>(item) - , m_name(name) - { - } - - delete_cmd(HW::item& item) - : rpc_cmd, MSG>(item) - , m_name() - { - } - - /** - * Destructor - */ - virtual ~delete_cmd() = default; - - /** - * Comparison operator - only used for UT - */ - virtual bool operator==(const delete_cmd& o) const - { - return (this->m_hw_item == o.m_hw_item); - } - - /** - * Indicate the succeeded, when the HW Q is disabled. - */ - void succeeded() {} - - /** - * remove the deleted interface from the DB - */ - void remove_interface() { interface::remove(this->item()); } - - protected: - /** - * The name of the interface to be created - */ - const std::string m_name; - }; - - struct event - { - event(const interface& itf, const interface::oper_state_t& state) - : itf(itf) - , state(state) - { - } - - const interface& itf; - interface::oper_state_t state; - }; - - /** - * A class that listens to interface Events - */ - class event_listener - { - public: - /** - * Default Constructor - */ - event_listener(); - - /** - * Virtual function called on the listener when the command has data - * ready to process - */ - virtual void handle_interface_event(std::vector es) = 0; - - /** - * Return the HW::item representing the status - */ - HW::item& status(); - - protected: - /** - * The status of the subscription - */ - HW::item m_status; - }; - - /** - * A class that listens to interface Stats - */ - class stat_listener - { - public: - /** - * Default Constructor - */ - stat_listener(); - - virtual ~stat_listener() = default; - - /** - * Virtual function called on the listener when the command has data - * ready to process - */ - virtual void handle_interface_stat(const interface&) = 0; - - /** - * Return the HW::item representing the status - */ - HW::item& status(); - - protected: - /** - * The status of the subscription - */ - HW::item m_status; - }; - - /** - * The the singular instance of the interface in the DB by handle - */ - static std::shared_ptr find(const handle_t& h); - - /** - * The the singular instance of the interface in the DB by key - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all interfaces into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Enable stats for this interface - */ - void enable_stats(stat_listener* el, - const stats_type_t& st = stats_type_t::NORMAL); - - /** - * Disable stats for this interface - */ - void disable_stats(); - - /** - * Enable the reception of events of all interfaces - */ - static void enable_events(interface::event_listener& el); - - /** - * disable the reception of events of all interfaces - */ - static void disable_events(); - -protected: - /** - * Set the handle of an interface object. Only called by the interface - * factory during the populate - */ - void set(const handle_t& handle); - friend class interface_factory; - friend class pipe; - /** - * The SW interface handle VPP has asigned to the interface - */ - HW::item m_hdl; - - /** - * Return the matching 'singular' of the interface - */ - virtual std::shared_ptr singular_i() const; - - /** - * release/remove an interface form the singular store - */ - void release(); - - /** - * Virtual functions to construct an interface create commands. - * Overridden in derived classes like the sub_interface - */ - virtual std::queue& mk_create_cmd(std::queue& cmds); - - /** - * Virtual functions to construct an interface delete commands. - * Overridden in derived classes like the sub_interface - */ - virtual std::queue& mk_delete_cmd(std::queue& cmds); - - /** - * Sweep/reap the object if still stale - */ - virtual void sweep(void); - - /** - * A map of all interfaces key against the interface's name - */ - static singular_db m_db; - - /** - * Add an interface to the DB keyed on handle - */ - static void add(const key_t& name, const HW::item& item); - - /** - * remove an interface from the DB keyed on handle - */ - static void remove(const HW::item& item); - -private: - /** - * 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; - - /** - * friend with stat_reader - */ - friend stat_reader; - - /** - * publish stats - */ - void publish_stats(); - - /** - * Set the interface stat - */ - void set(const counter_t& count, const std::string& stat_type); - - /** - * enable the interface stats in the singular instance - */ - void enable_stats_i(stat_listener* el, const stats_type_t& st); - - /** - * disable the interface stats in the singular instance - */ - void disable_stats_i(); - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const interface& obj); - - /* - * return the interface's handle in the singular instance - */ - const handle_t& handle_i() const; - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * The interfaces name - */ - const std::string m_name; - - /** - * The interface type. clearly this cannot be changed - * once the interface has been created. - */ - const type_t m_type; - - /** - * shared pointer to the routeDoamin the interface is in. - * NULL is not mapped - i.e. in the default table - */ - std::shared_ptr m_rd; - - /** - * The state of the interface - */ - HW::item m_state; - - /** - * HW state of the VPP table mapping - */ - HW::item m_table_id; - - /** - * HW state of the L2 address - */ - HW::item m_l2_address; - - /** - * The state of the detailed stats collection - */ - HW::item m_stats_type; - - /** - * Interface stats - */ - stats_t m_stats; - - /** - * reference to stat listener - */ - stat_listener* m_listener; - - /** - * Operational state of the interface - */ - oper_state_t m_oper; - - /** - * tag of the interface - */ - std::string m_tag; - - /** - * A map of all interfaces keyed against VPP's handle - */ - static std::map> m_hdl_db; - - /** - * replay the object to create it in hardware - */ - virtual void replay(void); - - /** - * Create commands are firends so they can add interfaces to the - * handle store. - */ - template - friend class create_cmd; - - /** - * Create commands are firends so they can remove interfaces from the - * handle store. - */ - template - friend class delete_cmd; - - static std::shared_ptr m_events_cmd; -}; - -/** - * stream insertion operator for interface stats - */ -std::ostream& operator<<(std::ostream& os, const interface::stats_t& stats); -}; -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ -#endif diff --git a/extras/vom/vom/interface_cmds.cpp b/extras/vom/vom/interface_cmds.cpp deleted file mode 100644 index 691040dd5f1..00000000000 --- a/extras/vom/vom/interface_cmds.cpp +++ /dev/null @@ -1,668 +0,0 @@ -/* - * 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/interface_cmds.hpp" -#include "vom/cmd.hpp" - -DEFINE_VAPI_MSG_IDS_VPE_API_JSON; -DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON; -DEFINE_VAPI_MSG_IDS_AF_PACKET_API_JSON; -DEFINE_VAPI_MSG_IDS_VHOST_USER_API_JSON; - -namespace VOM { -namespace interface_cmds { - -bvi_create_cmd::bvi_create_cmd(HW::item& item, - const std::string& name) - : create_cmd(item, name) -{ -} - -rc_t -bvi_create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.user_instance = ~0; - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) { - insert_interface(); - } - - return rc_t::OK; -} -std::string -bvi_create_cmd::to_string() const -{ - std::ostringstream s; - s << "bvi-itf-create: " << m_hw_item.to_string() << " name:" << m_name; - - return (s.str()); -} - -loopback_create_cmd::loopback_create_cmd(HW::item& item, - const std::string& name) - : create_cmd(item, name) -{ -} - -rc_t -loopback_create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) { - insert_interface(); - } - - return rc_t::OK; -} -std::string -loopback_create_cmd::to_string() const -{ - std::ostringstream s; - s << "loopback-itf-create: " << m_hw_item.to_string() << " name:" << m_name; - - return (s.str()); -} - -af_packet_create_cmd::af_packet_create_cmd(HW::item& item, - const std::string& name) - : create_cmd(item, name) -{ -} - -rc_t -af_packet_create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.use_random_hw_addr = 1; - memset(payload.host_if_name, 0, sizeof(payload.host_if_name)); - memcpy(payload.host_if_name, m_name.c_str(), - std::min(m_name.length(), sizeof(payload.host_if_name))); - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) { - insert_interface(); - } - - return rc_t::OK; -} -std::string -af_packet_create_cmd::to_string() const -{ - std::ostringstream s; - s << "af-packet-itf-create: " << m_hw_item.to_string() << " name:" << m_name; - - return (s.str()); -} - -vhost_create_cmd::vhost_create_cmd(HW::item& item, - const std::string& name, - const std::string& tag) - : create_cmd(item, name) - , m_tag(tag) -{ -} - -rc_t -vhost_create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - memset(payload.sock_filename, 0, sizeof(payload.sock_filename)); - memcpy(payload.sock_filename, m_name.c_str(), - std::min(m_name.length(), sizeof(payload.sock_filename))); - memset(payload.tag, 0, sizeof(payload.tag)); - - if (!m_tag.empty()) - memcpy(payload.tag, m_tag.c_str(), - std::min(m_tag.length(), sizeof(payload.tag))); - - payload.is_server = 0; - payload.use_custom_mac = 0; - payload.renumber = 0; - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) { - insert_interface(); - } - - return rc_t::OK; -} - -std::string -vhost_create_cmd::to_string() const -{ - std::ostringstream s; - s << "vhost-intf-create: " << m_hw_item.to_string() << " name:" << m_name - << " tag:" << m_tag; - - return (s.str()); -} - -bvi_delete_cmd::bvi_delete_cmd(HW::item& item) - : delete_cmd(item) -{ -} - -rc_t -bvi_delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_interface(); - return rc_t::OK; -} - -std::string -bvi_delete_cmd::to_string() const -{ - std::ostringstream s; - s << "bvi-itf-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -loopback_delete_cmd::loopback_delete_cmd(HW::item& item) - : delete_cmd(item) -{ -} - -rc_t -loopback_delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_interface(); - return rc_t::OK; -} - -std::string -loopback_delete_cmd::to_string() const -{ - std::ostringstream s; - s << "loopback-itf-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -af_packet_delete_cmd::af_packet_delete_cmd(HW::item& item, - const std::string& name) - : delete_cmd(item, name) -{ -} - -rc_t -af_packet_delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - memset(payload.host_if_name, 0, sizeof(payload.host_if_name)); - memcpy(payload.host_if_name, m_name.c_str(), - std::min(m_name.length(), sizeof(payload.host_if_name))); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_interface(); - return rc_t::OK; -} -std::string -af_packet_delete_cmd::to_string() const -{ - std::ostringstream s; - s << "af_packet-itf-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -vhost_delete_cmd::vhost_delete_cmd(HW::item& item, - const std::string& name) - : delete_cmd(item, name) -{ -} - -rc_t -vhost_delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - wait(); - remove_interface(); - - return rc_t::OK; -} -std::string -vhost_delete_cmd::to_string() const -{ - std::ostringstream s; - s << "vhost-itf-delete: " << m_hw_item.to_string() << " name:" << m_name; - - return (s.str()); -} - -state_change_cmd::state_change_cmd(HW::item& state, - const HW::item& hdl) - : rpc_cmd(state) - , m_hdl(hdl) -{ -} - -bool -state_change_cmd::operator==(const state_change_cmd& other) const -{ - return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item)); -} - -rc_t -state_change_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hdl.data().value(); - payload.flags = (vapi_enum_if_status_flags)m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -state_change_cmd::to_string() const -{ - std::ostringstream s; - s << "itf-state-change: " << m_hw_item.to_string() - << " hdl:" << m_hdl.to_string(); - return (s.str()); -} - -set_table_cmd::set_table_cmd(HW::item& table, - const l3_proto_t& proto, - const HW::item& hdl) - : rpc_cmd(table) - , m_hdl(hdl) - , m_proto(proto) -{ -} - -bool -set_table_cmd::operator==(const set_table_cmd& other) const -{ - return ((m_hdl == other.m_hdl) && (m_proto == other.m_proto) && - (m_hw_item == other.m_hw_item)); -} - -rc_t -set_table_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hdl.data().value(); - payload.is_ipv6 = m_proto.is_ipv6(); - payload.vrf_id = m_hw_item.data(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -set_table_cmd::to_string() const -{ - std::ostringstream s; - s << "itf-set-table: " << m_hw_item.to_string() - << " proto:" << m_proto.to_string() << " hdl:" << m_hdl.to_string(); - return (s.str()); -} - -set_mac_cmd::set_mac_cmd(HW::item& mac, - const HW::item& hdl) - : rpc_cmd(mac) - , m_hdl(hdl) -{ -} - -bool -set_mac_cmd::operator==(const set_mac_cmd& other) const -{ - return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item)); -} - -rc_t -set_mac_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hdl.data().value(); - m_hw_item.data().to_mac().to_bytes(payload.mac_address, - sizeof(payload.mac_address)); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -set_mac_cmd::to_string() const -{ - std::ostringstream s; - s << "itf-set-mac: " << m_hw_item.to_string() << " hdl:" << m_hdl.to_string(); - return (s.str()); -} - -collect_detail_stats_change_cmd::collect_detail_stats_change_cmd( - HW::item& item, - const handle_t& hdl, - bool enable) - : rpc_cmd(item) - , m_hdl(hdl) - , m_enable(enable) -{ -} - -bool -collect_detail_stats_change_cmd::operator==( - const collect_detail_stats_change_cmd& other) const -{ - return ((m_hdl == other.m_hdl) && (m_hw_item == other.m_hw_item) && - (m_enable == other.m_enable)); -} - -rc_t -collect_detail_stats_change_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hdl.value(); - payload.enable_disable = m_enable; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -collect_detail_stats_change_cmd::to_string() const -{ - std::ostringstream s; - s << "itf-stats: " << m_hw_item.to_string() << " hdl:" << m_hdl.to_string(); - return (s.str()); -} - -events_cmd::events_cmd(interface::event_listener& el) - : event_cmd(el.status()) - , m_listener(el) -{ -} - -bool -events_cmd::operator==(const events_cmd& other) const -{ - return (true); -} - -rc_t -events_cmd::issue(connection& con) -{ - /* - * First set the call back to handle the interface events - */ - m_reg.reset(new reg_t(con.ctx(), std::ref(*(static_cast(this))))); - - /* - * then send the request to enable them - */ - msg_t req(con.ctx(), std::ref(*(static_cast(this)))); - - auto& payload = req.get_request().get_payload(); - payload.enable_disable = 1; - payload.pid = getpid(); - - VAPI_CALL(req.execute()); - - wait(); - - return (rc_t::OK); -} - -void -events_cmd::retire(connection& con) -{ - /* - * disable interface events. - */ - msg_t req(con.ctx(), std::ref(*(static_cast(this)))); - - auto& payload = req.get_request().get_payload(); - payload.enable_disable = 0; - payload.pid = getpid(); - - VAPI_CALL(req.execute()); - - wait(); -} - -void -events_cmd::notify() -{ - std::lock_guard lg(*this); - std::vector events; - - for (auto& msg : *this) { - auto& payload = msg.get_payload(); - - handle_t handle(payload.sw_if_index); - std::shared_ptr sp = interface::find(handle); - - if (sp) { - interface::oper_state_t oper_state = interface::oper_state_t::from_int( - payload.flags & vapi_enum_if_status_flags::IF_STATUS_API_FLAG_LINK_UP); - - VOM_LOG(log_level_t::DEBUG) << "Interface Event: " << sp->to_string() - << " state: " << oper_state.to_string(); - - sp->set(oper_state); - events.push_back({ *sp, oper_state }); - } - } - - flush(); - - m_listener.handle_interface_event(events); -} - -std::string -events_cmd::to_string() const -{ - return ("itf-events"); -} - -dump_cmd::dump_cmd() -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.name_filter_valid = 0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("itf-dump"); -} - -vhost_dump_cmd::vhost_dump_cmd() -{ -} - -bool -vhost_dump_cmd::operator==(const vhost_dump_cmd& other) const -{ - return (true); -} - -rc_t -vhost_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 -vhost_dump_cmd::to_string() const -{ - return ("vhost-itf-dump"); -} - -bool -af_packet_dump_cmd::operator==(const af_packet_dump_cmd& other) const -{ - return (true); -} - -rc_t -af_packet_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 -af_packet_dump_cmd::to_string() const -{ - return ("af-packet-itf-dump"); -} - -set_tag::set_tag(HW::item& item, const std::string& name) - : rpc_cmd(item) - , m_name(name) -{ -} - -rc_t -set_tag::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.sw_if_index = m_hw_item.data().value(); - memset(payload.tag, 0, sizeof(payload.tag)); - memcpy(payload.tag, m_name.c_str(), m_name.length()); - - VAPI_CALL(req.execute()); - - return (wait()); -} -std::string -set_tag::to_string() const -{ - std::ostringstream s; - s << "itf-set-tag: " << m_hw_item.to_string() << " name:" << m_name; - - return (s.str()); -} - -bool -set_tag::operator==(const set_tag& o) const -{ - return ((m_name == o.m_name) && (m_hw_item.data() == o.m_hw_item.data())); -} -}; // namespace interface_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/interface_cmds.hpp b/extras/vom/vom/interface_cmds.hpp deleted file mode 100644 index 2ee892fc0f8..00000000000 --- a/extras/vom/vom/interface_cmds.hpp +++ /dev/null @@ -1,539 +0,0 @@ -/* - * 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_INTERFACE_CMDS_H__ -#define __VOM_INTERFACE_CMDS_H__ - -#include - -#include "vom/dump_cmd.hpp" -#include "vom/event_cmd.hpp" -#include "vom/interface.hpp" -#include "vom/rpc_cmd.hpp" - -#include -#include -#include -#include -#include - -namespace VOM { - -namespace interface_cmds { -/** - * Factory method to construct a new interface from the VPP record - */ -std::unique_ptr new_interface( - const vapi_payload_sw_interface_details& vd); - -/** - * A command class to create bvi interfaces in VPP - */ -class bvi_create_cmd : public interface::create_cmd -{ -public: - /** - * Constructor taking the HW::item to update - * and the name of the interface to create - */ - bvi_create_cmd(HW::item& item, const std::string& name); - ~bvi_create_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; -}; - -/** - * A command class to create Loopback interfaces in VPP - */ -class loopback_create_cmd : public interface::create_cmd -{ -public: - /** - * Constructor taking the HW::item to update - * and the name of the interface to create - */ - loopback_create_cmd(HW::item& item, const std::string& name); - ~loopback_create_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; -}; - -/** - * A command class to create af_packet interfaces in VPP - */ -class af_packet_create_cmd - : public interface::create_cmd -{ -public: - /** - * Constructor taking the HW::item to update - * and the name of the interface to create - */ - af_packet_create_cmd(HW::item& item, const std::string& name); - ~af_packet_create_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; -}; - -/** - * A functor class that creates an interface - */ -class vhost_create_cmd - : public interface::create_cmd -{ -public: - vhost_create_cmd(HW::item& item, - const std::string& name, - const std::string& tag); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - -private: - const std::string m_tag; -}; - -/** - * A command class to delete bvi interfaces in VPP - */ -class bvi_delete_cmd : public interface::delete_cmd -{ -public: - /** - * Constructor taking the HW::item to update - */ - bvi_delete_cmd(HW::item& item); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; -}; - -/** - * A command class to delete loopback interfaces in VPP - */ -class loopback_delete_cmd : public interface::delete_cmd -{ -public: - /** - * Constructor taking the HW::item to update - */ - loopback_delete_cmd(HW::item& item); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; -}; - -/** - * A command class to delete af-packet interfaces in VPP - */ -class af_packet_delete_cmd - : public interface::delete_cmd -{ -public: - /** - * Constructor taking the HW::item to update - * and the name of the interface to delete - */ - af_packet_delete_cmd(HW::item& item, const std::string& name); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; -}; - -/** - * A functor class that deletes a Vhost interface - */ -class vhost_delete_cmd - : public interface::delete_cmd -{ -public: - vhost_delete_cmd(HW::item& item, const std::string& name); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; -}; - -/** - * A command class to set tag on interfaces - */ -class set_tag - : public rpc_cmd, vapi::Sw_interface_tag_add_del> -{ -public: - /** - * Constructor taking the HW::item to update - */ - set_tag(HW::item& item, const std::string& name); - - /** - * 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 set_tag& i) const; - -private: - /** - * The tag to add - */ - const std::string m_name; -}; - -/** - * A cmd class that changes the admin state - */ -class state_change_cmd : public rpc_cmd, - vapi::Sw_interface_set_flags> -{ -public: - /** - * Constructor taking the HW::item to update - * and the name handle of the interface whose state is to change - */ - state_change_cmd(HW::item& s, - const HW::item& h); - - /** - * 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 state_change_cmd& i) const; - -private: - /** - * the handle of the interface to update - */ - const HW::item& m_hdl; -}; - -/** - * A command class that binds an interface to an L3 table - */ -class set_table_cmd - : public rpc_cmd, vapi::Sw_interface_set_table> -{ -public: - /** - * Constructor taking the HW::item to update - * and the name handle of the interface whose table is to change - */ - set_table_cmd(HW::item& item, - const l3_proto_t& proto, - const HW::item& h); - - /** - * 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 set_table_cmd& i) const; - -private: - /** - * the handle of the interface to update - */ - const HW::item& m_hdl; - - /** - * The L3 protocol of the table - */ - l3_proto_t m_proto; -}; - -/** - * A command class that changes the MAC address on an interface - */ -class set_mac_cmd - : public rpc_cmd, vapi::Sw_interface_set_mac_address> -{ -public: - /** - * Constructor taking the HW::item to update - * and the handle of the interface - */ - set_mac_cmd(HW::item& item, const HW::item& h); - - /** - * 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 set_mac_cmd& i) const; - -private: - /** - * the handle of the interface to update - */ - const HW::item& m_hdl; -}; - -/** - * A command class that enables detailed stats collection on an interface - */ -class collect_detail_stats_change_cmd - : public rpc_cmd, - vapi::Collect_detailed_interface_stats> -{ -public: - /** - * Constructor taking the HW::item to update - * and the handle of the interface - */ - collect_detail_stats_change_cmd(HW::item& item, - const handle_t& h, - bool enable); - - /** - * 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 collect_detail_stats_change_cmd& i) const; - -private: - /** - * the handle of the interface to update - */ - const handle_t& m_hdl; - - /** - * enable or disable the detailed stats collection - */ - bool m_enable; -}; - -/** - * A command class represents our desire to recieve interface events - */ -class events_cmd - : public event_cmd -{ -public: - /** - * Constructor taking the listner to notify - */ - events_cmd(interface::event_listener& el); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - - /** - * Retires the command - unsubscribe from the events. - */ - void retire(connection& con); - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Comparison operator - only used for UT - */ - bool operator==(const events_cmd& i) const; - - /** - * Called when it's time to poke the listeners - */ - void notify(); - -private: - /** - * The listeners to notify when data/events arrive - */ - interface::event_listener& m_listener; -}; - -/** - * A cmd class that Dumps all the Vpp interfaces - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Default Constructor - */ - dump_cmd(); - - /** - * 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; -}; - -/** - * A cmd class that Dumps all the Vpp Interfaces - */ -class vhost_dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Default Constructor - */ - vhost_dump_cmd(); - - /** - * 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 vhost_dump_cmd& i) const; -}; - -/** - * A cmd class that Dumps all the Vpp interfaces - */ -class af_packet_dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Default Constructor - */ - af_packet_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 af_packet_dump_cmd& i) const; -}; -}; -}; -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ -#endif diff --git a/extras/vom/vom/interface_factory.cpp b/extras/vom/vom/interface_factory.cpp deleted file mode 100644 index f0b25ffd837..00000000000 --- a/extras/vom/vom/interface_factory.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - * 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 - -#include "vom/bond_interface.hpp" -#include "vom/bond_member.hpp" -#include "vom/interface_factory.hpp" -#include "vom/sub_interface.hpp" -#include "vom/tap_interface.hpp" - -namespace VOM { -std::shared_ptr -interface_factory::new_interface(const vapi_payload_sw_interface_details& vd) -{ - std::shared_ptr sp; - - /** - * Determine the interface type from the name and VLAN attributes - */ - std::string name = reinterpret_cast(vd.interface_name); - std::string device_type = - reinterpret_cast(vd.interface_dev_type); - interface::type_t type = interface::type_t::from_string(device_type); - interface::admin_state_t state = interface::admin_state_t::from_int( - vd.flags & vapi_enum_if_status_flags::IF_STATUS_API_FLAG_ADMIN_UP); - handle_t hdl(vd.sw_if_index); - l2_address_t l2_address(vd.l2_address, 6); - std::string tag = ""; - - if (interface::type_t::UNKNOWN == type) { - return sp; - } - - sp = interface::find(hdl); - if (sp) { - sp->set(state); - sp->set(l2_address); - if (!tag.empty()) - sp->set(tag); - return sp; - } - - /* - * If here, Fall back to old routine - */ - if (interface::type_t::AFPACKET == type) { - /* - * need to strip VPP's "host-" prefix from the interface name - */ - name = name.substr(5); - } - /** - * if the tag is set, then we wrote that to specify a name to make - * the interface type more specific - */ - if (vd.tag[0] != 0) { - tag = std::string(reinterpret_cast(vd.tag)); - } - - if (!tag.empty() && interface::type_t::LOOPBACK == type) { - name = tag; - type = interface::type_t::from_string(name); - } - - /* - * pull out the other special cases - */ - if (interface::type_t::TAPV2 == type) { - /* - * TAP interfaces - */ - 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 - * split the name into the parent and VLAN - */ - std::vector parts; - std::shared_ptr parent; - boost::split(parts, name, boost::is_any_of(".")); - - if ((parent = interface::find(parts[0]))) - sp = sub_interface(*parent, state, vd.sub_id).singular(); - else { - interface parent_itf(parts[0], type, state, tag); - sp = sub_interface(parent_itf, state, vd.sub_id).singular(); - } - } else if (interface::type_t::VXLAN == type) { - /* - * there's not enough information in a SW interface record to - * construct a VXLAN tunnel. so skip it. They have - * their own dump routines - */ - } else if (interface::type_t::VHOST == type) { - /* - * vhost interface already exist in db, look for it using - * sw_if_index - */ - } else if (interface::type_t::BOND == type) { - sp = bond_interface( - name, state, l2_address, bond_interface::mode_t::UNSPECIFIED) - .singular(); - } else { - sp = interface(name, type, state, tag).singular(); - sp->set(l2_address); - } - - /* - * set the handle on the intterface - N.B. this is the sigluar instance - * not a stack local. - */ - if (sp) - sp->set(hdl); - - return (sp); -} - -std::shared_ptr -interface_factory::new_vhost_user_interface( - const vapi_payload_sw_interface_vhost_user_details& vd) -{ - std::shared_ptr sp; - std::string name = reinterpret_cast(vd.sock_filename); - handle_t hdl(vd.sw_if_index); - - sp = interface(name, interface::type_t::VHOST, interface::admin_state_t::DOWN) - .singular(); - sp->set(hdl); - return (sp); -} - -std::shared_ptr -interface_factory::new_af_packet_interface( - const vapi_payload_af_packet_details& vd) -{ - std::shared_ptr sp; - std::string name = reinterpret_cast(vd.host_if_name); - handle_t hdl(vd.sw_if_index); - - sp = - interface(name, interface::type_t::AFPACKET, interface::admin_state_t::DOWN) - .singular(); - sp->set(hdl); - return (sp); -} - -std::shared_ptr -interface_factory::new_tap_interface( - const vapi_payload_sw_interface_tap_v2_details& vd) -{ - std::shared_ptr sp; - handle_t hdl(vd.sw_if_index); - std::string name = reinterpret_cast(vd.host_if_name); - route::prefix_t pfx(route::prefix_t::ZERO); - boost::asio::ip::address addr; - - if (vd.host_ip4_prefix.len) - pfx = route::prefix_t( - 0, (uint8_t*)vd.host_ip4_prefix.address, vd.host_ip4_prefix.len); - else if (vd.host_ip6_prefix.len) - pfx = route::prefix_t( - 1, (uint8_t*)vd.host_ip6_prefix.address, vd.host_ip6_prefix.len); - - l2_address_t l2_address(vd.host_mac_addr, 6); - sp = tap_interface(name, interface::admin_state_t::UP, pfx, l2_address) - .singular(); - - sp->set(hdl); - - return (sp); -} - -std::shared_ptr -interface_factory::new_bond_interface( - const vapi_payload_sw_interface_bond_details& vd) -{ - std::shared_ptr sp; - std::string name = reinterpret_cast(vd.interface_name); - handle_t hdl(vd.sw_if_index); - bond_interface::mode_t mode = - bond_interface::mode_t::from_numeric_val(vd.mode); - bond_interface::lb_t lb = bond_interface::lb_t::from_numeric_val(vd.lb); - sp = bond_interface::find(hdl); - if (sp) { - sp->set(mode); - sp->set(lb); - } - return (sp); -} - -bond_member -interface_factory::new_bond_member_interface( - const vapi_payload_sw_interface_slave_details& vd) -{ - std::shared_ptr sp; - std::string name = reinterpret_cast(vd.interface_name); - handle_t hdl(vd.sw_if_index); - bond_member::mode_t mode = - bond_member::mode_t::from_numeric_val(vd.is_passive); - bond_member::rate_t rate = - bond_member::rate_t::from_numeric_val(vd.is_long_timeout); - std::shared_ptr itf = interface::find(hdl); - bond_member bm(*itf, mode, rate); - return (bm); -} - -std::shared_ptr -interface_factory::new_pipe_interface(const vapi_payload_pipe_details& payload) -{ - std::shared_ptr 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 - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/interface_factory.hpp b/extras/vom/vom/interface_factory.hpp deleted file mode 100644 index fef2b638c18..00000000000 --- a/extras/vom/vom/interface_factory.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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_INTERFACE_FACTORY_H__ -#define __VOM_INTERFACE_FACTORY_H__ - -#include - -#include "vom/bond_interface.hpp" -#include "vom/bond_member.hpp" -#include "vom/interface.hpp" -#include "vom/pipe.hpp" -#include "vom/tap_interface.hpp" - -#include -#include -#include -#include -#include -#include - -namespace VOM { - -class interface_factory -{ -public: - /** - * Factory method to construct a new interface from the VPP record - */ - static std::shared_ptr new_interface( - const vapi_payload_sw_interface_details& vd); - - static std::shared_ptr new_vhost_user_interface( - const vapi_payload_sw_interface_vhost_user_details& vd); - - static std::shared_ptr new_af_packet_interface( - const vapi_payload_af_packet_details& vd); - - static std::shared_ptr new_tap_interface( - const vapi_payload_sw_interface_tap_v2_details& vd); - - static std::shared_ptr new_bond_interface( - const vapi_payload_sw_interface_bond_details& vd); - - static bond_member new_bond_member_interface( - const vapi_payload_sw_interface_slave_details& vd); - - static std::shared_ptr new_pipe_interface( - const vapi_payload_pipe_details& payload); -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ -#endif diff --git a/extras/vom/vom/interface_ip6_nd.hpp b/extras/vom/vom/interface_ip6_nd.hpp deleted file mode 100644 index fa5a479248c..00000000000 --- a/extras/vom/vom/interface_ip6_nd.hpp +++ /dev/null @@ -1,382 +0,0 @@ -/* - * 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_INTERFACE_IP6_ND_H__ -#define __VOM_INTERFACE_IP6_ND_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/ra_config.hpp" -#include "vom/ra_prefix.hpp" -#include "vom/rpc_cmd.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of L3 configuration on an interface - */ -template -class interface_ip6_nd : public object_base -{ -public: - typedef CLASS class_t; - /** - * Construct a new object matching the desried state - */ - interface_ip6_nd(const interface& itf, const class_t cls) - : m_itf(itf.singular()) - , m_cls(cls) - , m_config(true) - { - } - - /** - * Copy Constructor - */ - interface_ip6_nd(const interface_ip6_nd& o) - : m_itf(o.m_itf) - , m_cls(o.m_cls) - , m_config(o.m_config) - { - } - - /** - * Destructor - */ - ~interface_ip6_nd() - { - sweep(); - m_db.release(m_itf->key(), this); - } - - /** - * Return the 'singular instance' of the interface ip6nd that matches - * this object - */ - std::shared_ptr singular() const - { - return find_or_add(*this); - } - - /** - * convert to string format for debug purposes - */ - std::string to_string() const - { - std::ostringstream s; - s << "interface-ip6-nd:[" - << " itf:" << m_itf->to_string() << " " << m_cls.to_string() << " " - << m_config.to_string() << "]"; - - return (s.str()); - } - - /** - * Dump all config into the stream provided - */ - static void dump(std::ostream& os) { m_db.dump(os); } - - /** - * The key type for interface ip6 nd - */ - typedef interface::key_t key_t; - - /** - * Find an singular instance in the DB for the interface passed - */ - static std::shared_ptr find(const interface& i) - { - /* - * Loop throught the entire map looking for matching interface. - * not the most efficient algorithm, but it will do for now. The - * number of ra configs is low. - */ - std::deque> rac; - - auto it = m_db.cbegin(); - - while (it != m_db.cend()) { - /* - * The key in the DB is a pair of the interface's name. - * If the keys match, save the ra-config - */ - auto key = it->first; - - if (i.key() == key.first) { - rac.push_back(it->second.lock()); - } - - ++it; - } - - return (rac); - } - - /** - * A functor class that binds the ra config to the interface - */ - class config_cmd : public rpc_cmd, CMD> - { - public: - /** - * Constructor - */ - config_cmd(HW::item& item, const handle_t& itf, const class_t& cls) - : rpc_cmd, CMD>(item) - , m_itf(itf) - , m_cls(cls) - { - } - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - - /** - * convert to string format for debug purposes - */ - std::string to_string() const - { - std::ostringstream s; - s << "interface-ip6-nd: " << this->item().to_string() - << " itf:" << m_itf.to_string() << " " << m_cls.to_string(); - - return (s.str()); - } - - /** - * Comparison operator - only used for UT - */ - bool operator==(const config_cmd& other) const - { - return ((m_itf == other.m_itf) && (m_cls == other.m_cls)); - } - - private: - /** - * Reference to the interface to bind to - */ - const handle_t& m_itf; - - /** - * Reference to the config class - */ - const class_t& m_cls; - }; - - /** - * A cmd class that Unbinds L3 Config from an interface - */ - class unconfig_cmd : public rpc_cmd, CMD> - { - public: - /** - * Constructor - */ - unconfig_cmd(HW::item& item, const handle_t& itf, const class_t& cls) - : rpc_cmd, CMD>(item) - , m_itf(itf) - , m_cls(cls) - { - } - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - - /** - * convert to string format for debug purposes - */ - std::string to_string() const - { - std::ostringstream s; - s << "interface-ip6-nd: " << this->item().to_string() - << " itf:" << m_itf.to_string() << " " << m_cls.to_string(); - - return (s.str()); - } - - /** - * Comparison operator - only used for UT - */ - bool operator==(const unconfig_cmd& other) const - { - return ((m_itf == other.m_itf) && (m_cls == other.m_cls)); - } - - private: - /** - * Reference to the interface to unbind fomr - */ - const handle_t& m_itf; - - /** - * Reference to the config class to undo configurations - */ - const class_t& m_cls; - }; - -private: - /** - * Class definition for listeners to OM events - */ - class event_handler : public OM::listener, public inspect::command_handler - { - public: - event_handler() - { - OM::register_listener(this); - inspect::register_handler({ "ip6_nd " }, "interface ip6 nd", this); - } - - virtual ~event_handler() = default; - - /** - * Handle a populate event - */ - void handle_populate(const client_db::key_t& key) - { - /** - * VPP provides no dump for ra config - */ - } - - /** - * Handle a replay event - */ - void handle_replay() { m_db.replay(); } - - /** - * Show the object in the Singular DB - */ - void show(std::ostream& os) { m_db.dump(os); } - - /** - * Get the sortable Id of the listener - */ - dependency_t order() const { return (dependency_t::BINDING); } - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enqueue commands to the VPP for the update - */ - void update(const interface_ip6_nd& obj) - { - if (!m_config) { - HW::enqueue(new config_cmd(m_config, m_itf->handle(), m_cls)); - } - } - - void sweep() - { - if (m_config) { - HW::enqueue(new unconfig_cmd(m_config, m_itf->handle(), m_cls)); - } - HW::write(); - } - - /** - * Replay the objects state to HW - */ - void replay(void) - { - if (m_config) { - HW::enqueue(new config_cmd(m_config, m_itf->handle(), m_cls)); - } - } - - /** - * Find or add the singular instance in the DB - */ - static std::shared_ptr find_or_add( - const interface_ip6_nd& temp) - { - return (m_db.find_or_add(temp.m_itf->key(), temp)); - } - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - const std::shared_ptr m_itf; - - const class_t m_cls; - - const key_t m_key; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_config; - - /** - * A map of all interface ip6 nd keyed against a combination of the - * interface and subnet's keys. - */ - static singular_db m_db; -}; - -/** - * Typedef the ip6nd_ra_config - */ -typedef interface_ip6_nd - ip6nd_ra_config; - -/** - * Typedef the ip6nd_ra_prefix - */ -typedef interface_ip6_nd - ip6nd_ra_prefix; - -/** - * Definition of the static singular_db for ACL Lists - */ -template -singular_db::key_t, - interface_ip6_nd> - interface_ip6_nd::m_db; - -template -typename interface_ip6_nd::event_handler - interface_ip6_nd::m_evh; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/interface_ip6_nd_cmds.cpp b/extras/vom/vom/interface_ip6_nd_cmds.cpp deleted file mode 100644 index 15ff1caa4b4..00000000000 --- a/extras/vom/vom/interface_ip6_nd_cmds.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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/interface_ip6_nd.hpp" - -#include - -namespace VOM { -template<> -rc_t -ip6nd_ra_config::config_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - m_cls.to_vpp(payload); - payload.is_no = 0; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -template<> -rc_t -ip6nd_ra_config::unconfig_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - m_cls.to_vpp(payload); - payload.is_no = 1; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -template<> -rc_t -ip6nd_ra_prefix::config_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - m_cls.to_vpp(payload); - payload.is_no = 0; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -template<> -rc_t -ip6nd_ra_prefix::unconfig_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - m_cls.to_vpp(payload); - payload.is_no = 1; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/interface_span.cpp b/extras/vom/vom/interface_span.cpp deleted file mode 100644 index 283ea1ece54..00000000000 --- a/extras/vom/vom/interface_span.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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/interface_span.hpp" -#include "vom/interface_span_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -/** - * A DB of all interface_span config - */ -singular_db interface_span::m_db; - -interface_span::event_handler interface_span::m_evh; - -interface_span::interface_span(const interface& itf_from, - const interface& itf_to, - interface_span::state_t state) - : m_itf_from(itf_from.singular()) - , m_itf_to(itf_to.singular()) - , m_state(state) - , m_config(true) -{ -} - -interface_span::interface_span(const interface_span& o) - : m_itf_from(o.m_itf_from) - , m_itf_to(o.m_itf_to) - , m_state(o.m_state) - , m_config(o.m_config) -{ -} - -interface_span::~interface_span() -{ - sweep(); - - // not in the DB anymore. - m_db.release(make_pair(m_itf_from->key(), m_itf_to->key()), this); -} - -void -interface_span::sweep() -{ - if (m_config) { - HW::enqueue(new interface_span_cmds::unconfig_cmd( - m_config, m_itf_from->handle(), m_itf_to->handle())); - } - HW::write(); -} - -void -interface_span::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -interface_span::replay() -{ - if (m_config) { - HW::enqueue(new interface_span_cmds::config_cmd( - m_config, m_itf_from->handle(), m_itf_to->handle(), m_state)); - } -} - -std::string -interface_span::to_string() const -{ - std::ostringstream s; - s << "Itf Span-config:" - << " itf-from:" << m_itf_from->to_string() - << " itf-to:" << m_itf_to->to_string() << " state:" << m_state.to_string(); - - return (s.str()); -} - -void -interface_span::update(const interface_span& desired) -{ - if (!m_config) { - HW::enqueue(new interface_span_cmds::config_cmd( - m_config, m_itf_from->handle(), m_itf_to->handle(), m_state)); - } -} - -std::ostream& -operator<<(std::ostream& os, const interface_span::key_t& key) -{ - os << "[" << key.first << ", " << key.second << "]"; - - return (os); -} - -std::shared_ptr -interface_span::find_or_add(const interface_span& temp) -{ - return (m_db.find_or_add( - make_pair(temp.m_itf_from->key(), temp.m_itf_to->key()), temp)); -} - -std::shared_ptr -interface_span::singular() const -{ - return find_or_add(*this); -} - -interface_span::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "itf-span" }, "interface span configurations", - this); -} - -void -interface_span::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -interface_span::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf_from = - interface::find(payload.sw_if_index_from); - std::shared_ptr itf_to = interface::find(payload.sw_if_index_to); - - interface_span itf_span(*itf_from, *itf_to, - state_t::from_int(payload.state)); - - VOM_LOG(log_level_t::DEBUG) << "span-dump: " << itf_from->to_string() - << itf_to->to_string() - << state_t::from_int(payload.state).to_string(); - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, itf_span); - } -} - -dependency_t -interface_span::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -interface_span::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -const interface_span::state_t interface_span::state_t::DISABLED(0, "disable"); -const interface_span::state_t interface_span::state_t::RX_ENABLED(1, - "rx-enable"); -const interface_span::state_t interface_span::state_t::TX_ENABLED(2, - "tx-enable"); -const interface_span::state_t interface_span::state_t::TX_RX_ENABLED( - 3, - "tx-rx-enable"); - -interface_span::state_t::state_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -interface_span::state_t -interface_span::state_t::from_int(uint8_t i) -{ - switch (i) { - case 0: - return interface_span::state_t::DISABLED; - break; - case 1: - return interface_span::state_t::RX_ENABLED; - break; - case 2: - return interface_span::state_t::TX_ENABLED; - break; - case 3: - default: - break; - } - - return interface_span::state_t::TX_RX_ENABLED; -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/interface_span.hpp b/extras/vom/vom/interface_span.hpp deleted file mode 100644 index baa2054a530..00000000000 --- a/extras/vom/vom/interface_span.hpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - * 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_INTERFACE_SPAN_H__ -#define __VOM_INTERFACE_SPAN_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of interface span configuration - */ -class interface_span : public object_base -{ -public: - /** - * The state of the interface - rx/tx or both to be mirrored - */ - struct state_t : enum_base - { - /** - * DISABLED state - */ - const static state_t DISABLED; - /** - * RX enable state - */ - const static state_t RX_ENABLED; - /** - * TX enable state - */ - const static state_t TX_ENABLED; - /** - * TX and RX enable state - */ - const static state_t TX_RX_ENABLED; - - /** - * Convert VPP's numerical value to enum type - */ - static state_t from_int(uint8_t val); - - private: - /** - * Private constructor taking the value and the string name - */ - state_t(int v, const std::string& s); - }; - - /** - * Construct a new object matching the desried state - * - * @param itf_from - The interface to be mirrored - * @param itf_to - The interface where the traffic is mirrored - */ - interface_span(const interface& itf_from, - const interface& itf_to, - state_t state); - - /** - * Copy Constructor - */ - interface_span(const interface_span& o); - - /** - * Destructor - */ - ~interface_span(); - - /** - * Return the 'singular instance' of the interface_span that matches - * this object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all interface_spans into the stream provided - */ - static void dump(std::ostream& os); - - /** - * The key type for interface_spans - */ - typedef std::pair key_t; - - /** - * Find a singular instance in the DB for the interface passed - */ - static std::shared_ptr find(const interface& i); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const interface_span& obj); - - /** - * Find or add the singular instance in the DB - */ - static std::shared_ptr find_or_add( - const interface_span& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - e* It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer the interface to be mirrored - */ - const std::shared_ptr m_itf_from; - /** - * A reference counting pointer the interface where the traffic is - * mirrored - */ - const std::shared_ptr m_itf_to; - - /** - * the state (rx, tx or both) of the interface to be mirrored - */ - const state_t m_state; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_config; - - /** - * A map of all interface span keyed against the interface to be - * mirrored. - */ - static singular_db m_db; -}; - -/** - * Ostream output for the key - */ -std::ostream& operator<<(std::ostream& os, const interface_span::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/interface_span_cmds.cpp b/extras/vom/vom/interface_span_cmds.cpp deleted file mode 100644 index 00dbdd0b895..00000000000 --- a/extras/vom/vom/interface_span_cmds.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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/interface_span_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_SPAN_API_JSON; - -namespace VOM { -namespace interface_span_cmds { - -config_cmd::config_cmd(HW::item& item, - const handle_t& itf_from, - const handle_t& itf_to, - const interface_span::state_t& state) - : rpc_cmd(item) - , m_itf_from(itf_from) - , m_itf_to(itf_to) - , m_state(state) -{} - -bool -config_cmd::operator==(const config_cmd& o) const -{ - return ((m_itf_from == o.m_itf_from) && (m_itf_to == o.m_itf_to) && - (m_state == o.m_state)); -} - -rc_t -config_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_l2 = 0; - payload.sw_if_index_from = m_itf_from.value(); - payload.sw_if_index_to = m_itf_to.value(); - payload.state = (vapi_enum_span_state)m_state.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -config_cmd::to_string() const -{ - std::ostringstream s; - s << "itf-span-config: " << m_hw_item.to_string() - << " itf-from:" << m_itf_from.to_string() - << " itf-to:" << m_itf_to.to_string() << " state:" << m_state.to_string(); - - return (s.str()); -} - -unconfig_cmd::unconfig_cmd(HW::item& item, - const handle_t& itf_from, - const handle_t& itf_to) - : rpc_cmd(item) - , m_itf_from(itf_from) - , m_itf_to(itf_to) -{} - -bool -unconfig_cmd::operator==(const unconfig_cmd& o) const -{ - return ((m_itf_from == o.m_itf_from) && (m_itf_to == o.m_itf_to)); -} - -rc_t -unconfig_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_l2 = 0; - payload.sw_if_index_from = m_itf_from.value(); - payload.sw_if_index_to = m_itf_to.value(); - payload.state = SPAN_STATE_API_DISABLED; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unconfig_cmd::to_string() const -{ - std::ostringstream s; - s << "itf-span-unconfig: " << m_hw_item.to_string() - << " itf-from:" << m_itf_from.to_string() - << " itf-to:" << m_itf_to.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() {} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.is_l2 = 0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("interface-span-dump"); -} - -}; // namespace interface_span_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/interface_span_cmds.hpp b/extras/vom/vom/interface_span_cmds.hpp deleted file mode 100644 index e83ed728fb1..00000000000 --- a/extras/vom/vom/interface_span_cmds.hpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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_INTERFACE_SPAN_CMDS_H__ -#define __VOM_INTERFACE_SPAN_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/interface_span.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace interface_span_cmds { - -/** - * A command class that configures the interface span - */ -class config_cmd - : public rpc_cmd, vapi::Sw_interface_span_enable_disable> -{ -public: - /** - * Constructor - */ - config_cmd(HW::item& item, - const handle_t& itf_from, - const handle_t& itf_to, - const interface_span::state_t& state); - - /** - * 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 config_cmd& i) const; - -private: - /** - * Reference to the interface to be mirrored - */ - const handle_t& m_itf_from; - /** - * Reference to the interface where the traffic is mirrored - */ - const handle_t& m_itf_to; - /** - * the state (rx, tx or both) of the interface to be mirrored - */ - const interface_span::state_t& m_state; -}; - -/** - * A cmd class that Unconfigs interface span - */ -class unconfig_cmd - : public rpc_cmd, vapi::Sw_interface_span_enable_disable> -{ -public: - /** - * Constructor - */ - unconfig_cmd(HW::item& item, - const handle_t& itf_from, - const handle_t& itf_to); - - /** - * 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 unconfig_cmd& i) const; - -private: - /** - * Reference to the interface to be mirrored - */ - const handle_t& m_itf_from; - /** - * Reference to the interface where the traffic is mirrored - */ - const handle_t& m_itf_to; -}; - -/** - * A cmd class that Dumps all the interface spans - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/interface_types.cpp b/extras/vom/vom/interface_types.cpp deleted file mode 100644 index 239c3e6abf6..00000000000 --- a/extras/vom/vom/interface_types.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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/interface.hpp" -namespace VOM { -/* - * constants and enums - */ -const interface::type_t interface::type_t::UNKNOWN(0, "unknown"); -const interface::type_t interface::type_t::BVI(1, "BVI"); -const interface::type_t interface::type_t::ETHERNET(2, "Ethernet"); -const interface::type_t interface::type_t::VXLAN(3, "VXLAN"); -const interface::type_t interface::type_t::AFPACKET(4, "AFPACKET"); -const interface::type_t interface::type_t::LOOPBACK(5, "LOOPBACK"); -const interface::type_t interface::type_t::LOCAL(6, "LOCAL"); -const interface::type_t interface::type_t::TAPV2(7, "TAPV2"); -const interface::type_t interface::type_t::VHOST(8, "VHOST"); -const interface::type_t interface::type_t::BOND(9, "Bond"); -const interface::type_t interface::type_t::PIPE(10, "Pipe"); -const interface::type_t interface::type_t::PIPE_END(11, "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"); - -const interface::admin_state_t interface::admin_state_t::DOWN(0, "down"); -const interface::admin_state_t interface::admin_state_t::UP(1, "up"); - -const interface::stats_type_t interface::stats_type_t::DETAILED(0, "detailed"); -const interface::stats_type_t interface::stats_type_t::NORMAL(1, "normal"); - -interface::type_t -interface::type_t::from_string(const std::string& str) -{ - if ((str.find("Virtual") != std::string::npos) || - (str.find("vhost") != std::string::npos) || - (str.find("vhu") != std::string::npos) || - (str.find("vhost-user") != std::string::npos)) { - return interface::type_t::VHOST; - } else if (str.find("bond") != std::string::npos) { - return interface::type_t::BOND; - } else if (str.find("dpdk") != std::string::npos) { - return interface::type_t::ETHERNET; - } else if (str.find("VXLAN") != std::string::npos) { - return interface::type_t::VXLAN; - } else if ((str.find("Loopback") != std::string::npos) || - (str.find("recirc") != std::string::npos)) { - return interface::type_t::LOOPBACK; - } else if (str.find("af-packet") != std::string::npos) { - return interface::type_t::AFPACKET; - } else if (str.find("local") != std::string::npos) { - return interface::type_t::LOCAL; - } else if ((str.find("tapcli") != std::string::npos) || - (str.find("tuntap") != std::string::npos)) { - return interface::type_t::UNKNOWN; - } else if (str.find("virtio") != std::string::npos) { - 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; -} - -interface::type_t::type_t(int v, const std::string& s) - : enum_base(v, s) -{} - -interface::oper_state_t::oper_state_t(int v, const std::string& s) - : enum_base(v, s) -{} - -interface::admin_state_t::admin_state_t(int v, const std::string& s) - : enum_base(v, s) -{} - -interface::stats_type_t::stats_type_t(int v, const std::string& s) - : enum_base(v, s) -{} - -interface::admin_state_t -interface::admin_state_t::from_int(uint8_t v) -{ - if (0 == v) { - return (interface::admin_state_t::DOWN); - } - return (interface::admin_state_t::UP); -} - -interface::oper_state_t -interface::oper_state_t::from_int(uint8_t v) -{ - if (0 == v) { - return (interface::oper_state_t::DOWN); - } - return (interface::oper_state_t::UP); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/ip_punt_redirect.cpp b/extras/vom/vom/ip_punt_redirect.cpp deleted file mode 100644 index 853546fe397..00000000000 --- a/extras/vom/vom/ip_punt_redirect.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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/ip_punt_redirect.hpp" -#include "vom/api_types.hpp" -#include "vom/ip_punt_redirect_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -/** - * A DB of all IP Punt configs - */ -singular_db ip_punt_redirect::m_db; - -ip_punt_redirect::event_handler ip_punt_redirect::m_evh; - -ip_punt_redirect::ip_punt_redirect(const interface& rx_itf, - const interface& tx_itf, - const boost::asio::ip::address& addr) - : m_rx_itf(rx_itf.singular()) - , m_tx_itf(tx_itf.singular()) - , m_addr(addr) -{ -} - -ip_punt_redirect::ip_punt_redirect(const interface& tx_itf, - const boost::asio::ip::address& addr) - : m_rx_itf(nullptr) - , m_tx_itf(tx_itf.singular()) - , m_addr(addr) -{ -} - -ip_punt_redirect::ip_punt_redirect(const ip_punt_redirect& o) - : m_rx_itf(o.m_rx_itf) - , m_tx_itf(o.m_tx_itf) - , m_addr(o.m_addr) - , m_config(o.m_config) -{ -} - -ip_punt_redirect::~ip_punt_redirect() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -const ip_punt_redirect::key_t -ip_punt_redirect::key() const -{ - if (m_rx_itf) - return m_rx_itf->key(); - else - return ("ALL"); -} - -void -ip_punt_redirect::sweep() -{ - if (m_config) { - HW::enqueue(new ip_punt_redirect_cmds::unconfig_cmd( - m_config, (m_rx_itf ? m_rx_itf->handle() : handle_t::INVALID), - m_tx_itf->handle(), m_addr)); - } - HW::write(); -} - -void -ip_punt_redirect::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -ip_punt_redirect::replay() -{ - if (m_config) { - HW::enqueue(new ip_punt_redirect_cmds::config_cmd( - m_config, (m_rx_itf ? m_rx_itf->handle() : handle_t::INVALID), - m_tx_itf->handle(), m_addr)); - } -} - -std::string -ip_punt_redirect::to_string() const -{ - std::ostringstream s; - s << "IP-punt-redirect:" - << " rx-itf:" << key() << " tx-itf:" << m_tx_itf->to_string() - << " next-hop:" << m_addr; - - return (s.str()); -} - -void -ip_punt_redirect::update(const ip_punt_redirect& desired) -{ - if (!m_config) { - HW::enqueue(new ip_punt_redirect_cmds::config_cmd( - m_config, (m_rx_itf ? m_rx_itf->handle() : handle_t::INVALID), - m_tx_itf->handle(), m_addr)); - } -} - -std::shared_ptr -ip_punt_redirect::find_or_add(const ip_punt_redirect& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -ip_punt_redirect::singular() const -{ - return find_or_add(*this); -} - -ip_punt_redirect::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "ip-punt-redirect" }, - "IP punt redirect configurations", this); -} - -void -ip_punt_redirect::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -ip_punt_redirect::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr tx_itf = - interface::find(payload.punt.tx_sw_if_index); - std::shared_ptr rx_itf = - interface::find(payload.punt.rx_sw_if_index); - boost::asio::ip::address nh = from_api(payload.punt.nh); - - VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.punt.tx_sw_if_index - << ", " << payload.punt.rx_sw_if_index << ", " - << nh << "]"; - - if (rx_itf && tx_itf) { - ip_punt_redirect ipr(*rx_itf, *tx_itf, nh); - OM::commit(key, ipr); - VOM_LOG(log_level_t::DEBUG) << "read: " << ipr.to_string(); - } else if (tx_itf) { - ip_punt_redirect ipr(*tx_itf, nh); - OM::commit(key, ipr); - VOM_LOG(log_level_t::DEBUG) << "read: " << ipr.to_string(); - } - } -} - -dependency_t -ip_punt_redirect::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -ip_punt_redirect::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/ip_punt_redirect.hpp b/extras/vom/vom/ip_punt_redirect.hpp deleted file mode 100644 index ed9cf34992c..00000000000 --- a/extras/vom/vom/ip_punt_redirect.hpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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_IP_PUNT_REDIRECT_H__ -#define __VOM_IP_PUNT_REDIRECT_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of IP punt_redirect configuration on an interface - */ -class ip_punt_redirect : public object_base -{ -public: - /** - * Construct a new object matching the desried state - * - * @param rx_itf - The interface from where the punt traffic should come. - * @param tx_itf - The interface to which traffic should be redirected. - * @param addr - The next hop ip address to redirect the traffic. - */ - ip_punt_redirect(const interface& rx_itf, - const interface& tx_itf, - const boost::asio::ip::address& addr); - - /** - * Construct a new object matching the desried state - * - * @param tx_itf - The interface to which traffic should be redirected. - * @param addr - The next hop ip address to redirect the traffic. - */ - ip_punt_redirect(const interface& tx_itf, - const boost::asio::ip::address& addr); - - /** - * Copy Constructor - */ - ip_punt_redirect(const ip_punt_redirect& o); - - /** - * Destructor - */ - ~ip_punt_redirect(); - - /** - * Return the 'singular instance' of the ip_punt_redirect that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all ip_punt_redirects into the stream provided - */ - static void dump(std::ostream& os); - - /** - * The key type for ip_punt_redirects - */ - typedef interface::key_t key_t; - - /** - * return the object's key - */ - const key_t key() const; - - /** - * Find an singular instance in the DB for the interface passed - */ - static std::shared_ptr find(const interface& i); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const ip_punt_redirect& obj); - - /** - * Find or add the singular instance in the DB - */ - static std::shared_ptr find_or_add( - const ip_punt_redirect& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer the interface that requires an address. - */ - const std::shared_ptr m_rx_itf; - /** - * A reference counting pointer the interface that has an address. - */ - const std::shared_ptr m_tx_itf; - - /** - * host Ip Prefix to redirect traffic to - */ - const boost::asio::ip::address m_addr; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_config; - - /** - * A map of all ip punt redirect keyed against a combination of the interface. - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/ip_punt_redirect_cmds.cpp b/extras/vom/vom/ip_punt_redirect_cmds.cpp deleted file mode 100644 index 419e3f17fba..00000000000 --- a/extras/vom/vom/ip_punt_redirect_cmds.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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/ip_punt_redirect_cmds.hpp" -#include - -namespace VOM { -namespace ip_punt_redirect_cmds { - -config_cmd::config_cmd(HW::item& item, - const handle_t rx_itf, - const handle_t tx_itf, - const boost::asio::ip::address& addr) - : rpc_cmd(item) - , m_rx_itf(rx_itf) - , m_tx_itf(tx_itf) - , m_addr(addr) -{ -} - -bool -config_cmd::operator==(const config_cmd& o) const -{ - return ((m_rx_itf == o.m_rx_itf) && (m_tx_itf == o.m_tx_itf) && - (m_addr == o.m_addr)); -} - -rc_t -config_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.is_add = 1; - payload.punt.rx_sw_if_index = m_rx_itf.value(); - payload.punt.tx_sw_if_index = m_tx_itf.value(); - to_api(m_addr, payload.punt.nh); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -config_cmd::to_string() const -{ - std::ostringstream s; - s << "IP-punt-redirect: " << m_hw_item.to_string() - << " rx-itf:" << m_rx_itf.to_string() << " tx-itf:" << m_tx_itf.to_string() - << " next-hop:" << m_addr; - - return (s.str()); -} - -unconfig_cmd::unconfig_cmd(HW::item& item, - const handle_t rx_itf, - const handle_t tx_itf, - const boost::asio::ip::address& addr) - : rpc_cmd(item) - , m_rx_itf(rx_itf) - , m_tx_itf(tx_itf) - , m_addr(addr) -{ -} - -bool -unconfig_cmd::operator==(const unconfig_cmd& o) const -{ - return ((m_rx_itf == o.m_rx_itf) && (m_tx_itf == o.m_tx_itf) && - (m_addr == o.m_addr)); -} - -rc_t -unconfig_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.is_add = 0; - payload.punt.rx_sw_if_index = m_rx_itf.value(); - payload.punt.tx_sw_if_index = m_tx_itf.value(); - to_api(m_addr, payload.punt.nh); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unconfig_cmd::to_string() const -{ - std::ostringstream s; - s << "IP-punt-redirect-unconfig: " << m_hw_item.to_string() - << " rx-itf:" << m_rx_itf.to_string() << " tx-itf:" << m_tx_itf.to_string() - << " next-hop:" << m_addr.to_string(); - - return (s.str()); -} - -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 ("ip-punt-redirect-dump"); -} - -}; // namespace ip_punt_redirect_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/ip_punt_redirect_cmds.hpp b/extras/vom/vom/ip_punt_redirect_cmds.hpp deleted file mode 100644 index 22e2a62a23c..00000000000 --- a/extras/vom/vom/ip_punt_redirect_cmds.hpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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_IP_PUNT_REDIRECT_CMDS_H__ -#define __VOM_IP_PUNT_REDIRECT_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/ip_punt_redirect.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace ip_punt_redirect_cmds { - -/** -*A command class that configures the IP punt_redirect -*/ -class config_cmd : public rpc_cmd, vapi::Ip_punt_redirect> -{ -public: - /** - * Constructor - */ - config_cmd(HW::item& item, - const handle_t rx_itf, - const handle_t tx_itf, - const boost::asio::ip::address& addr); - - /** - * 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 config_cmd& i) const; - -private: - /** - * Reference to the interface from which traffic is coming - */ - const handle_t m_rx_itf; - /** - * Reference to the interface where traffic will be redirected - */ - const handle_t m_tx_itf; - - /** - * Reference to nexh hop ip address - */ - const boost::asio::ip::address& m_addr; -}; - -/** - * A cmd class that Unconfigs Ip punt redirect - */ -class unconfig_cmd : public rpc_cmd, vapi::Ip_punt_redirect> -{ -public: - /** - * Constructor - */ - unconfig_cmd(HW::item& item, - const handle_t rx_itf, - const handle_t tx_itf, - const boost::asio::ip::address& addr); - - /** - * 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 unconfig_cmd& i) const; - -private: - /** - * Reference to the interface from which traffic is coming - */ - const handle_t m_rx_itf; - /** - * Reference to the interface where traffic will be redirected - */ - const handle_t m_tx_itf; - - /** - * Reference to nexh hop ip address - */ - const boost::asio::ip::address& m_addr; -}; - -/** - * A cmd class that Dumps all the IP punt redirect - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // namespace ip_punt_redirect_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/ip_unnumbered.cpp b/extras/vom/vom/ip_unnumbered.cpp deleted file mode 100644 index 74a6edeceeb..00000000000 --- a/extras/vom/vom/ip_unnumbered.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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/ip_unnumbered.hpp" -#include "vom/ip_unnumbered_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -/** - * A DB of all LLDP configs - */ -singular_db ip_unnumbered::m_db; - -ip_unnumbered::event_handler ip_unnumbered::m_evh; - -ip_unnumbered::ip_unnumbered(const interface& itf, const interface& l3_itf) - : m_itf(itf.singular()) - , m_l3_itf(l3_itf.singular()) -{ -} - -ip_unnumbered::ip_unnumbered(const ip_unnumbered& o) - : m_itf(o.m_itf) - , m_l3_itf(o.m_l3_itf) - , m_config(o.m_config) -{ -} - -ip_unnumbered::~ip_unnumbered() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_itf->key(), this); -} - -void -ip_unnumbered::sweep() -{ - if (m_config) { - HW::enqueue(new ip_unnumbered_cmds::unconfig_cmd(m_config, m_itf->handle(), - m_l3_itf->handle())); - } - HW::write(); -} - -void -ip_unnumbered::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -ip_unnumbered::replay() -{ - if (m_config) { - HW::enqueue(new ip_unnumbered_cmds::config_cmd(m_config, m_itf->handle(), - m_l3_itf->handle())); - } -} - -std::string -ip_unnumbered::to_string() const -{ - std::ostringstream s; - s << "IP Unnumbered-config:" - << " itf:" << m_itf->to_string() << " l3-itf:" << m_l3_itf->to_string(); - - return (s.str()); -} - -void -ip_unnumbered::update(const ip_unnumbered& desired) -{ - if (!m_config) { - HW::enqueue(new ip_unnumbered_cmds::config_cmd(m_config, m_itf->handle(), - m_l3_itf->handle())); - } -} - -std::shared_ptr -ip_unnumbered::find_or_add(const ip_unnumbered& temp) -{ - return (m_db.find_or_add(temp.m_itf->key(), temp)); -} - -std::shared_ptr -ip_unnumbered::singular() const -{ - return find_or_add(*this); -} - -ip_unnumbered::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "ip-un" }, "IP unnumbered configurations", this); -} - -void -ip_unnumbered::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -ip_unnumbered::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& ip_record : *cmd) { - auto& payload = ip_record.get_payload(); - - VOM_LOG(log_level_t::DEBUG) << "ip-unnumbered dump: " - << " itf: " << payload.sw_if_index - << " ip: " << payload.ip_sw_if_index; - - std::shared_ptr itf = interface::find(payload.sw_if_index); - std::shared_ptr ip_itf = interface::find(payload.ip_sw_if_index); - - if (itf && ip_itf) { - ip_unnumbered ipun(*itf, *ip_itf); - OM::commit(key, ipun); - } - } -} - -dependency_t -ip_unnumbered::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -ip_unnumbered::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/ip_unnumbered.hpp b/extras/vom/vom/ip_unnumbered.hpp deleted file mode 100644 index b736919744c..00000000000 --- a/extras/vom/vom/ip_unnumbered.hpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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_IP_UNNUMBERED_H__ -#define __VOM_IP_UNNUMBERED_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of IP unnumbered configuration on an interface - */ -class ip_unnumbered : public object_base -{ -public: - /** - * Construct a new object matching the desried state - * - * @param itf - The interface with no IP address - * @param l3_itf - The interface that has the IP address we wish to - * share. - */ - ip_unnumbered(const interface& itf, const interface& l3_itf); - - /** - * Copy Constructor - */ - ip_unnumbered(const ip_unnumbered& o); - - /** - * Destructor - */ - ~ip_unnumbered(); - - /** - * Return the 'singular instance' of the L3-Config that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all ip_unnumbereds into the stream provided - */ - static void dump(std::ostream& os); - - /** - * The key type for ip_unnumbereds - */ - typedef interface::key_t key_t; - - /** - * Find an singular instance in the DB for the interface passed - */ - static std::shared_ptr find(const interface& i); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const ip_unnumbered& obj); - - /** - * Find or add the singular instance in the DB - */ - static std::shared_ptr find_or_add(const ip_unnumbered& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer the interface that requires an address. - */ - const std::shared_ptr m_itf; - /** - * A reference counting pointer the interface that has an address. - */ - const std::shared_ptr m_l3_itf; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_config; - - /** - * A map of all L3 configs keyed against a combination of the interface - * and subnet's keys. - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/ip_unnumbered_cmds.cpp b/extras/vom/vom/ip_unnumbered_cmds.cpp deleted file mode 100644 index 227a1509e7e..00000000000 --- a/extras/vom/vom/ip_unnumbered_cmds.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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/ip_unnumbered_cmds.hpp" - -#include - -namespace VOM { -namespace ip_unnumbered_cmds { - -config_cmd::config_cmd(HW::item& item, - const handle_t& itf, - const handle_t& l3_itf) - : rpc_cmd(item) - , m_itf(itf) - , m_l3_itf(l3_itf) -{ -} - -bool -config_cmd::operator==(const config_cmd& o) const -{ - return ((m_itf == o.m_itf) && (m_l3_itf == o.m_l3_itf)); -} - -rc_t -config_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.sw_if_index = m_l3_itf.value(); - payload.unnumbered_sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -config_cmd::to_string() const -{ - std::ostringstream s; - s << "IP-unnumberd-config: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string() << " l3-itf:" << m_l3_itf.to_string(); - - return (s.str()); -} - -unconfig_cmd::unconfig_cmd(HW::item& item, - const handle_t& itf, - const handle_t& l3_itf) - : rpc_cmd(item) - , m_itf(itf) - , m_l3_itf(l3_itf) -{ -} - -bool -unconfig_cmd::operator==(const unconfig_cmd& o) const -{ - return ((m_itf == o.m_itf) && (m_l3_itf == o.m_l3_itf)); -} - -rc_t -unconfig_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.sw_if_index = m_l3_itf.value(); - payload.unnumbered_sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unconfig_cmd::to_string() const -{ - std::ostringstream s; - s << "IP-unnumberd-unconfig: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string() << " l3-itf:" << m_l3_itf.to_string(); - - return (s.str()); -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("ip-unnumbered-dump"); -} - -}; // namespace ip_unnumbered_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/ip_unnumbered_cmds.hpp b/extras/vom/vom/ip_unnumbered_cmds.hpp deleted file mode 100644 index 436b0c72130..00000000000 --- a/extras/vom/vom/ip_unnumbered_cmds.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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_IP_UNNUMBERED_CMDS_H__ -#define __VOM_IP_UNNUMBERED_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/ip_unnumbered.hpp" -#include "vom/rpc_cmd.hpp" - -#include -#include - -namespace VOM { -namespace ip_unnumbered_cmds { - -/** -*A command class that configures the IP unnumbered -*/ -class config_cmd - : public rpc_cmd, vapi::Sw_interface_set_unnumbered> -{ -public: - /** - * Constructor - */ - config_cmd(HW::item& item, const handle_t& itf, const handle_t& l3_itf); - - /** - * 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 config_cmd& i) const; - -private: - /** - * Reference to the interface for which the address is required - */ - const handle_t& m_itf; - /** - * Reference to the interface which has an address - */ - const handle_t& m_l3_itf; -}; - -/** - * A cmd class that Unconfigs L3 Config from an interface - */ -class unconfig_cmd - : public rpc_cmd, vapi::Sw_interface_set_unnumbered> -{ -public: - /** - * Constructor - */ - unconfig_cmd(HW::item& item, - const handle_t& itf, - const handle_t& l3_itf); - - /** - * 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 unconfig_cmd& i) const; - -private: - /** - * Reference to the interface for which the address is required - */ - const handle_t& m_itf; - /** - * Reference to the interface which has an address - */ - const handle_t& m_l3_itf; -}; - -/** - * A cmd class that Dumps all the IP unnumbered interfaces - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace ip_unnumbered_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l2_binding.cpp b/extras/vom/vom/l2_binding.cpp deleted file mode 100644 index 37039a0b930..00000000000 --- a/extras/vom/vom/l2_binding.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - * 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/l2_binding.hpp" -#include "vom/l2_binding_cmds.hpp" -#include "vom/l2_vtr_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -/** - * A DB of all the L2 Configs - */ -singular_db l2_binding::m_db; - -l2_binding::event_handler l2_binding::m_evh; - -const l2_binding::l2_port_type_t - l2_binding::l2_port_type_t::L2_PORT_TYPE_NORMAL(0, "normal"); -const l2_binding::l2_port_type_t l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI( - 1, - "bvi"); -const l2_binding::l2_port_type_t - l2_binding::l2_port_type_t::L2_PORT_TYPE_UU_FWD(2, "uu-fwd"); - -l2_binding::l2_port_type_t::l2_port_type_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -/** - * Construct a new object matching the desried state - */ -l2_binding::l2_binding(const interface& itf, const bridge_domain& bd) - : m_itf(itf.singular()) - , m_bd(bd.singular()) - , m_port_type(l2_port_type_t::L2_PORT_TYPE_NORMAL) - , m_binding(0) - , m_vtr_op(l2_vtr::option_t::DISABLED, rc_t::UNSET) - , m_vtr_op_tag(0) -{ - if (interface::type_t::BVI == m_itf->type()) - m_port_type = l2_port_type_t::L2_PORT_TYPE_BVI; -} - -/** - * Construct a new object matching the desried state - */ -l2_binding::l2_binding(const interface& itf, - const bridge_domain& bd, - const l2_port_type_t& port_type) - : m_itf(itf.singular()) - , m_bd(bd.singular()) - , m_port_type(port_type) - , m_binding(0) - , m_vtr_op(l2_vtr::option_t::DISABLED, rc_t::UNSET) - , m_vtr_op_tag(0) -{ -} - -l2_binding::l2_binding(const l2_binding& o) - : m_itf(o.m_itf) - , m_bd(o.m_bd) - , m_port_type(o.m_port_type) - , m_binding(0) - , m_vtr_op(o.m_vtr_op) - , m_vtr_op_tag(o.m_vtr_op_tag) -{ -} - -const l2_binding::key_t& -l2_binding::key() const -{ - return (m_itf->key()); -} - -bool -l2_binding::operator==(const l2_binding& l) const -{ - return ((*m_itf == *l.m_itf) && (*m_bd == *l.m_bd) && - (m_port_type == l.m_port_type)); -} - -std::shared_ptr -l2_binding::find(const key_t& key) -{ - return (m_db.find(key)); -} - -void -l2_binding::sweep() -{ - if (m_binding && handle_t::INVALID != m_itf->handle()) { - HW::enqueue(new l2_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), - m_bd->id(), m_port_type)); - } - - // no need to undo the VTR operation. - HW::write(); -} - -void -l2_binding::replay() -{ - if (m_binding && handle_t::INVALID != m_itf->handle()) { - HW::enqueue(new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), - m_bd->id(), m_port_type)); - } - - if (m_vtr_op && handle_t::INVALID != m_itf->handle()) { - HW::enqueue( - new l2_vtr_cmds::set_cmd(m_vtr_op, m_itf->handle(), m_vtr_op_tag)); - } -} - -l2_binding::~l2_binding() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_itf->key(), this); -} - -std::string -l2_binding::to_string() const -{ - std::ostringstream s; - s << "L2-binding:[" << m_itf->to_string() << " " << m_bd->to_string() << " " - << m_port_type.to_string() << " " << m_binding.to_string() << "]"; - - return (s.str()); -} - -void -l2_binding::set(const l2_vtr::option_t& op, uint16_t tag) -{ - assert(rc_t::UNSET == m_vtr_op.rc()); - m_vtr_op.set(rc_t::NOOP); - m_vtr_op.update(op); - m_vtr_op_tag = tag; -} - -void -l2_binding::update(const l2_binding& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (rc_t::OK != m_binding.rc()) { - HW::enqueue(new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), - m_bd->id(), m_port_type)); - } else if (!(*m_bd == *desired.m_bd)) { - /* - * re-binding to a different BD. do unbind, bind. - */ - HW::enqueue(new l2_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), - m_bd->id(), m_port_type)); - m_bd = desired.m_bd; - HW::enqueue(new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), - m_bd->id(), m_port_type)); - } - - /* - * set the VTR operation if request - */ - if (m_vtr_op.update(desired.m_vtr_op)) { - HW::enqueue( - new l2_vtr_cmds::set_cmd(m_vtr_op, m_itf->handle(), m_vtr_op_tag)); - } -} - -std::shared_ptr -l2_binding::find_or_add(const l2_binding& temp) -{ - return (m_db.find_or_add(temp.m_itf->key(), temp)); -} - -std::shared_ptr -l2_binding::singular() const -{ - return find_or_add(*this); -} - -void -l2_binding::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -l2_binding::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "l2" }, "L2 bindings", this); -} - -void -l2_binding::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -l2_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - /** - * This is done while populating the bridge-domain - */ -} - -dependency_t -l2_binding::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -l2_binding::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l2_binding.hpp b/extras/vom/vom/l2_binding.hpp deleted file mode 100644 index de3608a2626..00000000000 --- a/extras/vom/vom/l2_binding.hpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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_L2_BINDING_H__ -#define __VOM_L2_BINDING_H__ - -#include "vom/bridge_domain.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/l2_vtr.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A Clas representing the binding of an L2 interface to a bridge-domain - * and the properties of that binding. - */ -class l2_binding : public object_base -{ -public: - /** - * Key type for an L2 binding in the singular DB - */ - typedef interface::key_t key_t; - - struct l2_port_type_t : public enum_base - { - l2_port_type_t(const l2_port_type_t& l) = default; - ~l2_port_type_t() = default; - - const static l2_port_type_t L2_PORT_TYPE_NORMAL; - const static l2_port_type_t L2_PORT_TYPE_BVI; - const static l2_port_type_t L2_PORT_TYPE_UU_FWD; - - private: - l2_port_type_t(int v, const std::string s); - }; - - /** - * Construct a new object matching the desried state - */ - l2_binding(const interface& itf, const bridge_domain& bd); - l2_binding(const interface& itf, - const bridge_domain& bd, - const l2_port_type_t& port_type); - - /** - * Copy Constructor - */ - l2_binding(const l2_binding& o); - - /** - * Destructor - */ - ~l2_binding(); - - /** - * Return the binding's key - */ - const key_t& key() const; - - /** - * Comparison operator - for UT - */ - bool operator==(const l2_binding& l) const; - - /** - * Return the 'singular instance' of the L2 config that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all l2_bindings into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Set the VTR operation on the binding/interface - */ - void set(const l2_vtr::option_t& op, uint16_t tag); - - /** - * Static function to find the bridge_domain in the model - */ - static std::shared_ptr find(const key_t& key); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const l2_binding& obj); - - /** - * Find or Add the singular instance in the DB - */ - static std::shared_ptr find_or_add(const l2_binding& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer the interface that this L2 layer - * represents. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * A reference counting pointer the Bridge-Domain that this L2 - * interface is bound to. By holding the reference here, we can - * guarantee that this object will outlive the BD. - */ - std::shared_ptr m_bd; - - /** - * l2 port type i.e. normal, bvi or unknown unicast - */ - l2_port_type_t m_port_type; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * HW configuration for the VTR option - */ - HW::item m_vtr_op; - - /** - * The Dot1q tag for the VTR operation - */ - uint16_t m_vtr_op_tag; - - /** - * A map of all L2 interfaces key against the interface's handle_t - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l2_binding_cmds.cpp b/extras/vom/vom/l2_binding_cmds.cpp deleted file mode 100644 index 70413adb411..00000000000 --- a/extras/vom/vom/l2_binding_cmds.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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/l2_binding_cmds.hpp" - -namespace VOM { -namespace l2_binding_cmds { -bind_cmd::bind_cmd(HW::item& item, - const handle_t& itf, - uint32_t bd, - const l2_binding::l2_port_type_t& port_type) - : rpc_cmd(item) - , m_itf(itf) - , m_bd(bd) - , m_port_type(port_type) -{ -} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_bd == other.m_bd) && - (m_port_type == other.m_port_type)); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.rx_sw_if_index = m_itf.value(); - payload.bd_id = m_bd; - payload.shg = 0; - if (m_port_type == l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI) - payload.port_type = L2_API_PORT_TYPE_BVI; - else if (m_port_type == l2_binding::l2_port_type_t::L2_PORT_TYPE_UU_FWD) - payload.port_type = L2_API_PORT_TYPE_UU_FWD; - else - payload.port_type = L2_API_PORT_TYPE_NORMAL; - - payload.enable = 1; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "L2-bind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() - << " bd:" << m_bd << " port-type:" << m_port_type.to_string(); - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, - const handle_t& itf, - uint32_t bd, - const l2_binding::l2_port_type_t& port_type) - : rpc_cmd(item) - , m_itf(itf) - , m_bd(bd) - , m_port_type(port_type) -{ -} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_bd == other.m_bd) && - (m_port_type == other.m_port_type)); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.rx_sw_if_index = m_itf.value(); - payload.bd_id = m_bd; - payload.shg = 0; - if (m_port_type == l2_binding::l2_port_type_t::L2_PORT_TYPE_BVI) - payload.port_type = L2_API_PORT_TYPE_BVI; - else if (m_port_type == l2_binding::l2_port_type_t::L2_PORT_TYPE_UU_FWD) - payload.port_type = L2_API_PORT_TYPE_UU_FWD; - else - payload.port_type = L2_API_PORT_TYPE_NORMAL; - - payload.enable = 0; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return (rc_t::OK); -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "L2-unbind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() - << " bd:" << m_bd << " port-type:" << m_port_type; - - return (s.str()); -} -}; // namespace l2_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l2_binding_cmds.hpp b/extras/vom/vom/l2_binding_cmds.hpp deleted file mode 100644 index 45f90b0787f..00000000000 --- a/extras/vom/vom/l2_binding_cmds.hpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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_L2_BINDING_CMDS_H__ -#define __VOM_L2_BINDING_CMDS_H__ - -#include "vom/l2_binding.hpp" -#include "vom/rpc_cmd.hpp" - -#include -#include - -namespace VOM { -namespace l2_binding_cmds { - -/** - * A functor class that binds L2 configuration to an interface - */ -class bind_cmd - : public rpc_cmd, vapi::Sw_interface_set_l2_bridge> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, - const handle_t& itf, - uint32_t bd, - const l2_binding::l2_port_type_t& port_type); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The bridge-domain to bind to - */ - uint32_t m_bd; - - /** - * What is the port type i.e. normal, bvi, uu-fwd that is being bound - */ - const l2_binding::l2_port_type_t& m_port_type; -}; - -/** - * A cmd class that Unbinds L2 configuration from an interface - */ -class unbind_cmd - : public rpc_cmd, vapi::Sw_interface_set_l2_bridge> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, - const handle_t& itf, - uint32_t bd, - const l2_binding::l2_port_type_t& port_type); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The bridge-domain to bind to - */ - uint32_t m_bd; - - /** - * What is the port type i.e. bvi, normal or uu-fwd that is being bound - */ - const l2_binding::l2_port_type_t& m_port_type; -}; - -}; // namespace l2_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l2_emulation.cpp b/extras/vom/vom/l2_emulation.cpp deleted file mode 100644 index 7bc7ed657d4..00000000000 --- a/extras/vom/vom/l2_emulation.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 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/l2_emulation.hpp" -#include "vom/l2_emulation_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -/** - * A DB of all the L2 Configs - */ -singular_db l2_emulation::m_db; - -l2_emulation::event_handler l2_emulation::m_evh; - -/** - * Construct a new object matching the desried state - */ -l2_emulation::l2_emulation(const interface& itf) - : m_itf(itf.singular()) - , m_emulation(0) -{ -} - -l2_emulation::l2_emulation(const l2_emulation& o) - : m_itf(o.m_itf) - , m_emulation(0) -{ -} - -const l2_emulation::key_t& -l2_emulation::key() const -{ - return (m_itf->key()); -} - -bool -l2_emulation::operator==(const l2_emulation& l) const -{ - return ((*m_itf == *l.m_itf)); -} - -std::shared_ptr -l2_emulation::find(const key_t& key) -{ - return (m_db.find(key)); -} - -void -l2_emulation::sweep() -{ - if (m_emulation && handle_t::INVALID != m_itf->handle()) { - HW::enqueue( - new l2_emulation_cmds::disable_cmd(m_emulation, m_itf->handle())); - } - - // no need to undo the VTR operation. - HW::write(); -} - -void -l2_emulation::replay() -{ - if (m_emulation && handle_t::INVALID != m_itf->handle()) { - HW::enqueue( - new l2_emulation_cmds::enable_cmd(m_emulation, m_itf->handle())); - } -} - -l2_emulation::~l2_emulation() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_itf->key(), this); -} - -std::string -l2_emulation::to_string() const -{ - std::ostringstream s; - s << "L2-emulation:[" << m_itf->to_string() << "]"; - - return (s.str()); -} - -void -l2_emulation::update(const l2_emulation& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (rc_t::OK != m_emulation.rc()) { - HW::enqueue( - new l2_emulation_cmds::enable_cmd(m_emulation, m_itf->handle())); - } -} - -std::shared_ptr -l2_emulation::find_or_add(const l2_emulation& temp) -{ - return (m_db.find_or_add(temp.m_itf->key(), temp)); -} - -std::shared_ptr -l2_emulation::singular() const -{ - return find_or_add(*this); -} - -void -l2_emulation::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -l2_emulation::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "l2e" }, "L2 Emulation", this); -} - -void -l2_emulation::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -l2_emulation::event_handler::handle_populate(const client_db::key_t& key) -{ - /** - * This is done while populating the bridge-domain - */ -} - -dependency_t -l2_emulation::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -l2_emulation::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l2_emulation.hpp b/extras/vom/vom/l2_emulation.hpp deleted file mode 100644 index faf4df8b0a7..00000000000 --- a/extras/vom/vom/l2_emulation.hpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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_L2_EMULATION_H__ -#define __VOM_L2_EMULATION_H__ - -#include "vom/bridge_domain.hpp" -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A Clas representing the binding of an L2 interface to a bridge-domain - * and the properties of that binding. - */ -class l2_emulation : public object_base -{ -public: - /** - * Key type for an L2 emulation in the singular DB - */ - typedef interface::key_t key_t; - - /** - * Construct a new object matching the desried state - */ - l2_emulation(const interface& itf); - - /** - * Copy Constructor - */ - l2_emulation(const l2_emulation& o); - - /** - * Destructor - */ - ~l2_emulation(); - - /** - * Return the binding's key - */ - const key_t& key() const; - - /** - * Comparison operator - for UT - */ - bool operator==(const l2_emulation& l) const; - - /** - * Return the 'singular instance' of the L2 config that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all l2_emulations into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Static function to find the bridge_domain in the model - */ - static std::shared_ptr find(const key_t& key); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const l2_emulation& obj); - - /** - * Find or Add the singular instance in the DB - */ - static std::shared_ptr find_or_add(const l2_emulation& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer the interface that this L2 layer - * represents. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * HW configuration for the emulation. The bool representing the - * enable/disable. - */ - HW::item m_emulation; - - /** - * A map of all L2 emulation configurations - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l2_emulation_cmds.cpp b/extras/vom/vom/l2_emulation_cmds.cpp deleted file mode 100644 index fac764a1c66..00000000000 --- a/extras/vom/vom/l2_emulation_cmds.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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/l2_emulation_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_L2E_API_JSON; - -namespace VOM { -namespace l2_emulation_cmds { -enable_cmd::enable_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{ -} - -bool -enable_cmd::operator==(const enable_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -enable_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.enable = 1; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -enable_cmd::to_string() const -{ - std::ostringstream s; - s << "L2-emulation-enable: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string(); - - return (s.str()); -} - -disable_cmd::disable_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{ -} - -bool -disable_cmd::operator==(const disable_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -disable_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.enable = 0; - - VAPI_CALL(req.execute()); - - wait(); - - return (rc_t::OK); -} - -std::string -disable_cmd::to_string() const -{ - std::ostringstream s; - s << "L2-emulation-disable: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string(); - - return (s.str()); -} - -}; // namespace l2_emulation_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l2_emulation_cmds.hpp b/extras/vom/vom/l2_emulation_cmds.hpp deleted file mode 100644 index aab4af51faa..00000000000 --- a/extras/vom/vom/l2_emulation_cmds.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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_L2_EMULATION_CMDS_H__ -#define __VOM_L2_EMULATION_CMDS_H__ - -#include "vom/l2_emulation.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace l2_emulation_cmds { - -/** - * A functor class that enable L2 emulation to an interface - */ -class enable_cmd : public rpc_cmd, vapi::L2_emulation> -{ -public: - /** - * Constructor - */ - enable_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 enable_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; -}; - -/** - * A cmd class that Unbinds L2 configuration from an interface - */ -class disable_cmd : public rpc_cmd, vapi::L2_emulation> -{ -public: - /** - * Constructor - */ - disable_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 disable_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; -}; - -}; // namespace l2_emulation_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l2_vtr.cpp b/extras/vom/vom/l2_vtr.cpp deleted file mode 100644 index 61505f68210..00000000000 --- a/extras/vom/vom/l2_vtr.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2019 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/l2_vtr.hpp" - -namespace VOM { -namespace l2_vtr { - -/* - * Make sure these are in sync with the smae enum in VPP - */ -const option_t option_t::DISABLED(0, "disabled"); -const option_t option_t::PUSH_1(1, "push-1"); -const option_t option_t::PUSH_2(2, "push-2"); -const option_t option_t::POP_1(3, "pop-1"); -const option_t option_t::POP_2(4, "pop-2"); -const option_t option_t::TRANSLATE_1_1(5, "translate-1-1"); -const option_t option_t::TRANSLATE_1_2(6, "translate-1-2"); -const option_t option_t::TRANSLATE_2_1(7, "translate-2-1"); -const option_t option_t::TRANSLATE_2_2(5, "translate-2-2"); - -option_t::option_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -}; // namespace l2_vtr -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l2_vtr.hpp b/extras/vom/vom/l2_vtr.hpp deleted file mode 100644 index 688e87a8108..00000000000 --- a/extras/vom/vom/l2_vtr.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2019 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_L2_VTR_H__ -#define __VOM_L2_VTR_H__ - -#include "vom/hw.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" - -namespace VOM { -namespace l2_vtr { -struct option_t : public enum_base -{ - option_t(const option_t& l) = default; - ~option_t() = default; - - const static option_t DISABLED; - const static option_t PUSH_1; - const static option_t PUSH_2; - const static option_t POP_1; - const static option_t POP_2; - const static option_t TRANSLATE_1_1; - const static option_t TRANSLATE_1_2; - const static option_t TRANSLATE_2_1; - const static option_t TRANSLATE_2_2; - -private: - option_t(int v, const std::string s); -}; -}; // namespace l2_vtr -}; // namesapce VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ -#endif diff --git a/extras/vom/vom/l2_vtr_cmds.cpp b/extras/vom/vom/l2_vtr_cmds.cpp deleted file mode 100644 index 1c76cf0e490..00000000000 --- a/extras/vom/vom/l2_vtr_cmds.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2019 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/l2_vtr_cmds.hpp" - -namespace VOM { -namespace l2_vtr_cmds { - -set_cmd::set_cmd(HW::item& item, - const handle_t& itf, - uint16_t tag) - : rpc_cmd(item) - , m_itf(itf) - , m_tag(tag) -{ -} - -bool -set_cmd::operator==(const set_cmd& other) const -{ - return ( - (m_hw_item.data() == other.m_hw_item.data() && m_itf == other.m_itf) && - (m_tag == other.m_tag)); -} - -rc_t -set_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.vtr_op = m_hw_item.data().value(); - payload.push_dot1q = 1; - payload.tag1 = m_tag; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -set_cmd::to_string() const -{ - std::ostringstream s; - s << "L2-vtr-set: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() - << " tag:" << m_tag; - - return (s.str()); -} - -}; // namespace vtr_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l2_vtr_cmds.hpp b/extras/vom/vom/l2_vtr_cmds.hpp deleted file mode 100644 index 14477fd43f4..00000000000 --- a/extras/vom/vom/l2_vtr_cmds.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2019 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_L2_VTR_CMDS_H__ -#define __VOM_L2_VTR_CMDS_H__ - -#include "vom/l2_vtr.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace l2_vtr_cmds { -/** - * A cmd class sets the VTR operation - */ -class set_cmd : public rpc_cmd, - vapi::L2_interface_vlan_tag_rewrite> -{ -public: - /** - * Constructor - */ - set_cmd(HW::item& item, const handle_t& itf, uint16_t tag); - - /** - * 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 set_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The tag for the operation - */ - uint16_t m_tag; -}; - -}; // namespace vtr_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l2_xconnect.cpp b/extras/vom/vom/l2_xconnect.cpp deleted file mode 100644 index f54da6c8abf..00000000000 --- a/extras/vom/vom/l2_xconnect.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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/l2_xconnect.hpp" -#include "vom/l2_vtr_cmds.hpp" -#include "vom/l2_xconnect_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -/** - * A DB of all the L2 x-connect Configs - */ -singular_db l2_xconnect::m_db; - -l2_xconnect::event_handler l2_xconnect::m_evh; - -/** - * Construct a new object matching the desried state - */ -l2_xconnect::l2_xconnect(const interface& east_itf, const interface& west_itf) - : m_east_itf(east_itf.singular()) - , m_west_itf(west_itf.singular()) - , m_xconnect_east(0) - , m_xconnect_west(0) - , m_vtr_op(l2_vtr::option_t::DISABLED, rc_t::UNSET) - , m_vtr_op_tag(0) -{ -} - -l2_xconnect::l2_xconnect(const l2_xconnect& o) - : m_east_itf(o.m_east_itf) - , m_west_itf(o.m_west_itf) - , m_xconnect_east(o.m_xconnect_east) - , m_xconnect_west(o.m_xconnect_west) - , m_vtr_op(o.m_vtr_op) - , m_vtr_op_tag(o.m_vtr_op_tag) -{ -} - -const l2_xconnect::key_t -l2_xconnect::key() const -{ - if (m_east_itf->name() < m_west_itf->name()) - return (std::make_pair(m_east_itf->key(), m_west_itf->key())); - return (std::make_pair(m_west_itf->key(), m_east_itf->key())); -} - -bool -l2_xconnect::operator==(const l2_xconnect& l) const -{ - return ((*m_east_itf == *l.m_east_itf) && (*m_west_itf == *l.m_west_itf)); -} - -std::shared_ptr -l2_xconnect::find(const key_t& key) -{ - return (m_db.find(key)); -} - -void -l2_xconnect::sweep() -{ - if (m_xconnect_east && m_xconnect_west && - handle_t::INVALID != m_east_itf->handle() && - handle_t::INVALID != m_west_itf->handle()) { - HW::enqueue(new l2_xconnect_cmds::unbind_cmd( - m_xconnect_east, m_east_itf->handle(), m_west_itf->handle())); - HW::enqueue(new l2_xconnect_cmds::unbind_cmd( - m_xconnect_west, m_west_itf->handle(), m_east_itf->handle())); - } - - HW::write(); -} - -void -l2_xconnect::replay() -{ - if (m_xconnect_east && m_xconnect_west && - handle_t::INVALID != m_east_itf->handle() && - handle_t::INVALID != m_west_itf->handle()) { - HW::enqueue(new l2_xconnect_cmds::bind_cmd( - m_xconnect_east, m_east_itf->handle(), m_west_itf->handle())); - HW::enqueue(new l2_xconnect_cmds::bind_cmd( - m_xconnect_west, m_west_itf->handle(), m_east_itf->handle())); - } - - if (m_vtr_op && handle_t::INVALID != m_east_itf->handle()) { - HW::enqueue( - new l2_vtr_cmds::set_cmd(m_vtr_op, m_east_itf->handle(), m_vtr_op_tag)); - } -} - -l2_xconnect::~l2_xconnect() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -std::string -l2_xconnect::to_string() const -{ - std::ostringstream s; - s << "L2-xconnect:[" << m_east_itf->to_string() << " " - << m_west_itf->to_string() << " " << m_xconnect_east.to_string() << " " - << m_xconnect_west.to_string() << "]"; - - return (s.str()); -} - -void -l2_xconnect::set(const l2_vtr::option_t& op, uint16_t tag) -{ - assert(rc_t::UNSET == m_vtr_op.rc()); - m_vtr_op.set(rc_t::NOOP); - m_vtr_op.update(op); - m_vtr_op_tag = tag; -} - -void -l2_xconnect::update(const l2_xconnect& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (rc_t::OK != m_xconnect_east.rc() && rc_t::OK != m_xconnect_west.rc()) { - HW::enqueue(new l2_xconnect_cmds::bind_cmd( - m_xconnect_east, m_east_itf->handle(), m_west_itf->handle())); - HW::enqueue(new l2_xconnect_cmds::bind_cmd( - m_xconnect_west, m_west_itf->handle(), m_east_itf->handle())); - } - - /* - * set the VTR operation if request - */ - if (m_vtr_op.update(desired.m_vtr_op)) { - HW::enqueue( - new l2_vtr_cmds::set_cmd(m_vtr_op, m_east_itf->handle(), m_vtr_op_tag)); - } -} - -std::shared_ptr -l2_xconnect::find_or_add(const l2_xconnect& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -l2_xconnect::singular() const -{ - return find_or_add(*this); -} - -void -l2_xconnect::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -l2_xconnect::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "l2-xconnect" }, "L2 xconnects", this); -} - -void -l2_xconnect::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -l2_xconnect::event_handler::handle_populate(const client_db::key_t& key) -{ - /** - * This needs to be done here - */ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& x_record : *cmd) { - auto& payload = x_record.get_payload(); - - VOM_LOG(log_level_t::DEBUG) << "l2-xconnect dump: " - << " east-itf: " << payload.rx_sw_if_index - << " west-itf: " << payload.tx_sw_if_index; - - std::shared_ptr east_itf = - interface::find(payload.rx_sw_if_index); - std::shared_ptr west_itf = - interface::find(payload.tx_sw_if_index); - - if (east_itf && west_itf) { - if (east_itf->name() > west_itf->name()) - continue; - l2_xconnect l2_xc(*east_itf, *west_itf); - OM::commit(key, l2_xc); - } - } -} - -dependency_t -l2_xconnect::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -l2_xconnect::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l2_xconnect.hpp b/extras/vom/vom/l2_xconnect.hpp deleted file mode 100644 index 89acc1c32e6..00000000000 --- a/extras/vom/vom/l2_xconnect.hpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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_L2_XCONNECT_H__ -#define __VOM_L2_XCONNECT_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/l2_vtr.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A Class representing the cross connnect of an L2 interface with another - * l2 interface - */ -class l2_xconnect : public object_base -{ -public: - /** - * Key type for an L2 xconnect in the singular DB - */ - typedef std::pair key_t; - - /** - * Construct a new object matching the desried state - */ - l2_xconnect(const interface& east_itf, const interface& west_itf); - - /** - * Copy Constructor - */ - l2_xconnect(const l2_xconnect& o); - - /** - * Destructor - */ - ~l2_xconnect(); - - /** - * Return the xconnect's key - */ - const key_t key() const; - - /** - * Comparison operator - for UT - */ - bool operator==(const l2_xconnect& l) const; - - /** - * Return the 'singular instance' of the L2 config that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all l2_xconnects into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Set the VTR operation on the binding/interface - */ - void set(const l2_vtr::option_t& op, uint16_t tag); - - /** - * Static function to find the bridge_domain in the model - */ - static std::shared_ptr find(const key_t& key); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enque commands to the VPP command Q for the update - */ - void update(const l2_xconnect& obj); - - /** - * Find or Add the singular instance in the DB - */ - static std::shared_ptr find_or_add(const l2_xconnect& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer the interface that this L2 layer - * represents. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_east_itf; - - /** - * A reference counting pointer the Bridge-Domain that this L2 - * interface is bound to. By holding the reference here, we can - * guarantee that this object will outlive the BD. - */ - const std::shared_ptr m_west_itf; - - /** - * HW configuration for the xconnect. The bool representing the - * do/don't bind. - */ - HW::item m_xconnect_east; - - /** - * HW configuration for the xconnect. The bool representing the - * do/don't bind. - */ - HW::item m_xconnect_west; - - /** - * HW configuration for the VTR option - */ - HW::item m_vtr_op; - - /** - * The Dot1q tag for the VTR operation - */ - uint16_t m_vtr_op_tag; - - /** - * A map of all L2 interfaces key against the interface's handle_t - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, const l2_xconnect::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l2_xconnect_cmds.cpp b/extras/vom/vom/l2_xconnect_cmds.cpp deleted file mode 100644 index 37eca9ecfc8..00000000000 --- a/extras/vom/vom/l2_xconnect_cmds.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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/l2_xconnect_cmds.hpp" - -namespace VOM { -namespace l2_xconnect_cmds { -bind_cmd::bind_cmd(HW::item& item, - const handle_t& east_itf, - const handle_t& west_itf) - : rpc_cmd(item) - , m_east_itf(east_itf) - , m_west_itf(west_itf) -{ -} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return ((m_east_itf == other.m_east_itf) && (m_west_itf == other.m_west_itf)); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.rx_sw_if_index = m_east_itf.value(); - payload.tx_sw_if_index = m_west_itf.value(); - payload.enable = 1; - - VAPI_CALL(req.execute()); - - wait(); - - return (rc_t::OK); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "L2-bind: " << m_hw_item.to_string() - << " east-itf:" << m_east_itf.to_string() - << " west-itf:" << m_west_itf.to_string(); - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, - const handle_t& east_itf, - const handle_t& west_itf) - : rpc_cmd(item) - , m_east_itf(east_itf) - , m_west_itf(west_itf) -{ -} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return ((m_east_itf == other.m_east_itf) && (m_west_itf == other.m_west_itf)); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.rx_sw_if_index = m_east_itf.value(); - payload.tx_sw_if_index = m_west_itf.value(); - payload.enable = 0; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return (rc_t::OK); -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "L2-unbind: " << m_hw_item.to_string() - << " east-itf:" << m_east_itf.to_string() - << " west-itf:" << m_west_itf.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("l2-xconnect-dump"); -} - -}; // namespace l2_xconnect_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l2_xconnect_cmds.hpp b/extras/vom/vom/l2_xconnect_cmds.hpp deleted file mode 100644 index db0e721453f..00000000000 --- a/extras/vom/vom/l2_xconnect_cmds.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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_L2_XCONNECT_CMDS_H__ -#define __VOM_L2_XCONNECT_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/l2_xconnect.hpp" -#include "vom/rpc_cmd.hpp" - -#include -#include - -namespace VOM { -namespace l2_xconnect_cmds { - -/** - * A functor class that binds L2 configuration to an interface - */ -class bind_cmd - : public rpc_cmd, vapi::Sw_interface_set_l2_xconnect> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, - const handle_t& east_itf, - const handle_t& west_itf); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * The east interface for cross_connect - */ - const handle_t m_east_itf; - - /** - * The west interface for x-connect - */ - const handle_t m_west_itf; -}; - -/** - * A cmd class that Unbinds L2 configuration from an interface - */ -class unbind_cmd - : public rpc_cmd, vapi::Sw_interface_set_l2_xconnect> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, - const handle_t& east_itf, - const handle_t& west_itf); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * The east interface for x-connect - */ - const handle_t m_east_itf; - - /** - * The west interface for x-connect - */ - const handle_t m_west_itf; -}; - -/** - * A cmd class that Dumps all the bridge domains - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - - /** - * 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 l2_xconnect_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l3_binding.cpp b/extras/vom/vom/l3_binding.cpp deleted file mode 100644 index 6b8d36209a7..00000000000 --- a/extras/vom/vom/l3_binding.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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/l3_binding.hpp" -#include "vom/l3_binding_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -singular_db l3_binding::m_db; - -l3_binding::event_handler l3_binding::m_evh; - -/** - * Construct a new object matching the desried state - */ -l3_binding::l3_binding(const interface& itf, const route::prefix_t& pfx) - : m_itf(itf.singular()) - , m_pfx(pfx) - , m_binding(true, rc_t::NOOP) -{ -} - -l3_binding::l3_binding(const l3_binding& o) - : m_itf(o.m_itf) - , m_pfx(o.m_pfx) - , m_binding(o.m_binding) -{ -} - -l3_binding::~l3_binding() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -bool -l3_binding::operator==(const l3_binding& l) const -{ - return ((m_pfx == l.m_pfx) && (*m_itf == *l.m_itf)); -} - -const l3_binding::key_t -l3_binding::key() const -{ - return (make_pair(m_itf->key(), m_pfx)); -} - -void -l3_binding::sweep() -{ - if (m_binding) { - HW::enqueue( - new l3_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), m_pfx)); - } - HW::write(); -} - -void -l3_binding::replay() -{ - if (m_binding) { - HW::enqueue( - new l3_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_pfx)); - } -} - -const route::prefix_t& -l3_binding::prefix() const -{ - return (m_pfx); -} - -const interface& -l3_binding::itf() const -{ - return (*m_itf); -} - -l3_binding::const_iterator_t -l3_binding::cbegin() -{ - return m_db.begin(); -} - -l3_binding::const_iterator_t -l3_binding::cend() -{ - return m_db.end(); -} - -std::string -l3_binding::to_string() const -{ - std::ostringstream s; - s << "L3-binding:[" << m_itf->to_string() << " prefix:" << m_pfx.to_string() - << " " << m_binding.to_string() << "]"; - - return (s.str()); -} - -void -l3_binding::update(const l3_binding& desired) -{ - /* - * no updates for the binding. chaning the interface or the prefix is a change - * to the - * key, hence a new object - */ - if (!m_binding) { - HW::enqueue( - new l3_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_pfx)); - } -} - -std::shared_ptr -l3_binding::find_or_add(const l3_binding& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -l3_binding::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -l3_binding::singular() const -{ - return find_or_add(*this); -} - -void -l3_binding::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const l3_binding::key_t& key) -{ - os << "[" << key.first << ", " << key.second << "]"; - - return (os); -} - -l3_binding::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "l3" }, "L3 bindings", this); -} - -void -l3_binding::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -l3_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - /** - * This is done while populating the interfaces - */ -} - -dependency_t -l3_binding::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -l3_binding::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l3_binding.hpp b/extras/vom/vom/l3_binding.hpp deleted file mode 100644 index a2a46263dbd..00000000000 --- a/extras/vom/vom/l3_binding.hpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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_L3_BINDING_H__ -#define __VOM_L3_BINDING_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of L3 configuration on an interface - */ -class l3_binding : public object_base -{ -public: - /** - * The key type for l3_bindings - */ - typedef std::pair key_t; - - /** - * Construct a new object matching the desried state - */ - l3_binding(const interface& itf, const route::prefix_t& pfx); - - /** - * Copy Constructor - */ - l3_binding(const l3_binding& o); - - /** - * Destructor - */ - ~l3_binding(); - - /** - * Comparison operator - */ - bool operator==(const l3_binding& l) const; - - /** - * Get the object's key - */ - const key_t key() const; - - /** - * The iterator type - */ - typedef singular_db::const_iterator const_iterator_t; - - static const_iterator_t cbegin(); - static const_iterator_t cend(); - - /** - * Return the 'singular instance' of the L3-Config that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Return the prefix associated with this L3 binding - */ - const route::prefix_t& prefix() const; - - /** - * Return the interface associated with this L3 binding - */ - const interface& itf() const; - - /** - * Dump all l3_bindings into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Find a binding from its key - */ - static std::shared_ptr find(const key_t& k); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const l3_binding& obj); - - /** - * Find or add the singular instance in the DB - */ - static std::shared_ptr find_or_add(const l3_binding& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - e* It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - friend class interface; - - /** - * A reference counting pointer the interface that this L3 layer - * represents. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * The prefix for this L3 configuration - */ - const route::prefix_t m_pfx; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A map of all L3 configs keyed against a combination of the interface - * and subnet's keys. - */ - static singular_db m_db; -}; - -/** - * Ostream output for the key - */ -std::ostream& operator<<(std::ostream& os, const l3_binding::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/l3_binding_cmds.cpp b/extras/vom/vom/l3_binding_cmds.cpp deleted file mode 100644 index 15122bc9dd6..00000000000 --- a/extras/vom/vom/l3_binding_cmds.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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/l3_binding_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_IP_API_JSON; - -namespace VOM { -namespace l3_binding_cmds { -bind_cmd::bind_cmd(HW::item& item, - const handle_t& itf, - const route::prefix_t& pfx) - : rpc_cmd(item) - , m_itf(itf) - , m_pfx(pfx) -{ -} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_pfx == other.m_pfx)); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.is_add = 1; - payload.del_all = 0; - - m_pfx.to_vpp((uint8_t*)&payload.prefix.address.af, - (uint8_t*)&payload.prefix.address, - (uint8_t*)&payload.prefix.len); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "L3-bind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() - << " pfx:" << m_pfx.to_string(); - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, - const handle_t& itf, - const route::prefix_t& pfx) - : rpc_cmd(item) - , m_itf(itf) - , m_pfx(pfx) -{ -} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_pfx == other.m_pfx)); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.is_add = 0; - payload.del_all = 0; - - m_pfx.to_vpp((uint8_t*)&payload.prefix.address.af, - (uint8_t*)&payload.prefix.address, - (uint8_t*)&payload.prefix.len); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "L3-unbind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() - << " pfx:" << m_pfx.to_string(); - - return (s.str()); -} - -dump_v4_cmd::dump_v4_cmd(const handle_t& hdl) - : m_itf(hdl) -{ -} - -dump_v4_cmd::dump_v4_cmd(const dump_v4_cmd& d) - : m_itf(d.m_itf) -{ -} - -bool -dump_v4_cmd::operator==(const dump_v4_cmd& other) const -{ - return (true); -} - -rc_t -dump_v4_cmd::issue(connection& con) -{ - m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.is_ipv6 = 0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_v4_cmd::to_string() const -{ - return ("L3-binding-dump"); -} - -}; // namespace l3_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/l3_binding_cmds.hpp b/extras/vom/vom/l3_binding_cmds.hpp deleted file mode 100644 index b7a30f8865c..00000000000 --- a/extras/vom/vom/l3_binding_cmds.hpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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_L3_BINDING_CMDS_H__ -#define __VOM_L3_BINDING_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/l3_binding.hpp" -#include "vom/rpc_cmd.hpp" - -#include -#include - -namespace VOM { -namespace l3_binding_cmds { - -/** - * A functor class that binds the L3 config to the interface - */ -class bind_cmd - : public rpc_cmd, vapi::Sw_interface_add_del_address> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, - const handle_t& itf, - const route::prefix_t& pfx); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * Reference to the interface to bind to - */ - const handle_t& m_itf; - - /** - * The prefix to bind - */ - const route::prefix_t& m_pfx; -}; - -/** - * A cmd class that Unbinds L3 Config from an interface - */ -class unbind_cmd - : public rpc_cmd, vapi::Sw_interface_add_del_address> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, - const handle_t& itf, - const route::prefix_t& pfx); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * Reference to the interface to unbind fomr - */ - const handle_t& m_itf; - - /** - * The prefix to unbind - */ - const route::prefix_t& m_pfx; -}; - -/** - * A cmd class that Dumps all the IPv4 L3 configs - */ -class dump_v4_cmd : public dump_cmd -{ -public: - /** - * Constructor - */ - dump_v4_cmd(const handle_t& itf); - dump_v4_cmd(const dump_v4_cmd& d); - - /** - * 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_v4_cmd& i) const; - -private: - /** - * HW reutrn code - */ - HW::item item; - - /** - * The interface to get the addresses for - */ - const handle_t& m_itf; -}; - -}; // namespace l3_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/lldp_binding.cpp b/extras/vom/vom/lldp_binding.cpp deleted file mode 100644 index 69b30c2ce94..00000000000 --- a/extras/vom/vom/lldp_binding.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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/lldp_binding.hpp" -#include "vom/lldp_binding_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -/** - * A DB of all LLDP configs - */ -singular_db lldp_binding::m_db; - -lldp_binding::event_handler lldp_binding::m_evh; - -lldp_binding::lldp_binding(const interface& itf, const std::string& port_desc) - : m_itf(itf.singular()) - , m_port_desc(port_desc) - , m_binding(0) -{ -} - -lldp_binding::lldp_binding(const lldp_binding& o) - : m_itf(o.m_itf) - , m_port_desc(o.m_port_desc) - , m_binding(0) -{ -} - -lldp_binding::~lldp_binding() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_itf->key(), this); -} - -bool -lldp_binding::operator==(const lldp_binding& l) const -{ - return ((key() == l.key()) && (m_port_desc == l.m_port_desc)); -} - -const lldp_binding::key_t& -lldp_binding::key() const -{ - return (m_itf->key()); -} - -void -lldp_binding::sweep() -{ - if (m_binding) { - HW::enqueue(new lldp_binding_cmds::unbind_cmd(m_binding, m_itf->handle())); - } - HW::write(); -} - -void -lldp_binding::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -lldp_binding::replay() -{ - if (m_binding) { - HW::enqueue( - new lldp_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_port_desc)); - } -} - -std::string -lldp_binding::to_string() const -{ - std::ostringstream s; - s << "Lldp-binding: " << m_itf->to_string() << " port_desc:" << m_port_desc - << " " << m_binding.to_string(); - - return (s.str()); -} - -void -lldp_binding::update(const lldp_binding& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (!m_binding) { - HW::enqueue( - new lldp_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_port_desc)); - } -} - -std::shared_ptr -lldp_binding::find_or_add(const lldp_binding& temp) -{ - return (m_db.find_or_add(temp.m_itf->key(), temp)); -} - -std::shared_ptr -lldp_binding::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -lldp_binding::singular() const -{ - return find_or_add(*this); -} - -lldp_binding::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "lldp" }, "LLDP bindings", this); -} - -void -lldp_binding::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -lldp_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - // FIXME -} - -dependency_t -lldp_binding::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -lldp_binding::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/lldp_binding.hpp b/extras/vom/vom/lldp_binding.hpp deleted file mode 100644 index 0c5610013ac..00000000000 --- a/extras/vom/vom/lldp_binding.hpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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_LLDP_BINDING_H__ -#define __VOM_LLDP_BINDING_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of LLDP client configuration on an interface - */ -class lldp_binding : public object_base -{ -public: - /** - * Typedef for the key of a LLDP binding - */ - typedef interface::key_t key_t; - - /** - * Construct a new object matching the desried state - */ - lldp_binding(const interface& itf, const std::string& hostname); - - /** - * Copy Constructor - */ - lldp_binding(const lldp_binding& o); - - /** - * Destructor - */ - ~lldp_binding(); - - /** - * Comparison operator - */ - bool operator==(const lldp_binding& b) const; - - /** - * Return this object's key - */ - const key_t& key() const; - - /** - * Return the 'singular' of the LLDP binding that matches this object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all LLDP bindings into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Find or add LLDP binding based on its key - */ - static std::shared_ptr find(const key_t& k); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const lldp_binding& obj); - - /** - * Find or add LLDP binding to the OM - */ - static std::shared_ptr find_or_add(const lldp_binding& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * A reference counting pointer to the interface on which LLDP config - * resides. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * The port-description in the LLDP configuration - */ - const std::string m_port_desc; - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A map of all Lldp bindings keyed against the interface. - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/lldp_binding_cmds.cpp b/extras/vom/vom/lldp_binding_cmds.cpp deleted file mode 100644 index 02ed8cd450a..00000000000 --- a/extras/vom/vom/lldp_binding_cmds.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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/lldp_binding_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_LLDP_API_JSON; - -namespace VOM { -namespace lldp_binding_cmds { - -bind_cmd::bind_cmd(HW::item& item, - const handle_t& itf, - const std::string& port_desc) - : rpc_cmd(item) - , m_itf(itf) - , m_port_desc(port_desc) -{} - -bool -bind_cmd::operator==(const bind_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_port_desc == other.m_port_desc)); -} - -rc_t -bind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.enable = 1; - - memcpy(payload.port_desc.buf, m_port_desc.c_str(), m_port_desc.length()); - payload.port_desc.length = m_port_desc.length(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_cmd::to_string() const -{ - std::ostringstream s; - s << "Lldp-bind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string() - << " port_desc:" << m_port_desc; - - return (s.str()); -} - -unbind_cmd::unbind_cmd(HW::item& item, const handle_t& itf) - : rpc_cmd(item) - , m_itf(itf) -{} - -bool -unbind_cmd::operator==(const unbind_cmd& other) const -{ - return (m_itf == other.m_itf); -} - -rc_t -unbind_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.enable = 0; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -unbind_cmd::to_string() const -{ - std::ostringstream s; - s << "Lldp-unbind: " << m_hw_item.to_string() << " itf:" << m_itf.to_string(); - - return (s.str()); -} - -}; // namespace lldp_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/lldp_binding_cmds.hpp b/extras/vom/vom/lldp_binding_cmds.hpp deleted file mode 100644 index 77ba8ee90e7..00000000000 --- a/extras/vom/vom/lldp_binding_cmds.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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_LLDP_BINDING_CMDS_H__ -#define __VOM_LLDP_BINDING_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/lldp_binding.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace lldp_binding_cmds { - -/** -*A command class that binds the LLDP config to the interface -*/ -class bind_cmd : public rpc_cmd, vapi::Sw_interface_set_lldp> -{ -public: - /** - * Constructor - */ - bind_cmd(HW::item& item, - const handle_t& itf, - const std::string& port_desc); - - /** - * 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 bind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to bind - */ - const handle_t& m_itf; - - /** - * The LLDP client's hostname - */ - const std::string m_port_desc; -}; - -/** - * A cmd class that Unbinds Lldp Config from an interface - */ -class unbind_cmd : public rpc_cmd, vapi::Sw_interface_set_lldp> -{ -public: - /** - * Constructor - */ - unbind_cmd(HW::item& item, const handle_t& itf); - - /** - * 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 unbind_cmd& i) const; - -private: - /** - * Reference to the HW::item of the interface to unbind - */ - const handle_t& m_itf; -}; - -}; // namespace lldp_binding_cmds -}; // naemspace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/lldp_global.cpp b/extras/vom/vom/lldp_global.cpp deleted file mode 100644 index 6bae7993651..00000000000 --- a/extras/vom/vom/lldp_global.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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/lldp_global.hpp" -#include "vom/lldp_global_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -/** - * A DB of all LLDP configs - */ -singular_db lldp_global::m_db; - -lldp_global::event_handler lldp_global::m_evh; - -lldp_global::lldp_global(const std::string& system_name, - uint32_t tx_hold, - uint32_t tx_interval) - : m_system_name(system_name) - , m_tx_hold(tx_hold) - , m_tx_interval(tx_interval) -{ -} - -lldp_global::lldp_global(const lldp_global& o) - : m_system_name(o.m_system_name) - , m_tx_hold(o.m_tx_hold) - , m_tx_interval(o.m_tx_interval) -{ -} - -lldp_global::~lldp_global() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_system_name, this); -} - -const lldp_global::key_t& -lldp_global::key() const -{ - return (m_system_name); -} - -bool -lldp_global::operator==(const lldp_global& l) const -{ - return ((key() == l.key()) && (m_tx_hold == l.m_tx_hold) && - (m_tx_interval == l.m_tx_interval)); -} - -void -lldp_global::sweep() -{ - // no means to remove this in VPP -} - -void -lldp_global::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -lldp_global::replay() -{ - if (m_binding) { - HW::enqueue(new lldp_global_cmds::config_cmd(m_binding, m_system_name, - m_tx_hold, m_tx_interval)); - } -} - -std::string -lldp_global::to_string() const -{ - std::ostringstream s; - s << "LLDP-global:" - << " system_name:" << m_system_name << " tx-hold:" << m_tx_hold - << " tx-interval:" << m_tx_interval; - - return (s.str()); -} - -void -lldp_global::update(const lldp_global& desired) -{ - if (!m_binding) { - HW::enqueue(new lldp_global_cmds::config_cmd(m_binding, m_system_name, - m_tx_hold, m_tx_interval)); - } -} - -std::shared_ptr -lldp_global::find_or_add(const lldp_global& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -lldp_global::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -lldp_global::singular() const -{ - return find_or_add(*this); -} - -lldp_global::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "lldp-global" }, "LLDP global configurations", - this); -} - -void -lldp_global::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -lldp_global::event_handler::handle_populate(const client_db::key_t& key) -{ - // FIXME -} - -dependency_t -lldp_global::event_handler::order() const -{ - return (dependency_t::GLOBAL); -} - -void -lldp_global::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/lldp_global.hpp b/extras/vom/vom/lldp_global.hpp deleted file mode 100644 index f545a2828cc..00000000000 --- a/extras/vom/vom/lldp_global.hpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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_LLDP_GLOBAL_H__ -#define __VOM_LLDP_GLOBAL_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of LLDP global configuration - */ -class lldp_global : public object_base -{ -public: - /** - * The key for the global conifugration is the 'system' namse - */ - typedef std::string key_t; - - /** - * Construct a new object matching the desried state - */ - lldp_global(const std::string& system_name, - uint32_t tx_hold, - uint32_t tx_interval); - - /** - * Copy Constructor - */ - lldp_global(const lldp_global& o); - - /** - * Destructor - */ - ~lldp_global(); - - /** - * Get this objects key - */ - const key_t& key() const; - - /** - * Comparison operator - */ - bool operator==(const lldp_global& l) const; - - /** - * Return the 'singular' of the LLDP global that matches this object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Dump all LLDP globals into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Find LLDP global config from its key - */ - static std::shared_ptr find(const key_t& k); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const lldp_global& obj); - - /** - * Find or add LLDP global to the OM - */ - static std::shared_ptr find_or_add(const lldp_global& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * The system name - */ - const std::string m_system_name; - - /** - * TX timer configs - */ - uint32_t m_tx_hold; - uint32_t m_tx_interval; - - /** - * HW globaluration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A map of all Lldp globals keyed against the system name. - * there needs to be some sort of key, that will do. - */ - static singular_db m_db; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/lldp_global_cmds.cpp b/extras/vom/vom/lldp_global_cmds.cpp deleted file mode 100644 index 32931a621f0..00000000000 --- a/extras/vom/vom/lldp_global_cmds.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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/lldp_global_cmds.hpp" - -namespace VOM { -namespace lldp_global_cmds { -config_cmd::config_cmd(HW::item& item, - const std::string& system_name, - uint32_t tx_hold, - uint32_t tx_interval) - : rpc_cmd(item) - , m_system_name(system_name) - , m_tx_hold(tx_hold) - , m_tx_interval(tx_interval) -{} - -bool -config_cmd::operator==(const config_cmd& other) const -{ - return (m_system_name == other.m_system_name); -} - -rc_t -config_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.tx_hold = m_tx_hold; - payload.tx_interval = m_tx_interval; - - memcpy( - payload.system_name.buf, m_system_name.c_str(), m_system_name.length()); - payload.system_name.length = m_system_name.length(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -config_cmd::to_string() const -{ - std::ostringstream s; - s << "Lldp-global-config: " << m_hw_item.to_string() - << " system_name:" << m_system_name << " tx-hold:" << m_tx_hold - << " tx-interval:" << m_tx_interval; - - return (s.str()); -} - -}; // namespace lldp_global_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/lldp_global_cmds.hpp b/extras/vom/vom/lldp_global_cmds.hpp deleted file mode 100644 index 732c700062f..00000000000 --- a/extras/vom/vom/lldp_global_cmds.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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_LLDP_GLOBAL_CMDS_H__ -#define __VOM_LLDP_GLOBAL_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/lldp_global.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace lldp_global_cmds { - -/** - * A command class that binds the LLDP global to the interface - */ -class config_cmd : public rpc_cmd, vapi::Lldp_config> -{ -public: - /** - * Constructor - */ - config_cmd(HW::item& item, - const std::string& system_name, - uint32_t tx_hold, - uint32_t tx_interval); - - /** - * 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 config_cmd& i) const; - -private: - /** - * The system name - */ - const std::string m_system_name; - - /** - * TX timer configs - */ - uint32_t m_tx_hold; - uint32_t m_tx_interval; -}; - -}; // namespace lldp_global_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/logger.cpp b/extras/vom/vom/logger.cpp deleted file mode 100644 index 80f2d92c603..00000000000 --- a/extras/vom/vom/logger.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 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 -#include -#include - -#include - -#include "vom/logger.hpp" - -namespace VOM { -const log_level_t log_level_t::CRITICAL(4, "critical"); -const log_level_t log_level_t::ERROR(3, "error"); -const log_level_t log_level_t::WARNING(2, "warning"); -const log_level_t log_level_t::INFO(1, "info"); -const log_level_t log_level_t::DEBUG(0, "debug"); - -log_level_t::log_level_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -static log_t slog; - -log_t& -logger() -{ - return slog; -} - -log_t::log_t() - : m_level(log_level_t::ERROR) - , m_handler(new cout_handler()) -{ -} - -void -log_t::set(const log_level_t& level) -{ - m_level = level; -} - -void -log_t::set(handler* h) -{ - m_handler = h; -} - -void -log_t::write(const std::string& file, - const int line, - const std::string& function, - const log_level_t& level, - const std::string& message) -{ - m_handler->handle_message(file, line, function, level, message); -} - -/** - * The configured level - */ -const log_level_t& -log_t::level() const -{ - return (m_level); -} - -static std::string -get_filename(const std::string& file) -{ - std::vector dirs; - boost::split(dirs, file, boost::is_any_of("/")); - - return dirs.back(); -} - -log_t::entry::entry(const char* file, - const char* function, - int line, - const log_level_t& level) - : m_file(get_filename(file)) - , m_function(function) - , m_level(level) - , m_line(line) -{ -} - -log_t::entry::~entry() -{ - logger().write(m_file, m_line, m_function, m_level, m_stream.str()); -} - -std::stringstream& -log_t::entry::stream() -{ - return (m_stream); -} - -static std::string -get_timestamp() -{ - auto end = std::chrono::system_clock::now(); - auto end_time = std::chrono::system_clock::to_time_t(end); - - /* - * put-time is not support in gcc in 4.8 - * so we play this dance with ctime - */ - std::string display = std::ctime(&end_time); - display.pop_back(); - - return (display); -} - -file_handler::file_handler(const std::string& ofile) -{ - m_file_stream.open(ofile); -} - -file_handler::~file_handler() -{ - m_file_stream.close(); -} - -void -file_handler::handle_message(const std::string& file, - const int line, - const std::string& function, - const log_level_t& level, - const std::string& message) -{ - m_file_stream << get_timestamp(); - m_file_stream << " [" << level.to_string() << "]" << file << ":" << line - << " " << function << "() " << message << std::endl; -} - -void -cout_handler::handle_message(const std::string& file, - const int line, - const std::string& function, - const log_level_t& level, - const std::string& message) -{ - std::cout << get_timestamp(); - std::cout << " [" << level.to_string() << "]" << file << ":" << line << " " - << function << "() " << message << std::endl; -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/logger.hpp b/extras/vom/vom/logger.hpp deleted file mode 100644 index 6d2e3dd82f6..00000000000 --- a/extras/vom/vom/logger.hpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - * 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_LOGGER_H__ -#define __VOM_LOGGER_H__ - -#include -#include -#include - -#include "vom/enum_base.hpp" - -namespace VOM { -struct log_level_t : enum_base -{ - const static log_level_t CRITICAL; - const static log_level_t ERROR; - const static log_level_t WARNING; - const static log_level_t INFO; - const static log_level_t DEBUG; - -private: - /** - * Private constructor taking the value and the string name - */ - log_level_t(int v, const std::string& s); - - /* - * not allowed to construct - */ - log_level_t() = delete; -}; - -/** - * Ideally we'd use the boost logger but that is not prevelent - * in many distros. So something simple here instead. - */ -class log_t -{ -public: - /** - * - */ - class handler - { - public: - /** - * Default Constructor - */ - handler() = default; - - /** - * Default Destructor - */ - virtual ~handler() = default; - - /** - * Handle a log message - */ - virtual void handle_message(const std::string& file, - const int line, - const std::string& function, - const log_level_t& level, - const std::string& message) = 0; - }; - - /** - * Construct a logger - */ - log_t(handler* h); - log_t(); - - /** - * The configured level - */ - const log_level_t& level() const; - - /** - * set the logging level - */ - void set(const log_level_t& level); - - /** - * set a file to receive the logging data - */ - void set(handler* h); - - /** - * An entry in the log - */ - class entry - { - public: - entry(const char* file, - const char* function, - int line, - const log_level_t& level); - ~entry(); - - std::stringstream& stream(); - - private: - const std::string m_file; - const std::string m_function; - const log_level_t m_level; - const int m_line; - - std::stringstream m_stream; - }; - /** - * Register a log handler to receive the log output - */ - void register_handler(handler& h); - -private: - void write(const std::string& file, - const int line, - const std::string& function, - const log_level_t& level, - const std::string& message); - - /** - * the configured logging level - */ - log_level_t m_level; - - /** - * Pointer to a registered handler. Null if no handler registerd - */ - handler* m_handler; -}; - -class file_handler : public log_t::handler -{ -public: - file_handler(const std::string& ofile); - ~file_handler(); - - virtual void handle_message(const std::string& file, - const int line, - const std::string& function, - const log_level_t& level, - const std::string& message); - -private: - /** - * Opened file for debugging - */ - std::ofstream m_file_stream; -}; - -class cout_handler : public log_t::handler -{ -public: - cout_handler() = default; - ~cout_handler() = default; - virtual void handle_message(const std::string& file, - const int line, - const std::string& function, - const log_level_t& level, - const std::string& message); -}; - -/** - * Return a log object into which VPP objects can write - */ -log_t& logger(); - -#define VOM_LOG(lvl) \ - if (lvl >= logger().level()) \ - log_t::entry(__FILE__, __FUNCTION__, __LINE__, lvl).stream() -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/mroute_cmds.cpp b/extras/vom/vom/mroute_cmds.cpp deleted file mode 100644 index 2f4dd6e1a86..00000000000 --- a/extras/vom/vom/mroute_cmds.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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 - -#include "vom/api_types.hpp" -#include "vom/mroute_cmds.hpp" -#include "vom/route_api_types.hpp" - -namespace VOM { -namespace route { -namespace ip_mroute_cmds { - -update_cmd::update_cmd(HW::item& item, - table_id_t id, - const mprefix_t& mprefix, - const path& path, - const itf_flags_t& flags) - : rpc_cmd(item) - , m_id(id) - , m_mprefix(mprefix) - , m_path(path) - , m_flags(flags) -{ -} - -bool -update_cmd::operator==(const update_cmd& other) const -{ - return ((m_mprefix == other.m_mprefix) && (m_id == other.m_id)); -} - -rc_t -update_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), 1, std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.is_add = 1; - - payload.route.table_id = m_id; - payload.route.prefix = to_api(m_mprefix); - - to_api(m_path, payload.route.paths[0].path); - payload.route.paths[0].itf_flags = to_api(m_flags); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -update_cmd::to_string() const -{ - std::ostringstream s; - s << "ip-mroute-create: " << m_hw_item.to_string() << " table-id:" << m_id - << " mprefix:" << m_mprefix.to_string() << " path:" << m_path.to_string() - << " flags:" << m_flags; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - table_id_t id, - const mprefix_t& mprefix, - const path& path, - const itf_flags_t& flags) - : rpc_cmd(item) - , m_id(id) - , m_mprefix(mprefix) - , m_path(path) - , m_flags(flags) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return ((m_mprefix == other.m_mprefix) && (m_id == other.m_id)); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), 1, std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - - payload.route.table_id = m_id; - payload.route.prefix = to_api(m_mprefix); - - to_api(m_path, payload.route.paths[0].path); - payload.route.paths[0].itf_flags = to_api(m_flags); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "ip-mroute-delete: " << m_hw_item.to_string() << " id:" << m_id - << " mprefix:" << m_mprefix.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd(route::table_id_t id, const l3_proto_t& proto) - : m_id(id) - , m_proto(proto) -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - - payload.table.table_id = m_id; - payload.table.is_ip6 = m_proto.is_ipv6(); - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - std::ostringstream s; - s << "ip-mroute-dump: id:" << m_id << " proto:" << m_proto.to_string(); - - return (s.str()); -} - -} // namespace ip_mroute_cmds -} // namespace mroute -} // namespace vom - /* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/mroute_cmds.hpp b/extras/vom/vom/mroute_cmds.hpp deleted file mode 100644 index 3392d4a3b2b..00000000000 --- a/extras/vom/vom/mroute_cmds.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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_MROUTE_CMDS_H__ -#define __VOM_MROUTE_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/route.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace route { -namespace ip_mroute_cmds { - -/** - * A command class that creates or updates the route - */ -class update_cmd : public rpc_cmd, vapi::Ip_mroute_add_del> -{ -public: - /** - * Constructor - */ - update_cmd(HW::item& item, - table_id_t id, - const mprefix_t& mprefix, - const path& path, - const itf_flags_t& flags); - - /** - * 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 update_cmd& i) const; - -private: - route::table_id_t m_id; - mprefix_t m_mprefix; - const path m_path; - const itf_flags_t& m_flags; -}; - -/** - * A cmd class that deletes a route - */ -class delete_cmd : public rpc_cmd, vapi::Ip_mroute_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, - table_id_t id, - const mprefix_t& mprefix, - const path& path, - const itf_flags_t& flags); - - /** - * 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: - route::table_id_t m_id; - mprefix_t m_mprefix; - const path m_path; - const itf_flags_t& m_flags; -}; - -/** - * A cmd class that Dumps ipv4 fib - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(route::table_id_t id, const l3_proto_t& proto); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; - route::table_id_t m_id; - const l3_proto_t& m_proto; -}; - -}; // namespace ip_mroute_cmds -}; // namespace route -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/nat_binding.cpp b/extras/vom/vom/nat_binding.cpp deleted file mode 100644 index a3fdee77be4..00000000000 --- a/extras/vom/vom/nat_binding.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* - * 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/nat_binding.hpp" -#include "vom/cmd.hpp" -#include "vom/nat_binding_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -singular_db nat_binding::m_db; - -nat_binding::event_handler nat_binding::m_evh; - -const nat_binding::zone_t nat_binding::zone_t::INSIDE(0, "inside"); -const nat_binding::zone_t nat_binding::zone_t::OUTSIDE(0, "outside"); - -nat_binding::zone_t::zone_t(int v, const std::string s) - : enum_base(v, s) -{ -} -const nat_binding::zone_t& -nat_binding::zone_t::from_vpp(u8 is_inside) -{ - if (is_inside) - return zone_t::INSIDE; - return zone_t::OUTSIDE; -} - -/** - * Construct a new object matching the desried state - */ -nat_binding::nat_binding(const interface& itf, - const direction_t& dir, - const l3_proto_t& proto, - const zone_t& zone) - : m_binding(false) - , m_itf(itf.singular()) - , m_dir(dir) - , m_proto(proto) - , m_zone(zone) -{ -} - -nat_binding::nat_binding(const nat_binding& o) - : m_binding(o.m_binding) - , m_itf(o.m_itf) - , m_dir(o.m_dir) - , m_proto(o.m_proto) - , m_zone(o.m_zone) -{ -} - -nat_binding::~nat_binding() -{ - sweep(); - m_db.release(key(), this); -} - -const nat_binding::key_t -nat_binding::key() const -{ - return (make_tuple(m_itf->key(), m_dir, m_proto)); -} - -bool -nat_binding::operator==(const nat_binding& n) const -{ - return ((key() == n.key()) && (m_zone == n.m_zone)); -} - -void -nat_binding::sweep() -{ - if (m_binding) { - if (direction_t::INPUT == m_dir) { - if (l3_proto_t::IPV4 == m_proto) { - HW::enqueue(new nat_binding_cmds::unbind_44_input_cmd( - m_binding, m_itf->handle(), m_zone)); - } else { - HW::enqueue(new nat_binding_cmds::unbind_66_input_cmd( - m_binding, m_itf->handle(), m_zone)); - } - } else { - if (l3_proto_t::IPV4 == m_proto) { - HW::enqueue(new nat_binding_cmds::unbind_44_output_cmd( - m_binding, m_itf->handle(), m_zone)); - } else { - VOM_LOG(log_level_t::ERROR) << "NAT 66 output feature not supported"; - } - } - } - HW::write(); -} - -void -nat_binding::replay() -{ - if (m_binding) { - if (direction_t::INPUT == m_dir) { - if (l3_proto_t::IPV4 == m_proto) { - HW::enqueue(new nat_binding_cmds::bind_44_input_cmd( - m_binding, m_itf->handle(), m_zone)); - } else { - HW::enqueue(new nat_binding_cmds::bind_66_input_cmd( - m_binding, m_itf->handle(), m_zone)); - } - } else { - if (l3_proto_t::IPV4 == m_proto) { - HW::enqueue(new nat_binding_cmds::bind_44_output_cmd( - m_binding, m_itf->handle(), m_zone)); - } else { - VOM_LOG(log_level_t::ERROR) << "NAT 66 output feature not supported"; - } - } - } -} - -void -nat_binding::update(const nat_binding& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (!m_binding) { - if (direction_t::INPUT == m_dir) { - if (l3_proto_t::IPV4 == m_proto) { - HW::enqueue(new nat_binding_cmds::bind_44_input_cmd( - m_binding, m_itf->handle(), m_zone)); - } else { - HW::enqueue(new nat_binding_cmds::bind_66_input_cmd( - m_binding, m_itf->handle(), m_zone)); - } - } else { - if (l3_proto_t::IPV4 == m_proto) { - HW::enqueue(new nat_binding_cmds::bind_44_output_cmd( - m_binding, m_itf->handle(), m_zone)); - } else { - VOM_LOG(log_level_t::ERROR) << "NAT 66 output feature not supported"; - } - } - } -} - -std::string -nat_binding::to_string() const -{ - std::ostringstream s; - s << "nat-binding:[" << m_itf->to_string() - << " direction:" << m_dir.to_string() << " proto:" << m_proto.to_string() - << " zone:" << m_zone.to_string() << "]"; - - return (s.str()); -} - -std::shared_ptr -nat_binding::find_or_add(const nat_binding& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -nat_binding::find(const key_t& key) -{ - return (m_db.find(key)); -} - -std::shared_ptr -nat_binding::singular() const -{ - return find_or_add(*this); -} - -void -nat_binding::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const nat_binding::key_t& key) -{ - os << "[" << std::get<0>(key) << ", " << std::get<1>(key) << ", " - << std::get<2>(key) << "]"; - - return (os); -} - -nat_binding::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "nat-binding" }, "NAT bindings", this); -} - -void -nat_binding::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -nat_binding::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr icmd = - std::make_shared(); - - HW::enqueue(icmd); - HW::write(); - - for (auto& record : *icmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = interface::find(payload.sw_if_index); - - if (itf) { - nat_binding nb(*itf, direction_t::INPUT, l3_proto_t::IPV4, - zone_t::from_vpp(payload.flags & NAT_IS_INSIDE)); - OM::commit(key, nb); - } else { - VOM_LOG(log_level_t::ERROR) << "nat-binding-input-44 no sw_if_index: " - << payload.sw_if_index; - } - } - - std::shared_ptr ocmd = - std::make_shared(); - - HW::enqueue(ocmd); - HW::write(); - - for (auto& record : *ocmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = interface::find(payload.sw_if_index); - if (itf) { - nat_binding nb(*itf, direction_t::OUTPUT, l3_proto_t::IPV4, - zone_t::from_vpp(payload.flags & NAT_IS_INSIDE)); - OM::commit(key, nb); - } else { - VOM_LOG(log_level_t::ERROR) << "nat-binding-output-44 no sw_if_index: " - << payload.sw_if_index; - } - } - - std::shared_ptr i6cmd = - std::make_shared(); - - HW::enqueue(i6cmd); - HW::write(); - - for (auto& record : *i6cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr itf = interface::find(payload.sw_if_index); - if (itf) { - nat_binding nb(*itf, direction_t::INPUT, l3_proto_t::IPV6, - zone_t::from_vpp(payload.flags & NAT_IS_INSIDE)); - OM::commit(key, nb); - } else { - VOM_LOG(log_level_t::ERROR) << "nat-binding-input-66 no sw_if_index: " - << payload.sw_if_index; - } - } -} - -dependency_t -nat_binding::event_handler::order() const -{ - return (dependency_t::BINDING); -} - -void -nat_binding::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/nat_binding.hpp b/extras/vom/vom/nat_binding.hpp deleted file mode 100644 index a99d23af601..00000000000 --- a/extras/vom/vom/nat_binding.hpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 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_NAT_BINDING_H__ -#define __VOM_NAT_BINDING_H__ - -#include "vom/hw.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A Class representing the binding of an L2 interface to a bridge-domain - * and the properties of that binding. - */ -class nat_binding : public object_base -{ -public: - /** - * NAT Zoness - */ - struct zone_t : public enum_base - { - /** - * Constructor - */ - zone_t(int v, const std::string s); - - /** - * Destructor - */ - ~zone_t() = default; - - /** - * Permit Zone - */ - const static zone_t INSIDE; - - /** - * Deny Zone - */ - const static zone_t OUTSIDE; - - const static zone_t& from_vpp(u8 is_inside); - }; - - /** - * The key for a NAT Binding. - * The zoe is not included, since the same interface is never inside - * and outside. - */ - typedef std::tuple key_t; - - /** - * Construct a new object matching the desried state - * @param itf The interface onto which we bind/apply the feature - * @param dir The direction (input/output) - * @param proto The L3 proto used inside. - * @param zone The NAT zone for the link - */ - nat_binding(const interface& itf, - const direction_t& dir, - const l3_proto_t& proto, - const zone_t& zone); - - /** - * Copy Constructor - */ - nat_binding(const nat_binding& o); - - /** - * Destructor - */ - ~nat_binding(); - - /** - * Comparison operator - for UT - */ - bool operator==(const nat_binding& n) const; - - /** - * Return the binding's key - */ - const key_t key() const; - - /** - * Return the 'singular instance' of the L2 config that matches this - * object - */ - std::shared_ptr singular() const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Static function to find the bridge_domain in the model - */ - static std::shared_ptr find(const key_t& key); - - /** - * Dump all nat_bindings into the stream provided - */ - static void dump(std::ostream& os); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Enquue commonds to the VPP command Q for the update - */ - void update(const nat_binding& obj); - - /** - * Find or Add the singular instance in the DB - */ - static std::shared_ptr find_or_add(const nat_binding& temp); - - /* - * It's the OM class that calls singular() - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * HW configuration for the binding. The bool representing the - * do/don't bind. - */ - HW::item m_binding; - - /** - * A reference counting pointer the interface that this NAT binding - * represents. By holding the reference here, we can guarantee that - * this object will outlive the interface - */ - const std::shared_ptr m_itf; - - /** - * The direction in which the feature applies - */ - direction_t m_dir; - - /** - * The L3 protocol used on the inside - */ - l3_proto_t m_proto; - - /** - * The NAT zone the interface is in - */ - zone_t m_zone; - - /** - * A map of all L2 interfaces key against the interface's handle_t - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, const nat_binding::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/nat_binding_cmds.cpp b/extras/vom/vom/nat_binding_cmds.cpp deleted file mode 100644 index 4e69a67f2af..00000000000 --- a/extras/vom/vom/nat_binding_cmds.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/* - * 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/nat_binding_cmds.hpp" - -namespace VOM { -namespace nat_binding_cmds { -bind_44_input_cmd::bind_44_input_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone) - : rpc_cmd(item) - , m_itf(itf) - , m_zone(zone) -{ -} - -bool -bind_44_input_cmd::operator==(const bind_44_input_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); -} - -rc_t -bind_44_input_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.flags = (vapi_enum_nat_config_flags)( - nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_44_input_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-44-input-binding-create: " << m_hw_item.to_string() - << " itf:" << m_itf << " " << m_zone.to_string(); - - return (s.str()); -} - -unbind_44_input_cmd::unbind_44_input_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone) - : rpc_cmd(item) - , m_itf(itf) - , m_zone(zone) -{ -} - -bool -unbind_44_input_cmd::operator==(const unbind_44_input_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); -} - -rc_t -unbind_44_input_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.flags = (vapi_enum_nat_config_flags)( - nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -unbind_44_input_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-44-input-binding-create: " << m_hw_item.to_string() - << " itf:" << m_itf << " " << m_zone.to_string(); - - return (s.str()); -} - -bind_44_output_cmd::bind_44_output_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone) - : rpc_cmd(item) - , m_itf(itf) - , m_zone(zone) -{ -} - -bool -bind_44_output_cmd::operator==(const bind_44_output_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); -} - -rc_t -bind_44_output_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.flags = (vapi_enum_nat_config_flags)( - nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -bind_44_output_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-44-output-binding-create: " << m_hw_item.to_string() - << " itf:" << m_itf << " " << m_zone.to_string(); - - return (s.str()); -} - -unbind_44_output_cmd::unbind_44_output_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone) - : rpc_cmd(item) - , m_itf(itf) - , m_zone(zone) -{ -} - -bool -unbind_44_output_cmd::operator==(const unbind_44_output_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); -} - -rc_t -unbind_44_output_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.flags = (vapi_enum_nat_config_flags)( - nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -unbind_44_output_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-44-output-binding-create: " << m_hw_item.to_string() - << " itf:" << m_itf << " " << m_zone.to_string(); - - return (s.str()); -} - -dump_input_44_cmd::dump_input_44_cmd() -{ -} - -dump_input_44_cmd::dump_input_44_cmd(const dump_input_44_cmd& d) -{ -} - -bool -dump_input_44_cmd::operator==(const dump_input_44_cmd& other) const -{ - return (true); -} - -rc_t -dump_input_44_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_input_44_cmd::to_string() const -{ - return ("nat-44-input-binding-dump"); -} - -dump_output_44_cmd::dump_output_44_cmd() -{ -} - -dump_output_44_cmd::dump_output_44_cmd(const dump_output_44_cmd& d) -{ -} - -bool -dump_output_44_cmd::operator==(const dump_output_44_cmd& other) const -{ - return (true); -} - -rc_t -dump_output_44_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_output_44_cmd::to_string() const -{ - return ("nat-44-output-binding-dump"); -} - -bind_66_input_cmd::bind_66_input_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone) - : rpc_cmd(item) - , m_itf(itf) - , m_zone(zone) -{ -} - -bool -bind_66_input_cmd::operator==(const bind_66_input_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); -} - -rc_t -bind_66_input_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.flags = (vapi_enum_nat_config_flags)( - nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - wait(); - - return rc_t::OK; -} - -std::string -bind_66_input_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-66-input-binding-create: " << m_hw_item.to_string() - << " itf:" << m_itf << " " << m_zone.to_string(); - - return (s.str()); -} - -unbind_66_input_cmd::unbind_66_input_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone) - : rpc_cmd(item) - , m_itf(itf) - , m_zone(zone) -{ -} - -bool -unbind_66_input_cmd::operator==(const unbind_66_input_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_zone == other.m_zone)); -} - -rc_t -unbind_66_input_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.flags = (vapi_enum_nat_config_flags)( - nat_binding::zone_t::INSIDE == m_zone ? NAT_IS_INSIDE : 0); - payload.sw_if_index = m_itf.value(); - - VAPI_CALL(req.execute()); - - wait(); - - return rc_t::OK; -} - -std::string -unbind_66_input_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-66-input-binding-create: " << m_hw_item.to_string() - << " itf:" << m_itf << " " << m_zone.to_string(); - - return (s.str()); -} - -dump_input_66_cmd::dump_input_66_cmd() -{ -} - -dump_input_66_cmd::dump_input_66_cmd(const dump_input_66_cmd& d) -{ -} - -bool -dump_input_66_cmd::operator==(const dump_input_66_cmd& other) const -{ - return (true); -} - -rc_t -dump_input_66_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_input_66_cmd::to_string() const -{ - return ("nat-66-input-binding-dump"); -} - -}; // namespace nat_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/nat_binding_cmds.hpp b/extras/vom/vom/nat_binding_cmds.hpp deleted file mode 100644 index 40507e0374b..00000000000 --- a/extras/vom/vom/nat_binding_cmds.hpp +++ /dev/null @@ -1,380 +0,0 @@ -/* - * 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_NAT_BINDING_CMDS_H__ -#define __VOM_NAT_BINDING_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/nat_binding.hpp" -#include "vom/rpc_cmd.hpp" - -#include -#include - -namespace VOM { -namespace nat_binding_cmds { -/** - * A functor class that binds a NAT configuration to an input interface - */ -class bind_44_input_cmd - : public rpc_cmd, vapi::Nat44_interface_add_del_feature> -{ -public: - /** - * Constructor - */ - bind_44_input_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone); - - /** - * 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 bind_44_input_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The zone the interface is in - */ - const nat_binding::zone_t m_zone; -}; - -/** - * A cmd class that unbinds a NAT configuration from an input interface - */ -class unbind_44_input_cmd - : public rpc_cmd, vapi::Nat44_interface_add_del_feature> -{ -public: - /** - * Constructor - */ - unbind_44_input_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone); - - /** - * 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 unbind_44_input_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The zone the interface is in - */ - const nat_binding::zone_t m_zone; -}; - -/** - * A functor class that binds a NAT configuration to an output interface - */ -class bind_44_output_cmd - : public rpc_cmd, vapi::Nat44_interface_add_del_output_feature> -{ -public: - /** - * Constructor - */ - bind_44_output_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone); - - /** - * 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 bind_44_output_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The zone the interface is in - */ - const nat_binding::zone_t m_zone; -}; - -/** - * A cmd class that unbinds a NAT configuration from an output interface - */ -class unbind_44_output_cmd - : public rpc_cmd, vapi::Nat44_interface_add_del_output_feature> -{ -public: - /** - * Constructor - */ - unbind_44_output_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone); - - /** - * 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 unbind_44_output_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The zone the interface is in - */ - const nat_binding::zone_t m_zone; -}; - -/** - * A cmd class that Dumps all the nat_statics - */ -class dump_input_44_cmd : public dump_cmd -{ -public: - /** - * Constructor - */ - dump_input_44_cmd(); - dump_input_44_cmd(const dump_input_44_cmd& d); - - /** - * 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_input_44_cmd& i) const; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -/** - * A cmd class that Dumps all the nat_statics - */ -class dump_output_44_cmd - : public dump_cmd -{ -public: - /** - * Constructor - */ - dump_output_44_cmd(); - dump_output_44_cmd(const dump_output_44_cmd& d); - - /** - * 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_output_44_cmd& i) const; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -///// -/** - * A functor class that binds a NAT configuration to an input interface - */ -class bind_66_input_cmd - : public rpc_cmd, vapi::Nat66_add_del_interface> -{ -public: - /** - * Constructor - */ - bind_66_input_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone); - - /** - * 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 bind_66_input_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The zone the interface is in - */ - const nat_binding::zone_t m_zone; -}; - -/** - * A cmd class that unbinds a NAT configuration from an input interface - */ -class unbind_66_input_cmd - : public rpc_cmd, vapi::Nat66_add_del_interface> -{ -public: - /** - * Constructor - */ - unbind_66_input_cmd(HW::item& item, - const handle_t& itf, - const nat_binding::zone_t& zone); - - /** - * 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 unbind_66_input_cmd& i) const; - -private: - /** - * The interface to bind - */ - const handle_t m_itf; - - /** - * The zone the interface is in - */ - const nat_binding::zone_t m_zone; -}; - -/** - * A cmd class that Dumps all the nat_statics - */ -class dump_input_66_cmd : public dump_cmd -{ -public: - /** - * Constructor - */ - dump_input_66_cmd(); - dump_input_66_cmd(const dump_input_66_cmd& d); - - /** - * 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_input_66_cmd& i) const; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // namespace nat_binding_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/nat_static.cpp b/extras/vom/vom/nat_static.cpp deleted file mode 100644 index bf8573d333e..00000000000 --- a/extras/vom/vom/nat_static.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * 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/nat_static.hpp" -#include "vom/nat_static_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -singular_db nat_static::m_db; -nat_static::event_handler nat_static::m_evh; - -nat_static::nat_static(const boost::asio::ip::address& inside, - const boost::asio::ip::address& outside) - : m_hw(false) - , m_rd(route_domain::get_default()) - , m_inside(inside) - , m_outside(outside) -{ -} - -nat_static::nat_static(const route_domain& rd, - const boost::asio::ip::address& inside, - const boost::asio::ip::address& outside) - : m_hw(false) - , m_rd(rd.singular()) - , m_inside(inside) - , m_outside(outside) -{ -} - -nat_static::nat_static(const nat_static& ns) - : m_hw(ns.m_hw) - , m_rd(ns.m_rd) - , m_inside(ns.m_inside) - , m_outside(ns.m_outside) -{ -} - -nat_static::~nat_static() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -const nat_static::key_t -nat_static::key() const -{ - return (std::make_pair(m_rd->key(), m_outside)); -} - -bool -nat_static::operator==(const nat_static& n) const -{ - return ((key() == n.key()) && (m_inside == n.m_inside)); -} - -void -nat_static::sweep() -{ - if (m_hw) { - if (m_inside.is_v4()) { - HW::enqueue(new nat_static_cmds::delete_44_cmd( - m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside.to_v4())); - } else { - HW::enqueue(new nat_static_cmds::delete_66_cmd( - m_hw, m_rd->table_id(), m_inside.to_v6(), m_outside.to_v6())); - } - } - HW::write(); -} - -void -nat_static::replay() -{ - if (m_hw) { - if (m_inside.is_v4()) { - HW::enqueue(new nat_static_cmds::create_44_cmd( - m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside.to_v4())); - } else { - HW::enqueue(new nat_static_cmds::create_66_cmd( - m_hw, m_rd->table_id(), m_inside.to_v6(), m_outside.to_v6())); - } - } -} - -void -nat_static::update(const nat_static& r) -{ - /* - * create the table if it is not yet created - */ - if (rc_t::OK != m_hw.rc()) { - if (m_inside.is_v4()) { - HW::enqueue(new nat_static_cmds::create_44_cmd( - m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside.to_v4())); - } else { - HW::enqueue(new nat_static_cmds::create_66_cmd( - m_hw, m_rd->table_id(), m_inside.to_v6(), m_outside.to_v6())); - } - } -} - -std::string -nat_static::to_string() const -{ - std::ostringstream s; - s << "nat-static:[" - << "table:" << m_rd->to_string() << " inside:" << m_inside.to_string() - << " outside:" << m_outside.to_string() << "]"; - - return (s.str()); -} - -std::shared_ptr -nat_static::find_or_add(const nat_static& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -nat_static::find(const key_t& key) -{ - return (m_db.find(key)); -} - -std::shared_ptr -nat_static::singular() const -{ - return find_or_add(*this); -} - -void -nat_static::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -nat_static::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "nat-static" }, "NAT Statics", this); -} - -void -nat_static::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -nat_static::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump VPP current states - */ - std::shared_ptr cmd44 = - std::make_shared(); - - HW::enqueue(cmd44); - HW::write(); - - for (auto& record : *cmd44) { - - auto& payload = record.get_payload(); - - boost::asio::ip::address inside = from_bytes(0, payload.local_ip_address); - boost::asio::ip::address outside = - from_bytes(0, payload.external_ip_address); - nat_static n(route_domain(payload.vrf_id), inside, outside); - - /* - * Write each of the discovered mappings into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, n); - } - - std::shared_ptr cmd66 = - std::make_shared(); - - HW::enqueue(cmd66); - HW::write(); - - for (auto& record : *cmd66) { - - auto& payload = record.get_payload(); - - boost::asio::ip::address inside = from_bytes(1, payload.local_ip_address); - boost::asio::ip::address outside = - from_bytes(1, payload.external_ip_address); - nat_static n(route_domain(payload.vrf_id), inside, outside); - - /* - * Write each of the discovered mappings into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, n); - } -} - -dependency_t -nat_static::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -nat_static::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/nat_static.hpp b/extras/vom/vom/nat_static.hpp deleted file mode 100644 index 2dcadb3c904..00000000000 --- a/extras/vom/vom/nat_static.hpp +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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_NAT_STATIC_H__ -#define __VOM_NAT_STATIC_H__ - -#include "vom/route.hpp" -#include "vom/singular_db.hpp" -#include "vom/types.hpp" - -namespace VOM { -/** - * A entry in the ARP termination table of a Bridge Domain - */ -class nat_static : public object_base -{ -public: - /** - * The key for a NAT static mapping. - * So far only model the address only case. The address - * is the outside. - */ - typedef std::pair key_t; - - /** - * Construct an NAT Static binding with the outside address in default - * table - */ - nat_static(const boost::asio::ip::address& inside, - const boost::asio::ip::address& outside); - - /** - * Construct an NAT Static binding with the outside address in - * route-domain specified - */ - nat_static(const route_domain& rd, - const boost::asio::ip::address& inside, - const boost::asio::ip::address& outside); - - /** - * Copy Construct - */ - nat_static(const nat_static& r); - - /** - * Destructor - */ - ~nat_static(); - - /** - * Comparison operator - for UT - */ - bool operator==(const nat_static& n) const; - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& key); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const nat_static& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const nat_static& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the bridge_domain - */ - HW::item m_hw; - - /** - * The table-ID the outside address resides in - */ - std::shared_ptr m_rd; - - /** - * The 'inside' IP address, could be v4 or v6 - */ - const boost::asio::ip::address m_inside; - - /** - * The 'outside' IP address - */ - const boost::asio::ip::address m_outside; - - /** - * A map of all NAT statics - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, const nat_static::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/nat_static_cmds.cpp b/extras/vom/vom/nat_static_cmds.cpp deleted file mode 100644 index 7e2b05f7f1e..00000000000 --- a/extras/vom/vom/nat_static_cmds.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - * 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/nat_static_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_NAT_API_JSON; -DEFINE_VAPI_MSG_IDS_NAT66_API_JSON; - -namespace VOM { -namespace nat_static_cmds { - -create_44_cmd::create_44_cmd(HW::item& item, - route::table_id_t id, - const boost::asio::ip::address_v4& inside, - const boost::asio::ip::address_v4& outside) - : rpc_cmd(item) - , m_id(id) - , m_inside(inside) - , m_outside(outside) -{} - -bool -create_44_cmd::operator==(const create_44_cmd& other) const -{ - return ((m_id == other.m_id) && (m_inside == other.m_inside) && - (m_outside == other.m_outside)); -} - -rc_t -create_44_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.flags = NAT_IS_ADDR_ONLY; - payload.local_port = 0; - payload.external_port = 0; - payload.vrf_id = m_id; - payload.external_sw_if_index = ~0; - to_bytes(m_inside, payload.local_ip_address); - to_bytes(m_outside, payload.external_ip_address); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_44_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-44-static-create: " << m_hw_item.to_string() << " table:" << m_id - << " inside:" << m_inside.to_string() - << " outside:" << m_outside.to_string(); - - return (s.str()); -} - -delete_44_cmd::delete_44_cmd(HW::item& item, - route::table_id_t id, - const boost::asio::ip::address_v4& inside, - const boost::asio::ip::address_v4& outside) - : rpc_cmd(item) - , m_id(id) - , m_inside(inside) - , m_outside(outside) -{} - -bool -delete_44_cmd::operator==(const delete_44_cmd& other) const -{ - return ((m_id == other.m_id) && (m_inside == other.m_inside) && - (m_outside == other.m_outside)); -} - -rc_t -delete_44_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.flags = NAT_IS_ADDR_ONLY; - payload.local_port = 0; - payload.external_port = 0; - payload.vrf_id = m_id; - payload.external_sw_if_index = ~0; - to_bytes(m_inside, payload.local_ip_address); - to_bytes(m_outside, payload.external_ip_address); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_44_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-44-static-delete: " << m_hw_item.to_string() << " table:" << m_id - << " inside:" << m_inside.to_string() - << " outside:" << m_outside.to_string(); - - return (s.str()); -} - -bool -dump_44_cmd::operator==(const dump_44_cmd& other) const -{ - return (true); -} - -rc_t -dump_44_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_44_cmd::to_string() const -{ - return ("nat-44-static-dump"); -} - -create_66_cmd::create_66_cmd(HW::item& item, - route::table_id_t id, - const boost::asio::ip::address_v6& inside, - const boost::asio::ip::address_v6& outside) - : rpc_cmd(item) - , m_id(id) - , m_inside(inside) - , m_outside(outside) -{} - -bool -create_66_cmd::operator==(const create_66_cmd& other) const -{ - return ((m_id == other.m_id) && (m_inside == other.m_inside) && - (m_outside == other.m_outside)); -} - -rc_t -create_66_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.vrf_id = m_id; - to_bytes(m_inside, payload.local_ip_address); - to_bytes(m_outside, payload.external_ip_address); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_66_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-66-static-create: " << m_hw_item.to_string() << " table:" << m_id - << " inside:" << m_inside.to_string() - << " outside:" << m_outside.to_string(); - - return (s.str()); -} - -delete_66_cmd::delete_66_cmd(HW::item& item, - route::table_id_t id, - const boost::asio::ip::address_v6& inside, - const boost::asio::ip::address_v6& outside) - : rpc_cmd(item) - , m_id(id) - , m_inside(inside) - , m_outside(outside) -{} - -bool -delete_66_cmd::operator==(const delete_66_cmd& other) const -{ - return ((m_id == other.m_id) && (m_inside == other.m_inside) && - (m_outside == other.m_outside)); -} - -rc_t -delete_66_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.vrf_id = m_id; - to_bytes(m_inside, payload.local_ip_address); - to_bytes(m_outside, payload.external_ip_address); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_66_cmd::to_string() const -{ - std::ostringstream s; - s << "nat-66-static-delete: " << m_hw_item.to_string() << " table:" << m_id - << " inside:" << m_inside.to_string() - << " outside:" << m_outside.to_string(); - - return (s.str()); -} - -bool -dump_66_cmd::operator==(const dump_66_cmd& other) const -{ - return (true); -} - -rc_t -dump_66_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_66_cmd::to_string() const -{ - return ("nat-static-dump"); -} - -}; // namespace nat_static_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/nat_static_cmds.hpp b/extras/vom/vom/nat_static_cmds.hpp deleted file mode 100644 index 2213ef5ae47..00000000000 --- a/extras/vom/vom/nat_static_cmds.hpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * 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_NAT_STATIC_CMDS_H__ -#define __VOM_NAT_STATIC_CMDS_H__ - -#include "nat_static.hpp" -#include "vom/dump_cmd.hpp" - -#include -#include - -namespace VOM { -namespace nat_static_cmds { - -/** - * A command class that creates NAT 44 static mapping - */ -class create_44_cmd - : public rpc_cmd, vapi::Nat44_add_del_static_mapping> -{ -public: - /** - * Constructor - */ - create_44_cmd(HW::item& item, - route::table_id_t id, - const boost::asio::ip::address_v4& inside, - const boost::asio::ip::address_v4& outside); - - /** - * 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_44_cmd& i) const; - -private: - route::table_id_t m_id; - const boost::asio::ip::address_v4 m_inside; - const boost::asio::ip::address_v4 m_outside; -}; - -/** - * A cmd class that deletes a NAT 44 static mapping - */ -class delete_44_cmd - : public rpc_cmd, vapi::Nat44_add_del_static_mapping> -{ -public: - /** - * Constructor - */ - delete_44_cmd(HW::item& item, - route::table_id_t id, - const boost::asio::ip::address_v4& inside, - const boost::asio::ip::address_v4& outside); - - /** - * 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_44_cmd& i) const; - -private: - route::table_id_t m_id; - const boost::asio::ip::address_v4 m_inside; - const boost::asio::ip::address_v4 m_outside; -}; - -/** - * A cmd class that Dumps all the nat_statics - */ -class dump_44_cmd : public dump_cmd -{ -public: - /** - * Constructor - */ - dump_44_cmd() = default; - ~dump_44_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_44_cmd& i) const; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -/** - * A command class that creates NAT 66 static mapping - */ -class create_66_cmd - : public rpc_cmd, vapi::Nat66_add_del_static_mapping> -{ -public: - /** - * Constructor - */ - create_66_cmd(HW::item& item, - route::table_id_t id, - const boost::asio::ip::address_v6& inside, - const boost::asio::ip::address_v6& outside); - - /** - * 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_66_cmd& i) const; - -private: - route::table_id_t m_id; - const boost::asio::ip::address_v6 m_inside; - const boost::asio::ip::address_v6 m_outside; -}; - -/** - * A cmd class that deletes a NAT 66 static mapping - */ -class delete_66_cmd - : public rpc_cmd, vapi::Nat66_add_del_static_mapping> -{ -public: - /** - * Constructor - */ - delete_66_cmd(HW::item& item, - route::table_id_t id, - const boost::asio::ip::address_v6& inside, - const boost::asio::ip::address_v6& outside); - - /** - * 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_66_cmd& i) const; - -private: - route::table_id_t m_id; - const boost::asio::ip::address_v6 m_inside; - const boost::asio::ip::address_v6 m_outside; -}; - -/** - * A cmd class that Dumps all the nat_statics - */ -class dump_66_cmd : public dump_cmd -{ -public: - /** - * Constructor - */ - dump_66_cmd() = default; - ~dump_66_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_66_cmd& i) const; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // namespace nat_static_cmds -}; // namespace vom - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/neighbour.cpp b/extras/vom/vom/neighbour.cpp deleted file mode 100644 index a97892d7cdb..00000000000 --- a/extras/vom/vom/neighbour.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 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/neighbour.hpp" -#include "vom/api_types.hpp" -#include "vom/neighbour_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -singular_db neighbour::m_db; -neighbour::event_handler neighbour::m_evh; - -const neighbour::flags_t neighbour::flags_t::NONE(0, ""); -const neighbour::flags_t neighbour::flags_t::STATIC(1, "static"); -const neighbour::flags_t neighbour::flags_t::NO_FIB_ENTRY(2, "no-fib-entry"); - -neighbour::flags_t::flags_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -neighbour::neighbour(const interface& itf, - const boost::asio::ip::address& ip_addr, - const mac_address_t& mac, - const flags_t flags) - : m_hw(false) - , m_itf(itf.singular()) - , m_ip_addr(ip_addr) - , m_mac(mac) - , m_flags(flags) -{ -} - -neighbour::neighbour(const neighbour& n) - : m_hw(n.m_hw) - , m_itf(n.m_itf) - , m_ip_addr(n.m_ip_addr) - , m_mac(n.m_mac) - , m_flags(n.m_flags) -{ -} - -neighbour::~neighbour() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); -} - -bool -neighbour::operator==(const neighbour& n) const -{ - return ((key() == n.key()) && (m_mac == n.m_mac)); -} - -const neighbour::key_t -neighbour::key() const -{ - return (std::make_pair(m_itf->key(), m_ip_addr)); -} - -void -neighbour::sweep() -{ - if (m_hw) { - HW::enqueue(new neighbour_cmds::delete_cmd(m_hw, m_itf->handle(), m_mac, - m_ip_addr, m_flags)); - } - HW::write(); -} - -void -neighbour::replay() -{ - if (m_hw) { - HW::enqueue(new neighbour_cmds::create_cmd(m_hw, m_itf->handle(), m_mac, - m_ip_addr, m_flags)); - } -} - -std::string -neighbour::to_string() const -{ - std::ostringstream s; - s << "neighbour:[" << m_itf->to_string() << ", " << m_mac.to_string() << ", " - << m_ip_addr.to_string() << " " << m_flags.to_string() << "]"; - - return (s.str()); -} - -void -neighbour::update(const neighbour& r) -{ - /* - * create the table if it is not yet created - */ - if (rc_t::OK != m_hw.rc()) { - HW::enqueue(new neighbour_cmds::create_cmd(m_hw, m_itf->handle(), m_mac, - m_ip_addr, m_flags)); - } -} - -std::shared_ptr -neighbour::find_or_add(const neighbour& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -neighbour::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -neighbour::singular() const -{ - return find_or_add(*this); -} - -void -neighbour::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const neighbour::key_t& key) -{ - os << "[" << key.first << ", " << key.second << "]"; - - return (os); -} - -neighbour::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "neighbour" }, "Neighbours", this); -} - -void -neighbour::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -neighbour::populate_i(const client_db::key_t& key, - std::shared_ptr itf, - const l3_proto_t& proto) -{ - /* - * dump VPP current states - */ - std::shared_ptr cmd = - std::make_shared( - neighbour_cmds::dump_cmd(itf->handle(), proto)); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - /* - * construct a neighbour from each recieved record. - */ - auto& payload = record.get_payload(); - - mac_address_t mac = from_api(payload.neighbor.mac_address); - boost::asio::ip::address ip_addr = from_api(payload.neighbor.ip_address); - neighbour::flags_t f = from_api(payload.neighbor.flags); - neighbour n(*itf, ip_addr, mac, f); - ; - - VOM_LOG(log_level_t::DEBUG) << "neighbour-dump: " << itf->to_string() << " " - << mac.to_string() << " " << ip_addr.to_string() - << " " << f.to_string(); - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, n); - } -} - -void -neighbour::event_handler::handle_populate(const client_db::key_t& key) -{ - auto it = interface::cbegin(); - - while (it != interface::cend()) { - neighbour::populate_i(key, it->second.lock(), l3_proto_t::IPV4); - neighbour::populate_i(key, it->second.lock(), l3_proto_t::IPV6); - - ++it; - } -} - -dependency_t -neighbour::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -neighbour::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/neighbour.hpp b/extras/vom/vom/neighbour.hpp deleted file mode 100644 index 5b1f9c12847..00000000000 --- a/extras/vom/vom/neighbour.hpp +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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_NEIGHBOUR_H__ -#define __VOM_NEIGHBOUR_H__ - -#include "vom/interface.hpp" -#include "vom/singular_db.hpp" -#include "vom/types.hpp" - -namespace VOM { -/** - * A entry in the neighbour entry (ARP or IPv6 ND) - */ -class neighbour : public object_base -{ -public: - struct flags_t : public enum_base - { - /** - * Constructor - */ - flags_t(int v, const std::string s); - - /** - * Destructor - */ - ~flags_t() = default; - - flags_t operator|(const flags_t& e1) const - { - flags_t e = *this; - e |= e1; - return e; - } - - const static flags_t NONE; - const static flags_t STATIC; - const static flags_t NO_FIB_ENTRY; - }; - - /** - * The key for a neighbour entry; - * the interface and IP address - */ - typedef std::pair key_t; - - /** - * Construct an ARP entry - */ - neighbour(const interface& itf, - const boost::asio::ip::address& ip_addr, - const mac_address_t& mac, - const flags_t flags = flags_t::STATIC); - - /** - * Copy Construct - */ - neighbour(const neighbour& r); - - /** - * Destructor - */ - ~neighbour(); - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * Comparison operator - */ - bool operator==(const neighbour& n) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the neighbour fromits key - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all neighbours into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const neighbour& obj); - - /** - * Do the populate work - */ - static void populate_i(const client_db::key_t& key, - std::shared_ptr itf, - const l3_proto_t& proto); - - /** - * Find or add the instnace of the neighbour in the OM - */ - static std::shared_ptr find_or_add(const neighbour& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the bridge_domain - */ - HW::item m_hw; - - /** - * The bridge_domain domain the bridge_domain is in. - */ - std::shared_ptr m_itf; - - /** - * The IP address - */ - boost::asio::ip::address m_ip_addr; - - /** - * The mac to match - */ - mac_address_t m_mac; - - /** - * flags on the entry - */ - flags_t m_flags; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, const neighbour::key_t& key); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/neighbour_cmds.cpp b/extras/vom/vom/neighbour_cmds.cpp deleted file mode 100644 index d507bb74ea8..00000000000 --- a/extras/vom/vom/neighbour_cmds.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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/neighbour_cmds.hpp" -#include "vom/api_types.hpp" - -DEFINE_VAPI_MSG_IDS_IP_NEIGHBOR_API_JSON; - -namespace VOM { -namespace neighbour_cmds { -create_cmd::create_cmd(HW::item& item, - handle_t itf, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr, - const neighbour::flags_t& flags) - : srpc_cmd(item) - , m_itf(itf) - , m_mac(mac) - , m_ip_addr(ip_addr) - , m_flags(flags) -{} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_mac == other.m_mac) && (m_ip_addr == other.m_ip_addr) && - (m_itf == other.m_itf) && (m_flags == other.m_flags)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - payload.neighbor.sw_if_index = m_itf.value(); - - to_api(m_mac, payload.neighbor.mac_address); - to_api(m_ip_addr, payload.neighbor.ip_address); - payload.neighbor.flags = to_api(m_flags); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "nieghbour-create: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string() << " mac:" << m_mac.to_string() - << " ip:" << m_ip_addr.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - handle_t itf, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr, - const neighbour::flags_t& flags) - : srpc_cmd(item) - , m_itf(itf) - , m_mac(mac) - , m_ip_addr(ip_addr) - , m_flags(flags) -{} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return ((m_mac == other.m_mac) && (m_ip_addr == other.m_ip_addr) && - (m_itf == other.m_itf)); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.neighbor.sw_if_index = m_itf.value(); - - to_api(m_mac, payload.neighbor.mac_address); - to_api(m_ip_addr, payload.neighbor.ip_address); - payload.neighbor.flags = to_api(m_flags); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "neighbour-delete: " << m_hw_item.to_string() - << " itf:" << m_itf.to_string() << " mac:" << m_mac.to_string() - << " ip:" << m_ip_addr.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd(const handle_t& hdl, const l3_proto_t& proto) - : m_itf(hdl) - , m_proto(proto) -{} - -dump_cmd::dump_cmd(const dump_cmd& d) - : m_itf(d.m_itf) - , m_proto(d.m_proto) -{} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = m_itf.value(); - payload.af = to_api(m_proto); - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - std::ostringstream s; - - s << "neighbour-dump: " << m_itf.to_string() << " " << m_proto.to_string(); - - return (s.str()); -} -} // namespace neighbour_cmds -} // namespace vom - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/neighbour_cmds.hpp b/extras/vom/vom/neighbour_cmds.hpp deleted file mode 100644 index 024a021ce8d..00000000000 --- a/extras/vom/vom/neighbour_cmds.hpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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_NEIGHBOUR_CMDS_H__ -#define __VOM_NEIGHBOUR_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/srpc_cmd.hpp" -#include "neighbour.hpp" - -#include - -namespace VOM { -namespace neighbour_cmds { - -/** - * A command class that creates or updates the bridge domain ARP Entry - */ -class create_cmd : public srpc_cmd -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - handle_t itf, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr, - const neighbour::flags_t &flags); - - /** - * 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; - -private: - handle_t m_itf; - mac_address_t m_mac; - boost::asio::ip::address m_ip_addr; - const neighbour::flags_t &m_flags; -}; - -/** - * A cmd class that deletes a bridge domain ARP entry - */ -class delete_cmd : public srpc_cmd -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, - handle_t itf, - const mac_address_t& mac, - const boost::asio::ip::address& ip_addr, - const neighbour::flags_t &flags); - - /** - * 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: - handle_t m_itf; - mac_address_t m_mac; - boost::asio::ip::address m_ip_addr; - const neighbour::flags_t &m_flags; -}; - -/** - * A cmd class that Dumps all the neighbours - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(const handle_t& itf, const l3_proto_t& proto); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; - - /** - * The interface to dump - */ - handle_t m_itf; - - /** - * V4 or V6 - */ - l3_proto_t m_proto; -}; - -}; // namespace neighbour_cmds -}; // namespace vom -#endif - diff --git a/extras/vom/vom/object_base.cpp b/extras/vom/vom/object_base.cpp deleted file mode 100644 index 6ab4ee5cadc..00000000000 --- a/extras/vom/vom/object_base.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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/object_base.hpp" - -namespace VOM { -object_ref::object_ref(std::shared_ptr obj) - : m_obj(obj) - , m_state(OBJECT_STATE_NONE) -{ -} - -bool -object_ref::operator<(const object_ref& other) const -{ - return (m_obj.get() < other.m_obj.get()); -} - -std::shared_ptr -object_ref::obj() const -{ - return (m_obj); -} - -void -object_ref::mark() const -{ - m_state = OBJECT_STATE_STALE; -} - -void -object_ref::clear() const -{ - m_state = OBJECT_STATE_NONE; -} - -bool -object_ref::stale() const -{ - return (m_state == OBJECT_STATE_STALE); -} - -std::ostream& -operator<<(std::ostream& os, const object_base& o) -{ - os << o.to_string(); - - return (os); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/object_base.hpp b/extras/vom/vom/object_base.hpp deleted file mode 100644 index 2edafc58466..00000000000 --- a/extras/vom/vom/object_base.hpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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_OBJECT_H__ -#define __VOM_OBJECT_H__ - -#include -#include - -#include "vom/types.hpp" - -namespace VOM { -/** - * A base class for all object_base in the VPP object_base-Model. - * provides the abstract interface. - */ -class object_base -{ -public: - /** - * convert to string format for debug purposes - */ - virtual std::string to_string() const = 0; - - /** - * Sweep/reap the object if still stale - */ - virtual void sweep(void) = 0; - - /** - * replay the object to create it in hardware - */ - virtual void replay(void) = 0; - -protected: - /** - * Constructable by derived classes only - */ - object_base() = default; - /** - * Destructor - */ - virtual ~object_base() = default; - -private: - /** - * note we are not maintaining dependencies back to the - * keys. i.e. this object does not know all the keys that - * refer to it. - */ -}; - -/** - * object state - */ -enum obj_state_t -{ - OBJECT_STATE_NONE = 0, - /** - * indicates the object is stale. This flag is set - * when a new epoch is declared. the flag is cleared - * when the object is updated in the new epoch. If the - * flag is still set after convergence is declared then - * the object is deleted - */ - OBJECT_STATE_STALE, -}; - -/** - * A represenation of a reference to a VPP object. - * the reference counting is held through the use of shared pointers. - * We also maintain the state of the object ready for mark n' sweep. - */ -class object_ref -{ -public: - /** - * Constructor - */ - object_ref(std::shared_ptr obj); - - /** - * less than operator - */ - bool operator<(const object_ref& other) const; - - /** - * Return the shared pointer - */ - std::shared_ptr obj() const; - - /** - * Mark the reference object as stale - */ - void mark() const; - - /** - * Clear the stale flag on the object - */ - void clear() const; - - /** - * Query if the object is stale - */ - bool stale() const; - -private: - /** - * The reference object - */ - std::shared_ptr m_obj; - - /** - * Not part of the key (in the set) so we can change it - * whilst iterating - */ - mutable obj_state_t m_state; -}; - -/** - * ostream print of a VPP Obect - */ -std::ostream& operator<<(std::ostream& os, const object_base& o); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/om.cpp b/extras/vom/vom/om.cpp deleted file mode 100644 index edfc046e740..00000000000 --- a/extras/vom/vom/om.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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 - -#include "vom/logger.hpp" -#include "vom/om.hpp" - -namespace VOM { -client_db* OM::m_db; - -std::unique_ptr OM::m_listeners; - -/** - * Initialse the connection to VPP - */ -void -OM::init() -{ - m_db = new client_db(); -} - -void -OM::mark(const client_db::key_t& key) -{ - /* - * Find if the object already stored on behalf of this key. - * and mark them stale - */ - object_ref_list& objs = m_db->find(key); - - auto mark_obj = [](const object_ref& oref) { oref.mark(); }; - - std::for_each(objs.begin(), objs.end(), mark_obj); -} - -void -OM::sweep(const client_db::key_t& key) -{ - /* - * Find if the object already stored on behalf of this key. - * and mark them stale - */ - object_ref_list& objs = m_db->find(key); - - for (auto it = objs.begin(); it != objs.end();) { - if (it->stale()) { - it = objs.erase(it); - } else { - ++it; - } - } - - HW::write(); -} - -void -OM::remove(const client_db::key_t& key) -{ - /* - * Simply reset the list for this key. This will desctruct the - * object list and shared_ptrs therein. When the last shared_ptr - * goes the objects desctructor is called and the object is - * removed from OM - */ - m_db->flush(key); - - HW::write(); -} - -void -OM::replay() -{ - VOM_LOG(log_level_t::INFO) << "replay"; - /* - * the listeners are sorted in dependency order - */ - for (listener* l : *m_listeners) { - l->handle_replay(); - HW::write(); - } -} - -void -OM::dump(const client_db::key_t& key, std::ostream& os) -{ - m_db->dump(key, os); -} - -void -OM::dump(std::ostream& os) -{ - m_db->dump(os); -} - -void -OM::populate(const client_db::key_t& key) -{ - VOM_LOG(log_level_t::INFO) << "populate"; - - /* - * the listeners are sorted in dependency order - */ - for (listener* l : *m_listeners) { - l->handle_populate(key); - } - - /* - * once we have it all, mark it stale. - */ - mark(key); -} - -bool -OM::register_listener(OM::listener* listener) -{ - if (!m_listeners) { - m_listeners.reset(new listener_list); - } - - m_listeners->insert(listener); - - return (true); -} - -OM::mark_n_sweep::mark_n_sweep(const client_db::key_t& key) - : m_key(key) -{ - OM::mark(m_key); -} - -OM::mark_n_sweep::~mark_n_sweep() -{ - OM::sweep(m_key); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/om.hpp b/extras/vom/vom/om.hpp deleted file mode 100644 index e68d5ea0017..00000000000 --- a/extras/vom/vom/om.hpp +++ /dev/null @@ -1,356 +0,0 @@ -/* - * 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_OM_H__ -#define __VOM_OM_H__ - -#include -#include -#include - -#include "vom/client_db.hpp" -#include "vom/hw.hpp" - -/** - -The VPP Object Model (VOM) library. - -Before we begin, a glossary of terms: - - Agent or client: A user mode process that links to and uses the VOM library - to programme VPP - - VPP: A running instance of VPP - - High Availability (HA): Scenarios where the client and/or VPP restart with - minimal service interruption. - - CReate, Update, Delete (CRUD): An API style where the producer issues - notifications to changes to objects - -The VOM is a C++ library that models entities in VPP as C++ classes. The - relationships between VOM objects and VPP entities is not always 1:1. Some - effort has been made to construct a higher level, more abstract API to VPP - programming*. -The client programming model is simple (or at least I intended it to be..). The -client deals in ‘desired’ state, that is, it expresses the objects it wants to -exists (in VPP) and the properties that the object should have, i.e**; - Interface af1(“my-af-packet-1”, AFPACKET, admin::UP); -Then the client ‘writes’ this object into the ‘model’ - OM::write(“clients-thing-1”, af1); - -“clients-thing-1” is a description of the entity within the client’s domain that -‘owns’ (or has locked or has a reference to) the VOM object. There can be many -owners of each VOM object. It will be the last owner’s update that will be -programmed in VPP. This model means that the client is not burdened with -maintaining which of its objects have created which VOM objects. If the client -is itself driven by a CRUD API, then create notifications are implemented as - above. Update notifications add two extra statements; - OM::mark(“clients-thing-1”); - … do writes …. - OM::sweep(“clients-thing-1”); -These ‘mark’ and ‘sweep’ statements are indications to OM that firstly, indicate -that all the objects owned by “clients-thing-1” are now stale, i.e that the -client may no longer need them. If one of the subsequent writes should update a -stale object, then it is no longer stale. The sweep statement will ‘remove’ all -the remaining stale objects. In this model, the client does not need to maintain -the mapping of VOM objects to its own objects – it can simply express what it -needs now. -The delete notification is simply: - OM::remove(“clients-thing-1”); -Which will remove all the objects in VOM that are owned by “clients-thing-1”. -Where ‘remove’ in this sense means unlock and unreference, the VOM object, and -VPP state, will only be truly removed once there are no more owners. This is -equivalent to a mark & sweep with no intermediate writes. - -To provide this client side model the VOM is a stateful library, meaning that -for each entity it creates in VPP, VOM maintains its own representation of that -object. VOM can therefore be memory hungry. The desired state is expressed by -the client, the ‘actual’ state is maintained by VOM. VOM will consolidate the -two states when the client writes to the OM and thus issue VPP only the changes -required. - -The concepts of ownership and statefulness also allow the support for HA -scenarios. -VPP restart: When VPP restarts, VOM will reconnect and ‘replay’ its state, in -dependency order, to VPP. The client does not need to regenerate its desired -state. -Client restart: when the client restarts, VOM will read/dump the current state -of all VPP objects and store them in the OM owned by the special owner “boot”. -As the client reprogrammes its desired state, objects will become owned by both -the boot process and the client. At the point in time, as determined by the -client, all stale state, that owned only by boot, can be purged. Hence the -system reaches the correct final state, with no interruption to VPP forwarding. - - -Basic Design: - -Each object in VOM (i.e. an interface, route, bridge-domain, etc) is stored in a -per-type object database, with an object-type specific key. This ‘singular’ DB -has a value-type of a weak pointer to the object. I use the term ‘singular’ to -refer to the instance of the object stored in these databases, to be distinct -from the instances the client constructs to represent desired state. -The ‘client’ DB maintains the mapping of owner to object. The value type of the -client DB is a shared pointer to the singular instance of the owned object. -Once all the owners are gone, and all the shared pointers are destroyed, the -singular instance is also destroyed. - -Each VOM object has some basic behaviour: - update: issue to VPP an update to this object’s state. This could include the - create - sweep: delete the VPP entity – called when the object is destroyed. - replay: issue to VPP all the commands needed to re-programme (VPP restart HA - scenario) - populate: read state from VPP and add it to the OM (client restart HA -scenario) - -The object code is boiler-plate, in some cases (like the ACLs) even template. -The objects are purposefully left as simple, functionality free as possible. - -Communication with VPP is through a ‘queue’ of ‘commands’. A command is -essentially an object wrapper around a VPP binary API call (although we do use -the VAPI C++ bindings too). Commands come in three flavours: - RPC: do this; done. - DUMP: give me all of these things; here you go - EVENT; tell me about these events; here’s one …. Here’s one…. Oh here’s - another….. etc. - -RPC and DUMP commands are handled synchronously. Therefore on return from -OM::write(…) VPP has been issued with the request and responded. EVENTs are -asynchronous and will be delivered to the listeners in a different thread – so -beware!! - -* As such VOM provides some level of insulation to the changes to the VPP - binary API. -** some of the type names are shorten for brevity’s sake. - -*/ -namespace VOM { -/** - * The interface to writing objects into VPP OM. - */ -class OM -{ -public: - /** - * A class providing the RAII pattern for mark and sweep - */ - class mark_n_sweep - { - public: - /** - * Constructor - will call mark on the key - */ - mark_n_sweep(const client_db::key_t& key); - - /** - * Destructor - will call sweep on the key - */ - ~mark_n_sweep(); - - private: - /** - * no copies - */ - mark_n_sweep(const mark_n_sweep& ms) = delete; - - /** - * The client whose state we are guarding. - */ - client_db::key_t m_key; - }; - - /** - * Init - */ - static void init(); - - /** - * populate the OM with state read from HW. - */ - static void populate(const client_db::key_t& key); - - /** - * Mark all state owned by this key as stale - */ - static void mark(const client_db::key_t& key); - - /** - * Sweep all the key's objects that are stale - */ - static void sweep(const client_db::key_t& key); - - /** - * Replay all of the objects to HW. - */ - static void replay(void); - - /** - * Make the State in VPP reflect the expressed desired state. - * But don't call the HW - use this whilst processing dumped - * data from HW - */ - template - static rc_t commit(const client_db::key_t& key, const OBJ& obj) - { - rc_t rc = rc_t::OK; - - HW::disable(); - rc = OM::write(key, obj); - HW::enable(); - - return (rc); - } - - /** - * Make the State in VPP reflect the expressed desired state. - * After processing all the objects in the queue, in FIFO order, - * any remaining state owned by the client_db::key_t is purged. - * This is a template function so the object's update() function is - * always called with the derived type. - */ - template - static rc_t write(const client_db::key_t& key, const OBJ& obj) - { - rc_t rc = rc_t::OK; - - /* - * Find the singular instance another owner may have created. - * this always returns something. - */ - std::shared_ptr inst = obj.singular(); - - /* - * Update the existing object with the new desired state - */ - inst->update(obj); - - /* - * Find if the object already stored on behalf of this key. - * and mark them stale - */ - object_ref_list& objs = m_db->find(key); - - /* - * Iterate through this list to find a matchin' object - * to the one requested. - */ - auto match_ptr = [inst](const object_ref& oref) { - return (inst == oref.obj()); - }; - auto it = std::find_if(objs.begin(), objs.end(), match_ptr); - - if (it != objs.end()) { - /* - * yes, this key already owns this object. - */ - it->clear(); - } else { - /* - * Add the singular instance to the owners list - */ - objs.insert(object_ref(inst)); - } - - return (HW::write()); - } - - /** - * Remove all object in the OM referenced by the key - */ - static void remove(const client_db::key_t& key); - - /** - * Print each of the object in the DB into the stream provided - */ - static void dump(const client_db::key_t& key, std::ostream& os); - - /** - * Print each of the KEYS - */ - static void dump(std::ostream& os); - - /** - * Class definition for listeners to OM events - */ - class listener - { - public: - listener() = default; - virtual ~listener() = default; - - /** - * Handle a populate event - */ - virtual void handle_populate(const client_db::key_t& key) = 0; - - /** - * Handle a replay event - */ - virtual void handle_replay() = 0; - - /** - * Get the sortable Id of the listener - */ - virtual dependency_t order() const = 0; - - /** - * less than operator for set sorting - */ - bool operator<(const listener& listener) const - { - return (order() < listener.order()); - } - }; - - /** - * Register a listener of events - */ - static bool register_listener(listener* listener); - -private: - /** - * Database of object state created for each key - */ - static client_db* m_db; - - /** - * Comparator to keep the pointers to listeners in sorted order - */ - struct listener_comparator_t - { - bool operator()(const listener* l1, const listener* l2) const - { - return (l1->order() < l2->order()); - } - }; - - /** - * convenient typedef for the sorted set of listeners - */ - typedef std::multiset listener_list; - - /** - * The listeners for events - */ - static std::unique_ptr m_listeners; -}; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/pipe.cpp b/extras/vom/vom/pipe.cpp deleted file mode 100644 index 9e10aeb4ea6..00000000000 --- a/extras/vom/vom/pipe.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * 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& -pipe::mk_create_cmd(std::queue& q) -{ - q.push(new pipe_cmds::create_cmd(m_hdl, m_name, m_instance, m_hdl_pair)); - - return (q); -} - -std::queue& -pipe::mk_delete_cmd(std::queue& q) -{ - q.push(new pipe_cmds::delete_cmd(m_hdl, m_hdl_pair)); - - return (q); -} - -std::shared_ptr -pipe::singular() const -{ - return std::dynamic_pointer_cast(singular_i()); -} - -std::shared_ptr -pipe::singular_i() const -{ - return m_db.find_or_add(key(), *this); -} - -std::shared_ptr -pipe::find(const key_t& k) -{ - return std::dynamic_pointer_cast(m_db.find(k)); -} - -std::shared_ptr -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 -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& -pipe::pipe_end::mk_create_cmd(std::queue& q) -{ - return (q); -} - -std::queue& -pipe::pipe_end::mk_delete_cmd(std::queue& 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 cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - std::shared_ptr 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 deleted file mode 100644 index 7da3a1f162a..00000000000 --- a/extras/vom/vom/pipe.hpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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_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 singular() const; - - /** - * Find a subinterface from its key - */ - static std::shared_ptr find(const key_t& k); - - /** - * The interface that is the east end of the pipe - */ - std::shared_ptr 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 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& mk_create_cmd(std::queue& cmds); - virtual std::queue& mk_delete_cmd(std::queue& cmds); - - std::shared_ptr 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 singular_i() const; - - /** - * Virtual functions to construct an interface create commands. - */ - virtual std::queue& mk_create_cmd(std::queue& cmds); - - /** - * Virtual functions to construct an interface delete commands. - */ - virtual std::queue& mk_delete_cmd(std::queue& cmds); - - /** - * the handles that are set during the create command - */ - HW::item m_hdl_pair; - - /** - * The ends of the pipe - */ - std::shared_ptr 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 deleted file mode 100644 index b01ec2f92fc..00000000000 --- a/extras/vom/vom/pipe_cmds.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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& item, - const std::string& name, - uint32_t instance, - HW::item& ends) - : interface::create_cmd(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( - static_cast(payload.pipe_sw_if_index[0]), - static_cast(payload.pipe_sw_if_index[1])), - rc }; - - fulfill(HW::item(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& item, - HW::item& end_pair) - : interface::delete_cmd(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 deleted file mode 100644 index 8c26fd60fd3..00000000000 --- a/extras/vom/vom/pipe_cmds.hpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 - -namespace VOM { -namespace pipe_cmds { -/** - * A functor class that creates an interface - */ -class create_cmd : public interface::create_cmd -{ -public: - /** - * Cstrunctor taking the reference to the parent - * and the sub-interface's VLAN - */ - create_cmd(HW::item& item, - const std::string& name, - uint32_t instance, - HW::item& 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& m_hdl_pair; - uint32_t m_instance; -}; - -/** - * A cmd class that Delete an interface - */ -class delete_cmd : public interface::delete_cmd -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, HW::item& 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& m_hdl_pair; -}; - -/** - * A cmd class that Dumps all the Vpp interfaces - */ -class dump_cmd : public VOM::dump_cmd -{ -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 diff --git a/extras/vom/vom/prefix.cpp b/extras/vom/vom/prefix.cpp deleted file mode 100644 index 45cb6df54c9..00000000000 --- a/extras/vom/vom/prefix.cpp +++ /dev/null @@ -1,592 +0,0 @@ -/* - * 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 -#include - -#include "vom/prefix.hpp" - -namespace VOM { -/* - * Keep this in sync with VPP's fib_protocol_t - */ -const l3_proto_t l3_proto_t::IPV4(0, "ipv4"); -const l3_proto_t l3_proto_t::IPV6(1, "ipv6"); -const l3_proto_t l3_proto_t::MPLS(2, "mpls"); - -l3_proto_t::l3_proto_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -bool -l3_proto_t::is_ipv6() const -{ - return (*this == IPV6); -} - -bool -l3_proto_t::is_ipv4() const -{ - return (*this == IPV4); -} - -const l3_proto_t& -l3_proto_t::from_address(const boost::asio::ip::address& addr) -{ - if (addr.is_v6()) { - return IPV6; - } - - return IPV4; -} - -const nh_proto_t& -l3_proto_t::to_nh_proto() const -{ - if (*this == IPV4) - return nh_proto_t::IPV4; - else if (*this == IPV6) - return nh_proto_t::IPV6; - else if (*this == MPLS) - return nh_proto_t::MPLS; - - return nh_proto_t::IPV4; -} - -std::ostream& -operator<<(std::ostream& os, const l3_proto_t& l3p) -{ - os << l3p.to_string(); - return os; -} - -/* - * Keep this in sync with VPP's dpo_proto_t - */ -const nh_proto_t nh_proto_t::IPV4(0, "ipv4"); -const nh_proto_t nh_proto_t::IPV6(1, "ipv6"); -const nh_proto_t nh_proto_t::MPLS(2, "mpls"); -const nh_proto_t nh_proto_t::ETHERNET(3, "ethernet"); - -nh_proto_t::nh_proto_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const nh_proto_t& -nh_proto_t::from_address(const boost::asio::ip::address& addr) -{ - if (addr.is_v6()) { - return IPV6; - } - - return IPV4; -} - -const ip_dscp_t ip_dscp_t::DSCP_CS0(0, "CS0"); -const ip_dscp_t ip_dscp_t::DSCP_CS1(8, "CS1"); -const ip_dscp_t ip_dscp_t::DSCP_CS2(16, "CS2"); -const ip_dscp_t ip_dscp_t::DSCP_CS3(24, "CS3"); -const ip_dscp_t ip_dscp_t::DSCP_CS4(32, "CS4"); -const ip_dscp_t ip_dscp_t::DSCP_CS5(40, "CS5"); -const ip_dscp_t ip_dscp_t::DSCP_CS6(48, "CS6"); -const ip_dscp_t ip_dscp_t::DSCP_CS7(50, "CS7"); -const ip_dscp_t ip_dscp_t::DSCP_AF11(10, "AF11"); -const ip_dscp_t ip_dscp_t::DSCP_AF12(12, "AF12"); -const ip_dscp_t ip_dscp_t::DSCP_AF13(14, "AF13"); -const ip_dscp_t ip_dscp_t::DSCP_AF21(18, "AF21"); -const ip_dscp_t ip_dscp_t::DSCP_AF22(20, "AF22"); -const ip_dscp_t ip_dscp_t::DSCP_AF23(22, "AF23"); -const ip_dscp_t ip_dscp_t::DSCP_AF31(26, "AF31"); -const ip_dscp_t ip_dscp_t::DSCP_AF32(28, "AF32"); -const ip_dscp_t ip_dscp_t::DSCP_AF33(30, "AF33"); -const ip_dscp_t ip_dscp_t::DSCP_AF41(34, "AF41"); -const ip_dscp_t ip_dscp_t::DSCP_AF42(36, "AF42"); -const ip_dscp_t ip_dscp_t::DSCP_AF43(38, "AF43"); -const ip_dscp_t ip_dscp_t::DSCP_EF(46, "EF"); - -ip_dscp_t::ip_dscp_t(int v, const std::string& s) - : enum_base(v, s) -{ -} -ip_dscp_t::ip_dscp_t(int v) - : enum_base(v, std::to_string(v)) -{ -} - -/** - * The all Zeros prefix - */ -const route::prefix_t route::prefix_t::ZERO("0.0.0.0", 0); -const route::prefix_t route::prefix_t::ZEROv6("::", 0); - -route::prefix_t::prefix_t(const boost::asio::ip::address& addr, uint8_t len) - : m_addr(addr) - , m_len(len) -{ -} - -route::prefix_t::prefix_t(const boost::asio::ip::address& addr) - : m_addr(addr) - , m_len(VOM::mask_width(addr)) -{ -} - -route::prefix_t::prefix_t(const std::string& s, uint8_t len) - : m_addr(boost::asio::ip::address::from_string(s)) - , m_len(len) -{ -} - -route::prefix_t::prefix_t(const prefix_t& o) - : m_addr(o.m_addr) - , m_len(o.m_len) -{ -} - -route::prefix_t::prefix_t() - : m_addr() - , m_len(0) -{ -} - -route::prefix_t::~prefix_t() -{ -} - -route::prefix_t& -route::prefix_t::operator=(const route::prefix_t& o) -{ - m_addr = o.m_addr; - m_len = o.m_len; - - return (*this); -} - -const boost::asio::ip::address& -route::prefix_t::address() const -{ - return (m_addr); -} - -uint8_t -route::prefix_t::mask_width() const -{ - return (m_len); -} - -bool -route::prefix_t::operator<(const route::prefix_t& o) const -{ - if (m_len == o.m_len) { - return (m_addr < o.m_addr); - } else { - return (m_len < o.m_len); - } -} - -bool -route::prefix_t::operator==(const route::prefix_t& o) const -{ - return (m_len == o.m_len && m_addr == o.m_addr); -} - -bool -route::prefix_t::operator!=(const route::prefix_t& o) const -{ - return (!(*this == o)); -} - -std::string -route::prefix_t::to_string() const -{ - std::ostringstream s; - - s << m_addr.to_string() << "/" << std::to_string(m_len); - - return (s.str()); -} - -boost::asio::ip::address -from_bytes(uint8_t is_ip6, const uint8_t* bytes) -{ - boost::asio::ip::address addr; - - if (is_ip6) { - std::array a; - std::copy(bytes, bytes + 16, std::begin(a)); - boost::asio::ip::address_v6 v6(a); - addr = v6; - } else { - std::array a; - std::copy(bytes, bytes + 4, std::begin(a)); - boost::asio::ip::address_v4 v4(a); - addr = v4; - } - - return (addr); -} - -route::prefix_t::prefix_t(uint8_t is_ip6, uint8_t* addr, uint8_t len) - : m_addr(from_bytes(is_ip6, addr)) - , m_len(len) -{ -} -void -to_bytes(const boost::asio::ip::address_v6& addr, uint8_t* array) -{ - memcpy(array, addr.to_bytes().data(), 16); -} - -void -to_bytes(const boost::asio::ip::address_v4& addr, uint8_t* array) -{ - memcpy(array, addr.to_bytes().data(), 4); -} - -void -to_bytes(const boost::asio::ip::address& addr, uint8_t* is_ip6, uint8_t* array) -{ - if (addr.is_v6()) { - *is_ip6 = 1; - to_bytes(addr.to_v6(), array); - } else { - *is_ip6 = 0; - to_bytes(addr.to_v4(), array); - } -} - -uint32_t -mask_width(const boost::asio::ip::address& addr) -{ - if (addr.is_v6()) { - return 128; - } - return 32; -} - -void -route::prefix_t::to_vpp(uint8_t* is_ip6, uint8_t* addr, uint8_t* len) const -{ - *len = m_len; - to_bytes(m_addr, is_ip6, addr); -} - -l3_proto_t -route::prefix_t::l3_proto() const -{ - if (m_addr.is_v6()) { - return (l3_proto_t::IPV6); - } else { - return (l3_proto_t::IPV4); - } - - return (l3_proto_t::IPV4); -} - -std::ostream& -operator<<(std::ostream& os, const route::prefix_t& pfx) -{ - os << pfx.to_string(); - - return (os); -} - -boost::asio::ip::address_v4 -operator|(const boost::asio::ip::address_v4& addr1, - const boost::asio::ip::address_v4& addr2) -{ - uint32_t a; - a = addr1.to_ulong() | addr2.to_ulong(); - boost::asio::ip::address_v4 addr(a); - return (addr); -} - -boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4& addr1, - const boost::asio::ip::address_v4& addr2) -{ - uint32_t a; - a = addr1.to_ulong() & addr2.to_ulong(); - boost::asio::ip::address_v4 addr(a); - return (addr); -} - -boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1) -{ - uint32_t a; - a = ~addr1.to_ulong(); - boost::asio::ip::address_v4 addr(a); - return (addr); -} - -boost::asio::ip::address_v6 -operator|(const boost::asio::ip::address_v6& addr1, - const boost::asio::ip::address_v6& addr2) -{ - boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes(); - boost::asio::ip::address_v6::bytes_type b2 = addr2.to_bytes(); - - for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0; - ii < b1.max_size(); ii++) { - b1[ii] |= b2[ii]; - } - - boost::asio::ip::address_v6 addr(b1); - return (addr); -} - -boost::asio::ip::address_v6 operator&(const boost::asio::ip::address_v6& addr1, - const boost::asio::ip::address_v6& addr2) -{ - boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes(); - boost::asio::ip::address_v6::bytes_type b2 = addr2.to_bytes(); - - for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0; - ii < b1.max_size(); ii++) { - b1[ii] &= b2[ii]; - } - - boost::asio::ip::address_v6 addr(b1); - return (addr); -} - -boost::asio::ip::address_v6 operator~(const boost::asio::ip::address_v6& addr1) -{ - boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes(); - - for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0; - ii < b1.max_size(); ii++) { - b1[ii] = ~b1[ii]; - } - - boost::asio::ip::address_v6 addr(b1); - return (addr); -} -boost::asio::ip::address -operator|(const boost::asio::ip::address& addr1, - const boost::asio::ip::address& addr2) -{ - if (addr1.is_v6()) - return (addr1.to_v6() | addr2.to_v6()); - else - return (addr1.to_v4() | addr2.to_v4()); -} - -boost::asio::ip::address operator&(const boost::asio::ip::address& addr1, - const boost::asio::ip::address& addr2) -{ - if (addr1.is_v6()) - return (addr1.to_v6() & addr2.to_v6()); - else - return (addr1.to_v4() & addr2.to_v4()); -} - -boost::asio::ip::address operator~(const boost::asio::ip::address& addr1) -{ - if (addr1.is_v6()) - return ~(addr1.to_v6()); - else - return ~(addr1.to_v4()); -} - -boost::asio::ip::address -route::prefix_t::mask() const -{ - if (m_addr.is_v6()) { - boost::asio::ip::address_v6::bytes_type b = - boost::asio::ip::address_v6::any().to_bytes(); - - uint8_t n_bits = mask_width(); - - for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0; - ii < b.max_size(); ii++) { - for (int8_t bit = 7; bit >= 0 && n_bits; bit--) { - b[ii] |= (1 << bit); - n_bits--; - } - if (!n_bits) - break; - } - - return (boost::asio::ip::address_v6(b)); - } else { - uint32_t a; - - a = ~((1 << (32 - mask_width())) - 1); - - return (boost::asio::ip::address_v4(a)); - } -} - -route::prefix_t -route::prefix_t::low() const -{ - prefix_t pfx(*this); - - pfx.m_addr = pfx.m_addr & pfx.mask(); - - return (pfx); -} - -route::prefix_t -route::prefix_t::high() const -{ - prefix_t pfx(*this); - - pfx.m_addr = pfx.m_addr | ~pfx.mask(); - - return (pfx); -} - -/** - * The all Zeros prefix - */ -const route::mprefix_t route::mprefix_t::ZERO; -const route::mprefix_t route::mprefix_t::ZEROv6; - -route::mprefix_t::mprefix_t(const boost::asio::ip::address& gaddr, uint8_t len) - : m_gaddr(gaddr) - , m_saddr() - , m_len(len) -{ -} - -route::mprefix_t::mprefix_t(const boost::asio::ip::address& gaddr) - : m_gaddr(gaddr) - , m_saddr() - , m_len(VOM::mask_width(gaddr)) -{ -} - -route::mprefix_t::mprefix_t(const boost::asio::ip::address& saddr, - const boost::asio::ip::address& gaddr) - : m_gaddr(gaddr) - , m_saddr(saddr) - , m_len(2 * VOM::mask_width(gaddr)) -{ -} - -route::mprefix_t::mprefix_t(const boost::asio::ip::address& saddr, - const boost::asio::ip::address& gaddr, - uint16_t len) - : m_gaddr(gaddr) - , m_saddr(saddr) - , m_len(len) -{ -} - -route::mprefix_t::mprefix_t(const mprefix_t& o) - : m_gaddr(o.m_gaddr) - , m_saddr(o.m_saddr) - , m_len(o.m_len) -{ -} -route::mprefix_t::mprefix_t() - : m_gaddr() - , m_saddr() - , m_len(0) -{ -} - -route::mprefix_t::~mprefix_t() -{ -} - -const boost::asio::ip::address& -route::mprefix_t::grp_address() const -{ - return (m_gaddr); -} - -const boost::asio::ip::address& -route::mprefix_t::src_address() const -{ - return (m_saddr); -} - -uint8_t -route::mprefix_t::mask_width() const -{ - return (m_len); -} - -l3_proto_t -route::mprefix_t::l3_proto() const -{ - if (m_gaddr.is_v6()) { - return (l3_proto_t::IPV6); - } else { - return (l3_proto_t::IPV4); - } - - return (l3_proto_t::IPV4); -} - -route::mprefix_t& -route::mprefix_t::operator=(const route::mprefix_t& o) -{ - m_gaddr = o.m_gaddr; - m_saddr = o.m_saddr; - m_len = o.m_len; - - return (*this); -} - -bool -route::mprefix_t::operator<(const route::mprefix_t& o) const -{ - if (m_len == o.m_len) { - if (m_saddr == o.m_saddr) - return (m_gaddr < o.m_gaddr); - else - return (m_saddr < o.m_saddr); - } else { - return (m_len < o.m_len); - } -} - -bool -route::mprefix_t::operator==(const route::mprefix_t& o) const -{ - return (m_len == o.m_len && m_gaddr == o.m_gaddr && m_saddr == o.m_saddr); -} - -bool -route::mprefix_t::operator!=(const route::mprefix_t& o) const -{ - return (!(*this == o)); -} - -std::string -route::mprefix_t::to_string() const -{ - std::ostringstream s; - - s << "(" << m_saddr.to_string() << "," << m_gaddr.to_string() << "/" - << std::to_string(m_len) << ")"; - - return (s.str()); -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/prefix.hpp b/extras/vom/vom/prefix.hpp deleted file mode 100644 index fada1d3e274..00000000000 --- a/extras/vom/vom/prefix.hpp +++ /dev/null @@ -1,414 +0,0 @@ -/* - * 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_PREFIX_H__ -#define __VOM_PREFIX_H__ - -#include "vom/enum_base.hpp" -#include - -namespace VOM { -/** - * Types belonging to Routing - */ - -/** - * A next-hop protocol describes the protocol of a peer to which packets - * are sent after matching a route. - */ -class nh_proto_t : public enum_base -{ -public: - const static nh_proto_t IPV4; - const static nh_proto_t IPV6; - const static nh_proto_t MPLS; - const static nh_proto_t ETHERNET; - - static const nh_proto_t& from_address(const boost::asio::ip::address& addr); - -private: - /** - * Private constructor taking the value and the string name - */ - nh_proto_t(int v, const std::string& s); -}; - -/** - * An L3 protocol can be used to construct a prefix that is used - * to match packets are part of a route. - */ -class l3_proto_t : public enum_base -{ -public: - const static l3_proto_t IPV4; - const static l3_proto_t IPV6; - const static l3_proto_t MPLS; - - bool is_ipv4() const; - bool is_ipv6() const; - - static const l3_proto_t& from_address(const boost::asio::ip::address& addr); - - const nh_proto_t& to_nh_proto() const; - -private: - /** - * Private constructor taking the value and the string name - */ - l3_proto_t(int v, const std::string& s); -}; - -/** - * Ostream output for l3_proto_t - */ -std::ostream& operator<<(std::ostream& os, const l3_proto_t& l3p); - -/** - * IP DSCP values - */ -class ip_dscp_t : public enum_base -{ -public: - /* unfortunately some of the CSX names are defined in terminos.h - * as macros, hence the longer names */ - const static ip_dscp_t DSCP_CS0; - const static ip_dscp_t DSCP_CS1; - const static ip_dscp_t DSCP_CS2; - const static ip_dscp_t DSCP_CS3; - const static ip_dscp_t DSCP_CS4; - const static ip_dscp_t DSCP_CS5; - const static ip_dscp_t DSCP_CS6; - const static ip_dscp_t DSCP_CS7; - const static ip_dscp_t DSCP_AF11; - const static ip_dscp_t DSCP_AF12; - const static ip_dscp_t DSCP_AF13; - const static ip_dscp_t DSCP_AF21; - const static ip_dscp_t DSCP_AF22; - const static ip_dscp_t DSCP_AF23; - const static ip_dscp_t DSCP_AF31; - const static ip_dscp_t DSCP_AF32; - const static ip_dscp_t DSCP_AF33; - const static ip_dscp_t DSCP_AF41; - const static ip_dscp_t DSCP_AF42; - const static ip_dscp_t DSCP_AF43; - const static ip_dscp_t DSCP_EF; - - /** - * Constructor allows the creation of any DSCP value - */ - ip_dscp_t(int v); - -private: - ip_dscp_t(int v, const std::string& s); -}; - -namespace route { -/** - * type def the table-id - */ -typedef uint32_t table_id_t; - -/** - * The table-id for the default table - */ -const static table_id_t DEFAULT_TABLE = 0; - -/** - * A prefix defintion. Address + length - */ -class prefix_t -{ -public: - /** - * Default Constructor - creates ::/0 - */ - prefix_t(); - /** - * Constructor with address and length - */ - prefix_t(const boost::asio::ip::address& addr, uint8_t len); - /** - * Constructor with just the address, this creates a - * host prefix - */ - prefix_t(const boost::asio::ip::address& addr); - - /** - * Constructor with string and length - */ - prefix_t(const std::string& s, uint8_t len); - - /** - * Copy Constructor - */ - prefix_t(const prefix_t&); - - /** - * Constructor with VPP API prefix representation - */ - prefix_t(uint8_t is_ip6, uint8_t* addr, uint8_t len); - /** - * Destructor - */ - ~prefix_t(); - - /** - * Get the address - */ - const boost::asio::ip::address& address() const; - - /** - * Get the network mask width - */ - uint8_t mask_width() const; - - /** - * Assignement - */ - prefix_t& operator=(const prefix_t&); - - /** - * Less than operator - */ - bool operator<(const prefix_t& o) const; - - /** - * equals operator - */ - bool operator==(const prefix_t& o) const; - - /** - * not equal opartor - */ - bool operator!=(const prefix_t& o) const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * The all Zeros prefix - */ - const static prefix_t ZERO; - - /** - * The all Zeros v6 prefix - */ - const static prefix_t ZEROv6; - - /** - * Convert the prefix into VPP API parameters - */ - void to_vpp(uint8_t* is_ip6, uint8_t* addr, uint8_t* len) const; - - /** - * Return a address representation of the mask, e.g. 255.255.0.0 - */ - boost::asio::ip::address mask() const; - - /** - * get the lowest address in the prefix - */ - prefix_t low() const; - - /** - * Get the highest address in the prefix - */ - prefix_t high() const; - - /** - * Get the L3 protocol - */ - l3_proto_t l3_proto() const; - -private: - /** - * The address - */ - boost::asio::ip::address m_addr; - - /** - * The prefix length - */ - uint8_t m_len; -}; - -/** -* A prefix defintion. Address + length -*/ -class mprefix_t -{ -public: - /** - * Default Constructor - creates ::/0 - */ - mprefix_t(); - /** - * Constructor for (S,G) - */ - mprefix_t(const boost::asio::ip::address& saddr, - const boost::asio::ip::address& gaddr); - /* - * Constructor for (*,G) - */ - mprefix_t(const boost::asio::ip::address& gaddr); - - /* - * Constructor for (*,G/n) - */ - mprefix_t(const boost::asio::ip::address& gaddr, uint8_t len); - - /** - *Constructor for (S,G) - */ - mprefix_t(const boost::asio::ip::address& saddr, - const boost::asio::ip::address& gaddr, - uint16_t len); - - /** - * Copy Constructor - */ - mprefix_t(const mprefix_t&); - - /** - * Destructor - */ - ~mprefix_t(); - - /** - * Get the address - */ - const boost::asio::ip::address& grp_address() const; - const boost::asio::ip::address& src_address() const; - - /** - * Get the network mask width - */ - uint8_t mask_width() const; - - /** - * Assignement - */ - mprefix_t& operator=(const mprefix_t&); - - /** - * Less than operator - */ - bool operator<(const mprefix_t& o) const; - - /** - * equals operator - */ - bool operator==(const mprefix_t& o) const; - - /** - * not equal opartor - */ - bool operator!=(const mprefix_t& o) const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * The all Zeros prefix - */ - const static mprefix_t ZERO; - - /** - * The all Zeros v6 prefix - */ - const static mprefix_t ZEROv6; - - /** - * Get the L3 protocol - */ - l3_proto_t l3_proto() const; - -private: - /** - * The address - */ - boost::asio::ip::address m_gaddr; - boost::asio::ip::address m_saddr; - - /** - * The prefix length - */ - uint8_t m_len; -}; - -}; // namespace route - -boost::asio::ip::address_v4 operator|(const boost::asio::ip::address_v4& addr1, - const boost::asio::ip::address_v4& addr2); - -boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4& addr1, - const boost::asio::ip::address_v4& addr2); - -boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1); - -boost::asio::ip::address_v6 operator|(const boost::asio::ip::address_v6& addr1, - const boost::asio::ip::address_v6& addr2); - -boost::asio::ip::address_v6 operator&(const boost::asio::ip::address_v6& addr1, - const boost::asio::ip::address_v6& addr2); - -boost::asio::ip::address_v6 operator~(const boost::asio::ip::address_v6& addr1); - -boost::asio::ip::address operator|(const boost::asio::ip::address& addr1, - const boost::asio::ip::address& addr2); - -boost::asio::ip::address operator&(const boost::asio::ip::address& addr1, - const boost::asio::ip::address& addr2); - -boost::asio::ip::address operator~(const boost::asio::ip::address& addr1); - -/** - * Ostream printer for prefix_t - */ -std::ostream& operator<<(std::ostream& os, const route::prefix_t& pfx); - -/** - * Convert a boost address into a VPP bytes string - */ -void to_bytes(const boost::asio::ip::address& addr, - uint8_t* is_ip6, - uint8_t* array); -void to_bytes(const boost::asio::ip::address_v4& addr, uint8_t* array); -void to_bytes(const boost::asio::ip::address_v6& addr, uint8_t* array); - -/** - * Get the prefix mask length of a host route from the boost address - */ -uint32_t mask_width(const boost::asio::ip::address& addr); - -/** - * Convert a VPP byte stinrg into a boost addresss - */ -boost::asio::ip::address from_bytes(uint8_t is_ip6, const uint8_t* array); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_map.cpp b/extras/vom/vom/qos_map.cpp deleted file mode 100644 index 9e382ec2f55..00000000000 --- a/extras/vom/vom/qos_map.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_map.hpp" -#include "vom/api_types.hpp" -#include "vom/qos_map_cmds.hpp" -#include "vom/qos_types_api.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace QoS { - -singular_db map::m_db; - -map::event_handler map::m_evh; - -map::map(uint32_t id, const outputs_t& o) - : m_config(false) - , m_id(id) - , m_outputs(o) -{ -} - -map::map(const map& r) - : m_config(r.m_config) - , m_id(r.m_id) - , m_outputs(r.m_outputs) -{ -} - -map::~map() -{ - sweep(); - m_db.release(key(), this); -} - -const map::key_t -map::key() const -{ - return m_id; -} - -const uint32_t -map::id() const -{ - return m_id; -} - -bool -map::operator==(const map& m) const -{ - return (key() == m.key() && m_outputs == m.m_outputs); -} - -void -map::sweep() -{ - if (m_config) { - HW::enqueue(new map_cmds::delete_cmd(m_config, m_id)); - } - HW::write(); -} - -void -map::replay() -{ - if (m_config) { - HW::enqueue(new map_cmds::create_cmd(m_config, m_id, m_outputs)); - } -} - -std::string -map::to_string() const -{ - std::ostringstream s; - s << "qos-map:" << (int)m_id; - - return (s.str()); -} - -void -map::update(const map& m) -{ - m_outputs = m.m_outputs; - - if (rc_t::OK != m_config.rc()) { - HW::enqueue(new map_cmds::create_cmd(m_config, m_id, m_outputs)); - } -} - -std::shared_ptr -map::find_or_add(const map& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -map::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -map::singular() const -{ - return find_or_add(*this); -} - -void -map::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -map::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "qos-map" }, "QoS Map", this); -} - -void -map::event_handler::handle_replay() -{ - m_db.replay(); -} - -static const map::outputs_t -from_api(vapi_type_qos_egress_map_row rows[4]) -{ - map::outputs_t o; - - for (uint32_t ii = 0; ii < 4; ii++) { - std::copy(std::begin(rows[ii].outputs), std::end(rows[ii].outputs), - o[ii].begin()); - } - - return o; -} - -void -map::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& rr : *cmd) { - auto& payload = rr.get_payload(); - - map qr(payload.map.id, from_api(payload.map.rows)); - OM::commit(key, qr); - } -} - -dependency_t -map::event_handler::order() const -{ - return (dependency_t::TABLE); -} - -void -map::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_map.hpp b/extras/vom/vom/qos_map.hpp deleted file mode 100644 index 8d235c4994b..00000000000 --- a/extras/vom/vom/qos_map.hpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_MAP_H__ -#define __VOM_QOS_MAP_H__ - -#include - -#include "vom/interface.hpp" -#include "vom/qos_types.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * Types belonging to QoS - */ -namespace QoS { - -/** - * A QoS map determines how value from one source are translated to - * values of another source - */ -class map : public object_base -{ -public: - typedef std::array, 4> outputs_t; - - map(uint32_t id, const outputs_t& o); - map(const map& r); - - ~map(); - - typedef uint32_t key_t; - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * Return the object's ID - */ - const key_t id() const; - - /** - * comparison operator - */ - bool operator==(const map& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const map& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const map& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class VOM::OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the config. The bool representing the - * do/don't configured/unconfigured. - */ - HW::item m_config; - - /** - * unique ID of the MAP. - */ - uint32_t m_id; - - /** - * outputs from the translation - */ - outputs_t m_outputs; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -}; // namesapce QoS - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_map_cmds.cpp b/extras/vom/vom/qos_map_cmds.cpp deleted file mode 100644 index d9054a89fb2..00000000000 --- a/extras/vom/vom/qos_map_cmds.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_map_cmds.hpp" -#include "vom/qos_types_api.hpp" - -namespace VOM { -namespace QoS { -namespace map_cmds { - -static void -to_api(const map::outputs_t& o, vapi_type_qos_egress_map_row rows[4]) -{ - for (uint32_t ii = 0; ii < 4; ii++) { - std::copy(o[ii].begin(), o[ii].end(), std::begin(rows[ii].outputs)); - } -} - -create_cmd::create_cmd(HW::item& item, - uint32_t id, - const map::outputs_t& o) - : rpc_cmd(item) - , m_id(id) - , m_outputs(o) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return (m_id == other.m_id && m_outputs == other.m_outputs); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.map.id = m_id; - to_api(m_outputs, payload.map.rows); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "qos-map-create: " << m_hw_item.to_string() << " map:" << m_id; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, uint32_t id) - : rpc_cmd(item) - , m_id(id) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_hw_item == other.m_hw_item && m_id == other.m_id); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.map.id = m_id; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "qos-map-delete: " << m_hw_item.to_string() << " map:" << m_id; - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("qos-map-dump"); -} - -}; // namespace map_cmds -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_map_cmds.hpp b/extras/vom/vom/qos_map_cmds.hpp deleted file mode 100644 index 8321894d532..00000000000 --- a/extras/vom/vom/qos_map_cmds.hpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_MAP_CMDS_H__ -#define __VOM_QOS_MAP_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/qos_map.hpp" - -#include - -namespace VOM { -namespace QoS { -namespace map_cmds { - -/** - * A command class that creates or updates the GBP endpoint - */ -class create_cmd : public rpc_cmd, vapi::Qos_egress_map_update> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, uint32_t id, const map::outputs_t& o); - - /** - * 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; - -private: - uint32_t m_id; - const map::outputs_t& m_outputs; -}; - -/** - * A cmd class that deletes a GBP endpoint - */ -class delete_cmd : public rpc_cmd, vapi::Qos_egress_map_update> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, uint32_t id); - - /** - * 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: - uint32_t m_id; -}; - -/** - * A cmd class that Dumps all the GBP endpoints - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace map_cmds -}; // namespace Qos -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_mark.cpp b/extras/vom/vom/qos_mark.cpp deleted file mode 100644 index feb889380ff..00000000000 --- a/extras/vom/vom/qos_mark.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_mark.hpp" -#include "vom/api_types.hpp" -#include "vom/qos_mark_cmds.hpp" -#include "vom/qos_types_api.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace QoS { - -singular_db mark::m_db; - -mark::event_handler mark::m_evh; - -mark::mark(const interface& itf, const map& m, const source_t& src) - : m_config(false) - , m_itf(itf.singular()) - , m_map(m.singular()) - , m_src(src) -{ -} - -mark::mark(const mark& m) - : m_config(m.m_config) - , m_itf(m.m_itf) - , m_map(m.m_map) - , m_src(m.m_src) -{ -} - -mark::~mark() -{ - sweep(); - m_db.release(key(), this); -} - -const mark::key_t -mark::key() const -{ - return (std::make_pair(m_itf->key(), m_src)); -} - -bool -mark::operator==(const mark& m) const -{ - return (key() == m.key() && m_map->id() == m.m_map->id()); -} - -void -mark::sweep() -{ - if (m_config) { - HW::enqueue(new mark_cmds::delete_cmd(m_config, m_itf->handle(), m_src)); - } - HW::write(); -} - -void -mark::replay() -{ - if (m_config) { - HW::enqueue( - new mark_cmds::create_cmd(m_config, m_itf->handle(), m_map->id(), m_src)); - } -} - -std::string -mark::to_string() const -{ - std::ostringstream s; - s << "qos-mark:[" << m_itf->to_string() << ", map:" << m_map->id() - << ", src:" << m_src.to_string(); - - return (s.str()); -} - -void -mark::update(const mark& r) -{ - if (rc_t::OK != m_config.rc()) { - HW::enqueue( - new mark_cmds::create_cmd(m_config, m_itf->handle(), m_map->id(), m_src)); - } -} - -std::shared_ptr -mark::find_or_add(const mark& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -mark::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -mark::singular() const -{ - return find_or_add(*this); -} - -void -mark::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -mark::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "qos-mark" }, "QoS Mark", this); -} - -void -mark::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -mark::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& rr : *cmd) { - auto& payload = rr.get_payload(); - - std::shared_ptr itf = interface::find(payload.mark.sw_if_index); - std::shared_ptr map = map::find(payload.mark.map_id); - - VOM_LOG(log_level_t::DEBUG) << "data: " << payload.mark.sw_if_index; - - if (itf && map) { - mark qm(*itf, *map, from_api(payload.mark.output_source)); - OM::commit(key, qm); - - VOM_LOG(log_level_t::DEBUG) << "read: " << qm.to_string(); - } else { - VOM_LOG(log_level_t::ERROR) - << "no interface or map:" << payload.mark.sw_if_index << ", " - << payload.mark.map_id; - } - } -} - -dependency_t -mark::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -mark::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_mark.hpp b/extras/vom/vom/qos_mark.hpp deleted file mode 100644 index 63fec8456fe..00000000000 --- a/extras/vom/vom/qos_mark.hpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_MARK_H__ -#define __VOM_QOS_MARK_H__ - -#include - -#include "vom/interface.hpp" -#include "vom/qos_map.hpp" -#include "vom/qos_types.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -namespace QoS { - -/** - * The marking of packets with QoS bits as they egress an interface - */ -class mark : public object_base -{ -public: - mark(const interface& i, const map& m, const source_t& source); - mark(const mark& r); - - ~mark(); - - typedef std::pair key_t; - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const mark& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const mark& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const mark& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class VOM::OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the config. The bool representing the - * do/don't configured/unconfigured. - */ - HW::item m_config; - - /** - * The interface the mark applies to - */ - std::shared_ptr m_itf; - - /** - * The map the marking uses - */ - std::shared_ptr m_map; - - /** - * QoS source to mark from - */ - source_t m_src; - - /** - * A map of all QoS Markers - */ - static singular_db m_db; -}; - -}; // namesapce QoS - -std::ostream& operator<<(std::ostream& os, const QoS::mark::key_t& key); - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_mark_cmds.cpp b/extras/vom/vom/qos_mark_cmds.cpp deleted file mode 100644 index 50220b33325..00000000000 --- a/extras/vom/vom/qos_mark_cmds.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_mark_cmds.hpp" -#include "vom/qos_types_api.hpp" - -namespace VOM { -namespace QoS { -namespace mark_cmds { - -create_cmd::create_cmd(HW::item& item, - const handle_t& itf, - uint32_t map_id, - const source_t& s) - : rpc_cmd(item) - , m_itf(itf) - , m_map_id(map_id) - , m_src(s) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_src == other.m_src) && - (m_map_id == other.m_map_id)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.mark.sw_if_index = m_itf.value(); - payload.mark.map_id = m_map_id; - payload.mark.output_source = to_api(m_src); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "qos-mark-create: " << m_hw_item.to_string() << " itf:" << m_itf - << " src:" << m_src.to_string() << " map-id:" << m_map_id; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - const handle_t& itf, - const source_t& s) - : rpc_cmd(item) - , m_itf(itf) - , m_src(s) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_hw_item == other.m_hw_item && m_itf == other.m_itf && - m_src == other.m_src); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.mark.sw_if_index = m_itf.value(); - payload.mark.output_source = to_api(m_src); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "qos-mark-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("qos-mark-dump"); -} - -}; // namespace mark_cmds -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_mark_cmds.hpp b/extras/vom/vom/qos_mark_cmds.hpp deleted file mode 100644 index 976fddc4ea7..00000000000 --- a/extras/vom/vom/qos_mark_cmds.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_MARK_CMDS_H__ -#define __VOM_QOS_MARK_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/qos_mark.hpp" - -#include - -namespace VOM { -namespace QoS { -namespace mark_cmds { - -/** - * A command class that creates or updates the GBP endpoint - */ -class create_cmd : public rpc_cmd, vapi::Qos_mark_enable_disable> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - const handle_t& itf, - uint32_t map_id, - const source_t& src); - - /** - * 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; - -private: - handle_t m_itf; - uint32_t m_map_id; - const source_t& m_src; -}; - -/** - * A cmd class that deletes a GBP endpoint - */ -class delete_cmd : public rpc_cmd, vapi::Qos_mark_enable_disable> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, const handle_t& itf, const source_t& src); - - /** - * 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: - const handle_t m_itf; - const source_t& m_src; -}; - -/** - * A cmd class that Dumps all the GBP endpoints - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace mark_cmds -}; // namespace Qos -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_record.cpp b/extras/vom/vom/qos_record.cpp deleted file mode 100644 index d56295ca1c4..00000000000 --- a/extras/vom/vom/qos_record.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_record.hpp" -#include "vom/api_types.hpp" -#include "vom/qos_record_cmds.hpp" -#include "vom/qos_types_api.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace QoS { - -singular_db record::m_db; - -record::event_handler record::m_evh; - -record::record(const interface& itf, const source_t& src) - : m_config(false) - , m_itf(itf.singular()) - , m_src(src) -{ -} - -record::record(const record& r) - : m_config(r.m_config) - , m_itf(r.m_itf) - , m_src(r.m_src) -{ -} - -record::~record() -{ - sweep(); - m_db.release(key(), this); -} - -const record::key_t -record::key() const -{ - return (std::make_pair(m_itf->key(), m_src)); -} - -bool -record::operator==(const record& r) const -{ - return (key() == r.key()); -} - -void -record::sweep() -{ - if (m_config) { - HW::enqueue(new record_cmds::delete_cmd(m_config, m_itf->handle(), m_src)); - } - HW::write(); -} - -void -record::replay() -{ - if (m_config) { - HW::enqueue(new record_cmds::create_cmd(m_config, m_itf->handle(), m_src)); - } -} - -std::string -record::to_string() const -{ - std::ostringstream s; - s << "qos-record:[" << m_itf->to_string() << ", src:" << m_src.to_string(); - - return (s.str()); -} - -void -record::update(const record& r) -{ - if (rc_t::OK != m_config.rc()) { - HW::enqueue(new record_cmds::create_cmd(m_config, m_itf->handle(), m_src)); - } -} - -std::shared_ptr -record::find_or_add(const record& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -record::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -record::singular() const -{ - return find_or_add(*this); -} - -void -record::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -record::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "qos-record" }, "QoS Record", this); -} - -void -record::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -record::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& rr : *cmd) { - auto& payload = rr.get_payload(); - - std::shared_ptr itf = - interface::find(payload.record.sw_if_index); - - VOM_LOG(log_level_t::DEBUG) << "data: " << payload.record.sw_if_index; - - if (itf) { - record qr(*itf, from_api(payload.record.input_source)); - OM::commit(key, qr); - - VOM_LOG(log_level_t::DEBUG) << "read: " << qr.to_string(); - } else { - VOM_LOG(log_level_t::ERROR) << "no interface:" - << payload.record.sw_if_index; - } - } -} - -dependency_t -record::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -record::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -}; // namespace QoS - -std::ostream& -operator<<(std::ostream& os, const QoS::record::key_t& key) -{ - os << key.first << "," << key.second; - - return os; -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_record.hpp b/extras/vom/vom/qos_record.hpp deleted file mode 100644 index d74413f9293..00000000000 --- a/extras/vom/vom/qos_record.hpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_RECORD_H__ -#define __VOM_QOS_RECORD_H__ - -#include - -#include "vom/interface.hpp" -#include "vom/qos_types.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * Types belonging to QoS - */ -namespace QoS { - -class record : public object_base -{ -public: - record(const interface& i, const source_t& source); - record(const record& r); - - ~record(); - - typedef std::pair key_t; - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const record& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const record& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const record& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class VOM::OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the config. The bool representing the - * do/don't configured/unconfigured. - */ - HW::item m_config; - - /** - * The interface the endpoint is attached to. - */ - std::shared_ptr m_itf; - - /** - * QoS source to record from - */ - source_t m_src; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -}; // namesapce QoS - -std::ostream& operator<<(std::ostream& os, const QoS::record::key_t& key); - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_record_cmds.cpp b/extras/vom/vom/qos_record_cmds.cpp deleted file mode 100644 index a425187d63c..00000000000 --- a/extras/vom/vom/qos_record_cmds.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_record_cmds.hpp" -#include "vom/qos_types_api.hpp" - -namespace VOM { -namespace QoS { -namespace record_cmds { - -create_cmd::create_cmd(HW::item& item, - const handle_t& itf, - const source_t& s) - : rpc_cmd(item) - , m_itf(itf) - , m_src(s) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_src == other.m_src)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.record.sw_if_index = m_itf.value(); - payload.record.input_source = to_api(m_src); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "qos-record-create: " << m_hw_item.to_string() << " itf:" << m_itf - << " src:" << m_src.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - const handle_t& itf, - const source_t& s) - : rpc_cmd(item) - , m_itf(itf) - , m_src(s) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_hw_item == other.m_hw_item && m_itf == other.m_itf && - m_src == other.m_src); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.record.sw_if_index = m_itf.value(); - payload.record.input_source = to_api(m_src); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "qos-record-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("qos-record-dump"); -} - -}; // namespace record_cmds -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_record_cmds.hpp b/extras/vom/vom/qos_record_cmds.hpp deleted file mode 100644 index bf98e5da824..00000000000 --- a/extras/vom/vom/qos_record_cmds.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_RECORD_CMDS_H__ -#define __VOM_QOS_RECORD_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/qos_record.hpp" - -#include - -namespace VOM { -namespace QoS { -namespace record_cmds { - -/** - * A command class that creates or updates the GBP endpoint - */ -class create_cmd - : public rpc_cmd, vapi::Qos_record_enable_disable> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, const handle_t& itf, const source_t& src); - - /** - * 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; - -private: - const handle_t m_itf; - const source_t& m_src; -}; - -/** - * A cmd class that deletes a GBP endpoint - */ -class delete_cmd - : public rpc_cmd, vapi::Qos_record_enable_disable> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, const handle_t& itf, const source_t& src); - - /** - * 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: - const handle_t m_itf; - const source_t& m_src; -}; - -/** - * A cmd class that Dumps all the GBP endpoints - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace record_cmds -}; // namespace Qos -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_store.cpp b/extras/vom/vom/qos_store.cpp deleted file mode 100644 index 08c2586557d..00000000000 --- a/extras/vom/vom/qos_store.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_store.hpp" -#include "vom/api_types.hpp" -#include "vom/qos_store_cmds.hpp" -#include "vom/qos_types_api.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace QoS { - -singular_db store::m_db; - -store::event_handler store::m_evh; - -store::store(const interface& itf, const source_t& src, bits_t value) - : m_config(false) - , m_itf(itf.singular()) - , m_src(src) - , m_value(value) -{ -} - -store::store(const store& s) - : m_config(s.m_config) - , m_itf(s.m_itf) - , m_src(s.m_src) - , m_value(s.m_value) -{ -} - -store::~store() -{ - sweep(); - m_db.release(key(), this); -} - -const store::key_t -store::key() const -{ - return (std::make_pair(m_itf->key(), m_src)); -} - -bool -store::operator==(const store& r) const -{ - return (key() == r.key()); -} - -void -store::sweep() -{ - if (m_config) { - HW::enqueue(new store_cmds::delete_cmd(m_config, m_itf->handle(), m_src)); - } - HW::write(); -} - -void -store::replay() -{ - if (m_config) { - HW::enqueue( - new store_cmds::create_cmd(m_config, m_itf->handle(), m_src, m_value)); - } -} - -std::string -store::to_string() const -{ - std::ostringstream s; - s << "qos-store:[" << m_itf->to_string() << ", src:" << m_src.to_string() - << ", value:" << static_cast(m_value); - - return (s.str()); -} - -void -store::update(const store& r) -{ - if (rc_t::OK != m_config.rc()) { - HW::enqueue( - new store_cmds::create_cmd(m_config, m_itf->handle(), m_src, m_value)); - } -} - -std::shared_ptr -store::find_or_add(const store& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -store::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -store::singular() const -{ - return find_or_add(*this); -} - -void -store::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -store::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "qos-store" }, "QoS Store", this); -} - -void -store::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -store::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& rr : *cmd) { - auto& payload = rr.get_payload(); - - std::shared_ptr itf = interface::find(payload.store.sw_if_index); - - VOM_LOG(log_level_t::DEBUG) << "data: " << payload.store.sw_if_index; - - if (itf) { - store qr(*itf, from_api(payload.store.input_source), payload.store.value); - OM::commit(key, qr); - - VOM_LOG(log_level_t::DEBUG) << "read: " << qr.to_string(); - } else { - VOM_LOG(log_level_t::ERROR) << "no interface:" - << payload.store.sw_if_index; - } - } -} - -dependency_t -store::event_handler::order() const -{ - return (dependency_t::ENTRY); -} - -void -store::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -}; // namespace QoS - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_store.hpp b/extras/vom/vom/qos_store.hpp deleted file mode 100644 index b68831497ab..00000000000 --- a/extras/vom/vom/qos_store.hpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_STORE_H__ -#define __VOM_QOS_STORE_H__ - -#include - -#include "vom/interface.hpp" -#include "vom/qos_types.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * Types belonging to QoS - */ -namespace QoS { - -class store : public object_base -{ -public: - store(const interface& i, const source_t& source, bits_t value); - store(const store& r); - - ~store(); - - typedef std::pair key_t; - - /** - * Return the object's key - */ - const key_t key() const; - - /** - * comparison operator - */ - bool operator==(const store& bdae) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find(const key_t& k); - - /** - * Dump all bridge_domain-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const store& obj); - - /** - * Find or add the instnace of the bridge_domain domain in the OM - */ - static std::shared_ptr find_or_add(const store& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class VOM::OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the config. The bool representing the - * do/don't configured/unconfigured. - */ - HW::item m_config; - - /** - * The interface the endpoint is attached to. - */ - std::shared_ptr m_itf; - - /** - * QoS source to store from - */ - source_t m_src; - - /** - * QoS Value to store in the buffer - */ - bits_t m_value; - - /** - * A map of all bridge_domains - */ - static singular_db m_db; -}; - -}; // namesapce QoS - -std::ostream& operator<<(std::ostream& os, const QoS::store::key_t& key); - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_store_cmds.cpp b/extras/vom/vom/qos_store_cmds.cpp deleted file mode 100644 index 2718c7a66e4..00000000000 --- a/extras/vom/vom/qos_store_cmds.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_store_cmds.hpp" -#include "vom/qos_types_api.hpp" - -namespace VOM { -namespace QoS { -namespace store_cmds { - -create_cmd::create_cmd(HW::item& item, - const handle_t& itf, - const source_t& s, - bits_t value) - : rpc_cmd(item) - , m_itf(itf) - , m_src(s) - , m_value(value) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_itf == other.m_itf) && (m_src == other.m_src) && - (m_value == other.m_value)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.store.sw_if_index = m_itf.value(); - payload.store.input_source = to_api(m_src); - payload.store.value = m_value; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "qos-store-create: " << m_hw_item.to_string() << " itf:" << m_itf - << " src:" << m_src.to_string() << " value:" << static_cast(m_value); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - const handle_t& itf, - const source_t& s) - : rpc_cmd(item) - , m_itf(itf) - , m_src(s) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_hw_item == other.m_hw_item && m_itf == other.m_itf && - m_src == other.m_src); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.store.sw_if_index = m_itf.value(); - payload.store.input_source = to_api(m_src); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "qos-store-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("qos-store-dump"); -} - -}; // namespace store_cmds -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_store_cmds.hpp b/extras/vom/vom/qos_store_cmds.hpp deleted file mode 100644 index 35671088a72..00000000000 --- a/extras/vom/vom/qos_store_cmds.hpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_STORE_CMDS_H__ -#define __VOM_QOS_STORE_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/qos_store.hpp" - -#include - -namespace VOM { -namespace QoS { -namespace store_cmds { - -/** - * A command class that creates or updates the GBP endpoint - */ -class create_cmd - : public rpc_cmd, vapi::Qos_store_enable_disable> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, - const handle_t& itf, - const source_t& src, - bits_t value); - - /** - * 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; - -private: - handle_t m_itf; - const source_t& m_src; - bits_t m_value; -}; - -/** - * A cmd class that deletes a GBP endpoint - */ -class delete_cmd - : public rpc_cmd, vapi::Qos_store_enable_disable> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, const handle_t& itf, const source_t& src); - - /** - * 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: - const handle_t m_itf; - const source_t& m_src; -}; - -/** - * A cmd class that Dumps all the GBP endpoints - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; -}; // namespace store_cmds -}; // namespace Qos -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_types.cpp b/extras/vom/vom/qos_types.cpp deleted file mode 100644 index 7d5d77482b0..00000000000 --- a/extras/vom/vom/qos_types.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_types.hpp" - -namespace VOM { -namespace QoS { - -const source_t source_t::EXT(0, "ext"); -const source_t source_t::VLAN(1, "vlan"); -const source_t source_t::MPLS(2, "mpls"); -const source_t source_t::IP(3, "IP"); - -source_t::source_t(int v, const std::string& s) - : enum_base(v, s) -{ -} -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_types.hpp b/extras/vom/vom/qos_types.hpp deleted file mode 100644 index e3c6a169c60..00000000000 --- a/extras/vom/vom/qos_types.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2019 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_QOS_TYPES_H__ -#define __VOM_QOS_TYPES_H__ - -#include "vom/enum_base.hpp" - -namespace VOM { -/** - * Types belonging to QoS - */ -namespace QoS { - -typedef uint8_t bits_t; - -/** - * The Source of the QoS classification (i.e. which header the bits are - * associated with). - */ -class source_t : public enum_base -{ -public: - const static source_t EXT; - const static source_t VLAN; - const static source_t MPLS; - const static source_t IP; - -private: - /** - * Private constructor taking the value and the string name - */ - source_t(int v, const std::string& s); -}; - -}; // namesapce QoS - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/qos_types_api.cpp b/extras/vom/vom/qos_types_api.cpp deleted file mode 100644 index 27cbad7b9b0..00000000000 --- a/extras/vom/vom/qos_types_api.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_types.hpp" - -#include - -DEFINE_VAPI_MSG_IDS_QOS_API_JSON; - -namespace VOM { -namespace QoS { - -const source_t& -from_api(vapi_enum_qos_source e) -{ - switch (e) { - case QOS_API_SOURCE_EXT: - return source_t::EXT; - case QOS_API_SOURCE_VLAN: - return source_t::VLAN; - case QOS_API_SOURCE_IP: - return source_t::IP; - case QOS_API_SOURCE_MPLS: - return source_t::MPLS; - } - return source_t::EXT; -} - -vapi_enum_qos_source -to_api(const source_t& s) -{ - return static_cast((int)s); -} - -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/qos_types_api.hpp b/extras/vom/vom/qos_types_api.hpp deleted file mode 100644 index 53cff0d2c69..00000000000 --- a/extras/vom/vom/qos_types_api.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2019 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/qos_types.hpp" - -#include - -namespace VOM { -namespace QoS { - -const source_t& from_api(vapi_enum_qos_source e); -vapi_enum_qos_source to_api(const source_t& s); - -}; // namespace QoS -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/ra_config.cpp b/extras/vom/vom/ra_config.cpp deleted file mode 100644 index 67faae699c8..00000000000 --- a/extras/vom/vom/ra_config.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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 - -#include "vom/ra_config.hpp" - -DEFINE_VAPI_MSG_IDS_IP6_ND_API_JSON; - -namespace VOM { - -/** - * Construct a new object matching the desried state - */ -ra_config::ra_config(uint8_t suppress, - uint8_t send_unicast, - uint8_t default_router, - uint32_t max_interval) - : m_suppress(suppress) - , m_managed(0) - , m_other(0) - , m_ll_option(0) - , m_send_unicast(send_unicast) - , m_cease(0) - , m_default_router(default_router) - , m_max_interval(max_interval) - , m_min_interval((max_interval * 3) / 4) - , m_lifetime(600) - , m_initial_count(3) - , m_initial_interval(16) -{} - -void -ra_config::to_vpp(vapi_payload_sw_interface_ip6nd_ra_config& ra_config) const -{ - ra_config.suppress = m_suppress; - ra_config.managed = m_managed; - ra_config.other = m_other; - ra_config.ll_option = m_ll_option; - ra_config.send_unicast = m_send_unicast; - ra_config.cease = m_cease; - ra_config.max_interval = m_max_interval; - ra_config.min_interval = m_min_interval; - ra_config.lifetime = m_lifetime; - ra_config.initial_count = m_initial_count; - ra_config.initial_interval = m_initial_interval; -} - -bool -ra_config::operator==(const ra_config& other) const -{ - return ((m_suppress == other.m_suppress) && - (m_send_unicast == other.m_send_unicast) && - (m_default_router == other.m_default_router) && - (m_max_interval == other.m_max_interval)); -} - -std::string -ra_config::to_string() const -{ - std::ostringstream s; - - s << "ra-config:[" - << " suppress:" << m_suppress << " send-unicast:" << m_send_unicast - << " default-router:" << m_default_router - << " max_interval:" << m_max_interval << "]"; - - return (s.str()); -} -} -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/ra_config.hpp b/extras/vom/vom/ra_config.hpp deleted file mode 100644 index 81533162a39..00000000000 --- a/extras/vom/vom/ra_config.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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_RA_CONFIG_H__ -#define __VOM_RA_CONFIG_H__ - -#include - -namespace VOM { -/** - * A representation of Router Advertisement configuration - */ -class ra_config -{ -public: - /** - * Construct a new object matching the desried state - */ - ra_config(uint8_t suppress, - uint8_t send_unicast, - uint8_t default_router, - uint32_t max_interval); - - /** - * Copy Constructor - */ - ra_config(const ra_config& o) = default; - - /** - * Destructor - */ - ~ra_config() = default; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Comparison operator - only used for UT - */ - bool operator==(const ra_config& ra_config) const; - - /** - * convert the ra config to VPP API - */ - void to_vpp(vapi_payload_sw_interface_ip6nd_ra_config& ra_config) const; - -private: - /** - * Disables sending ICMPv6 router-advertisement messages. - */ - uint8_t m_suppress; - - /** - * Advertises in ICMPv6 router-advertisement messages to use - * stateful address auto-configuration to obtain address information. - */ - uint8_t m_managed; - - /** - * Indicates in ICMPv6 router-advertisement messages that - * hosts use stateful auto configuration to obtain nonaddress - * related information. - */ - uint8_t m_other; - - /** - * Indicates not to include the optional source link-layer - * address in the ICMPv6 router-advertisement messages. - */ - uint8_t m_ll_option; - - /** - * Use the source address of the router-solicitation message if - * availiable. - */ - uint8_t m_send_unicast; - - /** - * Cease sending ICMPv6 router-advertisement messages. - */ - uint8_t m_cease; - - /** - * .... ? - */ - uint8_t m_default_router; - - /** - * Configures the interval between sending ICMPv6 router-advertisement - * messages. The range for max-interval is from 4 to 200 seconds. - */ - uint32_t m_max_interval; - - /** - * min-interval can not be more than 75% of max-interval. - * If not set, min-interval will be set to 75% of max-interval. - * The range for min-interval is from 3 to 150 seconds. - */ - uint32_t m_min_interval; - - /** - * Advertises the lifetime of a default router in ICMPv6 - * router-advertisement messages. The range is from 0 to 9000 seconds. - * '' must be greater than ''. - * The default value is 600 seconds - */ - uint32_t m_lifetime; - - /** - * Number of initial ICMPv6 router-advertisement messages sent. - * Range for count is 1 - 3 and default is 3. - */ - uint32_t m_initial_count; - - /** - * The interval between each initial messages. - * Range for interval is 1 to 16 seconds, and default is 16 seconds. - */ - uint32_t m_initial_interval; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/ra_prefix.cpp b/extras/vom/vom/ra_prefix.cpp deleted file mode 100644 index fe3ad327f6d..00000000000 --- a/extras/vom/vom/ra_prefix.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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 - -#include "vom/api_types.hpp" -#include "vom/ra_prefix.hpp" - -namespace VOM { -ra_prefix::ra_prefix(const route::prefix_t& pfx, - uint8_t use_default, - uint8_t no_advertise, - uint32_t val_lifetime, - uint32_t pref_lifetime) - : m_pfx(pfx) - , m_use_default(use_default) - , m_no_advertise(no_advertise) - , m_off_link(0) - , m_no_autoconfig(0) - , m_no_onlink(0) - , m_val_lifetime(val_lifetime) - , m_pref_lifetime(pref_lifetime) -{ -} - -void -ra_prefix::to_vpp(vapi_payload_sw_interface_ip6nd_ra_prefix& ra_prefix) const -{ - ra_prefix.prefix = to_api(m_pfx); - - ra_prefix.use_default = m_use_default; - ra_prefix.no_advertise = m_no_advertise; - ra_prefix.off_link = m_off_link; - ra_prefix.no_autoconfig = m_no_autoconfig; - ra_prefix.no_onlink = m_no_onlink; - ra_prefix.val_lifetime = m_val_lifetime; - ra_prefix.pref_lifetime = m_pref_lifetime; -} - -bool -ra_prefix::operator==(const ra_prefix& other) const -{ - return ((m_pfx == other.m_pfx) && (m_use_default == other.m_use_default) && - (m_no_advertise == other.m_no_advertise) && - (m_val_lifetime == other.m_val_lifetime) && - (m_pref_lifetime == other.m_pref_lifetime)); -} - -std::string -ra_prefix::to_string() const -{ - std::ostringstream s; - - s << "ra-pfx-config:[" - << " pfx:" << m_pfx.to_string() << " use-default:" << m_use_default - << " no-advertise:" << m_no_advertise << " val-lifetime:" << m_val_lifetime - << " pref-lifetime:" << m_pref_lifetime << "]"; - - return (s.str()); -} - -const route::prefix_t& -ra_prefix::prefix() const -{ - return (m_pfx); -} -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/ra_prefix.hpp b/extras/vom/vom/ra_prefix.hpp deleted file mode 100644 index 8e0cf51c055..00000000000 --- a/extras/vom/vom/ra_prefix.hpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * 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_RA_PREFIX_H__ -#define __VOM_RA_PREFIX_H__ - -#include "vom/prefix.hpp" - -#include - -namespace VOM { -/** - * A representation of RA prefix configuration on given interface - */ -class ra_prefix -{ -public: - /** - * Construct a new object matching the desried state - */ - ra_prefix(const route::prefix_t& pfx, - uint8_t use_default, - uint8_t no_advertise, - uint32_t val_lifetime, - uint32_t pref_lifetime); - - /** - * Copy Constructor - */ - ra_prefix(const ra_prefix& o) = default; - - /** - * Destructor - */ - ~ra_prefix() = default; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Return the prefix associated with this ra prefix - */ - const route::prefix_t& prefix() const; - - /** - * Comparison operator - only used for UT - */ - bool operator==(const ra_prefix& ra_prefix) const; - - /** - * Convert the ra prefix configuration to Vpp Api - */ - void to_vpp(vapi_payload_sw_interface_ip6nd_ra_prefix& ra_prefix) const; - -private: - /** - * The prefix to be advertised. - */ - route::prefix_t m_pfx; - - /** - * Revert to default settings. - */ - uint8_t m_use_default; - - /** - * Do not send full router address in prefix advertisement. - * Default is to advertise. - */ - uint8_t m_no_advertise; - - /** - * Prefix is off-link. Default is on-link. - */ - uint8_t m_off_link; - - /** - * Do not use prefix for autoconfiguration. - * Default is autoconfig. - */ - uint8_t m_no_autoconfig; - - /** - * Do not use prefix for onlink determination. - * Default is on-link (this flag is off). - */ - uint8_t m_no_onlink; - - /** - * ' is the length of time in seconds during what - * the prefix is valid for the purpose of on-link determination. - * - * Range is 7203 to 2592000 seconds and default is 2592000 seconds. - * A value of all one bits (0xffffffff) represents infinity (no - * timeout). - */ - uint32_t m_val_lifetime; - - /** - * '' is the prefered-lifetime and is the length of - * time in seconds during what addresses generated from the prefix - * remain preferred. - * - * Range is 0 to 604800 seconds and default is 604800 seconds. - * A value of all one bits (0xffffffff) represents infinity (no - * timeout). - */ - uint32_t m_pref_lifetime; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/route.cpp b/extras/vom/vom/route.cpp deleted file mode 100644 index b5b93455230..00000000000 --- a/extras/vom/vom/route.cpp +++ /dev/null @@ -1,703 +0,0 @@ -/* - * 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/route.hpp" -#include "vom/api_types.hpp" -#include "vom/mroute_cmds.hpp" -#include "vom/route_api_types.hpp" -#include "vom/route_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { -namespace route { -ip_route::event_handler ip_route::m_evh; -ip_mroute::event_handler ip_mroute::m_evh; -singular_db ip_route::m_db; -singular_db ip_mroute::m_db; - -const path::special_t path::special_t::STANDARD(0, "standard"); -const path::special_t path::special_t::LOCAL(1, "local"); -const path::special_t path::special_t::DROP(2, "standard"); -const path::special_t path::special_t::UNREACH(3, "unreachable"); -const path::special_t path::special_t::PROHIBIT(4, "prohibit"); - -path::special_t::special_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const path::flags_t path::flags_t::NONE(0, "none"); -const path::flags_t path::flags_t::DVR((1 << 0), "dvr"); - -path::flags_t::flags_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -const itf_flags_t itf_flags_t::NONE(0, "none"); -const itf_flags_t itf_flags_t::ACCEPT((1 << 1), "accept"); -const itf_flags_t itf_flags_t::FORWARD((1 << 2), "forward"); - -itf_flags_t::itf_flags_t(int v, const std::string& s) - : enum_base(v, s) -{ -} - -path::path(special_t special, const nh_proto_t& proto) - : m_type(special) - , m_nh_proto(proto) - , m_flags(flags_t::NONE) - , m_nh() - , m_rd(nullptr) - , m_interface(nullptr) - , m_weight(1) - , m_preference(0) -{ -} - -path::path(const boost::asio::ip::address& nh, - const interface& interface, - uint8_t weight, - uint8_t preference) - : m_type(special_t::STANDARD) - , m_nh_proto(nh_proto_t::from_address(nh)) - , m_flags(flags_t::NONE) - , m_nh(nh) - , m_rd(nullptr) - , m_interface(interface.singular()) - , m_weight(weight) - , m_preference(preference) -{ -} - -path::path(const route_domain& rd, - const boost::asio::ip::address& nh, - uint8_t weight, - uint8_t preference) - : m_type(special_t::STANDARD) - , m_nh_proto(nh_proto_t::from_address(nh)) - , m_flags(flags_t::NONE) - , m_nh(nh) - , m_rd(rd.singular()) - , m_interface(nullptr) - , m_weight(weight) - , m_preference(preference) -{ -} - -path::path(const interface& interface, - const nh_proto_t& proto, - const flags_t& flags, - uint8_t weight, - uint8_t preference) - : m_type(special_t::STANDARD) - , m_nh_proto(proto) - , m_flags(flags) - , m_nh() - , m_rd(nullptr) - , m_interface(interface.singular()) - , m_weight(weight) - , m_preference(preference) -{ -} - -path::path(const path& p) - : m_type(p.m_type) - , m_nh_proto(p.m_nh_proto) - , m_flags(p.m_flags) - , m_nh(p.m_nh) - , m_rd(p.m_rd) - , m_interface(p.m_interface) - , m_weight(p.m_weight) - , m_preference(p.m_preference) -{ -} - -bool -path::operator<(const path& p) const -{ - if (m_nh_proto < p.m_nh_proto) - return true; - if (m_flags < p.m_flags) - return true; - if (m_type < p.m_type) - return true; - if (m_rd && !p.m_rd) - return false; - if (!m_rd && p.m_rd) - return true; - if (m_rd && p.m_rd) { - if (m_rd->table_id() < p.m_rd->table_id()) - return true; - else if (m_rd->table_id() > p.m_rd->table_id()) - return false; - } - if (m_nh < p.m_nh) - return true; - if (m_interface && !p.m_interface) - return false; - if (!m_interface && p.m_interface) - return true; - if (m_interface && p.m_interface) { - if (m_interface->handle() < p.m_interface->handle()) - return true; - if (p.m_interface->handle() < m_interface->handle()) - return false; - } - - return (false); -} - -path::~path() -{ -} - -bool -path::operator==(const path& p) const -{ - bool result = true; - if (m_rd && !p.m_rd) - return false; - if (!m_rd && p.m_rd) - return false; - if (m_rd && p.m_rd) - result &= (*m_rd == *p.m_rd); - if (m_interface && !p.m_interface) - return false; - if (!m_interface && p.m_interface) - return false; - if (m_interface && p.m_interface) - result &= (*m_interface == *p.m_interface); - return (result && (m_type == p.m_type) && (m_nh == p.m_nh) && - (m_nh_proto == p.m_nh_proto) && (m_flags == p.m_flags)); -} - -std::string -path::to_string() const -{ - std::ostringstream s; - - s << "path:[" - << "type:" << m_type.to_string() << " proto:" << m_nh_proto.to_string() - << " flags:" << m_flags.to_string() << " neighbour:" << m_nh.to_string(); - if (m_rd) { - s << " " << m_rd->to_string(); - } - if (m_interface) { - s << " " << m_interface->to_string(); - } - s << " weight:" << static_cast(m_weight) - << " preference:" << static_cast(m_preference) << "]"; - - return (s.str()); -} - -path::special_t -path::type() const -{ - return m_type; -} - -nh_proto_t -path::nh_proto() const -{ - return m_nh_proto; -} - -path::flags_t -path::flags() const -{ - return m_flags; -} - -const boost::asio::ip::address& -path::nh() const -{ - return m_nh; -} - -std::shared_ptr -path::rd() const -{ - return m_rd; -} - -std::shared_ptr -path::itf() const -{ - return m_interface; -} - -uint8_t -path::weight() const -{ - return m_weight; -} - -uint8_t -path::preference() const -{ - return m_preference; -} - -ip_route::ip_route(const prefix_t& prefix, const path& p) - : m_hw(false) - , m_rd(route_domain::get_default()) - , m_prefix(prefix) - , m_paths({ p }) -{ -} - -ip_route::ip_route(const prefix_t& prefix) - : m_hw(false) - , m_rd(route_domain::get_default()) - , m_prefix(prefix) - , m_paths() -{ -} - -ip_route::ip_route(const ip_route& r) - : m_hw(r.m_hw) - , m_rd(r.m_rd) - , m_prefix(r.m_prefix) - , m_paths(r.m_paths) -{ -} - -ip_route::ip_route(const route_domain& rd, const prefix_t& prefix) - : m_hw(false) - , m_rd(rd.singular()) - , m_prefix(prefix) - , m_paths() -{ -} - -ip_route::ip_route(const route_domain& rd, - const prefix_t& prefix, - const path& p) - : m_hw(false) - , m_rd(rd.singular()) - , m_prefix(prefix) - , m_paths({ p }) -{ -} - -ip_route::~ip_route() -{ - sweep(); - - // not in the DB anymore. - m_db.release(key(), this); - m_paths.clear(); -} - -const ip_route::key_t -ip_route::key() const -{ - return (std::make_pair(m_rd->table_id(), m_prefix)); -} - -bool -ip_route::operator==(const ip_route& i) const -{ - return ((key() == i.key()) && (m_paths == i.m_paths)); -} - -void -ip_route::add(const path& path) -{ - m_paths.insert(path); -} - -void -ip_route::remove(const path& path) -{ - m_paths.erase(path); -} - -void -ip_route::sweep() -{ - if (m_hw) { - HW::enqueue( - new ip_route_cmds::delete_cmd(m_hw, m_rd->table_id(), m_prefix)); - } - HW::write(); -} - -void -ip_route::replay() -{ - if (m_hw) { - HW::enqueue( - new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths)); - } -} -std::string -ip_route::to_string() const -{ - std::ostringstream s; - s << "route:[" << m_rd->to_string() << ", " << m_prefix.to_string() << " [" - << m_paths << "]" - << "]"; - - return (s.str()); -} - -void -ip_route::update(const ip_route& r) -{ - m_paths = r.m_paths; - HW::enqueue( - new ip_route_cmds::update_cmd(m_hw, m_rd->table_id(), m_prefix, m_paths)); -} - -std::shared_ptr -ip_route::find_or_add(const ip_route& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -ip_route::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -ip_route::singular() const -{ - return find_or_add(*this); -} - -void -ip_route::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -ip_route::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "ip-route" }, "ip route configurations", this); -} - -void -ip_route::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -ip_route::event_handler::handle_populate(const client_db::key_t& key) -{ - // for each known route-domain - auto it = route_domain::cbegin(); - - while (it != route_domain::cend()) { - - std::vector l3s = { l3_proto_t::IPV4, l3_proto_t::IPV4 }; - - for (auto l3 : l3s) { - std::shared_ptr cmd = - std::make_shared(it->second.lock()->table_id(), - l3); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr rd = - route_domain::find(payload.route.table_id); - - if (!rd) { - continue; - } - - prefix_t pfx = from_api(payload.route.prefix); - ip_route ip_r(*rd, pfx); - - for (unsigned int i = 0; i < payload.route.n_paths; i++) { - ip_r.add(from_api(payload.route.paths[i])); - } - - VOM_LOG(log_level_t::DEBUG) << "ip-route-dump: " << ip_r.to_string(); - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, ip_r); - } - } - ++it; - } -} - -dependency_t -ip_route::event_handler::order() const -{ - return (dependency_t::TABLE); -} - -void -ip_route::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -ip_mroute::ip_mroute(const mprefix_t& mprefix) - : m_hw(false) - , m_rd(route_domain::get_default()) - , m_mprefix(mprefix) - , m_paths() -{ -} - -ip_mroute::ip_mroute(const ip_mroute& r) - : m_hw(r.m_hw) - , m_rd(r.m_rd) - , m_mprefix(r.m_mprefix) - , m_paths(r.m_paths) -{ -} - -ip_mroute::ip_mroute(const route_domain& rd, const mprefix_t& mprefix) - : m_hw(false) - , m_rd(rd.singular()) - , m_mprefix(mprefix) - , m_paths() -{ -} - -void -ip_mroute::add(const path& path, const itf_flags_t& flag) -{ - m_paths.insert(std::make_pair(path, flag)); -} - -ip_mroute::~ip_mroute() -{ - sweep(); - m_db.release(key(), this); -} - -const ip_mroute::key_t -ip_mroute::key() const -{ - return (std::make_pair(m_rd->table_id(), m_mprefix)); -} - -bool -ip_mroute::operator==(const ip_mroute& i) const -{ - return ((key() == i.key()) && (m_paths == i.m_paths)); -} - -void -ip_mroute::sweep() -{ - if (m_hw) { - for (auto& p : m_paths) - HW::enqueue(new ip_mroute_cmds::delete_cmd(m_hw, m_rd->table_id(), - m_mprefix, p.first, p.second)); - } - HW::write(); -} - -void -ip_mroute::replay() -{ - if (m_hw) { - for (auto& p : m_paths) - HW::enqueue(new ip_mroute_cmds::update_cmd(m_hw, m_rd->table_id(), - m_mprefix, p.first, p.second)); - } -} -std::string -ip_mroute::to_string() const -{ - std::ostringstream s; - s << "route:[" << m_rd->to_string() << ", " << m_mprefix.to_string() << " [" - << m_paths << "]" - << "]"; - - return (s.str()); -} - -void -ip_mroute::update(const ip_mroute& r) -{ - if (rc_t::OK != m_hw.rc()) { - for (auto& p : m_paths) - HW::enqueue(new ip_mroute_cmds::update_cmd(m_hw, m_rd->table_id(), - m_mprefix, p.first, p.second)); - } -} - -std::shared_ptr -ip_mroute::find_or_add(const ip_mroute& temp) -{ - return (m_db.find_or_add(temp.key(), temp)); -} - -std::shared_ptr -ip_mroute::find(const key_t& k) -{ - return (m_db.find(k)); -} - -std::shared_ptr -ip_mroute::singular() const -{ - return find_or_add(*this); -} - -void -ip_mroute::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -ip_mroute::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "ip-mroute" }, - "ip multicast route configurations", this); -} - -void -ip_mroute::event_handler::handle_replay() -{ - m_db.replay(); -} - -void -ip_mroute::event_handler::handle_populate(const client_db::key_t& key) -{ - // for each known route-domain - auto it = route_domain::cbegin(); - - while (it != route_domain::cend()) { - - std::vector l3s = { l3_proto_t::IPV4, l3_proto_t::IPV4 }; - - for (auto l3 : l3s) { - std::shared_ptr cmd = - std::make_shared( - it->second.lock()->table_id(), l3); - - HW::enqueue(cmd); - HW::write(); - - VOM_LOG(log_level_t::DEBUG) << "ip-mroute-dump: "; - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - std::shared_ptr rd = - route_domain::find(payload.route.table_id); - - if (!rd) { - continue; - } - - mprefix_t pfx = from_api(payload.route.prefix); - ip_mroute ip_r(*rd, pfx); - - for (unsigned int i = 0; i < payload.route.n_paths; i++) { - ip_r.add(from_api(payload.route.paths[i].path), - from_api(payload.route.paths[i].itf_flags)); - } - - VOM_LOG(log_level_t::DEBUG) << "ip-mroute-dump: " << ip_r.to_string(); - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, ip_r); - } - } - ++it; - } -} - -dependency_t -ip_mroute::event_handler::order() const -{ - return (dependency_t::TABLE); -} - -void -ip_mroute::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -std::ostream& -operator<<(std::ostream& os, const ip_route::key_t& key) -{ - os << "[" << key.first << ", " << key.second.to_string() << "]"; - - return (os); -} - -std::ostream& -operator<<(std::ostream& os, const ip_mroute::key_t& key) -{ - os << "[" << key.first << ", " << key.second.to_string() << "]"; - - return (os); -} - -std::ostream& -operator<<(std::ostream& os, const path_list_t& key) -{ - os << "["; - for (auto k : key) { - os << k.to_string() << " "; - } - os << "]"; - - return (os); -} - -std::ostream& -operator<<(std::ostream& os, const mpath_list_t& key) -{ - os << "["; - for (auto k : key) { - os << "[" << k.first.to_string() << ", " << k.second.to_string() << "]"; - } - os << "]"; - - return (os); -} - -}; // namespace route -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/route.hpp b/extras/vom/vom/route.hpp deleted file mode 100644 index 8b68015f7ba..00000000000 --- a/extras/vom/vom/route.hpp +++ /dev/null @@ -1,595 +0,0 @@ -/* - * 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_ROUTE_H__ -#define __VOM_ROUTE_H__ - -#include "vom/interface.hpp" -#include "vom/prefix.hpp" -#include "vom/route_domain.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * Types belonging to Routing - */ -namespace route { -/** - * A path for IP or MPLS routes - */ -class path -{ -public: - /** - * Special path types - */ - class special_t : public enum_base - { - public: - /** - * A standard path type. this includes path types - * that use the next-hop and interface - */ - const static special_t STANDARD; - - /** - * A local/for-us/recieve - */ - const static special_t LOCAL; - - /** - * drop path - */ - const static special_t DROP; - - /** - * a path will return ICMP unreachables - */ - const static special_t UNREACH; - - /** - * a path will return ICMP prohibit - */ - const static special_t PROHIBIT; - - private: - /** - * Private constructor taking the value and the string name - */ - special_t(int v, const std::string& s); - }; - - /** - * Path flags - */ - class flags_t : public enum_base - { - public: - /** - * No flags - */ - const static flags_t NONE; - - /** - * A path that resolves via a DVR next-hop - */ - const static flags_t DVR; - - private: - /** - * Private constructor taking the value and the string name - */ - flags_t(int v, const std::string& s); - }; - - /** - * constructor for special paths - */ - path(special_t special, const nh_proto_t& proto = nh_proto_t::IPV4); - - /** - * Constructor for standard non-recursive paths - */ - path(const boost::asio::ip::address& nh, - const interface& interface, - uint8_t weight = 1, - uint8_t preference = 0); - - /** - * Constructor for standard recursive paths - */ - path(const route_domain& rd, - const boost::asio::ip::address& nh, - uint8_t weight = 1, - uint8_t preference = 0); - - /** - * Constructor for DVR paths or attached paths. - */ - path(const interface& interface, - const nh_proto_t& proto, - const flags_t& flags = flags_t::NONE, - uint8_t weight = 1, - uint8_t preference = 0); - - /** - * Copy Constructor - */ - path(const path& p); - - /** - * Destructor - */ - ~path(); - - /** - * comparison operator - */ - bool operator==(const path& p) const; - - /** - * Less than operator for set insertion - */ - bool operator<(const path& p) const; - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Getters - */ - special_t type() const; - nh_proto_t nh_proto() const; - flags_t flags() const; - const boost::asio::ip::address& nh() const; - std::shared_ptr rd() const; - std::shared_ptr itf() const; - uint8_t weight() const; - uint8_t preference() const; - -private: - /** - * The special path tpye - */ - special_t m_type; - - /** - * The next-hop protocol - */ - nh_proto_t m_nh_proto; - - /** - * Flags for the path - */ - flags_t m_flags; - - /** - * The next-hop - */ - boost::asio::ip::address m_nh; - - /** - * For recursive routes, this is the table in which the - * the next-hop exists. - */ - std::shared_ptr m_rd; - - /** - * The next-hop interface [if present]. - */ - std::shared_ptr m_interface; - - /** - * UCMP weight - */ - uint8_t m_weight; - - /** - * Path preference - */ - uint8_t m_preference; -}; - -class itf_flags_t : public enum_base -{ -public: - const static itf_flags_t NONE; - /** - * Path is accepting multicast traffic - */ - const static itf_flags_t ACCEPT; - - /** - * A local/for-us/recieve - */ - const static itf_flags_t FORWARD; - -private: - /** - * Private constructor taking the value and the string name - */ - itf_flags_t(int v, const std::string& s); -}; - -/** - * A path-list is a set of paths - */ -typedef std::set path_list_t; - -/** - * A mpath-list is a set of paths and interface flags - */ -typedef std::set> mpath_list_t; - -/** - * ostream output for iterator - */ -std::ostream& operator<<(std::ostream& os, const path_list_t& path_list); -std::ostream& operator<<(std::ostream& os, const mpath_list_t& path_list); - -/** - * A IP route - */ -class ip_route : public object_base -{ -public: - /** - * The key for a route - */ - typedef std::pair key_t; - - /** - * Construct a route in the default table - */ - ip_route(const prefix_t& prefix); - - /** - * Construct a route with a path - */ - ip_route(const prefix_t& prefix, const path& p); - - /** - * Copy Construct - */ - ip_route(const ip_route& r); - - /** - * Construct a route in the given route domain - */ - ip_route(const route_domain& rd, const prefix_t& prefix); - - /** - * Construct a route in the given route domain with a path - */ - ip_route(const route_domain& rd, const prefix_t& prefix, const path& p); - - /** - * Destructor - */ - ~ip_route(); - - /** - * Get the route's key - */ - const key_t key() const; - - /** - * Comparison operator - */ - bool operator==(const ip_route& i) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Add a path. - */ - void add(const path& path); - - /** - * remove a path. - */ - void remove(const path& path); - - /** - * Find the instnace of the route domain in the OM - */ - static std::shared_ptr find(const ip_route& temp); - - /** - * Dump all route-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - - /** - * Return the matching 'singular instance' - */ - static std::shared_ptr find(const key_t& k); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Find or add the instnace of the route domain in the OM - */ - static std::shared_ptr find_or_add(const ip_route& temp); - - /* - * It's the OM class that updates the objects in HW - */ - friend class VOM::OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const ip_route& obj); - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the route - */ - HW::item m_hw; - - /** - * The route domain the route is in. - */ - std::shared_ptr m_rd; - - /** - * The prefix to match - */ - prefix_t m_prefix; - - /** - * The set of paths - */ - path_list_t m_paths; - - /** - * A map of all routes - */ - static singular_db m_db; -}; - -/** - * A IP multicast route - */ -class ip_mroute : public object_base -{ -public: - /** - * The key for a route - */ - typedef std::pair key_t; - - /** - * Construct a route in the default table - */ - ip_mroute(const mprefix_t& mprefix); - - /** - * Copy Construct - */ - ip_mroute(const ip_mroute& r); - - /** - * Construct a route in the given route domain - */ - ip_mroute(const route_domain& rd, const mprefix_t& mprefix); - - /** - * Destructor - */ - ~ip_mroute(); - - /** - * Get the route's key - */ - const key_t key() const; - - /** - * Comparison operator - */ - bool operator==(const ip_mroute& i) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Find the instnace of the route domain in the OM - */ - static std::shared_ptr find(const ip_mroute& temp); - - /** - * Dump all route-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Convert to string for debugging - */ - std::string to_string() const; - - /** - * Return the matching 'singular instance' - */ - static std::shared_ptr find(const key_t& k); - - void add(const path& path, const itf_flags_t& flag); - -private: - /** - * 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; - }; - - /** - * event_handler to register with OM - */ - static event_handler m_evh; - - /** - * Find or add the instnace of the route domain in the OM - */ - static std::shared_ptr find_or_add(const ip_mroute& temp); - - /* - * It's the OM class that updates the objects in HW - */ - friend class VOM::OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const ip_mroute& obj); - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the route - */ - HW::item m_hw; - - /** - * The route domain the route is in. - */ - std::shared_ptr m_rd; - - /** - * The mprefix to match - */ - mprefix_t m_mprefix; - - /** - * The set of paths - */ - mpath_list_t m_paths; - - /** - * A map of all routes - */ - static singular_db m_db; -}; - -std::ostream& operator<<(std::ostream& os, const ip_route::key_t& key); -std::ostream& operator<<(std::ostream& os, const ip_mroute::key_t& key); -}; // namespace route -}; // namesapce VPP - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/route_api_types.cpp b/extras/vom/vom/route_api_types.cpp deleted file mode 100644 index b6ab6381b12..00000000000 --- a/extras/vom/vom/route_api_types.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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 -#include -#include - -namespace VOM { - -const route::itf_flags_t& -from_api(vapi_enum_mfib_itf_flags val) -{ - if (route::itf_flags_t::ACCEPT == val) - return route::itf_flags_t::ACCEPT; - else - return route::itf_flags_t::FORWARD; -} - -vapi_enum_mfib_itf_flags -to_api(const route::itf_flags_t& in) -{ - vapi_enum_mfib_itf_flags out = MFIB_API_ITF_FLAG_NONE; - - if (route::itf_flags_t::ACCEPT & in) - out = static_cast(out | MFIB_API_ITF_FLAG_ACCEPT); - if (route::itf_flags_t::FORWARD & in) - out = - static_cast(out | MFIB_API_ITF_FLAG_FORWARD); - - return (out); -} - -void -to_api(const route::path& p, vapi_type_fib_path& payload) -{ - payload.flags = FIB_API_PATH_FLAG_NONE; - payload.proto = to_api(p.nh_proto()); - payload.sw_if_index = ~0; - - if (route::path::flags_t::DVR & p.flags()) { - payload.type = FIB_API_PATH_TYPE_DVR; - } else if (route::path::special_t::STANDARD == p.type()) { - to_api(p.nh(), payload.nh.address); - - if (p.rd()) { - payload.table_id = p.rd()->table_id(); - } - if (p.itf()) { - payload.sw_if_index = p.itf()->handle().value(); - } - } else if (route::path::special_t::DROP == p.type()) { - payload.type = FIB_API_PATH_TYPE_DROP; - } else if (route::path::special_t::UNREACH == p.type()) { - payload.type = FIB_API_PATH_TYPE_ICMP_UNREACH; - } else if (route::path::special_t::PROHIBIT == p.type()) { - payload.type = FIB_API_PATH_TYPE_ICMP_PROHIBIT; - } else if (route::path::special_t::LOCAL == p.type()) { - payload.type = FIB_API_PATH_TYPE_LOCAL; - } - - payload.weight = p.weight(); - payload.preference = p.preference(); - payload.n_labels = 0; -} - -route::path -from_api(const vapi_type_fib_path& p) -{ - switch (p.type) { - case FIB_API_PATH_TYPE_DVR: { - std::shared_ptr itf = interface::find(p.sw_if_index); - if (!itf) - throw invalid_decode("fib-path deocde no interface:" + - std::to_string(p.sw_if_index)); - - return (route::path(*itf, from_api(p.proto), route::path::flags_t::DVR, - p.weight, p.preference)); - } - case FIB_API_PATH_TYPE_NORMAL: { - boost::asio::ip::address address = from_api(p.nh.address, p.proto); - std::shared_ptr itf = interface::find(p.sw_if_index); - if (itf) { - return (route::path(address, *itf, p.weight, p.preference)); - } else { - std::shared_ptr rd = route_domain::find(p.table_id); - - if (!rd) - throw invalid_decode("fib-path deocde no route-domain:" + - std::to_string(p.table_id)); - - return (route::path(*rd, address, p.weight, p.preference)); - } - } - case FIB_API_PATH_TYPE_LOCAL: - return (route::path(route::path::special_t::LOCAL)); - case FIB_API_PATH_TYPE_DROP: - return (route::path(route::path::special_t::DROP)); - case FIB_API_PATH_TYPE_ICMP_UNREACH: - return (route::path(route::path::special_t::PROHIBIT)); - case FIB_API_PATH_TYPE_ICMP_PROHIBIT: - return (route::path(route::path::special_t::UNREACH)); - - case FIB_API_PATH_TYPE_UDP_ENCAP: - case FIB_API_PATH_TYPE_BIER_IMP: - case FIB_API_PATH_TYPE_SOURCE_LOOKUP: - case FIB_API_PATH_TYPE_INTERFACE_RX: - case FIB_API_PATH_TYPE_CLASSIFY: - // not done yet - break; - } - return (route::path(route::path::special_t::DROP)); -}; - -vapi_enum_ip_dscp -to_api(const ip_dscp_t& d) -{ - return static_cast((int)d); -} -const ip_dscp_t& -from_api(vapi_enum_ip_dscp d) -{ - switch (d) { - case IP_API_DSCP_CS0: - return ip_dscp_t::DSCP_CS0; - case IP_API_DSCP_CS1: - return ip_dscp_t::DSCP_CS1; - case IP_API_DSCP_CS2: - return ip_dscp_t::DSCP_CS2; - case IP_API_DSCP_CS3: - return ip_dscp_t::DSCP_CS3; - case IP_API_DSCP_CS4: - return ip_dscp_t::DSCP_CS4; - case IP_API_DSCP_CS5: - return ip_dscp_t::DSCP_CS5; - case IP_API_DSCP_CS6: - return ip_dscp_t::DSCP_CS6; - case IP_API_DSCP_CS7: - return ip_dscp_t::DSCP_CS7; - case IP_API_DSCP_EF: - return ip_dscp_t::DSCP_EF; - case IP_API_DSCP_AF11: - return ip_dscp_t::DSCP_AF11; - case IP_API_DSCP_AF12: - return ip_dscp_t::DSCP_AF12; - case IP_API_DSCP_AF13: - return ip_dscp_t::DSCP_AF13; - case IP_API_DSCP_AF21: - return ip_dscp_t::DSCP_AF21; - case IP_API_DSCP_AF22: - return ip_dscp_t::DSCP_AF22; - case IP_API_DSCP_AF23: - return ip_dscp_t::DSCP_AF23; - case IP_API_DSCP_AF31: - return ip_dscp_t::DSCP_AF31; - case IP_API_DSCP_AF32: - return ip_dscp_t::DSCP_AF32; - case IP_API_DSCP_AF33: - return ip_dscp_t::DSCP_AF33; - case IP_API_DSCP_AF41: - return ip_dscp_t::DSCP_AF41; - case IP_API_DSCP_AF42: - return ip_dscp_t::DSCP_AF42; - case IP_API_DSCP_AF43: - return ip_dscp_t::DSCP_AF43; - } - - return ip_dscp_t::DSCP_CS0; -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/route_api_types.hpp b/extras/vom/vom/route_api_types.hpp deleted file mode 100644 index e741a9d5acc..00000000000 --- a/extras/vom/vom/route_api_types.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 - -#include - -namespace VOM { - -vapi_enum_mfib_itf_flags to_api(const route::itf_flags_t& flags); -const route::itf_flags_t& from_api(vapi_enum_mfib_itf_flags flags); - -void to_api(const route::path& p, vapi_type_fib_path& o); - -route::path from_api(const vapi_type_fib_path& p); - -vapi_enum_ip_dscp to_api(const ip_dscp_t& d); -const ip_dscp_t& from_api(vapi_enum_ip_dscp d); - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/route_cmds.cpp b/extras/vom/vom/route_cmds.cpp deleted file mode 100644 index 78676c225be..00000000000 --- a/extras/vom/vom/route_cmds.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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 - -#include -#include -#include - -namespace VOM { -namespace route { -namespace ip_route_cmds { - -update_cmd::update_cmd(HW::item& item, - table_id_t id, - const prefix_t& prefix, - const path_list_t& pl) - : srpc_cmd(item) - , m_id(id) - , m_prefix(prefix) - , m_pl(pl) -{ -} - -bool -update_cmd::operator==(const update_cmd& other) const -{ - return ((m_prefix == other.m_prefix) && (m_id == other.m_id) && - (m_pl == other.m_pl)); -} - -rc_t -update_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), m_pl.size(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.route.table_id = m_id; - payload.is_add = 1; - payload.is_multipath = 1; - - payload.route.table_id = m_id; - payload.route.prefix = to_api(m_prefix); - - uint32_t ii = 0; - for (auto& p : m_pl) - to_api(p, payload.route.paths[ii++]); - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -update_cmd::to_string() const -{ - std::ostringstream s; - s << "ip-route-create: " << m_hw_item.to_string() << " table-id:" << m_id - << " prefix:" << m_prefix.to_string() << " paths:"; - for (auto p : m_pl) - s << p.to_string() << " "; - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - table_id_t id, - const prefix_t& prefix) - : rpc_cmd(item) - , m_id(id) - , m_prefix(prefix) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return ((m_prefix == other.m_prefix) && (m_id == other.m_id)); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), 0, std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 0; - payload.is_multipath = 0; - - payload.route.table_id = m_id; - payload.route.n_paths = 0; - payload.route.table_id = m_id; - payload.route.prefix = to_api(m_prefix); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return rc_t::OK; -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "ip-route-delete: " << m_hw_item.to_string() << " id:" << m_id - << " prefix:" << m_prefix.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd(route::table_id_t id, const l3_proto_t& proto) - : m_id(id) - , m_proto(proto) -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - - payload.table.table_id = m_id; - payload.table.is_ip6 = m_proto.is_ipv6(); - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("ip-route-v4-dump"); -} - -} // namespace ip_route_cmds -} // namespace route -} // namespace vom - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/route_cmds.hpp b/extras/vom/vom/route_cmds.hpp deleted file mode 100644 index 3c43208f120..00000000000 --- a/extras/vom/vom/route_cmds.hpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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_ROUTE_CMDS_H__ -#define __VOM_ROUTE_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/route.hpp" -#include "vom/srpc_cmd.hpp" - -#include - -namespace VOM { -namespace route { -namespace ip_route_cmds { - -/** - * A command class that creates or updates the route - */ -class update_cmd : public srpc_cmd -{ -public: - /** - * Constructor - */ - update_cmd(HW::item& item, - table_id_t id, - const prefix_t& prefix, - const path_list_t& pl); - - /** - * 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 update_cmd& i) const; - -private: - route::table_id_t m_id; - prefix_t m_prefix; - const path_list_t& m_pl; -}; - -/** - * A cmd class that deletes a route - */ -class delete_cmd : public rpc_cmd, vapi::Ip_route_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, table_id_t id, const prefix_t& prefix); - - /** - * 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: - route::table_id_t m_id; - prefix_t m_prefix; -}; - -/** - * A cmd class that Dumps ip fib routes - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(route::table_id_t id, const l3_proto_t& proto); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; - route::table_id_t m_id; - const l3_proto_t& m_proto; -}; - -}; // namespace ip_route_cmds -}; // namespace route -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/route_domain.cpp b/extras/vom/vom/route_domain.cpp deleted file mode 100644 index 16bf5f36c90..00000000000 --- a/extras/vom/vom/route_domain.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* - * 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/route_domain.hpp" -#include "vom/cmd.hpp" -#include "vom/route_domain_cmds.hpp" -#include "vom/singular_db_funcs.hpp" - -namespace VOM { - -route_domain::event_handler route_domain::m_evh; - -/** - * A DB of al the interfaces, key on the name - */ -singular_db route_domain::m_db; - -/** - * Construct a new object matching the desried state - */ -route_domain::route_domain(route::table_id_t id) - : m_hw_v4(true) - , m_hw_v6(true) - , m_table_id(id) -{ -} - -route_domain::route_domain(const route_domain& o) - : m_hw_v4(o.m_hw_v4) - , m_hw_v6(o.m_hw_v6) - , m_table_id(o.m_table_id) -{ -} - -bool -route_domain::operator==(const route_domain& r) const -{ - return (m_table_id == r.m_table_id); -} - -route::table_id_t -route_domain::table_id() const -{ - return (m_table_id); -} - -route_domain::key_t -route_domain::key() const -{ - return (table_id()); -} - -route_domain::const_iterator_t -route_domain::cbegin() -{ - return m_db.begin(); -} - -route_domain::const_iterator_t -route_domain::cend() -{ - return m_db.end(); -} - -void -route_domain::sweep() -{ - if (m_hw_v4) { - HW::enqueue( - new route_domain_cmds::delete_cmd(m_hw_v4, l3_proto_t::IPV4, m_table_id)); - } - if (m_hw_v6) { - HW::enqueue( - new route_domain_cmds::delete_cmd(m_hw_v6, l3_proto_t::IPV6, m_table_id)); - } - HW::write(); -} - -void -route_domain::replay() -{ - if (m_hw_v4) { - HW::enqueue( - new route_domain_cmds::create_cmd(m_hw_v4, l3_proto_t::IPV4, m_table_id)); - } - if (m_hw_v6) { - HW::enqueue( - new route_domain_cmds::create_cmd(m_hw_v6, l3_proto_t::IPV6, m_table_id)); - } -} - -route_domain::~route_domain() -{ - sweep(); - - // not in the DB anymore. - m_db.release(m_table_id, this); -} - -std::string -route_domain::to_string() const -{ - std::ostringstream s; - s << "route-domain:[" - << "table-id:" << m_table_id << " v4:" << m_hw_v4.to_string() - << " v6:" << m_hw_v6.to_string() << "]"; - - return (s.str()); -} - -std::shared_ptr -route_domain::find(const key_t& k) -{ - return (m_db.find(k)); -} - -void -route_domain::update(const route_domain& desired) -{ - /* - * create the table if it is not yet created - */ - if (rc_t::OK != m_hw_v4.rc()) { - HW::enqueue( - new route_domain_cmds::create_cmd(m_hw_v4, l3_proto_t::IPV4, m_table_id)); - } - if (rc_t::OK != m_hw_v6.rc()) { - HW::enqueue( - new route_domain_cmds::create_cmd(m_hw_v6, l3_proto_t::IPV6, m_table_id)); - } -} - -std::shared_ptr -route_domain::get_default() -{ - route_domain rd(route::DEFAULT_TABLE); - - return (find_or_add(rd)); -} - -std::shared_ptr -route_domain::find_or_add(const route_domain& temp) -{ - return (m_db.find_or_add(temp.m_table_id, temp)); -} - -std::shared_ptr -route_domain::singular() const -{ - return find_or_add(*this); -} - -void -route_domain::dump(std::ostream& os) -{ - db_dump(m_db, os); -} - -void -route_domain::event_handler::handle_populate(const client_db::key_t& key) -{ - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - - route_domain rd(payload.table.table_id); - - VOM_LOG(log_level_t::DEBUG) << "ip-table-dump: " << rd.to_string(); - - /* - * Write each of the discovered interfaces into the OM, - * but disable the HW Command q whilst we do, so that no - * commands are sent to VPP - */ - OM::commit(key, rd); - } -} - -route_domain::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "rd", "route-domain" }, "Route Domains", this); -} - -void -route_domain::event_handler::handle_replay() -{ - m_db.replay(); -} - -dependency_t -route_domain::event_handler::order() const -{ - return (dependency_t::TABLE); -} - -void -route_domain::event_handler::show(std::ostream& os) -{ - db_dump(m_db, os); -} - -}; // namespace VOPM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/route_domain.hpp b/extras/vom/vom/route_domain.hpp deleted file mode 100644 index 78db63bbe59..00000000000 --- a/extras/vom/vom/route_domain.hpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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_ROUTE_DOMAIN_H__ -#define __VOM_ROUTE_DOMAIN_H__ - -#include "vom/inspect.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/prefix.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A route-domain is a VRF. - * creating a route-domain object will construct both an IPv4 - * and IPv6 table. - */ -class route_domain : public object_base -{ -public: - /** - * The Key for a route-domain - */ - typedef route::table_id_t key_t; - - /** - * The iterator type - */ - typedef singular_db::const_iterator - const_iterator_t; - - static const_iterator_t cbegin(); - static const_iterator_t cend(); - - /** - * Construct a new object matching the desried state - */ - route_domain(route::table_id_t id); - - /** - * Copy Constructor - */ - route_domain(const route_domain& o); - - /** - * Destructor - */ - ~route_domain(); - - /** - * comparison operator - for UT - */ - bool operator==(const route_domain& r) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Debug print function - */ - std::string to_string() const; - - /** - * Get the table ID - */ - route::table_id_t table_id() const; - - /** - * Get the route-domain's key - */ - key_t key() const; - - /** - * Find the instnace of the route domain in the OM - */ - static std::shared_ptr find(const key_t& temp); - - /** - * Dump all route-doamin into the stream provided - */ - static void dump(std::ostream& os); - - /** - * Return the sigular instance for the default table - */ - static std::shared_ptr get_default(); - - /** - * replay the object to create it in hardware - */ - void replay(void); - -private: - /** - * 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; - }; - - /** - * Instance of the event handler to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const route_domain& obj); - - /** - * Find or add the instnace of the route domain in the OM - */ - static std::shared_ptr find_or_add(const route_domain& temp); - - /* - * It's the OM class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * HW configuration for the result of creating the v4 table - */ - HW::item m_hw_v4; - - /** - * HW configuration for the result of creating the v6 table - */ - HW::item m_hw_v6; - - /** - * VPP understands Table-IDs not table names. - * The table IDs for V4 and V6 are the same. - */ - route::table_id_t m_table_id; - - /** - * A map of all interfaces key against the interface's name - */ - static singular_db m_db; -}; -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/route_domain_cmds.cpp b/extras/vom/vom/route_domain_cmds.cpp deleted file mode 100644 index 8f135e50ef5..00000000000 --- a/extras/vom/vom/route_domain_cmds.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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/route_domain_cmds.hpp" - -namespace VOM { -namespace route_domain_cmds { - -create_cmd::create_cmd(HW::item& item, - l3_proto_t proto, - route::table_id_t id) - : rpc_cmd(item) - , m_id(id) - , m_proto(proto) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return (m_id == other.m_id); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.table.table_id = m_id; - payload.table.is_ip6 = m_proto.is_ipv6(); - payload.is_add = 1; - - VAPI_CALL(req.execute()); - - return (wait()); -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "ip-table-create: " << m_hw_item.to_string() << " id:" << m_id - << " af:" << m_proto.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - l3_proto_t proto, - route::table_id_t id) - : rpc_cmd(item) - , m_id(id) - , m_proto(proto) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_id == other.m_id); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.table.table_id = m_id; - payload.table.is_ip6 = m_proto.is_ipv6(); - payload.is_add = 0; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - return (rc_t::OK); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "ip-table-delete: " << m_hw_item.to_string() << " id:" << m_id - << " af:" << m_proto.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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 ("ip-table-dump"); -} - -} // namespace route_domain_cmds -} // namespace VOM - /* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/route_domain_cmds.hpp b/extras/vom/vom/route_domain_cmds.hpp deleted file mode 100644 index 42546da91b4..00000000000 --- a/extras/vom/vom/route_domain_cmds.hpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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_ROUTE_DOMAIN_CMDS_H__ -#define __VOM_ROUTE_DOMAIN_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/route_domain.hpp" -#include "vom/rpc_cmd.hpp" - -#include - -namespace VOM { -namespace route_domain_cmds { - -/** - * A command class that creates the IP table - */ -class create_cmd : public rpc_cmd, vapi::Ip_table_add_del> -{ -public: - /** - * Constructor - */ - create_cmd(HW::item& item, l3_proto_t proto, route::table_id_t id); - - /** - * 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; - -private: - /** - * table-ID to create - */ - route::table_id_t m_id; - - /** - * L3 protocol of the table - */ - l3_proto_t m_proto; -}; - -/** - * A cmd class that Deletes the IP Table - */ -class delete_cmd : public rpc_cmd, vapi::Ip_table_add_del> -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item, l3_proto_t proto, route::table_id_t id); - - /** - * 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: - /** - * table-ID to create - */ - route::table_id_t m_id; - - /** - * L3 protocol of the table - */ - l3_proto_t m_proto; -}; - -/** - * A cmd class that Dumps IP fib tables - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Constructor - */ - dump_cmd(); - dump_cmd(const dump_cmd& d); - - /** - * 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; - -private: - /** - * HW reutrn code - */ - HW::item item; -}; - -}; // namespace route_domain_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/rpc_cmd.hpp b/extras/vom/vom/rpc_cmd.hpp deleted file mode 100644 index ccb41abbd2d..00000000000 --- a/extras/vom/vom/rpc_cmd.hpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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_RPC_CMD_H__ -#define __VOM_RPC_CMD_H__ - -#include - -#include - -#include "vom/cmd.hpp" -#include "vom/logger.hpp" - -namespace VOM { -/** - * A base class for all RPC commands to VPP. - * RPC commands are one of the sub-set of command types to VPP - * that modify/create state in VPP and thus return an error code. - * Commands are issued in one thread context, but read in another. The - * command has an associated std::promise that is met by the RX thread. - * this allows the sender, which waits on the promise's future, to - * experience a synchronous command. - * - * 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 -class rpc_cmd : public cmd -{ -public: - /** - * convenient typedef - */ - typedef MSG msg_t; - - /** - * Constructor taking the HW item that will be updated by the command - */ - rpc_cmd(HWITEM& item) - : cmd() - , m_hw_item(item) - , m_promise() - { - } - - /** - * Desructor - */ - virtual ~rpc_cmd() {} - - /** - * return the HW item the command updates - */ - HWITEM& item() { return m_hw_item; } - - /** - * return the const HW item the command updates - */ - const HWITEM& item() const { return m_hw_item; } - - /** - * Fulfill the commands promise. Called from the RX thread - */ - void fulfill(const HWITEM& d) { m_promise.set_value(d); } - - /** - * Wait on the commands promise. i.e. block on the completion - * of the command. - */ - rc_t wait() - { - std::future_status status; - std::future result; - - result = m_promise.get_future(); - status = result.wait_for(std::chrono::seconds(5)); - - if (status != std::future_status::ready) { - m_hw_item.set(rc_t::TIMEOUT); - } else { - m_hw_item = result.get(); - } - - return (m_hw_item.rc()); - } - - /** - * Called by the HW Command Q when it is disabled to indicate the - * command can be considered successful without issuing it to HW - */ - virtual void succeeded() - { - m_hw_item.set(rc_t::OK); - VOM_LOG(log_level_t::DEBUG) << to_string(); - } - - /** - * call operator used as a callback by VAPI when the reply is available - */ - 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; - - /* set a temporary value in this callback thread */ - hi.set(rc_t::from_vpp_retval(retval)); - fulfill(hi); - - return (VAPI_OK); - } - - /** - * Retire/cancel a long running command - */ - virtual void retire(connection& con) {} - -protected: - /** - * A reference to an object's HW::item that the command will update - */ - HWITEM& m_hw_item; - - /** - * The promise that implements the synchronous issue - */ - std::promise m_promise; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/singular_db.hpp b/extras/vom/vom/singular_db.hpp deleted file mode 100644 index afca9a3509e..00000000000 --- a/extras/vom/vom/singular_db.hpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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_INST_DB_H__ -#define __VOM_INST_DB_H__ - -#include -#include -#include - -#include "vom/logger.hpp" - -namespace VOM { -/** - * A Database to store the unique 'singular' instances of a single object - * type. - * The instances are stored as weak pointers. So the DB does not own these - * objects, they are owned by object in the client_db. - */ -template -class singular_db -{ -public: - /** - * Constructor - */ - singular_db() {} - - /** - * Iterator - */ - typedef - typename std::map>::const_iterator const_iterator; - - /** - * Get iterator to the beginning of the DB - */ - const_iterator begin() const { return m_map.cbegin(); } - - /** - * Get iterator to the beginning of the DB - */ - const_iterator end() const { return m_map.cend(); } - - /** - * Find or add the object to the store. - * The object passed is deisred state. A new instance will be copy - * constructed from it. This function is templatised on the object type - * passed, which may be drrived from, the object type stored. this - * prevents slicing during the make_shared construction. - */ - template - std::shared_ptr find_or_add(const KEY& key, const DERIVED& obj) - { - auto search = m_map.find(key); - - if (search == m_map.end()) { - std::shared_ptr sp = std::make_shared(obj); - - m_map[key] = sp; - - VOM_LOG(log_level_t::DEBUG) << *sp; - return (sp); - } - - return (search->second.lock()); - } - - /** - * Find the object to the store. - */ - std::shared_ptr find(const KEY& key) - { - auto search = m_map.find(key); - - if (search == m_map.end()) { - std::shared_ptr sp(NULL); - - return (sp); - } - - return (search->second.lock()); - } - - /** - * Release the object from the DB store, if it's the one we have stored - */ - void release(const KEY& key, const OBJ* obj) - { - auto search = m_map.find(key); - - if (search != m_map.end()) { - if (search->second.expired()) { - m_map.erase(key); - } else { - std::shared_ptr sp = m_map[key].lock(); - - if (sp.get() == obj) { - m_map.erase(key); - } - } - } - } - - /** - * Find the object to the store. - */ - void add(const KEY& key, std::shared_ptr sp) { m_map[key] = sp; } - - /** - * Populate VPP from current state, on VPP restart - */ - void replay() - { - for (auto entry : m_map) { - entry.second.lock()->replay(); - } - } - -private: - /** - * the map of objects against their key - */ - std::map> m_map; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/singular_db_funcs.hpp b/extras/vom/vom/singular_db_funcs.hpp deleted file mode 100644 index dddc6e4c229..00000000000 --- a/extras/vom/vom/singular_db_funcs.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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_INST_DB_FUNCS_H__ -#define __VOM_INST_DB_FUNCS_H__ - -#include - -#include "singular_db.hpp" - -/** - * A set of helper function to iterate over objects in the DB. - * These functions are delcared not as DB member functions so that - * the template instatiation of the DB does not require the definitions - * of the functions used to be declared. - */ -namespace VOM { -/** - * Print each of the objects in the DB into the stream provided - */ -template -void -db_dump(const DB& db, std::ostream& os) -{ - for (const auto entry : db) { - os << "key: " << entry.first << std::endl; - os << " " << entry.second.lock()->to_string() << std::endl; - } -} -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/srpc_cmd.hpp b/extras/vom/vom/srpc_cmd.hpp deleted file mode 100644 index da6064dafba..00000000000 --- a/extras/vom/vom/srpc_cmd.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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_SRPC_CMD_H__ -#define __VOM_SRPC_CMD_H__ - -#include "vom/hw.hpp" -#include "vom/rpc_cmd.hpp" - -namespace VOM { -template -class srpc_cmd : public rpc_cmd, MSG> -{ -public: - /** - * convenient typedef - */ - typedef MSG msg_t; - - /** - * Constructor taking the HW item that will be updated by the command - */ - srpc_cmd(HW::item& item) - : rpc_cmd, MSG>(item) - { - } - - /** - * Desructor - */ - virtual ~srpc_cmd() {} - - virtual vapi_error_e operator()(MSG& reply) - { - int stats_index = reply.get_response().get_payload().stats_index; - int retval = reply.get_response().get_payload().retval; - - VOM_LOG(log_level_t::DEBUG) << this->to_string() << " " << retval; - - rc_t rc = rc_t::from_vpp_retval(retval); - handle_t handle = handle_t::INVALID; - - if (rc_t::OK == rc) { - handle = stats_index; - } - - this->fulfill(HW::item(handle, rc)); - - return (VAPI_OK); - } -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/stat_client.cpp b/extras/vom/vom/stat_client.cpp deleted file mode 100644 index 00751dd8d49..00000000000 --- a/extras/vom/vom/stat_client.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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/stat_client.hpp" - -namespace VOM { - -stat_client::stat_data_t::stat_data_t(const stat_segment_data_t& stat_seg_data) - : m_name(stat_seg_data.name) - , m_type(stat_seg_data.type) -{ - switch (m_type) { - case STAT_DIR_TYPE_SCALAR_INDEX: - m_scalar_value = stat_seg_data.scalar_value; - break; - case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE: - m_simple_counter_vec = stat_seg_data.simple_counter_vec; - break; - case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED: - m_combined_counter_vec = stat_seg_data.combined_counter_vec; - break; - case STAT_DIR_TYPE_ERROR_INDEX: - m_error_vec = stat_seg_data.error_vector; - break; - case STAT_DIR_TYPE_NAME_VECTOR: - break; - case STAT_DIR_TYPE_ILLEGAL: - break; - case STAT_DIR_TYPE_EMPTY: - break; - } -} - -const std::string& -stat_client::stat_data_t::name() const -{ - return m_name; -} - -const stat_directory_type_t& -stat_client::stat_data_t::type() const -{ - return m_type; -} - -double -stat_client::stat_data_t::get_stat_segment_scalar_data() const -{ - return m_scalar_value; -} - -uint64_t* -stat_client::stat_data_t::get_stat_segment_error_data() const -{ - return m_error_vec; -} - -uint64_t** -stat_client::stat_data_t::get_stat_segment_simple_counter_data() const -{ - return m_simple_counter_vec; -} - -vlib_counter_t** -stat_client::stat_data_t::get_stat_segment_combined_counter_data() const -{ - return m_combined_counter_vec; -} - -stat_client::stat_client(std::string& socket_name) - : m_socket_name(socket_name) - , m_patterns() - , m_stat_connect(false) - , m_counter_vec() - , m_stat_seg_data(nullptr) - , m_stat_data() -{ - m_patterns.push_back("/if"); -} - -stat_client::stat_client(std::vector& pattern) - : m_socket_name("/run/vpp/stats.sock") - , m_patterns(pattern) - , m_stat_connect(false) - , m_counter_vec() - , m_stat_seg_data(nullptr) - , m_stat_data() -{} - -stat_client::stat_client(std::string socket_name, - std::vector patterns) - : m_socket_name(socket_name) - , m_patterns(patterns) - , m_stat_connect(false) - , m_counter_vec() - , m_stat_seg_data(nullptr) - , m_stat_data() -{} - -stat_client::stat_client() - : m_socket_name("/run/vpp/stats.sock") - , m_patterns() - , m_stat_connect(false) - , m_counter_vec() - , m_stat_seg_data(nullptr) - , m_stat_data() -{ - m_patterns.push_back("/if"); -} - -stat_client::~stat_client() -{ - stat_segment_vec_free(m_counter_vec); - data_free(); - if (m_stat_connect) - stat_segment_disconnect(); -} - -stat_client::stat_client(const stat_client& o) - : m_socket_name(o.m_socket_name) - , m_patterns(o.m_patterns) -{} - -int -stat_client::connect() -{ - if (stat_segment_connect(m_socket_name.c_str()) == 0) { - m_stat_connect = true; - ls(); - } - return m_stat_connect; -} - -void -stat_client::disconnect() -{ - if (m_stat_connect) - stat_segment_disconnect(); - m_stat_connect = false; -} - -int -stat_client::vec_len(void* vec) -{ - return stat_segment_vec_len(vec); -} - -void -stat_client::vec_free(void* vec) -{ - stat_segment_vec_free(vec); -} - -void -stat_client::ls() -{ - uint8_t** string_vec = { 0 }; - for (auto& pattern : m_patterns) { - string_vec = stat_segment_string_vector(string_vec, pattern.c_str()); - } - m_counter_vec = stat_segment_ls(string_vec); - stat_segment_vec_free(string_vec); -} - -const stat_client::stat_data_vec_t& -stat_client::dump() -{ - stat_segment_data_free(m_stat_seg_data); - m_stat_seg_data = NULL; - if (m_stat_data.size()) { - m_stat_data.clear(); - } - if (m_stat_connect) { - m_stat_seg_data = stat_segment_dump(m_counter_vec); - if (!m_stat_seg_data) { - ls(); - return m_stat_data; - } - for (int i = 0; i < stat_segment_vec_len(m_stat_seg_data); i++) { - stat_data_t sd(m_stat_seg_data[i]); - m_stat_data.push_back(sd); - } - } - return m_stat_data; -} - -const stat_client::stat_data_vec_t& -stat_client::dump_entry(uint32_t index) -{ - stat_segment_data_free(m_stat_seg_data); - m_stat_seg_data = NULL; - if (m_stat_data.size()) { - m_stat_data.clear(); - } - if (m_stat_connect) { - m_stat_seg_data = stat_segment_dump_entry(index); - if (!m_stat_seg_data) { - ls(); - return m_stat_data; - } - for (int i = 0; i < stat_segment_vec_len(m_stat_seg_data); i++) { - stat_data_t sd(m_stat_seg_data[i]); - m_stat_data.push_back(sd); - } - } - return m_stat_data; -} - -void -stat_client::data_free() -{ - stat_segment_data_free(m_stat_seg_data); -} - -double -stat_client::heartbeat() -{ - return stat_segment_heartbeat(); -} - -std::string -stat_client::index_to_name(uint32_t index) -{ - return stat_segment_index_to_name(index); -} - -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/stat_client.hpp b/extras/vom/vom/stat_client.hpp deleted file mode 100644 index f1745c87b20..00000000000 --- a/extras/vom/vom/stat_client.hpp +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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_STAT_CLIENT_H__ -#define __VOM_STAT_CLIENT_H__ - -#include -#include -#include - -extern "C" { -#include -} - -namespace VOM { - -/** - * A representation of a stat client in VPP - */ -class stat_client -{ -public: - /** - * stat data representation - */ - struct stat_data_t - { - /** - * stat data custom constructor - */ - stat_data_t(const stat_segment_data_t& stat_seg_data); - - /** - * get name of stat - */ - const std::string& name() const; - - /** - * get type of stat - */ - const stat_directory_type_t& type() const; - - /** - * Get pointer to actual data - */ - double get_stat_segment_scalar_data() const; - uint64_t* get_stat_segment_error_data() const; - uint64_t** get_stat_segment_simple_counter_data() const; - vlib_counter_t** get_stat_segment_combined_counter_data() const; - - private: - /** - * name of stat data - */ - const std::string m_name; - - /** - * type of stat data - */ - const stat_directory_type_t m_type; - - /** - * union of pointers to actual stat data - */ - union - { - double m_scalar_value; - counter_t* m_error_vec; - counter_t** m_simple_counter_vec; - vlib_counter_t** m_combined_counter_vec; - }; - }; - - /** - * vector of stat_data_t - */ - typedef std::vector stat_data_vec_t; - - /** - * Stat Client constructor with custom socket name - */ - stat_client(std::string& socket_name); - - /** - * Stat Client constructor with custom vector of patterns - */ - stat_client(std::vector& pattern); - - /** - * Stat Client constructor with custom socket name and vector of patterns - */ - stat_client(std::string socket_name, std::vector patterns); - - /** - * Stat Client constructor - */ - stat_client(); - - /** - * Stat Client destructor - */ - ~stat_client(); - - /** - * Stat Client copy constructor - */ - stat_client(const stat_client& o); - - /** - * Connect to stat segment - */ - int connect(); - - /** - * Disconnect to stat segment - */ - void disconnect(); - - /** - * dump all the stats for given pattern - */ - const stat_data_vec_t& dump(); - - /** - * dump stats for given index in stat directory - */ - const stat_data_vec_t& dump_entry(uint32_t index); - - /** - * Get vector length of VPP style vector - */ - int vec_len(void* vec); - - double heartbeat(); - - /** - * get index to name of stat - */ - std::string index_to_name(uint32_t index); - -private: - /** - * Free VPP style vector - */ - void vec_free(void* vec); - - /** - * Free stat segment data - */ - void data_free(); - - /** - * ls on the stat directory using given pattern - */ - void ls(); - - /** - * socket name - */ - std::string m_socket_name; - - /** - * vector of patterns for stats - */ - std::vector m_patterns; - - /** - * connection bit - */ - bool m_stat_connect; - - /** - * Pointer to VPP style vector of stat indexes - */ - uint32_t* m_counter_vec; - - /** - * Pointer to stat segment - */ - stat_segment_data_t* m_stat_seg_data; - - /** - * Vector of stat data - */ - stat_data_vec_t m_stat_data; -}; -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/stat_reader.cpp b/extras/vom/vom/stat_reader.cpp deleted file mode 100644 index 50a25d2e0ba..00000000000 --- a/extras/vom/vom/stat_reader.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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/stat_reader.hpp" -#include "vom/interface.hpp" - -namespace VOM { - -stat_reader::stat_indexes_t stat_reader::m_stat_itf_indexes; - -stat_reader::stat_reader() - : m_client() -{} - -stat_reader::stat_reader(stat_client sc) - : m_client(sc) -{} - -stat_reader::~stat_reader() {} - -int -stat_reader::connect() -{ - return m_client.connect(); -} - -void -stat_reader::disconnect() -{ - m_client.disconnect(); -} - -void -stat_reader::registers(const interface& intf) -{ - m_stat_itf_indexes.insert(intf.handle_i().value()); -} - -void -stat_reader::unregisters(const interface& intf) -{ - m_stat_itf_indexes.erase(intf.handle_i().value()); -} - -void -stat_reader::read() -{ - std::set> itfs_w_stats; - const stat_client::stat_data_vec_t& sd = m_client.dump(); - - for (auto& sde : sd) { - std::string name; - - if (sde.name().empty()) - continue; - - name = sde.name(); - - if (name.find("/if") != std::string::npos) - name.erase(0, 4); - - switch (sde.type()) { - case STAT_DIR_TYPE_ERROR_INDEX: - case STAT_DIR_TYPE_SCALAR_INDEX: - case STAT_DIR_TYPE_NAME_VECTOR: - case STAT_DIR_TYPE_ILLEGAL: - case STAT_DIR_TYPE_EMPTY: - break; - - case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE: { - uint64_t** data; - - data = sde.get_stat_segment_simple_counter_data(); - - for (auto& i : m_stat_itf_indexes) { - counter_t count; - - for (int k = 0; k < m_client.vec_len(data); k++) { - count.packets += data[k][i]; - } - - std::shared_ptr itf = interface::find(i); - if (itf) { - itf->set(count, name); - itfs_w_stats.insert(itf); - } - } - break; - } - - case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED: { - vlib_counter_t** data; - - data = sde.get_stat_segment_combined_counter_data(); - - for (auto& i : m_stat_itf_indexes) { - counter_t count; - - for (int k = 0; k < m_client.vec_len(data); k++) { - count.packets += data[k][i].packets; - count.bytes += data[k][i].bytes; - } - - std::shared_ptr itf = interface::find(i); - if (itf) { - itf->set(count, name); - itfs_w_stats.insert(itf); - } - } - break; - } - } - } - for (auto itf : itfs_w_stats) { - itf->publish_stats(); - } -} - -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/stat_reader.hpp b/extras/vom/vom/stat_reader.hpp deleted file mode 100644 index f90b2561602..00000000000 --- a/extras/vom/vom/stat_reader.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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_STAT_READER_H__ -#define __VOM_STAT_READER_H__ - -#include "vom/stat_client.hpp" -#include - -namespace VOM { - -class interface; - -/** - * Stat reader: single interface to get stats - */ -class stat_reader -{ -public: - /** - * Default Constructor - */ - stat_reader(); - - /** - * Constructor - */ - stat_reader(stat_client sc); - - /** - * Destructor - */ - ~stat_reader(); - - /** - * connection to stat object - */ - virtual int connect(); - - /** - * disconnect to stat object - */ - virtual void disconnect(); - - /** - * read stats for registered objects from stat_segment - * and set those stats to respective objects - */ - virtual void read(); - -private: - /** - * friend to interface class to call stat_register and - * stat_unregister methods - */ - friend class interface; - - /** - * Register objects to get stats for - */ - static void registers(const interface& itf); - - /** - * Unregister objects - */ - static void unregisters(const interface& itf); - - /** - * typedef of stat_indexes - */ - typedef std::set stat_indexes_t; - - /** - * stat_client object - */ - stat_client m_client; - - /** - * static pointer to set of registered interfaces - */ - static stat_indexes_t m_stat_itf_indexes; -}; -}; -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ -#endif diff --git a/extras/vom/vom/sub_interface.cpp b/extras/vom/vom/sub_interface.cpp deleted file mode 100644 index 42f75791968..00000000000 --- a/extras/vom/vom/sub_interface.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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/sub_interface.hpp" -#include "vom/sub_interface_cmds.hpp" - -namespace VOM { -/** - * Construct a new object matching the desried state - */ -sub_interface::sub_interface(const interface& parent, - admin_state_t state, - vlan_id_t vlan) - : interface(mk_name(parent, vlan), parent.type(), state) - , m_parent(parent.singular()) - , m_vlan(vlan) -{ -} - -/** - * Construct a new object matching the desried state - */ -sub_interface::sub_interface(const interface& parent, - admin_state_t state, - const route_domain& rd, - vlan_id_t vlan) - : interface(mk_name(parent, vlan), parent.type(), state, rd) - , m_parent(parent.singular()) - , m_vlan(vlan) -{ -} - -sub_interface::~sub_interface() -{ - sweep(); - release(); -} - -sub_interface::sub_interface(const sub_interface& o) - : interface(o) - , m_parent(o.m_parent) - , m_vlan(o.m_vlan) -{ -} - -bool -sub_interface::operator==(const sub_interface& s) const -{ - return (interface::operator==(s) && (m_parent->key() == s.m_parent->key()) && - (m_vlan == s.m_vlan)); -} - -std::string -sub_interface::mk_name(const interface& parent, vlan_id_t vlan) -{ - return (parent.name() + "." + std::to_string(vlan)); -} - -std::queue& -sub_interface::mk_create_cmd(std::queue& q) -{ - q.push(new sub_interface_cmds::create_cmd(m_hdl, name(), m_parent->handle(), - m_vlan)); - - return (q); -} - -std::queue& -sub_interface::mk_delete_cmd(std::queue& q) -{ - q.push(new sub_interface_cmds::delete_cmd(m_hdl)); - - return (q); -} - -std::shared_ptr -sub_interface::singular() const -{ - return std::dynamic_pointer_cast(singular_i()); -} - -std::shared_ptr -sub_interface::singular_i() const -{ - return m_db.find_or_add(key(), *this); -} - -std::shared_ptr -sub_interface::find(const key_t& k) -{ - return std::dynamic_pointer_cast(m_db.find(k)); -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/sub_interface.hpp b/extras/vom/vom/sub_interface.hpp deleted file mode 100644 index 506133c900d..00000000000 --- a/extras/vom/vom/sub_interface.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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_SUB_INTERFACE_H__ -#define __VOM_SUB_INTERFACE_H__ - -#include "vom/interface.hpp" - -namespace VOM { -/** - * A Sub-interface. e.g. a VLAN sub-interface on an Ethernet interface - */ -class sub_interface : public interface -{ - /* - * Typedef for VLAN ID - */ - typedef uint16_t vlan_id_t; - -public: - /** - * Construct a new object matching the desried state - */ - sub_interface(const interface& parent, admin_state_t state, vlan_id_t vlan); - - sub_interface(const interface& parent, - admin_state_t state, - const route_domain& rd, - vlan_id_t vlan); - - /** - * Destructor - */ - ~sub_interface(); - /** - * Copy Constructor - */ - sub_interface(const sub_interface& o); - - /** - * comparison operator - for UT - */ - bool operator==(const sub_interface& s) const; - - /** - * Return the matching 'singular instance' of the sub-interface - */ - std::shared_ptr singular() const; - - /** - * Find a subinterface from its key - */ - static std::shared_ptr find(const key_t& k); - -private: - /** - * Return the matching 'instance' of the sub-interface - * over-ride from the base class - */ - std::shared_ptr singular_i() const; - - /** - * Virtual functions to construct an interface create commands. - */ - virtual std::queue& mk_create_cmd(std::queue& cmds); - - /** - * Virtual functions to construct an interface delete commands. - */ - virtual std::queue& mk_delete_cmd(std::queue& cmds); - - /** - * From the name of the parent and the vlan, - * construct the sub-interface's name - */ - static std::string mk_name(const interface& parent, vlan_id_t vlan); - - /** - * Refernece conter lock on the parent - */ - const std::shared_ptr m_parent; - - /** - * VLAN ID - */ - vlan_id_t m_vlan; -}; -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/sub_interface_cmds.cpp b/extras/vom/vom/sub_interface_cmds.cpp deleted file mode 100644 index 853a9b63698..00000000000 --- a/extras/vom/vom/sub_interface_cmds.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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/sub_interface_cmds.hpp" -#include "vom/cmd.hpp" - -#include - -namespace VOM { -namespace sub_interface_cmds { - -create_cmd::create_cmd(HW::item& item, - const std::string& name, - const handle_t& parent, - uint16_t vlan) - : interface::create_cmd(item, name) - , m_parent(parent) - , m_vlan(vlan) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return ((m_name == other.m_name) && (m_parent == other.m_parent) && - (m_vlan == other.m_vlan)); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_parent.value(); - payload.vlan_id = m_vlan; - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) { - insert_interface(); - } - - return rc_t::OK; -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "sub-itf-create: " << m_hw_item.to_string() << " parent:" << m_parent - << " vlan:" << m_vlan; - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item) - : interface::delete_cmd(item) -{ -} - -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)); - - auto& payload = req.get_request().get_payload(); - payload.sw_if_index = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_interface(); - return (rc_t::OK); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - - s << "sub-itf-delete: " << m_hw_item.to_string(); - - return (s.str()); -} -} // namespace sub_interface_cmds -} // namespace VOM - /* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/sub_interface_cmds.hpp b/extras/vom/vom/sub_interface_cmds.hpp deleted file mode 100644 index a21323200bb..00000000000 --- a/extras/vom/vom/sub_interface_cmds.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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_SUB_INTERFACE_CMDS_H__ -#define __VOM_SUB_INTERFACE_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" -#include "vom/sub_interface.hpp" - -#include - -namespace VOM { -namespace sub_interface_cmds { - -/** - * A functor class that creates an interface - */ -class create_cmd : public interface::create_cmd -{ -public: - /** - * Cstrunctor taking the reference to the parent - * and the sub-interface's VLAN - */ - create_cmd(HW::item& item, - const std::string& name, - const handle_t& parent, - uint16_t vlan); - - /** - * 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; - -private: - /** - * Refernece to the parents handle - */ - const handle_t& m_parent; - - /** - * The VLAN of the sub-interface - */ - uint16_t m_vlan; -}; - -/** - * A cmd class that Delete an interface - */ -class delete_cmd : public interface::delete_cmd -{ -public: - /** - * Constructor - */ - delete_cmd(HW::item& item); - - /** - * 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; -}; - -}; // namespace sub_interface_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/tap_interface.cpp b/extras/vom/vom/tap_interface.cpp deleted file mode 100644 index 6555aeae5ee..00000000000 --- a/extras/vom/vom/tap_interface.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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/tap_interface.hpp" -#include "vom/tap_interface_cmds.hpp" - -#include - -namespace VOM { -tap_interface::event_handler tap_interface::m_evh; - -/** - * Construct a new object matching the desried state - */ -tap_interface::tap_interface(const std::string& name, - const admin_state_t& state, - const route::prefix_t& prefix) - : interface(name, type_t::TAPV2, state) - , m_prefix(prefix) - , m_l2_address(l2_address_t::ZERO) -{ -} - -tap_interface::tap_interface(const std::string& name, - const admin_state_t& state, - const route::prefix_t& prefix, - const l2_address_t& l2_address) - : interface(name, type_t::TAPV2, state) - , m_prefix(prefix) - , m_l2_address(l2_address) -{ -} - -tap_interface::~tap_interface() -{ - sweep(); - release(); -} - -tap_interface::tap_interface(const tap_interface& o) - : interface(o) - , m_prefix(o.m_prefix) - , m_l2_address(o.m_l2_address) -{ -} - -std::queue& -tap_interface::mk_create_cmd(std::queue& q) -{ - q.push(new tap_interface_cmds::tapv2_create_cmd(m_hdl, name(), m_prefix, - m_l2_address)); - - return (q); -} - -std::queue& -tap_interface::mk_delete_cmd(std::queue& q) -{ - q.push(new tap_interface_cmds::tapv2_delete_cmd(m_hdl)); - - return (q); -} - -std::shared_ptr -tap_interface::singular() const -{ - return std::dynamic_pointer_cast(singular_i()); -} - -std::shared_ptr -tap_interface::singular_i() const -{ - return m_db.find_or_add(name(), *this); -} - -void -tap_interface::event_handler::handle_populate(const client_db::key_t& key) -{ - // It will be polulate by interface handler -} - -tap_interface::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "tap" }, "tap_interfaces", this); -} - -void -tap_interface::event_handler::handle_replay() -{ - // It will be replayed by interface handler -} - -dependency_t -tap_interface::event_handler::order() const -{ - return (dependency_t::INTERFACE); -} - -void -tap_interface::event_handler::show(std::ostream& os) -{ - // dumped by the interface handler -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/tap_interface.hpp b/extras/vom/vom/tap_interface.hpp deleted file mode 100644 index a29ad358b52..00000000000 --- a/extras/vom/vom/tap_interface.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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_TAP_INTERFACE_H__ -#define __VOM_TAP_INTERFACE_H__ - -#include "vom/interface.hpp" - -namespace VOM { -/** - * A tap-interface. e.g. a tap interface - */ -class tap_interface : public interface -{ -public: - tap_interface(const std::string& name, - const admin_state_t& state, - const route::prefix_t& prefix); - - tap_interface(const std::string& name, - const admin_state_t& state, - const route::prefix_t& prefix, - const l2_address_t& l2_address); - - ~tap_interface(); - tap_interface(const tap_interface& o); - - /** - * Return the matching 'singular instance' of the TAP interface - */ - std::shared_ptr singular() const; - -private: - /** - * 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; - - /** - * host Ip Prefix - */ - route::prefix_t m_prefix; - - /** - * host mac address - */ - l2_address_t m_l2_address; - - /** - * Return the matching 'instance' of the sub-interface - * over-ride from the base class - */ - std::shared_ptr singular_i() const; - - /** - * Virtual functions to construct an interface create commands. - */ - virtual std::queue& mk_create_cmd(std::queue& cmds); - - /** - * Virtual functions to construct an interface delete commands. - */ - virtual std::queue& mk_delete_cmd(std::queue& cmds); - - /* - * It's the OM class that call singular() - */ - friend class OM; -}; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/tap_interface_cmds.cpp b/extras/vom/vom/tap_interface_cmds.cpp deleted file mode 100644 index 16bb065e016..00000000000 --- a/extras/vom/vom/tap_interface_cmds.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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/tap_interface_cmds.hpp" - -#include - -DEFINE_VAPI_MSG_IDS_TAPV2_API_JSON; - -namespace VOM { -namespace tap_interface_cmds { -/* - * TAPV2 - */ -tapv2_create_cmd::tapv2_create_cmd(HW::item& item, - const std::string& name, - const route::prefix_t& prefix, - const l2_address_t& l2_address) - : interface::create_cmd(item, name) - , m_prefix(prefix) - , m_l2_address(l2_address) -{} - -rc_t -tapv2_create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - memset(payload.host_if_name, 0, sizeof(payload.host_if_name)); - memcpy(payload.host_if_name, - m_name.c_str(), - std::min(m_name.length(), sizeof(payload.host_if_name))); - payload.host_if_name_set = 1; - - if (m_prefix != route::prefix_t::ZERO) { - if (m_prefix.address().is_v6()) { - m_prefix.to_vpp((uint8_t*)&payload.host_ip6_prefix_set, - payload.host_ip6_prefix.address, - &payload.host_ip6_prefix.len); - } else { - m_prefix.to_vpp((uint8_t*)&payload.host_ip4_prefix_set, - payload.host_ip4_prefix.address, - &payload.host_ip4_prefix.len); - payload.host_ip4_prefix_set = 1; - } - } - - if (m_l2_address != l2_address_t::ZERO) { - m_l2_address.to_bytes(payload.host_mac_addr, 6); - payload.host_mac_addr_set = 1; - } - - payload.id = 0xffffffff; - payload.use_random_mac = 1; - payload.tx_ring_sz = 1024; - payload.rx_ring_sz = 1024; - - VAPI_CALL(req.execute()); - - wait(); - - if (m_hw_item.rc() == rc_t::OK) { - insert_interface(); - } - - return rc_t::OK; -} - -std::string -tapv2_create_cmd::to_string() const -{ - std::ostringstream s; - s << "tapv2-intf-create: " << m_hw_item.to_string() - << " ip-prefix:" << m_prefix.to_string(); - - return (s.str()); -} - -tapv2_delete_cmd::tapv2_delete_cmd(HW::item& item) - : interface::delete_cmd(item) -{} - -rc_t -tapv2_delete_cmd::issue(connection& con) -{ - - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.sw_if_index = m_hw_item.data().value(); - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_interface(); - return rc_t::OK; -} -std::string -tapv2_delete_cmd::to_string() const -{ - std::ostringstream s; - s << "tapv2-itf-delete: " << m_hw_item.to_string(); - - return (s.str()); -} - -tapv2_dump_cmd::tapv2_dump_cmd() {} - -bool -tapv2_dump_cmd::operator==(const tapv2_dump_cmd& other) const -{ - return (true); -} - -rc_t -tapv2_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 -tapv2_dump_cmd::to_string() const -{ - return ("tapv2-itf-dump"); -} - -} // namespace tap_interface_cmds -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/tap_interface_cmds.hpp b/extras/vom/vom/tap_interface_cmds.hpp deleted file mode 100644 index 386dafaa648..00000000000 --- a/extras/vom/vom/tap_interface_cmds.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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_TAP_INTERFACE_CMDS_H__ -#define __VOM_TAP_INTERFACE_CMDS_H__ - -#include "vom/interface.hpp" -#include "vom/tap_interface.hpp" -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" - -#include -#include - -namespace VOM { -namespace tap_interface_cmds { - -/** - * A functor class that creates an interface - */ -class tapv2_create_cmd : public interface::create_cmd -{ -public: - tapv2_create_cmd(HW::item& item, - const std::string& name, - const route::prefix_t& prefix, - const l2_address_t& l2_address); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - -private: - const route::prefix_t& m_prefix; - const l2_address_t& m_l2_address; -}; - -/** - * A functor class that deletes a Tap interface - */ -class tapv2_delete_cmd : public interface::delete_cmd -{ -public: - tapv2_delete_cmd(HW::item& item); - - /** - * Issue the command to VPP/HW - */ - rc_t issue(connection& con); - /** - * convert to string format for debug purposes - */ - std::string to_string() const; -}; - -/** - * A cmd class that Dumps all the Vpp Interfaces - */ -class tapv2_dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Default Constructor - */ - tapv2_dump_cmd(); - - /** - * 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 tapv2_dump_cmd& i) const; -}; - -}; // namespace tap_interface_cmds -}; // namespace VOM - -#endif diff --git a/extras/vom/vom/test_stats.cpp b/extras/vom/vom/test_stats.cpp deleted file mode 100644 index 6235dd44e3f..00000000000 --- a/extras/vom/vom/test_stats.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include -#include -#include - -class listener : public VOM::interface::stat_listener -{ -public: - listener() {} - ~listener() {} - void handle_interface_stat(const VOM::interface& itf) - { - std::cout << itf.name() << " " << itf.get_stats(); - } -}; - -/** - * Run VPP on another terminal before running vom_stats_test - */ -int main() -{ - uint8_t i = 5; - listener *listen = new listener(); - - VOM::HW::init(new VOM::HW::cmd_q()); - VOM::OM::init(); - - while (VOM::HW::connect() != true) - ; - - VOM::tap_interface itf("tap0", VOM::interface::admin_state_t::UP, VOM::route::prefix_t::ZERO); - VOM::OM::write("__TAP__", itf); - - std::shared_ptr intf = itf.singular(); - - - VOM::tap_interface itf1("tap1", VOM::interface::admin_state_t::UP, VOM::route::prefix_t::ZERO); - VOM::OM::write("__TAP__", itf1); - - std::shared_ptr intf1 = itf1.singular(); - - VOM::tap_interface itf2("tap2", VOM::interface::admin_state_t::UP, VOM::route::prefix_t::ZERO); - VOM::OM::write("__TAP__", itf2); - - std::shared_ptr intf2 = itf2.singular(); - - if (VOM::handle_t::INVALID == intf->handle() || VOM::handle_t::INVALID == intf1->handle() - || VOM::handle_t::INVALID == intf2->handle()) - { - std::cout << "Interface index is INVALID" << std::endl; - VOM::HW::disconnect(); - - return 0; - } - else - { - std::cout << "Interface #1 index is " << intf->handle().value() << std::endl; - std::cout << "Interface #2 index is " << intf1->handle().value() << std::endl; - std::cout << "Interface #3 index is " << intf2->handle().value() << std::endl; - } - - intf->enable_stats(listen); - intf1->enable_stats(listen); - intf2->enable_stats(listen); - - while (i--) - { - sleep(3); - std::cout << "stats # " << std::to_string(i) << std::endl; - VOM::HW::read_stats(); - - if (i == 2) - intf->disable_stats(); - - } - - intf1->disable_stats(); - intf2->disable_stats(); - - intf.reset(); - intf1.reset(); - intf2.reset(); - - VOM::OM::remove("__TAP__"); - - delete listen; - sleep(2); - VOM::HW::disconnect(); - - return 0; -} diff --git a/extras/vom/vom/types.cpp b/extras/vom/vom/types.cpp deleted file mode 100644 index 0236df28417..00000000000 --- a/extras/vom/vom/types.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include - -#include "vom/types.hpp" - -namespace VOM { - -rc_t::rc_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -const rc_t& -rc_t::from_vpp_retval(int32_t rv) -{ - if (0 == rv) { - return (rc_t::OK); - } - if (-68 == rv) { - // sub interface already exists - return (rc_t::OK); - } - if (-79 == rv) { - // interface already exists - return (rc_t::OK); - } - - return (rc_t::INVALID); -} - -const rc_t rc_t::UNSET(0, "un-set"); -const rc_t rc_t::NOOP(1, "no-op"); -const rc_t rc_t::OK(2, "ok"); -const rc_t rc_t::INVALID(3, "invalid"); -const rc_t rc_t::TIMEOUT(4, "timeout"); - -const handle_t handle_t::INVALID(~0); - -handle_t::handle_t(int value) - : m_value(value) -{ -} - -handle_t::handle_t() - : m_value(~0) -{ -} - -std::string -handle_t::to_string() const -{ - return (std::to_string(m_value)); -} - -bool -handle_t::operator==(const handle_t& other) const -{ - return (m_value == other.m_value); -} - -bool -handle_t::operator!=(const handle_t& other) const -{ - return (!(*this == other)); -} - -bool -handle_t::operator<(const handle_t& other) const -{ - return (m_value < other.m_value); -} - -uint32_t -handle_t::value() const -{ - return (m_value); -} - -void -handle_t::reset() -{ - m_value = ~0; -} - -std::ostream& -operator<<(std::ostream& os, const handle_t& h) -{ - os << h.value(); - - return (os); -} - -mac_address_t::mac_address_t(const uint8_t b[6]) -{ - std::copy(b, b + 6, std::begin(bytes)); -} - -mac_address_t::mac_address_t(std::initializer_list i) -{ - std::copy(i.begin(), i.end(), std::begin(bytes)); -} - -mac_address_t::mac_address_t(const std::string& str) -{ - std::vector parts; - - boost::split(parts, str, boost::is_any_of(":")); - - size_t n_bytes = std::min(bytes.size(), parts.size()); - - for (uint32_t ii = 0; ii < n_bytes; ii++) { - bytes[ii] = std::stoul(parts[ii], nullptr, 16); - } -} - -const mac_address_t mac_address_t::ONE({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }); - -const mac_address_t mac_address_t::ZERO({ 0x0 }); - -void -mac_address_t::to_bytes(uint8_t* array, uint8_t len) const -{ - for (int i = 0; i < 6 && i < len; i++) { - array[i] = bytes[i]; - } -} - -std::string -mac_address_t::to_string() const -{ - std::ostringstream s; - bool first = true; - - s.fill('0'); - s << std::hex; - for (auto byte : bytes) { - if (first) - first = false; - else - s << ":"; - s << std::setw(2) << static_cast(byte); - } - - return (s.str()); -} - -bool -mac_address_t::operator==(const mac_address_t& mac) const -{ - return (bytes == mac.bytes); -} -bool -mac_address_t::operator<(const mac_address_t& m) const -{ - return (bytes < m.bytes); -} - -std::ostream& -operator<<(std::ostream& os, const mac_address_t& mac) -{ - os << mac.to_string(); - - return (os); -} - -l2_address_t::l2_address_t(const uint8_t b[8], uint8_t n_bytes) - : bytes(n_bytes) -{ - std::copy_n(b, n_bytes, std::begin(bytes)); -} - -l2_address_t::l2_address_t(std::initializer_list i) - : bytes(i) -{ -} - -l2_address_t::l2_address_t(const mac_address_t& mac) - : bytes(6) -{ - std::copy(begin(mac.bytes), std::end(mac.bytes), std::begin(bytes)); -} - -const l2_address_t l2_address_t::ONE({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff }); - -const l2_address_t l2_address_t::ZERO({ 0x0 }); - -void -l2_address_t::to_bytes(uint8_t* array, uint8_t len) const -{ - for (uint8_t i = 0; i < bytes.size() && i < len; i++) { - array[i] = bytes[i]; - } -} - -mac_address_t -l2_address_t::to_mac() const -{ - mac_address_t mac({}); - - std::copy_n(bytes.begin(), mac.bytes.size(), mac.bytes.begin()); - - return (mac); -} - -std::string -l2_address_t::to_string() const -{ - std::ostringstream s; - bool first = true; - - s.fill('0'); - s << std::hex; - for (auto byte : bytes) { - if (first) - first = false; - else - s << ":"; - s << std::setw(2) << static_cast(byte); - } - - return (s.str()); -} - -bool -l2_address_t::operator==(const l2_address_t& l2) const -{ - return (bytes == l2.bytes); -} - -bool -l2_address_t::operator!=(const l2_address_t& l2) const -{ - return (bytes != l2.bytes); -} - -std::ostream& -operator<<(std::ostream& os, const l2_address_t& l2) -{ - os << l2.to_string(); - - return (os); -} - -const direction_t direction_t::INPUT(1, "input"); -const direction_t direction_t::OUTPUT(0, "output"); - -direction_t::direction_t(int v, const std::string s) - : enum_base(v, s) -{ -} -std::ostream& -operator<<(std::ostream& os, const direction_t& dir) -{ - os << dir.to_string(); - return os; -} - -const ethertype_t ethertype_t::ARP(0x0806, "arp"); -const ethertype_t ethertype_t::FCOE(0x8906, "fcoe"); -const ethertype_t ethertype_t::IPV4(0x0800, "ipv4"); -const ethertype_t ethertype_t::IPV6(0x86DD, "ipv6"); -const ethertype_t ethertype_t::MAC_SECURITY(0x88E5, "mac-security"); -const ethertype_t ethertype_t::MPLS_UNICAST(0x8847, "mpls-unicast"); -const ethertype_t ethertype_t::TRILL(0x22F3, "trill"); -const ethertype_t ethertype_t::UNSPECIFIED(0x0, "unspecified"); - -ethertype_t::ethertype_t(int v, const std::string s) - : enum_base(v, s) -{ -} - -std::ostream& -operator<<(std::ostream& os, const ethertype_t& ether) -{ - os << ether.to_string(); - return os; -} - -const ethertype_t& -ethertype_t::from_numeric_val(uint16_t numeric) -{ - if (0x0806 == numeric) { - return (ethertype_t::ARP); - } - if (0x8906 == numeric) { - return (ethertype_t::FCOE); - } - if (0x0800 == numeric) { - return (ethertype_t::IPV4); - } - if (0x86DD == numeric) { - return (ethertype_t::IPV6); - } - if (0x88E5 == numeric) { - return (ethertype_t::MAC_SECURITY); - } - if (0x8847 == numeric) { - return (ethertype_t::MPLS_UNICAST); - } - if (0x22F3 == numeric) { - return (ethertype_t::TRILL); - } - - return (ethertype_t::UNSPECIFIED); -} - -std::ostream& -operator<<(std::ostream& os, const counter_t& c) -{ - os << "[packets: " << c.packets << " bytes:" << c.bytes << "]"; - return os; -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/types.hpp b/extras/vom/vom/types.hpp deleted file mode 100644 index 383735b2756..00000000000 --- a/extras/vom/vom/types.hpp +++ /dev/null @@ -1,426 +0,0 @@ -/* - * 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_TYPES_H__ -#define __VOM_TYPES_H__ - -#include -#include - -#include - -#include "vom/enum_base.hpp" - -/** - * Convenince wrapper macro for error handling in VAPI sends - */ -#define VAPI_CALL(_stmt) \ - { \ - vapi_error_e _rv; \ - do { \ - _rv = (_stmt); \ - } while (VAPI_OK != _rv); \ - } - -namespace VOM { -/** - * There needs to be a strict order in which object types are read from VPP - * (at boot time) and replayed to VPP (if VPP restarts). That ordering is - * defined in this enum types - */ -enum class dependency_t -{ - /** - * Global Configuration has no dependency - */ - GLOBAL = 0, - - /** - * interfaces are the root of the dependency graph - */ - INTERFACE, - - /** - * virtual interfaces - those that depend on some real interface - */ - VIRTUAL_INTERFACE, - - /** - * Tables in which entries are added, e.g bridge/route-domains - */ - TABLE, - - /** - * virtual tables - tables with a dependency on another table - */ - VIRTUAL_TABLE, - - /** - * ACLs - */ - ACL, - - /** - * Then L2/objects that bind to interfaces, BD, ACLS, etc - */ - BINDING, - - /** - * Entries in Tables - */ - ENTRY, -}; - -/** - * Error codes that VPP will return during a HW write - */ -struct rc_t : public enum_base -{ - /** - * Destructor - */ - ~rc_t() = default; - - /** - * The value un-set - */ - const static rc_t UNSET; - - /** - * The HW write/update action was/has not been attempted - */ - const static rc_t NOOP; - - /** - * The HW write was successfull - */ - const static rc_t OK; - - /** - * HW write reported invalid input - */ - const static rc_t INVALID; - - /** - * HW write timedout - VPP did not respond within a timely manner - */ - const static rc_t TIMEOUT; - - /** - * Get the rc_t from the VPP API value - */ - static const rc_t& from_vpp_retval(int32_t rv); - -private: - /** - * Constructor - */ - rc_t(int v, const std::string s); -}; - -/** - * Feature Directions - */ -struct direction_t : public enum_base -{ - /** - * Constructor - */ - direction_t(int v, const std::string s); - - /** - * Destructor - */ - ~direction_t() = default; - - /** - * Permit Direction - */ - const static direction_t INPUT; - - /** - * Deny Direction - */ - const static direction_t OUTPUT; -}; - -/** - * Output ostream for direction_t - */ -std::ostream& operator<<(std::ostream& os, const direction_t& dir); - -/** - * Feature Ethertype - */ -struct ethertype_t : public enum_base -{ - /** - * Constructor - */ - ethertype_t(int v, const std::string s); - - /** - * Destructor - */ - ~ethertype_t() = default; - - /** - * Ethertype Arp - */ - const static ethertype_t ARP; - - /** - * Ethertype FCoE - */ - const static ethertype_t FCOE; - - /** - * Ethertype IPv4 - */ - const static ethertype_t IPV4; - - /** - * Ethertype Ipv6 - */ - const static ethertype_t IPV6; - - /** - * Ethertype MAC Security - */ - const static ethertype_t MAC_SECURITY; - - /** - * Ethertype MPLS unicast - */ - const static ethertype_t MPLS_UNICAST; - - /** - * Ethertype TRILL - */ - const static ethertype_t TRILL; - - /** - * Ethertype Unspecified - */ - const static ethertype_t UNSPECIFIED; - - /** - * Get the ethertype from the numeric value - */ - static const ethertype_t& from_numeric_val(uint16_t numeric); -}; - -/** - * Output ostream for ethertype_t - */ -std::ostream& operator<<(std::ostream& os, const ethertype_t& eth); - -/** - * A type declaration of an interface handle in VPP - */ -struct handle_t -{ - /** - * Constructor - */ - handle_t(int value); - - /** - * Constructor - */ - handle_t(); - - /** - * convert to string format for debug purposes - */ - std::string to_string() const; - - /** - * Comparison operator - */ - bool operator==(const handle_t& other) const; - - /** - * Comparison operator - */ - bool operator!=(const handle_t& other) const; - - /** - * less than operator - */ - bool operator<(const handle_t& other) const; - - /** - * A value of an interface handle_t that means the itf does not exist - */ - const static handle_t INVALID; - - /** - * get the value of the handle - */ - uint32_t value() const; - - /** - * reset the value of the handle to ~0 - */ - void reset(); - -private: - /** - * VPP's handle value - */ - uint32_t m_value; -}; - -/** - * ostream print of a handle_t - */ -std::ostream& operator<<(std::ostream& os, const handle_t& h); - -/** - * Type def of a Ethernet address - */ -struct mac_address_t -{ - mac_address_t(const uint8_t bytes[6]); - mac_address_t(const std::string& str); - mac_address_t(std::initializer_list bytes); - /** - * Convert to byte array - */ - void to_bytes(uint8_t* array, uint8_t len) const; - - /** - * An all 1's MAC address - */ - const static mac_address_t ONE; - - /** - * An all 0's MAC address - */ - const static mac_address_t ZERO; - - /** - * Comparison operator - */ - bool operator==(const mac_address_t& m) const; - - /** - * less than operator - */ - bool operator<(const mac_address_t& m) const; - - /** - * String conversion - */ - std::string to_string() const; - - /** - * Underlying bytes array - */ - std::array bytes; -}; - -/** - * Type def of a L2 address as read from VPP - */ -struct l2_address_t -{ - l2_address_t(const uint8_t bytes[8], uint8_t n_bytes); - l2_address_t(std::initializer_list bytes); - l2_address_t(const mac_address_t& mac); - - /** - * Convert to byte array - */ - void to_bytes(uint8_t* array, uint8_t len) const; - - /** - * An all 1's L2 address - */ - const static l2_address_t ONE; - - /** - * An all 0's L2 address - */ - const static l2_address_t ZERO; - - /** - * Comparison operator - */ - bool operator==(const l2_address_t& m) const; - - /** - * Comparison operator - */ - bool operator!=(const l2_address_t& m) const; - - /** - * String conversion - */ - std::string to_string() const; - - /** - * MAC address conversion - */ - mac_address_t to_mac() const; - - /** - * Underlying bytes array - filled from least to most significant - */ - std::vector bytes; -}; - -struct counter_t -{ - counter_t() - : packets(0) - , bytes(0) - { - } - counter_t(const counter_t& c) - : packets(c.packets) - , bytes(c.bytes) - { - } - uint64_t packets; - uint64_t bytes; -}; - -/** - * Ostream operator for a MAC address - */ -std::ostream& operator<<(std::ostream& os, const mac_address_t& mac); - -/** - * Ostream operator for a MAC address - */ -std::ostream& operator<<(std::ostream& os, const l2_address_t& l2); - -/** - * Ostream operator for a MAC address - */ -std::ostream& operator<<(std::ostream& os, const counter_t& c); -}; - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp b/extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp deleted file mode 100644 index db4e7fc796c..00000000000 --- a/extras/vom/vom/vxlan_gbp_tunnel_cmds.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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/vxlan_gbp_tunnel_cmds.hpp" -#include "vom/api_types.hpp" - -DEFINE_VAPI_MSG_IDS_VXLAN_GBP_API_JSON; - -namespace VOM { -namespace vxlan_gbp_tunnel_cmds { - -create_cmd::create_cmd(HW::item& item, - const std::string& name, - const vxlan_tunnel::endpoint_t& ep, - bool is_l2, - handle_t mcast_itf) - : interface::create_cmd(item, name) - , m_ep(ep) - , m_is_l2(is_l2) - , m_mcast_itf(mcast_itf) -{ -} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return (m_ep == other.m_ep); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - - payload.is_add = 1; - - to_api(m_ep.src, payload.tunnel.src); - to_api(m_ep.dst, payload.tunnel.dst); - payload.tunnel.mcast_sw_if_index = m_mcast_itf.value(); - payload.tunnel.encap_table_id = 0; - payload.tunnel.vni = m_ep.vni; - payload.tunnel.instance = ~0; - payload.tunnel.mode = - (m_is_l2 ? VXLAN_GBP_API_TUNNEL_MODE_L2 : VXLAN_GBP_API_TUNNEL_MODE_L3); - - VAPI_CALL(req.execute()); - - wait(); - - if (rc_t::OK == m_hw_item.rc()) { - insert_interface(); - } - - return rc_t::OK; -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "vxlan-gbp-tunnel-create: " << m_hw_item.to_string() << " " - << m_ep.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - const vxlan_tunnel::endpoint_t& ep) - : interface::delete_cmd(item) - , m_ep(ep) -{ -} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_ep == other.m_ep); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto payload = req.get_request().get_payload(); - - payload.is_add = 0; - - to_api(m_ep.src, payload.tunnel.src); - to_api(m_ep.dst, payload.tunnel.dst); - payload.tunnel.mcast_sw_if_index = ~0; - payload.tunnel.encap_table_id = 0; - payload.tunnel.vni = m_ep.vni; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_interface(); - return (rc_t::OK); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "vxlan-gbp-tunnel-delete: " << m_hw_item.to_string() << m_ep.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() -{ -} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("vxlan-gbp-tunnel-dump"); -} -} // namespace vxlan_tunnel_cmds -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp b/extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp deleted file mode 100644 index 87bca98d302..00000000000 --- a/extras/vom/vom/vxlan_gbp_tunnel_cmds.hpp +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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_VXLAN_GBP_TUNNEL_CMDS_H__ -#define __VOM_VXLAN_GBP_TUNNEL_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" -#include "vom/vxlan_tunnel.hpp" - -#include - -namespace VOM { -namespace vxlan_gbp_tunnel_cmds { - -/** - * A Command class that creates an VXLAN tunnel - */ -class create_cmd : public interface::create_cmd -{ -public: - /** - * Create command constructor taking HW item to update and the - * endpoint values - */ - create_cmd(HW::item& item, - const std::string& name, - const vxlan_tunnel::endpoint_t& ep, - bool is_l2, - handle_t mcast_itf); - - /** - * 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; - -private: - /** - * Enpoint values of the tunnel to be created - */ - const vxlan_tunnel::endpoint_t m_ep; - bool m_is_l2; - handle_t m_mcast_itf; -}; - -/** - * A functor class that creates an VXLAN tunnel - */ -class delete_cmd : public interface::delete_cmd -{ -public: - /** - * delete command constructor taking HW item to update and the - * endpoint values - */ - delete_cmd(HW::item& item, const vxlan_tunnel::endpoint_t& ep); - - /** - * 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: - /** - * Enpoint values of the tunnel to be deleted - */ - const vxlan_tunnel::endpoint_t m_ep; -}; - -/** - * A cmd class that Dumps all the Vpp interfaces - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Default Constructor - */ - dump_cmd(); - - /** - * 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 vxlan_tunnel_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/vxlan_tunnel.cpp b/extras/vom/vom/vxlan_tunnel.cpp deleted file mode 100644 index e37d160e92b..00000000000 --- a/extras/vom/vom/vxlan_tunnel.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* - * 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/vxlan_tunnel.hpp" -#include "vom/api_types.hpp" -#include "vom/interface_cmds.hpp" -#include "vom/logger.hpp" -#include "vom/singular_db_funcs.hpp" -#include "vom/vxlan_gbp_tunnel_cmds.hpp" -#include "vom/vxlan_tunnel_cmds.hpp" - -namespace VOM { -const std::string VXLAN_TUNNEL_NAME = "vxlan-tunnel-itf"; - -vxlan_tunnel::event_handler vxlan_tunnel::m_evh; - -const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::STANDARD(0, "standard"); -const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::GBP_L2(1, "GBP-L2"); -const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::GBP_L3(2, "GBP-L3"); -const vxlan_tunnel::mode_t vxlan_tunnel::mode_t::GPE(3, "GPE"); - -vxlan_tunnel::mode_t::mode_t(int v, const std::string s) - : enum_base(v, s) -{} - -vxlan_tunnel::endpoint_t::endpoint_t(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni) - : src(src) - , dst(dst) - , vni(vni) -{} - -vxlan_tunnel::endpoint_t::endpoint_t() - : src() - , dst() - , vni(0) -{} - -bool -vxlan_tunnel::endpoint_t::operator==(const endpoint_t& other) const -{ - return ((src == other.src) && (dst == other.dst) && (vni == other.vni)); -} - -std::string -vxlan_tunnel::endpoint_t::to_string() const -{ - std::ostringstream s; - - s << "ep:[" - << "src:" << src.to_string() << " dst:" << dst.to_string() << " vni:" << vni - << "]"; - - return (s.str()); -} - -std::string -vxlan_tunnel::mk_name(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - const mode_t& mode, - uint32_t vni) -{ - std::ostringstream s; - - s << VXLAN_TUNNEL_NAME << "-" << mode.to_string() << "-" << src << "-" << dst - << ":" << vni; - - return (s.str()); -} - -vxlan_tunnel::vxlan_tunnel(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni, - const mode_t& mode) - : interface(mk_name(src, dst, mode, vni), - interface::type_t::VXLAN, - interface::admin_state_t::UP) - , m_tep(src, dst, vni) - , m_mode(mode) - , m_mcast_itf() - , m_rd() - , m_table_id(route::DEFAULT_TABLE) -{} - -vxlan_tunnel::vxlan_tunnel(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni, - const interface& mcast_itf, - const mode_t& mode) - : interface(mk_name(src, dst, mode, vni), - interface::type_t::VXLAN, - interface::admin_state_t::UP) - , m_tep(src, dst, vni) - , m_mode(mode) - , m_mcast_itf(mcast_itf.singular()) - , m_rd() - , m_table_id(route::DEFAULT_TABLE) -{} - -vxlan_tunnel::vxlan_tunnel(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni, - const route_domain& rd, - const mode_t& mode) - : interface(mk_name(src, dst, mode, vni), - interface::type_t::VXLAN, - interface::admin_state_t::UP) - , m_tep(src, dst, vni) - , m_mode(mode) - , m_mcast_itf() - , m_rd(rd.singular()) - , m_table_id(m_rd->table_id()) -{} - -vxlan_tunnel::vxlan_tunnel(const vxlan_tunnel& o) - : interface(o) - , m_tep(o.m_tep) - , m_mode(o.m_mode) - , m_mcast_itf(o.m_mcast_itf) - , m_rd(o.m_rd) - , m_table_id(o.m_table_id) -{} - -bool -vxlan_tunnel::operator==(const vxlan_tunnel& other) const -{ - return ((m_tep == other.m_tep) && (m_mode == other.m_mode) && - (m_mcast_itf == other.m_mcast_itf)); -} - -const handle_t& -vxlan_tunnel::handle() const -{ - return (m_hdl.data()); -} - -std::shared_ptr -vxlan_tunnel::find(const interface::key_t& k) -{ - return std::dynamic_pointer_cast(m_db.find(k)); -} - -void -vxlan_tunnel::sweep() -{ - if (m_hdl) { - if (mode_t::STANDARD == m_mode) - HW::enqueue(new vxlan_tunnel_cmds::delete_cmd(m_hdl, m_tep)); - else if (mode_t::GBP_L2 == m_mode || mode_t::GBP_L3 == m_mode) - HW::enqueue(new vxlan_gbp_tunnel_cmds::delete_cmd(m_hdl, m_tep)); - } - HW::write(); -} - -void -vxlan_tunnel::replay() -{ - if (m_hdl) { - if (mode_t::STANDARD == m_mode) - HW::enqueue(new vxlan_tunnel_cmds::create_cmd( - m_hdl, - name(), - m_tep, - (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); - else if (mode_t::GBP_L2 == m_mode) - HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd( - m_hdl, - name(), - m_tep, - true, - (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); - else if (mode_t::GBP_L3 == m_mode) - HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd( - m_hdl, - name(), - m_tep, - false, - (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); - } - if (m_rd && (m_rd->table_id() != route::DEFAULT_TABLE)) { - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); - } -} - -vxlan_tunnel::~vxlan_tunnel() -{ - sweep(); - release(); -} - -std::string -vxlan_tunnel::to_string() const -{ - std::ostringstream s; - s << "vxlan-tunnel: " << m_hdl.to_string() << " " << m_mode.to_string() << " " - << m_tep.to_string(); - if (m_mcast_itf) - s << " " << m_mcast_itf->to_string(); - - return (s.str()); -} - -void -vxlan_tunnel::update(const vxlan_tunnel& desired) -{ - /* - * the desired state is always that the interface should be created - */ - if (rc_t::OK != m_hdl.rc()) { - if (mode_t::STANDARD == m_mode) - HW::enqueue(new vxlan_tunnel_cmds::create_cmd( - m_hdl, - name(), - m_tep, - (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); - else if (mode_t::GBP_L2 == m_mode) - HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd( - m_hdl, - name(), - m_tep, - true, - (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); - else if (mode_t::GBP_L3 == m_mode) - HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd( - m_hdl, - name(), - m_tep, - false, - (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID))); - } - if (!m_table_id && m_rd) { - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl)); - HW::enqueue( - new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl)); - } -} - -std::shared_ptr -vxlan_tunnel::singular() const -{ - return std::dynamic_pointer_cast(singular_i()); -} - -std::shared_ptr -vxlan_tunnel::singular_i() const -{ - return m_db.find_or_add(key(), *this); -} - -void -vxlan_tunnel::event_handler::handle_populate(const client_db::key_t& key) -{ - /* - * dump VPP current states - */ - { - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - handle_t hdl(payload.sw_if_index); - boost::asio::ip::address src = - from_bytes(payload.src_address.af, (uint8_t*)&payload.src_address.un); - boost::asio::ip::address dst = - from_bytes(payload.dst_address.af, (uint8_t*)&payload.dst_address.un); - - std::shared_ptr vt = - vxlan_tunnel(src, dst, payload.vni).singular(); - vt->set(hdl); - - VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string(); - - OM::commit(key, *vt); - } - } - { - std::shared_ptr cmd = - std::make_shared(); - - HW::enqueue(cmd); - HW::write(); - - for (auto& record : *cmd) { - auto& payload = record.get_payload(); - handle_t hdl(payload.tunnel.sw_if_index); - boost::asio::ip::address src = from_api(payload.tunnel.src); - boost::asio::ip::address dst = from_api(payload.tunnel.dst); - - std::shared_ptr vt = - vxlan_tunnel(src, - dst, - payload.tunnel.vni, - (payload.tunnel.mode == VXLAN_GBP_API_TUNNEL_MODE_L2 - ? mode_t::GBP_L2 - : mode_t::GBP_L3)) - .singular(); - vt->set(hdl); - - VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string(); - - OM::commit(key, *vt); - } - } -} - -vxlan_tunnel::event_handler::event_handler() -{ - OM::register_listener(this); - inspect::register_handler({ "vxlan" }, "VXLAN Tunnels", this); -} - -void -vxlan_tunnel::event_handler::handle_replay() -{ - // replay is handled from the interface DB -} - -dependency_t -vxlan_tunnel::event_handler::order() const -{ - return (dependency_t::VIRTUAL_INTERFACE); -} - -void -vxlan_tunnel::event_handler::show(std::ostream& os) -{ - // dumped by the interface handler -} - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/vxlan_tunnel.hpp b/extras/vom/vom/vxlan_tunnel.hpp deleted file mode 100644 index 4c46e75a700..00000000000 --- a/extras/vom/vom/vxlan_tunnel.hpp +++ /dev/null @@ -1,269 +0,0 @@ -/* - * 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_VXLAN_TUNNEL_H__ -#define __VOM_VXLAN_TUNNEL_H__ - -#include "vom/hw.hpp" -#include "vom/inspect.hpp" -#include "vom/interface.hpp" -#include "vom/object_base.hpp" -#include "vom/om.hpp" -#include "vom/prefix.hpp" -#include "vom/route_domain.hpp" -#include "vom/singular_db.hpp" - -namespace VOM { -/** - * A representation of a VXLAN Tunnel in VPP - */ -class vxlan_tunnel : public interface -{ -public: - /** - * Combaintion of attributes that are a unique key - * for a VXLAN tunnel - */ - struct endpoint_t - { - /** - * Default constructor - */ - endpoint_t(); - /** - * Constructor taking endpoint values - */ - endpoint_t(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni); - - /** - * Comparison operator - */ - bool operator==(const endpoint_t& o) const; - - /** - * Debug print function - */ - std::string to_string() const; - - /** - * The src IP address of the endpoint - */ - boost::asio::ip::address src; - - /** - * The destination IP address of the endpoint - */ - boost::asio::ip::address dst; - - /** - * The VNI of the endpoint - */ - uint32_t vni; - }; - - /** - * mode for the tunnel - */ - struct mode_t : public enum_base - { - ~mode_t() = default; - const static mode_t STANDARD; - const static mode_t GBP_L2; - const static mode_t GBP_L3; - const static mode_t GPE; - - private: - mode_t(int v, const std::string s); - mode_t() = default; - }; - - /** - * Construct a new object matching the desried state - */ - vxlan_tunnel(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni, - const mode_t& mode = mode_t::STANDARD); - vxlan_tunnel(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni, - const interface& mcast_itf, - const mode_t& mode = mode_t::STANDARD); - vxlan_tunnel(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - uint32_t vni, - const route_domain& rd, - const mode_t& mode = mode_t::STANDARD); - - /* - * Destructor - */ - ~vxlan_tunnel(); - - /** - * Copy constructor - */ - vxlan_tunnel(const vxlan_tunnel& o); - - /** - * comparison operator - */ - bool operator==(const vxlan_tunnel& vx) const; - - /** - * Return the matching 'singular instance' - */ - std::shared_ptr singular() const; - - /** - * Debug rpint function - */ - virtual std::string to_string() const; - - /** - * Return VPP's handle to this object - */ - const handle_t& handle() const; - - /** - * Fond the singular instance of the interface in the DB by key - */ - static std::shared_ptr find(const interface::key_t& k); - -private: - /** - * 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; - }; - - /** - * Event handle to register with OM - */ - static event_handler m_evh; - - /** - * Commit the acculmulated changes into VPP. i.e. to a 'HW" write. - */ - void update(const vxlan_tunnel& obj); - - /** - * Return the matching 'instance' of the sub-interface - * over-ride from the base class - */ - std::shared_ptr singular_i() const; - - /** - * Find the VXLAN tunnel in the OM - */ - static std::shared_ptr find_or_add(const vxlan_tunnel& temp); - - /* - * It's the VPPHW class that updates the objects in HW - */ - friend class OM; - - /** - * It's the singular_db class that calls replay() - */ - friend class singular_db; - - /** - * Sweep/reap the object if still stale - */ - void sweep(void); - - /** - * replay the object to create it in hardware - */ - void replay(void); - - /** - * Tunnel enpoint/key - */ - endpoint_t m_tep; - - /** - * The tunnel mode - */ - mode_t m_mode; - - /** - * The interface on which to send the packets if the destination - * is multicast - */ - std::shared_ptr m_mcast_itf; - - /** - * The RD an L3 interface is bound to - */ - std::shared_ptr m_rd; - - /** - * HW state of the VPP table mapping - */ - HW::item m_table_id; - - /** - * Construct a unique name for the tunnel - */ - static std::string mk_name(const boost::asio::ip::address& src, - const boost::asio::ip::address& dst, - const mode_t& mode, - uint32_t vni); -}; - -/** - * Ostream output for a tunnel endpoint - */ -std::ostream& operator<<(std::ostream& os, const vxlan_tunnel::endpoint_t& ep); - -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif diff --git a/extras/vom/vom/vxlan_tunnel_cmds.cpp b/extras/vom/vom/vxlan_tunnel_cmds.cpp deleted file mode 100644 index da71a99967e..00000000000 --- a/extras/vom/vom/vxlan_tunnel_cmds.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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/vxlan_tunnel_cmds.hpp" - -DEFINE_VAPI_MSG_IDS_VXLAN_API_JSON; - -namespace VOM { -namespace vxlan_tunnel_cmds { - -create_cmd::create_cmd(HW::item& item, - const std::string& name, - const vxlan_tunnel::endpoint_t& ep, - handle_t mcast_itf) - : interface::create_cmd(item, name) - , m_ep(ep) - , m_mcast_itf(mcast_itf) -{} - -bool -create_cmd::operator==(const create_cmd& other) const -{ - return (m_ep == other.m_ep); -} - -rc_t -create_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto& payload = req.get_request().get_payload(); - payload.is_add = 1; - to_bytes(m_ep.src, - (uint8_t*)&payload.src_address.af, - (uint8_t*)&payload.src_address.un); - to_bytes(m_ep.dst, - (uint8_t*)&payload.dst_address.af, - (uint8_t*)&payload.dst_address.un); - payload.mcast_sw_if_index = m_mcast_itf.value(); - payload.encap_vrf_id = 0; - payload.decap_next_index = ~0; - payload.vni = m_ep.vni; - - VAPI_CALL(req.execute()); - - wait(); - - if (rc_t::OK == m_hw_item.rc()) { - insert_interface(); - } - - return rc_t::OK; -} - -std::string -create_cmd::to_string() const -{ - std::ostringstream s; - s << "vxlan-tunnel-create: " << m_hw_item.to_string() << " " - << m_ep.to_string(); - - return (s.str()); -} - -delete_cmd::delete_cmd(HW::item& item, - const vxlan_tunnel::endpoint_t& ep) - : interface::delete_cmd(item) - , m_ep(ep) -{} - -bool -delete_cmd::operator==(const delete_cmd& other) const -{ - return (m_ep == other.m_ep); -} - -rc_t -delete_cmd::issue(connection& con) -{ - msg_t req(con.ctx(), std::ref(*this)); - - auto payload = req.get_request().get_payload(); - payload.is_add = 0; - to_bytes(m_ep.src, - (uint8_t*)&payload.src_address.af, - (uint8_t*)&payload.src_address.un); - to_bytes(m_ep.dst, - (uint8_t*)&payload.dst_address.af, - (uint8_t*)&payload.dst_address.un); - payload.mcast_sw_if_index = ~0; - payload.encap_vrf_id = 0; - payload.decap_next_index = ~0; - payload.vni = m_ep.vni; - - VAPI_CALL(req.execute()); - - wait(); - m_hw_item.set(rc_t::NOOP); - - remove_interface(); - return (rc_t::OK); -} - -std::string -delete_cmd::to_string() const -{ - std::ostringstream s; - s << "vxlan-tunnel-delete: " << m_hw_item.to_string() << m_ep.to_string(); - - return (s.str()); -} - -dump_cmd::dump_cmd() {} - -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))); - - auto& payload = m_dump->get_request().get_payload(); - payload.sw_if_index = ~0; - - VAPI_CALL(m_dump->execute()); - - wait(); - - return rc_t::OK; -} - -std::string -dump_cmd::to_string() const -{ - return ("Vpp-vxlan_tunnels-Dump"); -} -} // namespace vxlan_tunnel_cmds -} // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ diff --git a/extras/vom/vom/vxlan_tunnel_cmds.hpp b/extras/vom/vom/vxlan_tunnel_cmds.hpp deleted file mode 100644 index 423fcdac950..00000000000 --- a/extras/vom/vom/vxlan_tunnel_cmds.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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_VXLAN_TUNNEL_CMDS_H__ -#define __VOM_VXLAN_TUNNEL_CMDS_H__ - -#include "vom/dump_cmd.hpp" -#include "vom/rpc_cmd.hpp" -#include "vom/vxlan_tunnel.hpp" - -#include -#include - -namespace VOM { -namespace vxlan_tunnel_cmds { - -/** - * A Command class that creates an VXLAN tunnel - */ -class create_cmd : public interface::create_cmd -{ -public: - /** - * Create command constructor taking HW item to update and the - * endpoint values - */ - create_cmd(HW::item& item, - const std::string& name, - const vxlan_tunnel::endpoint_t& ep, - handle_t mcast_itf); - - /** - * 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; - -private: - /** - * Enpoint values of the tunnel to be created - */ - const vxlan_tunnel::endpoint_t m_ep; - handle_t m_mcast_itf; -}; - -/** - * A functor class that creates an VXLAN tunnel - */ -class delete_cmd : public interface::delete_cmd -{ -public: - /** - * delete command constructor taking HW item to update and the - * endpoint values - */ - delete_cmd(HW::item& item, const vxlan_tunnel::endpoint_t& ep); - - /** - * 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: - /** - * Enpoint values of the tunnel to be deleted - */ - const vxlan_tunnel::endpoint_t m_ep; -}; - -/** - * A cmd class that Dumps all the Vpp interfaces - */ -class dump_cmd : public VOM::dump_cmd -{ -public: - /** - * Default Constructor - */ - dump_cmd(); - - /** - * 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 vxlan_tunnel_cmds -}; // namespace VOM - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "mozilla") - * End: - */ - -#endif -- cgit 1.2.3-korg