GBP: use sclass in the DP for policy
[vpp.git] / extras / vom / vom / gbp_recirc.cpp
1 /*
2  * Copyright (c) 2018 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_recirc.hpp"
17 #include "vom/gbp_recirc_cmds.hpp"
18 #include "vom/singular_db_funcs.hpp"
19
20 namespace VOM {
21
22 gbp_recirc::type_t::type_t(int v, const std::string s)
23   : enum_base<gbp_recirc::type_t>(v, s)
24 {
25 }
26
27 const gbp_recirc::type_t gbp_recirc::type_t::INTERNAL(0, "internal");
28 const gbp_recirc::type_t gbp_recirc::type_t::EXTERNAL(1, "external");
29
30 singular_db<gbp_recirc::key_t, gbp_recirc> gbp_recirc::m_db;
31
32 gbp_recirc::event_handler gbp_recirc::m_evh;
33
34 gbp_recirc::gbp_recirc(const interface& itf,
35                        const type_t& type,
36                        const gbp_endpoint_group& epg)
37   : m_hw(false)
38   , m_itf(itf.singular())
39   , m_type(type)
40   , m_epg(epg.singular())
41 {
42 }
43
44 gbp_recirc::gbp_recirc(const gbp_recirc& gbpe)
45   : m_hw(gbpe.m_hw)
46   , m_itf(gbpe.m_itf)
47   , m_type(gbpe.m_type)
48   , m_epg(gbpe.m_epg)
49 {
50 }
51
52 gbp_recirc::~gbp_recirc()
53 {
54   sweep();
55   m_db.release(key(), this);
56 }
57
58 const gbp_recirc::key_t
59 gbp_recirc::key() const
60 {
61   return (m_itf->key());
62 }
63
64 const handle_t&
65 gbp_recirc::handle() const
66 {
67   return m_itf->handle();
68 }
69
70 bool
71 gbp_recirc::operator==(const gbp_recirc& gbpe) const
72 {
73   return ((key() == gbpe.key()) && (m_type == gbpe.m_type) &&
74           (m_itf == gbpe.m_itf) && (m_epg == gbpe.m_epg));
75 }
76
77 void
78 gbp_recirc::sweep()
79 {
80   if (m_hw) {
81     HW::enqueue(new gbp_recirc_cmds::delete_cmd(m_hw, m_itf->handle()));
82   }
83   HW::write();
84 }
85
86 void
87 gbp_recirc::replay()
88 {
89   if (m_hw) {
90     HW::enqueue(new gbp_recirc_cmds::create_cmd(
91       m_hw, m_itf->handle(), (m_type == type_t::EXTERNAL), m_epg->sclass()));
92   }
93 }
94
95 std::string
96 gbp_recirc::to_string() const
97 {
98   std::ostringstream s;
99   s << "gbp-recirc:[" << m_itf->to_string() << ", type:" << m_type.to_string()
100     << ", " << m_epg->to_string() << "]";
101
102   return (s.str());
103 }
104
105 void
106 gbp_recirc::update(const gbp_recirc& r)
107 {
108   if (rc_t::OK != m_hw.rc()) {
109     HW::enqueue(new gbp_recirc_cmds::create_cmd(
110       m_hw, m_itf->handle(), (m_type == type_t::EXTERNAL), m_epg->sclass()));
111   }
112 }
113
114 std::shared_ptr<gbp_recirc>
115 gbp_recirc::find_or_add(const gbp_recirc& temp)
116 {
117   return (m_db.find_or_add(temp.key(), temp));
118 }
119
120 std::shared_ptr<gbp_recirc>
121 gbp_recirc::find(const key_t& k)
122 {
123   return (m_db.find(k));
124 }
125
126 std::shared_ptr<gbp_recirc>
127 gbp_recirc::singular() const
128 {
129   return find_or_add(*this);
130 }
131
132 void
133 gbp_recirc::dump(std::ostream& os)
134 {
135   db_dump(m_db, os);
136 }
137
138 gbp_recirc::event_handler::event_handler()
139 {
140   OM::register_listener(this);
141   inspect::register_handler({ "gbp-recirc" }, "GBP Recircs", this);
142 }
143
144 void
145 gbp_recirc::event_handler::handle_replay()
146 {
147   m_db.replay();
148 }
149
150 void
151 gbp_recirc::event_handler::handle_populate(const client_db::key_t& key)
152 {
153   std::shared_ptr<gbp_recirc_cmds::dump_cmd> cmd =
154     std::make_shared<gbp_recirc_cmds::dump_cmd>();
155
156   HW::enqueue(cmd);
157   HW::write();
158
159   for (auto& record : *cmd) {
160     auto& payload = record.get_payload();
161
162     std::shared_ptr<interface> itf =
163       interface::find(payload.recirc.sw_if_index);
164     std::shared_ptr<gbp_endpoint_group> epg =
165       gbp_endpoint_group::find(payload.recirc.sclass);
166
167     VOM_LOG(log_level_t::DEBUG) << "data: [" << payload.recirc.sw_if_index
168                                 << ", " << payload.recirc.sclass << "]";
169
170     if (itf && epg) {
171       gbp_recirc recirc(
172         *itf, (payload.recirc.is_ext ? type_t::EXTERNAL : type_t::INTERNAL),
173         *epg);
174       OM::commit(key, recirc);
175
176       VOM_LOG(log_level_t::DEBUG) << "read: " << recirc.to_string();
177     }
178   }
179 }
180
181 dependency_t
182 gbp_recirc::event_handler::order() const
183 {
184   return (dependency_t::BINDING);
185 }
186
187 void
188 gbp_recirc::event_handler::show(std::ostream& os)
189 {
190   db_dump(m_db, os);
191 }
192 } // namespace VOM
193
194 /*
195  * fd.io coding-style-patch-verification: ON
196  *
197  * Local Variables:
198  * eval: (c-set-style "mozilla")
199  * End:
200  */