vxlan: vxlan/vxlan.api API cleanup
[vpp.git] / extras / vom / vom / gbp_vxlan.cpp
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include "vom/gbp_vxlan.hpp"
17 #include "vom/api_types.hpp"
18 #include "vom/gbp_vxlan_cmds.hpp"
19 #include "vom/interface.hpp"
20 #include "vom/singular_db_funcs.hpp"
21
22 namespace VOM {
23
24 const std::string GBP_VXLAN_NAME = "gbp-vxlan";
25
26 /**
27  * A DB of al the interfaces, key on the name
28  */
29 singular_db<gbp_vxlan::key_t, gbp_vxlan> gbp_vxlan::m_db;
30
31 gbp_vxlan::event_handler gbp_vxlan::m_evh;
32
33 gbp_vxlan::gbp_vxlan(uint32_t vni,
34                      const gbp_route_domain& grd,
35                      const boost::asio::ip::address_v4& src)
36   : interface(mk_name(vni),
37               interface::type_t::UNKNOWN,
38               interface::admin_state_t::UP)
39   , m_vni(vni)
40   , m_gbd()
41   , m_grd(grd.singular())
42   , m_src(src)
43 {
44 }
45 gbp_vxlan::gbp_vxlan(uint32_t vni,
46                      const gbp_bridge_domain& gbd,
47                      const boost::asio::ip::address_v4& src)
48   : interface(mk_name(vni),
49               interface::type_t::UNKNOWN,
50               interface::admin_state_t::UP)
51   , m_vni(vni)
52   , m_gbd(gbd.singular())
53   , m_grd()
54   , m_src(src)
55 {
56 }
57
58 gbp_vxlan::gbp_vxlan(const gbp_vxlan& vt)
59   : interface(vt)
60   , m_vni(vt.m_vni)
61   , m_gbd(vt.m_gbd)
62   , m_grd(vt.m_grd)
63   , m_src(vt.m_src)
64 {
65 }
66
67 std::string
68 gbp_vxlan::mk_name(uint32_t vni)
69 {
70   std::ostringstream s;
71
72   s << GBP_VXLAN_NAME << "-" << vni;
73
74   return (s.str());
75 }
76
77 const gbp_vxlan::key_t
78 gbp_vxlan::key() const
79 {
80   return (m_vni);
81 }
82
83 bool
84 gbp_vxlan::operator==(const gbp_vxlan& vt) const
85 {
86   return (m_vni == vt.m_vni && m_src == vt.m_src);
87 }
88
89 void
90 gbp_vxlan::sweep()
91 {
92   if (rc_t::OK == m_hdl) {
93     HW::enqueue(new gbp_vxlan_cmds::delete_cmd(m_hdl, m_vni));
94   }
95   HW::write();
96 }
97
98 void
99 gbp_vxlan::replay()
100 {
101   if (rc_t::OK == m_hdl) {
102     if (m_grd)
103       HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni,
104                                                  false, m_grd->id()));
105     else if (m_gbd)
106       HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni,
107                                                  true, m_gbd->id()));
108   }
109 }
110
111 gbp_vxlan::~gbp_vxlan()
112 {
113   sweep();
114   m_db.release(key(), this);
115 }
116
117 std::string
118 gbp_vxlan::to_string() const
119 {
120   std::ostringstream s;
121   s << "gbp-vxlan:[" << m_vni << "]";
122
123   return (s.str());
124 }
125
126 std::shared_ptr<gbp_vxlan>
127 gbp_vxlan::find(const key_t key)
128 {
129   return (m_db.find(key));
130 }
131
132 void
133 gbp_vxlan::update(const gbp_vxlan& desired)
134 {
135   /*
136    * the desired state is always that the interface should be created
137    */
138   if (rc_t::OK != m_hdl) {
139     if (m_grd)
140       HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni,
141                                                  false, m_grd->id()));
142     else if (m_gbd)
143       HW::enqueue(new gbp_vxlan_cmds::create_cmd(m_hdl, name(), m_src, m_vni,
144                                                  true, m_gbd->id()));
145   }
146 }
147
148 std::shared_ptr<gbp_vxlan>
149 gbp_vxlan::find_or_add(const gbp_vxlan& temp)
150 {
151   return (m_db.find_or_add(temp.key(), temp));
152 }
153
154 std::shared_ptr<gbp_vxlan>
155 gbp_vxlan::singular() const
156 {
157   return find_or_add(*this);
158 }
159
160 std::shared_ptr<interface>
161 gbp_vxlan::singular_i() const
162 {
163   return find_or_add(*this);
164 }
165
166 void
167 gbp_vxlan::dump(std::ostream& os)
168 {
169   db_dump(m_db, os);
170 }
171
172 void
173 gbp_vxlan::event_handler::handle_populate(const client_db::key_t& key)
174 {
175   /*
176    * dump VPP Bridge domains
177    */
178   std::shared_ptr<gbp_vxlan_cmds::dump_cmd> cmd =
179     std::make_shared<gbp_vxlan_cmds::dump_cmd>();
180
181   HW::enqueue(cmd);
182   HW::write();
183
184   for (auto& record : *cmd) {
185     auto& payload = record.get_payload();
186
187     boost::asio::ip::address_v4 src = from_api(payload.tunnel.src);
188
189     if (GBP_VXLAN_TUNNEL_MODE_L3 == payload.tunnel.mode) {
190       auto rd = gbp_route_domain::find(payload.tunnel.bd_rd_id);
191
192       if (rd) {
193         gbp_vxlan vt(payload.tunnel.vni, *rd, src);
194         OM::commit(key, vt);
195         VOM_LOG(log_level_t::DEBUG) << "dump: " << vt.to_string();
196       }
197     } else {
198       auto bd = gbp_bridge_domain::find(payload.tunnel.bd_rd_id);
199
200       if (bd) {
201         gbp_vxlan vt(payload.tunnel.vni, *bd, src);
202         OM::commit(key, vt);
203         VOM_LOG(log_level_t::DEBUG) << "dump: " << vt.to_string();
204       }
205     }
206   }
207 }
208
209 gbp_vxlan::event_handler::event_handler()
210 {
211   OM::register_listener(this);
212   inspect::register_handler({ "gvt", "gbp-vxlan-tunnel" }, "GBP VXLAN Tunnels",
213                             this);
214 }
215
216 void
217 gbp_vxlan::event_handler::handle_replay()
218 {
219   m_db.replay();
220 }
221
222 dependency_t
223 gbp_vxlan::event_handler::order() const
224 {
225   return (dependency_t::BINDING);
226 }
227
228 void
229 gbp_vxlan::event_handler::show(std::ostream& os)
230 {
231   db_dump(m_db, os);
232 }
233 }
234
235 /*
236  * fd.io coding-style-patch-verification: ON
237  *
238  * Local Variables:
239  * eval: (c-set-style "mozilla")
240  * End:
241  */