VOM reshuffle
[vpp.git] / src / vpp-api / vom / nat_binding.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_binding.hpp"
17 #include "vom/cmd.hpp"
18 #include "vom/nat_binding_cmds.hpp"
19
20 namespace VOM {
21 singular_db<const nat_binding::key_t, nat_binding> nat_binding::m_db;
22
23 nat_binding::event_handler nat_binding::m_evh;
24
25 const nat_binding::zone_t nat_binding::zone_t::INSIDE(0, "inside");
26 const nat_binding::zone_t nat_binding::zone_t::OUTSIDE(0, "outside");
27
28 nat_binding::zone_t::zone_t(int v, const std::string s)
29   : enum_base(v, s)
30 {
31 }
32
33 /**
34  * Construct a new object matching the desried state
35  */
36 nat_binding::nat_binding(const interface& itf,
37                          const direction_t& dir,
38                          const l3_proto_t& proto,
39                          const zone_t& zone)
40   : m_binding(false)
41   , m_itf(itf.singular())
42   , m_dir(dir)
43   , m_proto(proto)
44   , m_zone(zone)
45 {
46 }
47
48 nat_binding::nat_binding(const nat_binding& o)
49   : m_binding(o.m_binding)
50   , m_itf(o.m_itf)
51   , m_dir(o.m_dir)
52   , m_proto(o.m_proto)
53   , m_zone(o.m_zone)
54 {
55 }
56
57 nat_binding::~nat_binding()
58 {
59   sweep();
60   m_db.release(make_tuple(m_itf->key(), m_dir, m_proto), this);
61 }
62
63 void
64 nat_binding::sweep()
65 {
66   if (m_binding) {
67     if (direction_t::INPUT == m_dir) {
68       HW::enqueue(new nat_binding_cmds::unbind_44_input_cmd(
69         m_binding, m_itf->handle(), m_zone));
70     } else {
71       assert(!"Unimplemented");
72     }
73   }
74   HW::write();
75 }
76
77 void
78 nat_binding::replay()
79 {
80   if (m_binding) {
81     if (direction_t::INPUT == m_dir) {
82       HW::enqueue(new nat_binding_cmds::bind_44_input_cmd(
83         m_binding, m_itf->handle(), m_zone));
84     } else {
85       assert(!"Unimplemented");
86     }
87   }
88 }
89
90 void
91 nat_binding::update(const nat_binding& desired)
92 {
93   /*
94  * the desired state is always that the interface should be created
95  */
96   if (!m_binding) {
97     if (direction_t::INPUT == m_dir) {
98       HW::enqueue(new nat_binding_cmds::bind_44_input_cmd(
99         m_binding, m_itf->handle(), m_zone));
100     } else {
101       assert(!"Unimplemented");
102     }
103   }
104 }
105
106 std::string
107 nat_binding::to_string() const
108 {
109   std::ostringstream s;
110   s << "nat-binding:[" << m_itf->to_string() << " " << m_dir.to_string() << " "
111     << m_proto.to_string() << " " << m_zone.to_string() << "]";
112
113   return (s.str());
114 }
115
116 std::shared_ptr<nat_binding>
117 nat_binding::find_or_add(const nat_binding& temp)
118 {
119   return (m_db.find_or_add(
120     make_tuple(temp.m_itf->key(), temp.m_dir, temp.m_proto), temp));
121 }
122
123 std::shared_ptr<nat_binding>
124 nat_binding::singular() const
125 {
126   return find_or_add(*this);
127 }
128
129 void
130 nat_binding::dump(std::ostream& os)
131 {
132   m_db.dump(os);
133 }
134
135 std::ostream&
136 operator<<(std::ostream& os, const nat_binding::key_t& key)
137 {
138   os << "[" << std::get<0>(key) << ", " << std::get<1>(key) << ", "
139      << std::get<2>(key) << "]";
140
141   return (os);
142 }
143
144 nat_binding::event_handler::event_handler()
145 {
146   OM::register_listener(this);
147   inspect::register_handler({ "nat-binding" }, "NAT bindings", this);
148 }
149
150 void
151 nat_binding::event_handler::handle_replay()
152 {
153   m_db.replay();
154 }
155
156 void
157 nat_binding::event_handler::handle_populate(const client_db::key_t& key)
158 {
159   /**
160  * This is done while populating the interfaces
161  */
162 }
163
164 dependency_t
165 nat_binding::event_handler::order() const
166 {
167   return (dependency_t::BINDING);
168 }
169
170 void
171 nat_binding::event_handler::show(std::ostream& os)
172 {
173   m_db.dump(os);
174 }
175 }
176
177 /*
178  * fd.io coding-style-patch-verification: ON
179  *
180  * Local Variables:
181  * eval: (c-set-style "mozilla")
182  * End:
183  */