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