Introduce a mac_address_t on the API and in VPP
[vpp.git] / extras / vom / vom / types.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 <algorithm>
17 #include <iomanip>
18 #include <iostream>
19 #include <sstream>
20
21 #include <boost/algorithm/string.hpp>
22
23 #include "vom/types.hpp"
24
25 namespace VOM {
26
27 rc_t::rc_t(int v, const std::string s)
28   : enum_base<rc_t>(v, s)
29 {
30 }
31
32 const rc_t&
33 rc_t::from_vpp_retval(int32_t rv)
34 {
35   if (0 == rv) {
36     return (rc_t::OK);
37   }
38   if (-68 == rv) {
39     // sub interface already exists
40     return (rc_t::OK);
41   }
42   if (-79 == rv) {
43     // interface already exists
44     return (rc_t::OK);
45   }
46
47   return (rc_t::INVALID);
48 }
49
50 const rc_t rc_t::UNSET(0, "un-set");
51 const rc_t rc_t::NOOP(1, "no-op");
52 const rc_t rc_t::OK(2, "ok");
53 const rc_t rc_t::INVALID(3, "invalid");
54 const rc_t rc_t::TIMEOUT(4, "timeout");
55
56 const handle_t handle_t::INVALID(~0);
57
58 handle_t::handle_t(int value)
59   : m_value(value)
60 {
61 }
62
63 handle_t::handle_t()
64   : m_value(~0)
65 {
66 }
67
68 std::string
69 handle_t::to_string() const
70 {
71   return (std::to_string(m_value));
72 }
73
74 bool
75 handle_t::operator==(const handle_t& other) const
76 {
77   return (m_value == other.m_value);
78 }
79
80 bool
81 handle_t::operator!=(const handle_t& other) const
82 {
83   return (!(*this == other));
84 }
85
86 bool
87 handle_t::operator<(const handle_t& other) const
88 {
89   return (m_value < other.m_value);
90 }
91
92 uint32_t
93 handle_t::value() const
94 {
95   return (m_value);
96 }
97
98 void
99 handle_t::reset()
100 {
101   m_value = ~0;
102 }
103
104 std::ostream&
105 operator<<(std::ostream& os, const handle_t& h)
106 {
107   os << h.value();
108
109   return (os);
110 }
111
112 mac_address_t::mac_address_t(const uint8_t b[6])
113 {
114   std::copy(b, b + 6, std::begin(bytes));
115 }
116
117 mac_address_t::mac_address_t(std::initializer_list<uint8_t> i)
118 {
119   std::copy(i.begin(), i.end(), std::begin(bytes));
120 }
121
122 mac_address_t::mac_address_t(const std::string& str)
123 {
124   std::vector<std::string> parts;
125
126   boost::split(parts, str, boost::is_any_of(":"));
127
128   size_t n_bytes = std::min(bytes.size(), parts.size());
129
130   for (uint32_t ii = 0; ii < n_bytes; ii++) {
131     bytes[ii] = std::stoul(parts[ii], nullptr, 16);
132   }
133 }
134
135 const mac_address_t mac_address_t::ONE({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff });
136
137 const mac_address_t mac_address_t::ZERO({ 0x0 });
138
139 void
140 mac_address_t::to_bytes(uint8_t* array, uint8_t len) const
141 {
142   for (int i = 0; i < 6 && i < len; i++) {
143     array[i] = bytes[i];
144   }
145 }
146
147 std::string
148 mac_address_t::to_string() const
149 {
150   std::ostringstream s;
151   bool first = true;
152
153   s.fill('0');
154   s << std::hex;
155   for (auto byte : bytes) {
156     if (first)
157       first = false;
158     else
159       s << ":";
160     s << std::setw(2) << static_cast<unsigned int>(byte);
161   }
162
163   return (s.str());
164 }
165
166 bool
167 mac_address_t::operator==(const mac_address_t& mac) const
168 {
169   return (bytes == mac.bytes);
170 }
171 bool
172 mac_address_t::operator<(const mac_address_t& m) const
173 {
174   return (bytes < m.bytes);
175 }
176
177 std::ostream&
178 operator<<(std::ostream& os, const mac_address_t& mac)
179 {
180   os << mac.to_string();
181
182   return (os);
183 }
184
185 l2_address_t::l2_address_t(const uint8_t b[8], uint8_t n_bytes)
186   : bytes(n_bytes)
187 {
188   std::copy_n(b, n_bytes, std::begin(bytes));
189 }
190
191 l2_address_t::l2_address_t(std::initializer_list<uint8_t> i)
192   : bytes(i)
193 {
194 }
195
196 l2_address_t::l2_address_t(const mac_address_t& mac)
197   : bytes(6)
198 {
199   std::copy(begin(mac.bytes), std::end(mac.bytes), std::begin(bytes));
200 }
201
202 const l2_address_t l2_address_t::ONE({ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
203                                        0xff });
204
205 const l2_address_t l2_address_t::ZERO({ 0x0 });
206
207 void
208 l2_address_t::to_bytes(uint8_t* array, uint8_t len) const
209 {
210   for (uint8_t i = 0; i < bytes.size() && i < len; i++) {
211     array[i] = bytes[i];
212   }
213 }
214
215 mac_address_t
216 l2_address_t::to_mac() const
217 {
218   mac_address_t mac({});
219
220   std::copy_n(bytes.begin(), mac.bytes.size(), mac.bytes.begin());
221
222   return (mac);
223 }
224
225 std::string
226 l2_address_t::to_string() const
227 {
228   std::ostringstream s;
229   bool first = true;
230
231   s.fill('0');
232   s << std::hex;
233   for (auto byte : bytes) {
234     if (first)
235       first = false;
236     else
237       s << ":";
238     s << std::setw(2) << static_cast<unsigned int>(byte);
239   }
240
241   return (s.str());
242 }
243
244 bool
245 l2_address_t::operator==(const l2_address_t& l2) const
246 {
247   return (bytes == l2.bytes);
248 }
249
250 bool
251 l2_address_t::operator!=(const l2_address_t& l2) const
252 {
253   return (bytes != l2.bytes);
254 }
255
256 std::ostream&
257 operator<<(std::ostream& os, const l2_address_t& l2)
258 {
259   os << l2.to_string();
260
261   return (os);
262 }
263
264 const direction_t direction_t::INPUT(1, "input");
265 const direction_t direction_t::OUTPUT(0, "output");
266
267 direction_t::direction_t(int v, const std::string s)
268   : enum_base(v, s)
269 {
270 }
271 std::ostream&
272 operator<<(std::ostream& os, const direction_t& dir)
273 {
274   os << dir.to_string();
275   return os;
276 }
277
278 const ethertype_t ethertype_t::ARP(0x0806, "arp");
279 const ethertype_t ethertype_t::FCOE(0x8906, "fcoe");
280 const ethertype_t ethertype_t::IPV4(0x0800, "ipv4");
281 const ethertype_t ethertype_t::IPV6(0x86DD, "ipv6");
282 const ethertype_t ethertype_t::MAC_SECURITY(0x88E5, "mac-security");
283 const ethertype_t ethertype_t::MPLS_UNICAST(0x8847, "mpls-unicast");
284 const ethertype_t ethertype_t::TRILL(0x22F3, "trill");
285 const ethertype_t ethertype_t::UNSPECIFIED(0x0, "unspecified");
286
287 ethertype_t::ethertype_t(int v, const std::string s)
288   : enum_base(v, s)
289 {
290 }
291
292 std::ostream&
293 operator<<(std::ostream& os, const ethertype_t& ether)
294 {
295   os << ether.to_string();
296   return os;
297 }
298
299 const ethertype_t&
300 ethertype_t::from_numeric_val(uint16_t numeric)
301 {
302   if (0x0806 == numeric) {
303     return (ethertype_t::ARP);
304   }
305   if (0x8906 == numeric) {
306     return (ethertype_t::FCOE);
307   }
308   if (0x0800 == numeric) {
309     return (ethertype_t::IPV4);
310   }
311   if (0x86DD == numeric) {
312     return (ethertype_t::IPV6);
313   }
314   if (0x88E5 == numeric) {
315     return (ethertype_t::MAC_SECURITY);
316   }
317   if (0x8847 == numeric) {
318     return (ethertype_t::MPLS_UNICAST);
319   }
320   if (0x22F3 == numeric) {
321     return (ethertype_t::TRILL);
322   }
323
324   return (ethertype_t::UNSPECIFIED);
325 }
326
327 }; // namespace VOM
328
329 /*
330  * fd.io coding-style-patch-verification: ON
331  *
332  * Local Variables:
333  * eval: (c-set-style "mozilla")
334  * End:
335  */