Fixes for 'make UNATTENDED=yes CC=clang CXX=clang verify'
[vpp.git] / src / vpp-api / vom / nat_static.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/nat_static.hpp"
17 #include "vom/nat_static_cmds.hpp"
18 #include "vom/singular_db_funcs.hpp"
19
20 namespace VOM {
21 singular_db<nat_static::key_t, nat_static> nat_static::m_db;
22 nat_static::event_handler nat_static::m_evh;
23
24 nat_static::nat_static(const boost::asio::ip::address& inside,
25                        const boost::asio::ip::address_v4& outside)
26   : m_hw(false)
27   , m_rd(route_domain::get_default())
28   , m_inside(inside)
29   , m_outside(outside)
30 {
31 }
32
33 nat_static::nat_static(const route_domain& rd,
34                        const boost::asio::ip::address& inside,
35                        const boost::asio::ip::address_v4& outside)
36   : m_hw(false)
37   , m_rd(rd.singular())
38   , m_inside(inside)
39   , m_outside(outside)
40 {
41 }
42
43 nat_static::nat_static(const nat_static& ns)
44   : m_hw(ns.m_hw)
45   , m_rd(ns.m_rd)
46   , m_inside(ns.m_inside)
47   , m_outside(ns.m_outside)
48 {
49 }
50
51 nat_static::~nat_static()
52 {
53   sweep();
54
55   // not in the DB anymore.
56   m_db.release(key(), this);
57 }
58
59 const nat_static::key_t
60 nat_static::key() const
61 {
62   return (std::make_pair(m_rd->key(), m_outside));
63 }
64
65 bool
66 nat_static::operator==(const nat_static& n) const
67 {
68   return ((key() == n.key()) && (m_inside == n.m_inside));
69 }
70
71 void
72 nat_static::sweep()
73 {
74   if (m_hw) {
75     if (m_inside.is_v4()) {
76       HW::enqueue(new nat_static_cmds::delete_44_cmd(
77         m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside));
78     }
79   }
80   HW::write();
81 }
82
83 void
84 nat_static::replay()
85 {
86   if (m_hw) {
87     if (m_inside.is_v4()) {
88       HW::enqueue(new nat_static_cmds::create_44_cmd(
89         m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside));
90     }
91   }
92 }
93
94 void
95 nat_static::update(const nat_static& r)
96 {
97   /*
98  * create the table if it is not yet created
99  */
100   if (rc_t::OK != m_hw.rc()) {
101     if (m_inside.is_v4()) {
102       HW::enqueue(new nat_static_cmds::create_44_cmd(
103         m_hw, m_rd->table_id(), m_inside.to_v4(), m_outside));
104     }
105   }
106 }
107
108 std::string
109 nat_static::to_string() const
110 {
111   std::ostringstream s;
112   s << "nat-static:["
113     << "table:" << m_rd->to_string() << " inside:" << m_inside.to_string()
114     << " outside:" << m_outside.to_string() << "]";
115
116   return (s.str());
117 }
118
119 std::shared_ptr<nat_static>
120 nat_static::find_or_add(const nat_static& temp)
121 {
122   return (m_db.find_or_add(temp.key(), temp));
123 }
124
125 std::shared_ptr<nat_static>
126 nat_static::find(const key_t& key)
127 {
128   return (m_db.find(key));
129 }
130
131 std::shared_ptr<nat_static>
132 nat_static::singular() const
133 {
134   return find_or_add(*this);
135 }
136
137 void
138 nat_static::dump(std::ostream& os)
139 {
140   db_dump(m_db, os);
141 }
142
143 nat_static::event_handler::event_handler()
144 {
145   OM::register_listener(this);
146   inspect::register_handler({ "nat-static" }, "NAT Statics", this);
147 }
148
149 void
150 nat_static::event_handler::handle_replay()
151 {
152   m_db.replay();
153 }
154
155 void
156 nat_static::event_handler::handle_populate(const client_db::key_t& key)
157 {
158   /*
159    * dump VPP current states
160    */
161   std::shared_ptr<nat_static_cmds::dump_44_cmd> cmd =
162     std::make_shared<nat_static_cmds::dump_44_cmd>();
163
164   HW::enqueue(cmd);
165   HW::write();
166
167   for (auto& record : *cmd) {
168
169     auto& payload = record.get_payload();
170
171     boost::asio::ip::address inside = from_bytes(0, payload.local_ip_address);
172     boost::asio::ip::address outside =
173       from_bytes(0, payload.external_ip_address);
174     nat_static n(route_domain(payload.vrf_id), inside, outside.to_v4());
175
176     /*
177      * Write each of the discovered mappings into the OM,
178      * but disable the HW Command q whilst we do, so that no
179      * commands are sent to VPP
180      */
181     OM::commit(key, n);
182   }
183 }
184
185 dependency_t
186 nat_static::event_handler::order() const
187 {
188   return (dependency_t::ENTRY);
189 }
190
191 void
192 nat_static::event_handler::show(std::ostream& os)
193 {
194   db_dump(m_db, os);
195 }
196 }
197
198 /*
199  * fd.io coding-style-patch-verification: ON
200  *
201  * Local Variables:
202  * eval: (c-set-style "mozilla")
203  * End:
204  */