aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2017-11-14 11:04:28 -0800
committerNeale Ranns <nranns@cisco.com>2017-11-15 10:38:29 +0000
commit352ea0c4931b54012ce8d55634e3dd3f6ee6802b (patch)
tree491444faeb0a42062baee95884fda3eb99cb1609 /src
parent10e7a9f8d8c8572be16f9b3f0395da6f8eff22ec (diff)
VOM: interface RD update reconfigures L3 bindings
Change-Id: I273e1ea28c3c146e4a88d031c790c1cc56dccf00 Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
Diffstat (limited to 'src')
-rw-r--r--src/vpp-api/vom/interface.cpp50
-rw-r--r--src/vpp-api/vom/interface.hpp4
-rw-r--r--src/vpp-api/vom/l3_binding.cpp24
-rw-r--r--src/vpp-api/vom/l3_binding.hpp25
4 files changed, 82 insertions, 21 deletions
diff --git a/src/vpp-api/vom/interface.cpp b/src/vpp-api/vom/interface.cpp
index 8e270136d8b..1c9f20d2a5d 100644
--- a/src/vpp-api/vom/interface.cpp
+++ b/src/vpp-api/vom/interface.cpp
@@ -149,7 +149,7 @@ interface::cend()
void
interface::sweep()
{
- if (m_table_id) {
+ if (m_table_id && (m_table_id.data() != route::DEFAULT_TABLE)) {
m_table_id.data() = route::DEFAULT_TABLE;
HW::enqueue(
new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl));
@@ -181,7 +181,7 @@ interface::replay()
HW::enqueue(new interface_cmds::state_change_cmd(m_state, m_hdl));
}
- if (m_table_id) {
+ if (m_table_id && (m_table_id.data() != route::DEFAULT_TABLE)) {
HW::enqueue(
new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl));
HW::enqueue(
@@ -267,32 +267,58 @@ void
interface::update(const interface& desired)
{
/*
- * the desired state is always that the interface should be created
- */
+ * the desired state is always that the interface should be created
+ */
if (rc_t::OK != m_hdl.rc()) {
std::queue<cmd*> cmds;
HW::enqueue(mk_create_cmd(cmds));
}
/*
- * change the interface state to that which is deisred
- */
+ * change the interface state to that which is deisred
+ */
if (m_state.update(desired.m_state)) {
HW::enqueue(new interface_cmds::state_change_cmd(m_state, m_hdl));
}
/*
- * change the interface state to that which is deisred
- */
+ * change the interface state to that which is deisred
+ */
if (m_l2_address.update(desired.m_l2_address)) {
HW::enqueue(new interface_cmds::set_mac_cmd(m_l2_address, m_hdl));
}
/*
- * If the interface is mapped into a route domain, set VPP's
- * table ID
- */
- if (!m_table_id && m_rd) {
+ * If the interface is mapped into a route domain, set VPP's
+ * table ID
+ */
+ if (m_rd != desired.m_rd) {
+ /*
+ * changing route domains. need to remove all L3 bindings, swap the table
+ * then reapply the bindings.
+ */
+ auto it = l3_binding::cbegin();
+
+ while (it != l3_binding::cend()) {
+ if (it->second.lock()->itf().key() == key())
+ it->second.lock()->sweep();
+ ++it;
+ }
+ m_rd = desired.m_rd;
+ m_table_id.update(m_rd ? m_rd->table_id() : route::DEFAULT_TABLE);
+ HW::enqueue(
+ new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl));
+ HW::enqueue(
+ new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl));
+ HW::write();
+
+ it = l3_binding::cbegin();
+ while (it != l3_binding::cend()) {
+ if (it->second.lock()->itf().key() == key())
+ it->second.lock()->replay(); //(*it->second.lock());
+ ++it;
+ }
+ } else if (!m_table_id && m_rd) {
HW::enqueue(
new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl));
HW::enqueue(
diff --git a/src/vpp-api/vom/interface.hpp b/src/vpp-api/vom/interface.hpp
index 6fdd1e1eb62..f11e3591a44 100644
--- a/src/vpp-api/vom/interface.hpp
+++ b/src/vpp-api/vom/interface.hpp
@@ -540,9 +540,9 @@ private:
/**
* shared pointer to the routeDoamin the interface is in.
- * NULL is not mapped - i.e. in eht default table
+ * NULL is not mapped - i.e. in the default table
*/
- const std::shared_ptr<route_domain> m_rd;
+ std::shared_ptr<route_domain> m_rd;
/**
* The state of the interface
diff --git a/src/vpp-api/vom/l3_binding.cpp b/src/vpp-api/vom/l3_binding.cpp
index 8bc7c7c3af3..8f90d45eec4 100644
--- a/src/vpp-api/vom/l3_binding.cpp
+++ b/src/vpp-api/vom/l3_binding.cpp
@@ -71,6 +71,24 @@ l3_binding::prefix() const
return (m_pfx);
}
+const interface&
+l3_binding::itf() const
+{
+ return (*m_itf);
+}
+
+l3_binding::const_iterator_t
+l3_binding::cbegin()
+{
+ return m_db.cbegin();
+}
+
+l3_binding::const_iterator_t
+l3_binding::cend()
+{
+ return m_db.cend();
+}
+
std::string
l3_binding::to_string() const
{
@@ -85,8 +103,10 @@ void
l3_binding::update(const l3_binding& desired)
{
/*
- * the desired state is always that the interface should be created
- */
+ * no updates for the binding. chaning the interface or the prefix is a change
+ * to the
+ * key, hence a new object
+ */
if (!m_binding) {
HW::enqueue(
new l3_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_pfx));
diff --git a/src/vpp-api/vom/l3_binding.hpp b/src/vpp-api/vom/l3_binding.hpp
index d94ff696b23..4403760180e 100644
--- a/src/vpp-api/vom/l3_binding.hpp
+++ b/src/vpp-api/vom/l3_binding.hpp
@@ -46,6 +46,19 @@ public:
~l3_binding();
/**
+ * The key type for l3_bindings
+ */
+ typedef std::pair<interface::key_type, route::prefix_t> key_type_t;
+
+ /**
+ * The iterator type
+ */
+ typedef singular_db<key_type_t, l3_binding>::const_iterator const_iterator_t;
+
+ static const_iterator_t cbegin();
+ static const_iterator_t cend();
+
+ /**
* Return the 'singular instance' of the L3-Config that matches this
* object
*/
@@ -57,19 +70,19 @@ public:
std::string to_string() const;
/**
- * Return the prefix associated with this L3config
+ * Return the prefix associated with this L3 binding
*/
const route::prefix_t& prefix() const;
/**
- * Dump all l3_bindings into the stream provided
+ * Return the interface associated with this L3 binding
*/
- static void dump(std::ostream& os);
+ const interface& itf() const;
/**
- * The key type for l3_bindings
+ * Dump all l3_bindings into the stream provided
*/
- typedef std::pair<interface::key_type, route::prefix_t> key_type_t;
+ static void dump(std::ostream& os);
/**
* Find an singular instance in the DB for the interface passed
@@ -142,6 +155,8 @@ private:
*/
void replay(void);
+ friend class interface;
+
/**
* A reference counting pointer the interface that this L3 layer
* represents. By holding the reference here, we can guarantee that