blob: 9b53cb2a6bbba18d6bc26f56cf259446e023ff82 [file] [log] [blame]
Neale Ranns812ed392017-10-16 04:20:13 -07001/*
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/neighbour.hpp"
Neale Ranns9ef1c0a2017-11-03 04:39:05 -070017#include "vom/neighbour_cmds.hpp"
Neale Ranns812ed392017-10-16 04:20:13 -070018
19namespace VOM {
20singular_db<neighbour::key_t, neighbour> neighbour::m_db;
21neighbour::event_handler neighbour::m_evh;
22
23neighbour::neighbour(const interface& itf,
Neale Rannsfd920602017-11-23 12:15:00 -080024 const boost::asio::ip::address& ip_addr,
25 const mac_address_t& mac)
Neale Ranns812ed392017-10-16 04:20:13 -070026 : m_hw(false)
27 , m_itf(itf.singular())
Neale Ranns812ed392017-10-16 04:20:13 -070028 , m_ip_addr(ip_addr)
Neale Rannsfd920602017-11-23 12:15:00 -080029 , m_mac(mac)
Neale Ranns812ed392017-10-16 04:20:13 -070030{
31}
32
33neighbour::neighbour(const neighbour& bde)
34 : m_hw(bde.m_hw)
35 , m_itf(bde.m_itf)
Neale Ranns812ed392017-10-16 04:20:13 -070036 , m_ip_addr(bde.m_ip_addr)
Neale Rannsfd920602017-11-23 12:15:00 -080037 , m_mac(bde.m_mac)
Neale Ranns812ed392017-10-16 04:20:13 -070038{
39}
40
41neighbour::~neighbour()
42{
43 sweep();
44
45 // not in the DB anymore.
Neale Rannsfd920602017-11-23 12:15:00 -080046 m_db.release(key(), this);
47}
48
49bool
50neighbour::operator==(const neighbour& n) const
51{
52 return ((key() == n.key()) && (m_mac == n.m_mac));
53}
54
55const neighbour::key_t
56neighbour::key() const
57{
58 return (std::make_pair(m_itf->key(), m_ip_addr));
Neale Ranns812ed392017-10-16 04:20:13 -070059}
60
61void
62neighbour::sweep()
63{
64 if (m_hw) {
Neale Ranns9ef1c0a2017-11-03 04:39:05 -070065 HW::enqueue(
66 new neighbour_cmds::delete_cmd(m_hw, m_itf->handle(), m_mac, m_ip_addr));
Neale Ranns812ed392017-10-16 04:20:13 -070067 }
68 HW::write();
69}
70
71void
72neighbour::replay()
73{
74 if (m_hw) {
Neale Ranns9ef1c0a2017-11-03 04:39:05 -070075 HW::enqueue(
76 new neighbour_cmds::create_cmd(m_hw, m_itf->handle(), m_mac, m_ip_addr));
Neale Ranns812ed392017-10-16 04:20:13 -070077 }
78}
79
80std::string
81neighbour::to_string() const
82{
83 std::ostringstream s;
Neale Ranns17d2c4f2017-12-13 00:55:58 -080084 s << "neighbour:[" << m_itf->to_string() << ", " << m_mac.to_string() << ", "
Neale Ranns812ed392017-10-16 04:20:13 -070085 << m_ip_addr.to_string() << "]";
86
87 return (s.str());
88}
89
90void
91neighbour::update(const neighbour& r)
92{
93 /*
94 * create the table if it is not yet created
95 */
96 if (rc_t::OK != m_hw.rc()) {
Neale Ranns9ef1c0a2017-11-03 04:39:05 -070097 HW::enqueue(
98 new neighbour_cmds::create_cmd(m_hw, m_itf->handle(), m_mac, m_ip_addr));
Neale Ranns812ed392017-10-16 04:20:13 -070099 }
100}
101
102std::shared_ptr<neighbour>
103neighbour::find_or_add(const neighbour& temp)
104{
Neale Rannsfd920602017-11-23 12:15:00 -0800105 return (m_db.find_or_add(temp.key(), temp));
106}
107
108std::shared_ptr<neighbour>
109neighbour::find(const key_t& k)
110{
111 return (m_db.find(k));
Neale Ranns812ed392017-10-16 04:20:13 -0700112}
113
114std::shared_ptr<neighbour>
115neighbour::singular() const
116{
117 return find_or_add(*this);
118}
119
120void
121neighbour::dump(std::ostream& os)
122{
123 m_db.dump(os);
124}
125
126std::ostream&
127operator<<(std::ostream& os, const neighbour::key_t& key)
128{
Neale Rannsfd920602017-11-23 12:15:00 -0800129 os << "[" << key.first << ", " << key.second << "]";
Neale Ranns812ed392017-10-16 04:20:13 -0700130
131 return (os);
132}
133
134neighbour::event_handler::event_handler()
135{
136 OM::register_listener(this);
137 inspect::register_handler({ "neighbour" }, "Neighbours", this);
138}
139
140void
141neighbour::event_handler::handle_replay()
142{
143 m_db.replay();
144}
145
146void
147neighbour::populate_i(const client_db::key_t& key,
148 std::shared_ptr<interface> itf,
149 const l3_proto_t& proto)
150{
151 /*
Neale Rannsfd920602017-11-23 12:15:00 -0800152 * dump VPP current states
153 */
Neale Ranns9ef1c0a2017-11-03 04:39:05 -0700154 std::shared_ptr<neighbour_cmds::dump_cmd> cmd =
155 std::make_shared<neighbour_cmds::dump_cmd>(
156 neighbour_cmds::dump_cmd(itf->handle(), proto));
Neale Ranns812ed392017-10-16 04:20:13 -0700157
158 HW::enqueue(cmd);
159 HW::write();
160
161 for (auto& record : *cmd) {
162 /*
Neale Rannsfd920602017-11-23 12:15:00 -0800163 * construct a neighbour from each recieved record.
164 */
Neale Ranns812ed392017-10-16 04:20:13 -0700165 auto& payload = record.get_payload();
166
167 mac_address_t mac(payload.mac_address);
168 boost::asio::ip::address ip_addr =
169 from_bytes(payload.is_ipv6, payload.ip_address);
Neale Rannsfd920602017-11-23 12:15:00 -0800170 neighbour n(*itf, ip_addr, mac);
Neale Ranns812ed392017-10-16 04:20:13 -0700171
172 VOM_LOG(log_level_t::DEBUG) << "neighbour-dump: " << itf->to_string()
173 << mac.to_string() << ip_addr.to_string();
174
175 /*
Neale Rannsfd920602017-11-23 12:15:00 -0800176 * Write each of the discovered interfaces into the OM,
177 * but disable the HW Command q whilst we do, so that no
178 * commands are sent to VPP
179 */
Neale Ranns812ed392017-10-16 04:20:13 -0700180 OM::commit(key, n);
181 }
182}
183
184void
185neighbour::event_handler::handle_populate(const client_db::key_t& key)
186{
187 auto it = interface::cbegin();
188
189 while (it != interface::cend()) {
190 neighbour::populate_i(key, it->second.lock(), l3_proto_t::IPV4);
191 neighbour::populate_i(key, it->second.lock(), l3_proto_t::IPV6);
192
193 ++it;
194 }
195}
196
197dependency_t
198neighbour::event_handler::order() const
199{
200 return (dependency_t::ENTRY);
201}
202
203void
204neighbour::event_handler::show(std::ostream& os)
205{
206 m_db.dump(os);
207}
208}
209
210/*
211 * fd.io coding-style-patch-verification: ON
212 *
213 * Local Variables:
214 * eval: (c-set-style "mozilla")
215 * End:
216 */