VPP Object Model (VOM)
The VOM is a C++ library for use by clients/agents of VPP for programming state. It uses the binary APIs to do so. Various other common client side functions are also provided. Please see om.hpp for a more detailed description. Change-Id: Ib756bfe99817093815a9e26ccf464aa5583fc523 Signed-off-by: Neale Ranns <neale.ranns@cisco.com> Co-authored-by: Mohsin Kazmi <sykazmi@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
14edd97c20
commit
812ed39f9d
1
.gitignore
vendored
1
.gitignore
vendored
@@ -18,6 +18,7 @@
|
||||
/build-root/test-cov/
|
||||
/build-root/python/
|
||||
/build-root/vapi_test/
|
||||
/build-root/vom_test/
|
||||
/build-config.mk
|
||||
/dpdk/*.tar.gz
|
||||
/dpdk/*.tar.xz
|
||||
|
2
Makefile
2
Makefile
@@ -69,6 +69,7 @@ DEB_DEPENDS += debhelper dkms git libtool libapr1-dev dh-systemd
|
||||
DEB_DEPENDS += libconfuse-dev git-review exuberant-ctags cscope pkg-config
|
||||
DEB_DEPENDS += lcov chrpath autoconf nasm indent clang-format libnuma-dev
|
||||
DEB_DEPENDS += python-all python-dev python-virtualenv python-pip libffi6 check
|
||||
DEB_DEPENDS += libboost-all-dev
|
||||
ifeq ($(OS_VERSION_ID),14.04)
|
||||
DEB_DEPENDS += openjdk-8-jdk-headless
|
||||
DEB_DEPENDS += libssl-dev
|
||||
@@ -88,6 +89,7 @@ RPM_DEPENDS = redhat-lsb glibc-static java-1.8.0-openjdk-devel yum-utils
|
||||
RPM_DEPENDS += apr-devel
|
||||
RPM_DEPENDS += numactl-devel
|
||||
RPM_DEPENDS += check check-devel
|
||||
RPM_DEPENDS += boost boost-devel
|
||||
|
||||
ifeq ($(OS_ID)-$(OS_VERSION_ID),fedora-25)
|
||||
RPM_DEPENDS += subunit subunit-devel
|
||||
|
@@ -20,6 +20,7 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
AM_LIBTOOLFLAGS = --quiet
|
||||
|
||||
AM_CFLAGS = -Wall
|
||||
AM_CXXFLAGS = -Wall -std=gnu++11
|
||||
|
||||
SUBDIRS = .
|
||||
SUFFIXES = .api.h .api .api.json
|
||||
@@ -82,6 +83,7 @@ SUBDIRS += vpp-api/java
|
||||
endif
|
||||
|
||||
SUBDIRS += vpp-api/vapi
|
||||
SUBDIRS += vpp-api/vom
|
||||
|
||||
###############################################################################
|
||||
# API
|
||||
|
@@ -3,11 +3,12 @@ LT_INIT
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
AM_INIT_AUTOMAKE([subdir-objects])
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_FILES([Makefile plugins/Makefile vpp-api/python/Makefile vpp-api/java/Makefile vpp-api/vapi/Makefile])
|
||||
AC_CONFIG_FILES([Makefile plugins/Makefile vpp-api/python/Makefile vpp-api/java/Makefile vpp-api/vapi/Makefile vpp-api/vom/Makefile])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CPP
|
||||
AM_PROG_AS
|
||||
AM_PROG_LIBTOOL
|
||||
AC_PROG_YACC
|
||||
|
@@ -105,7 +105,7 @@ public:
|
||||
|
||||
private:
|
||||
Connection &con;
|
||||
Common_req (Connection &con) : con{con}, response_state{RESPONSE_NOT_READY}
|
||||
Common_req (Connection &con) : con (con), response_state{RESPONSE_NOT_READY}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -759,7 +759,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
Result_set (Connection &con) : con{con}, complete{false}
|
||||
Result_set (Connection &con) : con (con), complete{false}
|
||||
{
|
||||
}
|
||||
|
||||
|
3
src/vpp-api/vom/.clang-format
Normal file
3
src/vpp-api/vom/.clang-format
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
BasedOnStyle: mozilla
|
||||
BinPackParameters: false
|
151
src/vpp-api/vom/Makefile.am
Normal file
151
src/vpp-api/vom/Makefile.am
Normal file
@@ -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.
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
AM_LIBTOOLFLAGS = --quiet
|
||||
|
||||
AM_CXXFLAGS = -Wall -std=gnu++11 -I${top_srcdir} -I${top_builddir}/vpp-api/vapi/ -I$(top_srcdir)/vpp-api/ -I${libdir}/../include
|
||||
AM_LDFLAGS = -shared -avoid-version -no-undefined
|
||||
|
||||
bin_PROGRAMS =
|
||||
noinst_LTLIBRARIES =
|
||||
CLEANDIRS =
|
||||
|
||||
lib_LTLIBRARIES = libvom.la
|
||||
|
||||
libvom_la_DEPENDENCIES =
|
||||
libvom_la_LIBADD = \
|
||||
$(top_builddir)/vpp-api/vapi/libvapiclient.la \
|
||||
-lpthread \
|
||||
-lboost_thread \
|
||||
$(BOOST_SYSTEM_LIB) \
|
||||
$(BOOST_FILESYSTEM_LIB) \
|
||||
$(BOOST_ASIO_LIB) \
|
||||
-lm -lrt
|
||||
|
||||
libvom_la_SOURCES = \
|
||||
acl_binding_cmds.cpp \
|
||||
acl_binding.cpp \
|
||||
acl_l2_rule.cpp \
|
||||
acl_l3_rule.cpp \
|
||||
acl_list_cmds.cpp \
|
||||
acl_list.cpp \
|
||||
acl_types.cpp \
|
||||
arp_proxy_binding_cmds.cpp \
|
||||
arp_proxy_binding.cpp \
|
||||
arp_proxy_config_cmds.cpp \
|
||||
arp_proxy_config.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_config_cmds.cpp \
|
||||
dhcp_config.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_unnumbered_cmds.cpp \
|
||||
ip_unnumbered.cpp \
|
||||
l2_binding_cmds.cpp \
|
||||
l2_binding.cpp \
|
||||
l3_binding_cmds.cpp \
|
||||
l3_binding.cpp \
|
||||
lldp_binding_cmds.cpp \
|
||||
lldp_binding.cpp \
|
||||
lldp_global_cmds.cpp \
|
||||
lldp_global.cpp \
|
||||
logger.cpp \
|
||||
nat_static.cpp \
|
||||
nat_static_cmds.cpp \
|
||||
nat_binding.cpp \
|
||||
nat_binding_cmds.cpp \
|
||||
neighbour.cpp \
|
||||
neighbour_cmds.cpp \
|
||||
object_base.cpp \
|
||||
om.cpp \
|
||||
prefix.cpp \
|
||||
ra_config.cpp \
|
||||
ra_prefix.cpp \
|
||||
route.cpp \
|
||||
route_cmds.cpp \
|
||||
route_domain.cpp \
|
||||
route_domain_cmds.cpp \
|
||||
sub_interface_cmds.cpp \
|
||||
sub_interface.cpp \
|
||||
tap_interface.cpp \
|
||||
tap_interface_cmds.cpp \
|
||||
types.cpp \
|
||||
vxlan_tunnel_cmds.cpp \
|
||||
vxlan_tunnel.cpp
|
||||
|
||||
vomincludedir = $(includedir)/vom
|
||||
|
||||
vominclude_HEADERS = \
|
||||
acl_binding.hpp \
|
||||
acl_l2_rule.hpp \
|
||||
acl_l3_rule.hpp \
|
||||
acl_list.hpp \
|
||||
acl_types.hpp \
|
||||
arp_proxy_binding.hpp \
|
||||
arp_proxy_config.hpp \
|
||||
bridge_domain.hpp \
|
||||
bridge_domain_arp_entry.hpp \
|
||||
bridge_domain_entry.hpp \
|
||||
client_db.hpp \
|
||||
cmd.hpp \
|
||||
connection.hpp \
|
||||
dhcp_config.hpp \
|
||||
dump_cmd.hpp \
|
||||
enum_base.hpp \
|
||||
event_cmd.hpp \
|
||||
hw.hpp \
|
||||
inspect.hpp \
|
||||
interface.hpp \
|
||||
interface_ip6_nd.hpp \
|
||||
interface_span.hpp \
|
||||
ip_unnumbered.hpp \
|
||||
l2_binding.hpp \
|
||||
l3_binding.hpp \
|
||||
lldp_binding.hpp \
|
||||
lldp_global.hpp \
|
||||
logger.hpp \
|
||||
nat_static.hpp \
|
||||
nat_binding.hpp \
|
||||
neighbour.hpp \
|
||||
object_base.hpp \
|
||||
om.hpp \
|
||||
prefix.hpp \
|
||||
ra_config.hpp \
|
||||
ra_prefix.hpp \
|
||||
route.hpp \
|
||||
route_domain.hpp \
|
||||
rpc_cmd.hpp \
|
||||
singular_db.hpp \
|
||||
sub_interface.hpp \
|
||||
tap_interface.hpp \
|
||||
types.hpp \
|
||||
vxlan_tunnel.hpp
|
||||
|
||||
# vi:syntax=automake
|
95
src/vpp-api/vom/acl_binding.cpp
Normal file
95
src/vpp-api/vom/acl_binding.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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/om.hpp"
|
||||
|
||||
namespace VOM {
|
||||
namespace ACL {
|
||||
template <>
|
||||
void
|
||||
l2_binding::event_handler::handle_populate(const client_db::key_t& key)
|
||||
{
|
||||
/*
|
||||
* dump VPP Bridge domains
|
||||
*/
|
||||
std::shared_ptr<l2_binding::dump_cmd> cmd(new l2_binding::dump_cmd());
|
||||
|
||||
HW::enqueue(cmd);
|
||||
HW::write();
|
||||
|
||||
for (auto& record : *cmd) {
|
||||
auto& payload = record.get_payload();
|
||||
|
||||
std::shared_ptr<interface> itf = interface::find(payload.sw_if_index);
|
||||
|
||||
for (int ii = 0; ii < payload.count; ii++) {
|
||||
std::shared_ptr<l2_list> acl = l2_list::find(payload.acls[ii]);
|
||||
|
||||
l2_binding binding(direction_t::INPUT, *itf, *acl);
|
||||
|
||||
OM::commit(key, binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void
|
||||
l3_binding::event_handler::handle_populate(const client_db::key_t& key)
|
||||
{
|
||||
std::shared_ptr<l3_binding::dump_cmd> cmd(new l3_binding::dump_cmd());
|
||||
|
||||
HW::enqueue(cmd);
|
||||
HW::write();
|
||||
|
||||
for (auto& record : *cmd) {
|
||||
auto& payload = record.get_payload();
|
||||
|
||||
std::shared_ptr<interface> itf = interface::find(payload.sw_if_index);
|
||||
uint8_t n_input = payload.n_input;
|
||||
|
||||
for (int ii = 0; ii < payload.count; ii++) {
|
||||
std::shared_ptr<l3_list> acl = l3_list::find(payload.acls[ii]);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os,
|
||||
const std::pair<direction_t, interface::key_type>& 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:
|
||||
*/
|
422
src/vpp-api/vom/acl_binding.hpp
Normal file
422
src/vpp-api/vom/acl_binding.hpp
Normal file
File diff suppressed because it is too large
Load Diff
138
src/vpp-api/vom/acl_binding_cmds.cpp
Normal file
138
src/vpp-api/vom/acl_binding_cmds.cpp
Normal file
@@ -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.
|
||||
*/
|
||||
|
||||
#include "vom/acl_binding.hpp"
|
||||
|
||||
DEFINE_VAPI_MSG_IDS_ACL_API_JSON;
|
||||
|
||||
namespace VOM {
|
||||
namespace ACL {
|
||||
template <>
|
||||
rc_t
|
||||
l3_binding::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());
|
||||
|
||||
m_hw_item.set(wait());
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
template <>
|
||||
rc_t
|
||||
l3_binding::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());
|
||||
|
||||
m_hw_item.set(wait());
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
template <>
|
||||
rc_t
|
||||
l3_binding::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 <>
|
||||
rc_t
|
||||
l2_binding::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());
|
||||
|
||||
m_hw_item.set(wait());
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
template <>
|
||||
rc_t
|
||||
l2_binding::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());
|
||||
|
||||
m_hw_item.set(wait());
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
template <>
|
||||
rc_t
|
||||
l2_binding::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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
78
src/vpp-api/vom/acl_l2_rule.cpp
Normal file
78
src/vpp-api/vom/acl_l2_rule.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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 <sstream>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
void
|
||||
l2_rule::to_vpp(vapi_type_macip_acl_rule& rule) const
|
||||
{
|
||||
rule.is_permit = m_action.value();
|
||||
m_src_ip.to_vpp(&rule.is_ipv6, rule.src_ip_addr, &rule.src_ip_prefix_len);
|
||||
m_mac.to_bytes(rule.src_mac, 6);
|
||||
m_mac_mask.to_bytes(rule.src_mac_mask, 6);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
113
src/vpp-api/vom/acl_l2_rule.hpp
Normal file
113
src/vpp-api/vom/acl_l2_rule.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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"
|
||||
|
||||
#include <vapi/acl.api.vapi.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;
|
||||
|
||||
/**
|
||||
* Convert to VPP API fromat
|
||||
*/
|
||||
void to_vpp(vapi_type_macip_acl_rule& rule) 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
|
156
src/vpp-api/vom/acl_l3_rule.cpp
Normal file
156
src/vpp-api/vom/acl_l3_rule.cpp
Normal file
@@ -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 <sstream>
|
||||
|
||||
#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)
|
||||
: m_priority(priority)
|
||||
, m_action(action)
|
||||
, m_src(src)
|
||||
, m_dst(dst)
|
||||
, m_proto(0)
|
||||
, m_srcport_or_icmptype_first(0)
|
||||
, m_srcport_or_icmptype_last(0)
|
||||
, m_dstport_or_icmpcode_first(0)
|
||||
, m_dstport_or_icmpcode_last(0)
|
||||
, m_tcp_flags_mask(0)
|
||||
, m_tcp_flags_value(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
l3_rule::operator<(const l3_rule& other) const
|
||||
{
|
||||
return (other.m_priority < m_priority);
|
||||
}
|
||||
|
||||
void
|
||||
l3_rule::to_vpp(vapi_type_acl_rule& rule) const
|
||||
{
|
||||
rule.is_permit = m_action.value();
|
||||
m_src.to_vpp(&rule.is_ipv6, rule.src_ip_addr, &rule.src_ip_prefix_len);
|
||||
m_dst.to_vpp(&rule.is_ipv6, rule.dst_ip_addr, &rule.dst_ip_prefix_len);
|
||||
|
||||
rule.proto = m_proto;
|
||||
rule.srcport_or_icmptype_first = m_srcport_or_icmptype_first;
|
||||
rule.srcport_or_icmptype_last = m_srcport_or_icmptype_last;
|
||||
rule.dstport_or_icmpcode_first = m_dstport_or_icmpcode_first;
|
||||
rule.dstport_or_icmpcode_last = m_dstport_or_icmpcode_last;
|
||||
|
||||
rule.tcp_flags_mask = m_tcp_flags_mask;
|
||||
rule.tcp_flags_value = m_tcp_flags_value;
|
||||
}
|
||||
|
||||
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:" << m_tcp_flags_mask
|
||||
<< " tcpflagvalue:" << 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
181
src/vpp-api/vom/acl_l3_rule.hpp
Normal file
181
src/vpp-api/vom/acl_l3_rule.hpp
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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"
|
||||
|
||||
#include <vapi/acl.api.vapi.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);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Convert to VPP API fromat
|
||||
*/
|
||||
void to_vpp(vapi_type_acl_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);
|
||||
|
||||
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
|
113
src/vpp-api/vom/acl_list.cpp
Normal file
113
src/vpp-api/vom/acl_list.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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.hpp"
|
||||
#include "vom/logger.hpp"
|
||||
|
||||
namespace VOM {
|
||||
namespace ACL {
|
||||
template <>
|
||||
void
|
||||
l2_list::event_handler::handle_populate(const client_db::key_t& key)
|
||||
{
|
||||
/* hack to get this function instantiated */
|
||||
m_evh.order();
|
||||
|
||||
/*
|
||||
* dump VPP Bridge domains
|
||||
*/
|
||||
std::shared_ptr<l2_list::dump_cmd> cmd(new l2_list::dump_cmd());
|
||||
|
||||
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<const char*>(payload.tag)));
|
||||
|
||||
for (unsigned int ii = 0; ii < payload.count; ii++) {
|
||||
const route::prefix_t pfx(payload.r[ii].is_ipv6,
|
||||
payload.r[ii].src_ip_addr,
|
||||
payload.r[ii].src_ip_prefix_len);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void
|
||||
l3_list::event_handler::handle_populate(const client_db::key_t& key)
|
||||
{
|
||||
/* hack to get this function instantiated */
|
||||
m_evh.order();
|
||||
|
||||
/*
|
||||
* dump VPP Bridge domains
|
||||
*/
|
||||
std::shared_ptr<l3_list::dump_cmd> cmd(new l3_list::dump_cmd());
|
||||
|
||||
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<const char*>(payload.tag)));
|
||||
|
||||
for (unsigned int ii = 0; ii < payload.count; ii++) {
|
||||
const route::prefix_t src(payload.r[ii].is_ipv6,
|
||||
payload.r[ii].src_ip_addr,
|
||||
payload.r[ii].src_ip_prefix_len);
|
||||
const route::prefix_t dst(payload.r[ii].is_ipv6,
|
||||
payload.r[ii].dst_ip_addr,
|
||||
payload.r[ii].dst_ip_prefix_len);
|
||||
l3_rule rule(ii, action_t::from_int(payload.r[ii].is_permit), src, dst);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
475
src/vpp-api/vom/acl_list.hpp
Normal file
475
src/vpp-api/vom/acl_list.hpp
Normal file
File diff suppressed because it is too large
Load Diff
153
src/vpp-api/vom/acl_list_cmds.cpp
Normal file
153
src/vpp-api/vom/acl_list_cmds.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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.hpp"
|
||||
|
||||
namespace VOM {
|
||||
namespace ACL {
|
||||
template <>
|
||||
rc_t
|
||||
l3_list::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()) {
|
||||
it->to_vpp(payload.r[ii]);
|
||||
++it;
|
||||
++ii;
|
||||
}
|
||||
|
||||
VAPI_CALL(req.execute());
|
||||
|
||||
m_hw_item = wait();
|
||||
complete();
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
template <>
|
||||
rc_t
|
||||
l3_list::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);
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
template <>
|
||||
rc_t
|
||||
l3_list::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_list::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()) {
|
||||
it->to_vpp(payload.r[ii]);
|
||||
++it;
|
||||
++ii;
|
||||
}
|
||||
|
||||
VAPI_CALL(req.execute());
|
||||
|
||||
m_hw_item = wait();
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
template <>
|
||||
rc_t
|
||||
l2_list::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);
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
template <>
|
||||
rc_t
|
||||
l2_list::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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
59
src/vpp-api/vom/acl_types.cpp
Normal file
59
src/vpp-api/vom/acl_types.cpp
Normal file
@@ -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: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
75
src/vpp-api/vom/acl_types.hpp
Normal file
75
src/vpp-api/vom/acl_types.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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<action_t>
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
action_t(int v, const std::string s);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~action_t() = default;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
||||
|
||||
#endif
|
142
src/vpp-api/vom/arp_proxy_binding.cpp
Normal file
142
src/vpp-api/vom/arp_proxy_binding.cpp
Normal file
@@ -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_binding.hpp"
|
||||
#include "vom/cmd.hpp"
|
||||
|
||||
namespace VOM {
|
||||
|
||||
/**
|
||||
* A DB of all LLDP configs
|
||||
*/
|
||||
singular_db<interface::key_type, arp_proxy_binding> arp_proxy_binding::m_db;
|
||||
|
||||
arp_proxy_binding::event_handler arp_proxy_binding::m_evh;
|
||||
|
||||
arp_proxy_binding::arp_proxy_binding(const interface& itf,
|
||||
const arp_proxy_config& proxy_cfg)
|
||||
: m_itf(itf.singular())
|
||||
, m_arp_proxy_cfg(proxy_cfg.singular())
|
||||
, m_binding(true)
|
||||
{
|
||||
}
|
||||
|
||||
arp_proxy_binding::arp_proxy_binding(const arp_proxy_binding& o)
|
||||
: m_itf(o.m_itf)
|
||||
, m_arp_proxy_cfg(o.m_arp_proxy_cfg)
|
||||
, m_binding(o.m_binding)
|
||||
{
|
||||
}
|
||||
|
||||
arp_proxy_binding::~arp_proxy_binding()
|
||||
{
|
||||
sweep();
|
||||
|
||||
// not in the DB anymore.
|
||||
m_db.release(m_itf->key(), this);
|
||||
}
|
||||
|
||||
void
|
||||
arp_proxy_binding::sweep()
|
||||
{
|
||||
if (m_binding) {
|
||||
HW::enqueue(new unbind_cmd(m_binding, m_itf->handle()));
|
||||
}
|
||||
HW::write();
|
||||
}
|
||||
|
||||
void
|
||||
arp_proxy_binding::dump(std::ostream& os)
|
||||
{
|
||||
m_db.dump(os);
|
||||
}
|
||||
|
||||
void
|
||||
arp_proxy_binding::replay()
|
||||
{
|
||||
if (m_binding) {
|
||||
HW::enqueue(new 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 bind_cmd(m_binding, m_itf->handle()));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<arp_proxy_binding>
|
||||
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>
|
||||
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" }, "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)
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
dependency_t
|
||||
arp_proxy_binding::event_handler::order() const
|
||||
{
|
||||
return (dependency_t::BINDING);
|
||||
}
|
||||
|
||||
void
|
||||
arp_proxy_binding::event_handler::show(std::ostream& os)
|
||||
{
|
||||
m_db.dump(os);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
234
src/vpp-api/vom/arp_proxy_binding.hpp
Normal file
234
src/vpp-api/vom/arp_proxy_binding.hpp
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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/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/rpc_cmd.hpp"
|
||||
#include "vom/singular_db.hpp"
|
||||
|
||||
#include <vapi/vpe.api.vapi.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, const arp_proxy_config& proxy_cfg);
|
||||
|
||||
/**
|
||||
* 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<arp_proxy_binding> 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);
|
||||
|
||||
/**
|
||||
* A command class that binds the LLDP config to the interface
|
||||
*/
|
||||
class bind_cmd
|
||||
: public rpc_cmd<HW::item<bool>, rc_t, vapi::Proxy_arp_intfc_enable_disable>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
bind_cmd(HW::item<bool>& 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<HW::item<bool>, rc_t, vapi::Proxy_arp_intfc_enable_disable>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
unbind_cmd(HW::item<bool>& 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;
|
||||
};
|
||||
|
||||
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<arp_proxy_binding> 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<interface::key_type, arp_proxy_binding>;
|
||||
|
||||
/**
|
||||
* 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<interface> m_itf;
|
||||
|
||||
/**
|
||||
* A reference counting pointer to the prxy config.
|
||||
*/
|
||||
const std::shared_ptr<arp_proxy_config> m_arp_proxy_cfg;
|
||||
|
||||
/**
|
||||
* HW configuration for the binding. The bool representing the
|
||||
* do/don't bind.
|
||||
*/
|
||||
HW::item<bool> m_binding;
|
||||
|
||||
/**
|
||||
* A map of all ArpProxy bindings keyed against the interface.
|
||||
*/
|
||||
static singular_db<interface::key_type, arp_proxy_binding> m_db;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
||||
|
||||
#endif
|
104
src/vpp-api/vom/arp_proxy_binding_cmds.cpp
Normal file
104
src/vpp-api/vom/arp_proxy_binding_cmds.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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"
|
||||
|
||||
namespace VOM {
|
||||
|
||||
arp_proxy_binding::bind_cmd::bind_cmd(HW::item<bool>& item, const handle_t& itf)
|
||||
: rpc_cmd(item)
|
||||
, m_itf(itf)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
arp_proxy_binding::bind_cmd::operator==(const bind_cmd& other) const
|
||||
{
|
||||
return (m_itf == other.m_itf);
|
||||
}
|
||||
|
||||
rc_t
|
||||
arp_proxy_binding::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_disable = 1;
|
||||
|
||||
VAPI_CALL(req.execute());
|
||||
|
||||
m_hw_item.set(wait());
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
std::string
|
||||
arp_proxy_binding::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());
|
||||
}
|
||||
|
||||
arp_proxy_binding::unbind_cmd::unbind_cmd(HW::item<bool>& item,
|
||||
const handle_t& itf)
|
||||
: rpc_cmd(item)
|
||||
, m_itf(itf)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
arp_proxy_binding::unbind_cmd::operator==(const unbind_cmd& other) const
|
||||
{
|
||||
return (m_itf == other.m_itf);
|
||||
}
|
||||
|
||||
rc_t
|
||||
arp_proxy_binding::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_disable = 0;
|
||||
|
||||
VAPI_CALL(req.execute());
|
||||
|
||||
wait();
|
||||
m_hw_item.set(rc_t::NOOP);
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
std::string
|
||||
arp_proxy_binding::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());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
147
src/vpp-api/vom/arp_proxy_config.cpp
Normal file
147
src/vpp-api/vom/arp_proxy_config.cpp
Normal file
@@ -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.
|
||||
*/
|
||||
|
||||
#include "vom/arp_proxy_config.hpp"
|
||||
#include "vom/cmd.hpp"
|
||||
|
||||
namespace VOM {
|
||||
/**
|
||||
* A DB of all LLDP configs
|
||||
*/
|
||||
singular_db<arp_proxy_config::key_t, arp_proxy_config> 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 unconfig_cmd(m_config, m_low, m_high));
|
||||
}
|
||||
HW::write();
|
||||
}
|
||||
|
||||
void
|
||||
arp_proxy_config::dump(std::ostream& os)
|
||||
{
|
||||
m_db.dump(os);
|
||||
}
|
||||
|
||||
void
|
||||
arp_proxy_config::replay()
|
||||
{
|
||||
if (m_config) {
|
||||
HW::enqueue(new 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 config_cmd(m_config, m_low, m_high));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<arp_proxy_config>
|
||||
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>
|
||||
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" }, "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)
|
||||
{
|
||||
// VPP provides no dump for ARP proxy.
|
||||
}
|
||||
|
||||
dependency_t
|
||||
arp_proxy_config::event_handler::order() const
|
||||
{
|
||||
return (dependency_t::GLOBAL);
|
||||
}
|
||||
|
||||
void
|
||||
arp_proxy_config::event_handler::show(std::ostream& os)
|
||||
{
|
||||
m_db.dump(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:
|
||||
*/
|
241
src/vpp-api/vom/arp_proxy_config.hpp
Normal file
241
src/vpp-api/vom/arp_proxy_config.hpp
Normal file
@@ -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.
|
||||
*/
|
||||
|
||||
#ifndef __VOM_ARP_PROXY_CONFIG_H__
|
||||
#define __VOM_ARP_PROXY_CONFIG_H__
|
||||
|
||||
#include "vom/dump_cmd.hpp"
|
||||
#include "vom/hw.hpp"
|
||||
#include "vom/inspect.hpp"
|
||||
#include "vom/object_base.hpp"
|
||||
#include "vom/om.hpp"
|
||||
#include "vom/rpc_cmd.hpp"
|
||||
#include "vom/singular_db.hpp"
|
||||
|
||||
#include <vapi/vpe.api.vapi.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<boost::asio::ip::address_v4, boost::asio::ip::address_v4>
|
||||
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<arp_proxy_config> 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);
|
||||
|
||||
/**
|
||||
* A command class that adds the ARP Proxy config
|
||||
*/
|
||||
class config_cmd
|
||||
: public rpc_cmd<HW::item<bool>, rc_t, vapi::Proxy_arp_add_del>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
config_cmd(HW::item<bool>& 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<HW::item<bool>, rc_t, vapi::Proxy_arp_add_del>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
unconfig_cmd(HW::item<bool>& 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;
|
||||
};
|
||||
|
||||
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<arp_proxy_config> 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<arp_proxy_config::key_t, arp_proxy_config>;
|
||||
|
||||
/**
|
||||
* 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<arp_proxy_config::key_t, arp_proxy_config> m_db;
|
||||
|
||||
/**
|
||||
* HW configuration for the config. The bool representing the
|
||||
* do/don't configured/unconfigured.
|
||||
*/
|
||||
HW::item<bool> 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
|
120
src/vpp-api/vom/arp_proxy_config_cmds.cpp
Normal file
120
src/vpp-api/vom/arp_proxy_config_cmds.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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 <vapi/vpe.api.vapi.hpp>
|
||||
|
||||
namespace VOM {
|
||||
arp_proxy_config::config_cmd::config_cmd(
|
||||
HW::item<bool>& 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
|
||||
arp_proxy_config::config_cmd::operator==(const config_cmd& o) const
|
||||
{
|
||||
return ((m_low == o.m_low) && (m_high == o.m_high));
|
||||
}
|
||||
|
||||
rc_t
|
||||
arp_proxy_config::config_cmd::issue(connection& con)
|
||||
{
|
||||
msg_t req(con.ctx(), std::ref(*this));
|
||||
|
||||
auto& payload = req.get_request().get_payload();
|
||||
payload.is_add = 1;
|
||||
|
||||
std::copy_n(std::begin(m_low.to_bytes()), m_low.to_bytes().size(),
|
||||
payload.low_address);
|
||||
std::copy_n(std::begin(m_high.to_bytes()), m_high.to_bytes().size(),
|
||||
payload.hi_address);
|
||||
|
||||
VAPI_CALL(req.execute());
|
||||
|
||||
m_hw_item.set(wait());
|
||||
|
||||
return (rc_t::OK);
|
||||
}
|
||||
|
||||
std::string
|
||||
arp_proxy_config::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());
|
||||
}
|
||||
|
||||
arp_proxy_config::unconfig_cmd::unconfig_cmd(
|
||||
HW::item<bool>& 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
|
||||
arp_proxy_config::unconfig_cmd::operator==(const unconfig_cmd& o) const
|
||||
{
|
||||
return ((m_low == o.m_low) && (m_high == o.m_high));
|
||||
}
|
||||
|
||||
rc_t
|
||||
arp_proxy_config::unconfig_cmd::issue(connection& con)
|
||||
{
|
||||
msg_t req(con.ctx(), std::ref(*this));
|
||||
|
||||
auto& payload = req.get_request().get_payload();
|
||||
payload.is_add = 0;
|
||||
|
||||
std::copy_n(std::begin(m_low.to_bytes()), m_low.to_bytes().size(),
|
||||
payload.low_address);
|
||||
std::copy_n(std::begin(m_high.to_bytes()), m_high.to_bytes().size(),
|
||||
payload.hi_address);
|
||||
|
||||
VAPI_CALL(req.execute());
|
||||
|
||||
wait();
|
||||
m_hw_item.set(rc_t::NOOP);
|
||||
|
||||
return (rc_t::OK);
|
||||
}
|
||||
|
||||
std::string
|
||||
arp_proxy_config::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());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
210
src/vpp-api/vom/bridge_domain.cpp
Normal file
210
src/vpp-api/vom/bridge_domain.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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/cmd.hpp"
|
||||
#include "vom/interface.hpp"
|
||||
#include "vom/l2_binding.hpp"
|
||||
#include "vom/logger.hpp"
|
||||
|
||||
namespace VOM {
|
||||
/**
|
||||
* A DB of al the interfaces, key on the name
|
||||
*/
|
||||
singular_db<uint32_t, bridge_domain> 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)
|
||||
: m_id(id)
|
||||
{
|
||||
}
|
||||
|
||||
bridge_domain::bridge_domain(const bridge_domain& o)
|
||||
: m_id(o.m_id)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t
|
||||
bridge_domain::id() const
|
||||
{
|
||||
return (m_id.data());
|
||||
}
|
||||
|
||||
void
|
||||
bridge_domain::sweep()
|
||||
{
|
||||
if (rc_t::OK == m_id.rc()) {
|
||||
HW::enqueue(new delete_cmd(m_id));
|
||||
}
|
||||
HW::write();
|
||||
}
|
||||
|
||||
void
|
||||
bridge_domain::replay()
|
||||
{
|
||||
if (rc_t::OK == m_id.rc()) {
|
||||
HW::enqueue(new create_cmd(m_id));
|
||||
}
|
||||
}
|
||||
|
||||
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() << "]";
|
||||
|
||||
return (s.str());
|
||||
}
|
||||
|
||||
std::shared_ptr<bridge_domain>
|
||||
bridge_domain::find(uint32_t id)
|
||||
{
|
||||
/*
|
||||
* Loop throught the entire map looking for matching interface.
|
||||
* not the most efficient algorithm, but it will do for now. The
|
||||
* number of L3 configs is low and this is only called during bootup
|
||||
*/
|
||||
std::shared_ptr<bridge_domain> bd;
|
||||
|
||||
auto it = m_db.cbegin();
|
||||
|
||||
while (it != m_db.cend()) {
|
||||
/*
|
||||
* The key in the DB is a pair of the interface's name and prefix.
|
||||
* If the keys match, save the L3-config
|
||||
*/
|
||||
auto key = it->first;
|
||||
|
||||
if (id == key) {
|
||||
bd = it->second.lock();
|
||||
break;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
return (bd);
|
||||
}
|
||||
|
||||
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 create_cmd(m_id));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<bridge_domain>
|
||||
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>
|
||||
bridge_domain::singular() const
|
||||
{
|
||||
return find_or_add(*this);
|
||||
}
|
||||
|
||||
void
|
||||
bridge_domain::dump(std::ostream& os)
|
||||
{
|
||||
m_db.dump(os);
|
||||
}
|
||||
|
||||
void
|
||||
bridge_domain::event_handler::handle_populate(const client_db::key_t& key)
|
||||
{
|
||||
/*
|
||||
* dump VPP Bridge domains
|
||||
*/
|
||||
std::shared_ptr<bridge_domain::dump_cmd> cmd(new bridge_domain::dump_cmd());
|
||||
|
||||
HW::enqueue(cmd);
|
||||
HW::write();
|
||||
|
||||
for (auto& record : *cmd) {
|
||||
auto& payload = record.get_payload();
|
||||
|
||||
bridge_domain bd(payload.bd_id);
|
||||
|
||||
VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.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);
|
||||
|
||||
/**
|
||||
* For each interface in the BD construct an l2_binding
|
||||
*/
|
||||
for (unsigned int ii = 0; ii < payload.n_sw_ifs; ii++) {
|
||||
std::shared_ptr<interface> itf =
|
||||
interface::find(payload.sw_if_details[ii].sw_if_index);
|
||||
l2_binding l2(*itf, bd);
|
||||
OM::commit(key, l2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_db.dump(os);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
254
src/vpp-api/vom/bridge_domain.hpp
Normal file
254
src/vpp-api/vom/bridge_domain.hpp
Normal file
@@ -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.
|
||||
*/
|
||||
|
||||
#ifndef __VOM_BRIDGE_DOMAIN_H__
|
||||
#define __VOM_BRIDGE_DOMAIN_H__
|
||||
|
||||
#include "vom/dump_cmd.hpp"
|
||||
#include "vom/enum_base.hpp"
|
||||
#include "vom/hw.hpp"
|
||||
#include "vom/inspect.hpp"
|
||||
#include "vom/object_base.hpp"
|
||||
#include "vom/om.hpp"
|
||||
#include "vom/rpc_cmd.hpp"
|
||||
#include "vom/singular_db.hpp"
|
||||
|
||||
#include <vapi/l2.api.vapi.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:
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* Copy Constructor
|
||||
*/
|
||||
bridge_domain(const bridge_domain& o);
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~bridge_domain();
|
||||
|
||||
/**
|
||||
* Return the matchin 'singular' instance of the bridge-domain
|
||||
*/
|
||||
std::shared_ptr<bridge_domain> singular() const;
|
||||
|
||||
/**
|
||||
* convert to string format for debug purposes
|
||||
*/
|
||||
std::string to_string(void) const;
|
||||
|
||||
/**
|
||||
* Return VPP's handle for this obejct
|
||||
*/
|
||||
uint32_t id() const;
|
||||
|
||||
/**
|
||||
* Static function to find the bridge_domain in the model
|
||||
*/
|
||||
static std::shared_ptr<bridge_domain> find(uint32_t id);
|
||||
|
||||
/**
|
||||
* Dump all bridge-doamin into the stream provided
|
||||
*/
|
||||
static void dump(std::ostream& os);
|
||||
|
||||
/**
|
||||
* A command class that creates an Bridge-Domain
|
||||
*/
|
||||
class create_cmd
|
||||
: public rpc_cmd<HW::item<uint32_t>, rc_t, vapi::Bridge_domain_add_del>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
create_cmd(HW::item<uint32_t>& 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 create_cmd& i) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* A cmd class that Delete an Bridge-Domain
|
||||
*/
|
||||
class delete_cmd
|
||||
: public rpc_cmd<HW::item<uint32_t>, rc_t, vapi::Bridge_domain_add_del>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
delete_cmd(HW::item<uint32_t>& 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 IPv4 L3 configs
|
||||
*/
|
||||
class dump_cmd : public VOM::dump_cmd<vapi::Bridge_domain_dump>
|
||||
{
|
||||
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<bool> 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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<bridge_domain> 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<uint32_t, bridge_domain>;
|
||||
|
||||
/**
|
||||
* 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<uint32_t> m_id;
|
||||
|
||||
/**
|
||||
* A map of all interfaces key against the interface's name
|
||||
*/
|
||||
static singular_db<uint32_t, bridge_domain> m_db;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
||||
|
||||
#endif
|
172
src/vpp-api/vom/bridge_domain_arp_entry.cpp
Normal file
172
src/vpp-api/vom/bridge_domain_arp_entry.cpp
Normal file
@@ -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/bridge_domain_arp_entry.hpp"
|
||||
|
||||
namespace VOM {
|
||||
|
||||
singular_db<bridge_domain_arp_entry::key_t, bridge_domain_arp_entry>
|
||||
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 mac_address_t& mac,
|
||||
const boost::asio::ip::address& ip_addr)
|
||||
: m_hw(false)
|
||||
, m_bd(bd.singular())
|
||||
, m_mac(mac)
|
||||
, m_ip_addr(ip_addr)
|
||||
{
|
||||
}
|
||||
|
||||
bridge_domain_arp_entry::bridge_domain_arp_entry(
|
||||
const mac_address_t& mac,
|
||||
const boost::asio::ip::address& ip_addr)
|
||||
: m_hw(false)
|
||||
, m_bd(nullptr)
|
||||
, m_mac(mac)
|
||||
, m_ip_addr(ip_addr)
|
||||
{
|
||||
/*
|
||||
* 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_mac(bde.m_mac)
|
||||
, m_ip_addr(bde.m_ip_addr)
|
||||
{
|
||||
}
|
||||
|
||||
bridge_domain_arp_entry::~bridge_domain_arp_entry()
|
||||
{
|
||||
sweep();
|
||||
|
||||
// not in the DB anymore.
|
||||
m_db.release(std::make_tuple(m_bd->id(), m_mac, m_ip_addr), this);
|
||||
}
|
||||
|
||||
void
|
||||
bridge_domain_arp_entry::sweep()
|
||||
{
|
||||
if (m_hw) {
|
||||
HW::enqueue(new 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 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 create_cmd(m_hw, m_bd->id(), m_mac, m_ip_addr));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<bridge_domain_arp_entry>
|
||||
bridge_domain_arp_entry::find_or_add(const bridge_domain_arp_entry& temp)
|
||||
{
|
||||
return (m_db.find_or_add(
|
||||
std::make_tuple(temp.m_bd->id(), temp.m_mac, temp.m_ip_addr), temp));
|
||||
}
|
||||
|
||||
std::shared_ptr<bridge_domain_arp_entry>
|
||||
bridge_domain_arp_entry::singular() const
|
||||
{
|
||||
return find_or_add(*this);
|
||||
}
|
||||
|
||||
void
|
||||
bridge_domain_arp_entry::dump(std::ostream& os)
|
||||
{
|
||||
m_db.dump(os);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const bridge_domain_arp_entry::key_t& key)
|
||||
{
|
||||
os << "[" << std::get<0>(key) << ", " << std::get<1>(key) << ", "
|
||||
<< std::get<2>(key) << "]";
|
||||
|
||||
return (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)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_db.dump(os);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
260
src/vpp-api/vom/bridge_domain_arp_entry.hpp
Normal file
260
src/vpp-api/vom/bridge_domain_arp_entry.hpp
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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"
|
||||
|
||||
#include <vapi/l2.api.vapi.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::tuple<uint32_t, mac_address_t, boost::asio::ip::address> key_t;
|
||||
|
||||
/**
|
||||
* Construct a bridge_domain in the given bridge domain
|
||||
*/
|
||||
bridge_domain_arp_entry(const bridge_domain& bd,
|
||||
const mac_address_t& mac,
|
||||
const boost::asio::ip::address& ip_addr);
|
||||
|
||||
/**
|
||||
* Construct a bridge_domain in the default table
|
||||
*/
|
||||
bridge_domain_arp_entry(const mac_address_t& mac,
|
||||
const boost::asio::ip::address& ip_addr);
|
||||
|
||||
/**
|
||||
* Copy Construct
|
||||
*/
|
||||
bridge_domain_arp_entry(const bridge_domain_arp_entry& r);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~bridge_domain_arp_entry();
|
||||
|
||||
/**
|
||||
* Return the matching 'singular instance'
|
||||
*/
|
||||
std::shared_ptr<bridge_domain_arp_entry> singular() const;
|
||||
|
||||
/**
|
||||
* Find the instnace of the bridge_domain domain in the OM
|
||||
*/
|
||||
static std::shared_ptr<bridge_domain_arp_entry> find(
|
||||
const bridge_domain_arp_entry& temp);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A command class that creates or updates the bridge domain ARP Entry
|
||||
*/
|
||||
class create_cmd
|
||||
: public rpc_cmd<HW::item<bool>, rc_t, vapi::Bd_ip_mac_add_del>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
create_cmd(HW::item<bool>& 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<HW::item<bool>, rc_t, vapi::Bd_ip_mac_add_del>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
delete_cmd(HW::item<bool>& 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;
|
||||
};
|
||||
|
||||
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<bridge_domain_arp_entry> 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<key_t, bridge_domain_arp_entry>;
|
||||
|
||||
/**
|
||||
* Sweep/reap the object if still stale
|
||||
*/
|
||||
void sweep(void);
|
||||
|
||||
/**
|
||||
* HW configuration for the result of creating the bridge_domain
|
||||
*/
|
||||
HW::item<bool> m_hw;
|
||||
|
||||
/**
|
||||
* The bridge_domain domain the bridge_domain is in.
|
||||
*/
|
||||
std::shared_ptr<bridge_domain> m_bd;
|
||||
|
||||
/**
|
||||
* The mac to match
|
||||
*/
|
||||
mac_address_t m_mac;
|
||||
|
||||
/**
|
||||
* The IP address
|
||||
*/
|
||||
boost::asio::ip::address m_ip_addr;
|
||||
|
||||
/**
|
||||
* A map of all bridge_domains
|
||||
*/
|
||||
static singular_db<key_t, bridge_domain_arp_entry> m_db;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
const bridge_domain_arp_entry::key_t& key);
|
||||
};
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
||||
|
||||
#endif
|
124
src/vpp-api/vom/bridge_domain_arp_entry_cmds.cpp
Normal file
124
src/vpp-api/vom/bridge_domain_arp_entry_cmds.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT 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"
|
||||
|
||||
namespace VOM {
|
||||
|
||||
bridge_domain_arp_entry::create_cmd::create_cmd(
|
||||
HW::item<bool>& 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
|
||||
bridge_domain_arp_entry::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
|
||||
bridge_domain_arp_entry::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_address, 6);
|
||||
to_bytes(m_ip_addr, &payload.is_ipv6, payload.ip_address);
|
||||
|
||||
VAPI_CALL(req.execute());
|
||||
|
||||
m_hw_item.set(wait());
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
std::string
|
||||
bridge_domain_arp_entry::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());
|
||||
}
|
||||
|
||||
bridge_domain_arp_entry::delete_cmd::delete_cmd(
|
||||
HW::item<bool>& 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
|
||||
bridge_domain_arp_entry::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
|
||||
bridge_domain_arp_entry::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_address, 6);
|
||||
to_bytes(m_ip_addr, &payload.is_ipv6, payload.ip_address);
|
||||
|
||||
VAPI_CALL(req.execute());
|
||||
|
||||
wait();
|
||||
m_hw_item.set(rc_t::NOOP);
|
||||
|
||||
return rc_t::OK;
|
||||
}
|
||||
|
||||
std::string
|
||||
bridge_domain_arp_entry::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());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "mozilla")
|
||||
* End:
|
||||
*/
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user