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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #ifndef __VOM_INTERFACE_H__
17 #define __VOM_INTERFACE_H__
19 #include "vom/dump_cmd.hpp"
20 #include "vom/enum_base.hpp"
21 #include "vom/event_cmd.hpp"
23 #include "vom/inspect.hpp"
24 #include "vom/object_base.hpp"
26 #include "vom/prefix.hpp"
27 #include "vom/route_domain.hpp"
28 #include "vom/rpc_cmd.hpp"
29 #include "vom/singular_db.hpp"
31 #include <vapi/af_packet.api.vapi.hpp>
32 #include <vapi/interface.api.vapi.hpp>
33 #include <vapi/stats.api.vapi.hpp>
34 #include <vapi/tap.api.vapi.hpp>
35 #include <vapi/vapi.hpp>
36 #include <vapi/vpe.api.vapi.hpp>
40 * A representation of an interface in VPP
42 class interface : public object_base
46 * The key for interface's key
48 typedef std::string key_type;
53 typedef singular_db<const std::string, interface>::const_iterator
59 struct type_t : enum_base<type_t>
64 const static type_t UNKNOWN;
66 * A brideged Virtual interface (aka SVI or IRB)
68 const static type_t BVI;
72 const static type_t VXLAN;
74 * Ethernet interface type
76 const static type_t ETHERNET;
78 * AF-Packet interface type
80 const static type_t AFPACKET;
82 * loopback interface type
84 const static type_t LOOPBACK;
86 * Local interface type (specific to VPP)
88 const static type_t LOCAL;
92 const static type_t TAP;
95 * Convert VPP's name of the interface to a type
97 static type_t from_string(const std::string& str);
101 * Private constructor taking the value and the string name
103 type_t(int v, const std::string& s);
107 * The admin state of the interface
109 struct admin_state_t : enum_base<admin_state_t>
114 const static admin_state_t DOWN;
118 const static admin_state_t UP;
121 * Convert VPP's numerical value to enum type
123 static admin_state_t from_int(uint8_t val);
127 * Private constructor taking the value and the string name
129 admin_state_t(int v, const std::string& s);
133 * The oper state of the interface
135 struct oper_state_t : enum_base<oper_state_t>
138 * Operational DOWN state
140 const static oper_state_t DOWN;
142 * Operational UP state
144 const static oper_state_t UP;
147 * Convert VPP's numerical value to enum type
149 static oper_state_t from_int(uint8_t val);
153 * Private constructor taking the value and the string name
155 oper_state_t(int v, const std::string& s);
159 * Construct a new object matching the desried state
161 interface(const std::string& name, type_t type, admin_state_t state);
163 * Construct a new object matching the desried state mapped
164 * to a specific route_domain
166 interface(const std::string& name,
169 const route_domain& rd);
173 virtual ~interface();
178 interface(const interface& o);
180 static const_iterator_t cbegin();
181 static const_iterator_t cend();
184 * Return the matching'singular' of the interface
186 std::shared_ptr<interface> singular() const;
189 * convert to string format for debug purposes
191 virtual std::string to_string(void) const;
194 * Return VPP's handle to this object
196 const handle_t& handle() const;
199 * Return the interface type
201 const type_t& type() const;
204 * Return the interface type
206 const std::string& name() const;
209 * Return the interface type
211 const key_type& key() const;
214 * Return the L2 Address
216 const l2_address_t& l2_address() const;
221 void set(const l2_address_t& addr);
224 * Set the operational state of the interface, as reported by VPP
226 void set(const oper_state_t& state);
229 * A base class for interface Create commands
231 template <typename MSG>
232 class create_cmd : public rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>
235 create_cmd(HW::item<handle_t>& item, const std::string& name)
236 : rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>(item)
244 virtual ~create_cmd() = default;
247 * Comparison operator - only used for UT
249 virtual bool operator==(const create_cmd& o) const
251 return (m_name == o.m_name);
255 * Indicate the succeeded, when the HW Q is disabled.
259 rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>::succeeded();
260 interface::add(m_name, this->item());
263 virtual vapi_error_e operator()(MSG& reply)
265 int sw_if_index = reply.get_response().get_payload().sw_if_index;
266 int retval = reply.get_response().get_payload().retval;
268 VOM_LOG(log_level_t::DEBUG) << this->to_string() << " " << retval;
270 rc_t rc = rc_t::from_vpp_retval(retval);
271 handle_t handle = handle_t::INVALID;
273 if (rc_t::OK == rc) {
274 handle = sw_if_index;
277 HW::item<handle_t> res(handle, rc);
286 * The name of the interface to be created
288 const std::string& m_name;
292 * A command class to create Loopback interfaces in VPP
294 class loopback_create_cmd : public create_cmd<vapi::Create_loopback>
298 * Constructor taking the HW::item to update
299 * and the name of the interface to create
301 loopback_create_cmd(HW::item<handle_t>& item, const std::string& name);
302 ~loopback_create_cmd() = default;
305 * Issue the command to VPP/HW
307 rc_t issue(connection& con);
309 * convert to string format for debug purposes
311 std::string to_string() const;
315 * A command class to create af_packet interfaces in VPP
317 class af_packet_create_cmd : public create_cmd<vapi::Af_packet_create>
321 * Constructor taking the HW::item to update
322 * and the name of the interface to create
324 af_packet_create_cmd(HW::item<handle_t>& item, const std::string& name);
325 ~af_packet_create_cmd() = default;
327 * Issue the command to VPP/HW
329 rc_t issue(connection& con);
331 * convert to string format for debug purposes
333 std::string to_string() const;
337 * A command class to create TAP interfaces in VPP
339 class tap_create_cmd : public create_cmd<vapi::Tap_connect>
343 * Constructor taking the HW::item to update
344 * and the name of the interface to create
346 tap_create_cmd(HW::item<handle_t>& item, const std::string& name);
347 ~tap_create_cmd() = default;
350 * Issue the command to VPP/HW
352 rc_t issue(connection& con);
355 * convert to string format for debug purposes
357 std::string to_string() const;
361 * Base class for intterface Delete commands
363 template <typename MSG>
364 class delete_cmd : public rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>
367 delete_cmd(HW::item<handle_t>& item, const std::string& name)
368 : rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>(item)
373 delete_cmd(HW::item<handle_t>& item)
374 : rpc_cmd<HW::item<handle_t>, HW::item<handle_t>, MSG>(item)
382 virtual ~delete_cmd() = default;
385 * Comparison operator - only used for UT
387 virtual bool operator==(const delete_cmd& o) const
389 return (this->m_hw_item == o.m_hw_item);
393 * Indicate the succeeded, when the HW Q is disabled.
399 * The name of the interface to be created
401 const std::string m_name;
405 * A command class to delete loopback interfaces in VPP
407 class loopback_delete_cmd : public delete_cmd<vapi::Delete_loopback>
411 * Constructor taking the HW::item to update
413 loopback_delete_cmd(HW::item<handle_t>& item);
416 * Issue the command to VPP/HW
418 rc_t issue(connection& con);
420 * convert to string format for debug purposes
422 std::string to_string() const;
426 * A command class to delete af-packet interfaces in VPP
428 class af_packet_delete_cmd : public delete_cmd<vapi::Af_packet_delete>
432 * Constructor taking the HW::item to update
433 * and the name of the interface to delete
435 af_packet_delete_cmd(HW::item<handle_t>& item, const std::string& name);
438 * Issue the command to VPP/HW
440 rc_t issue(connection& con);
442 * convert to string format for debug purposes
444 std::string to_string() const;
448 * A command class to delete TAP interfaces in VPP
450 class tap_delete_cmd : public delete_cmd<vapi::Tap_delete>
454 * Constructor taking the HW::item to update
456 tap_delete_cmd(HW::item<handle_t>& item);
459 * Issue the command to VPP/HW
461 rc_t issue(connection& con);
463 * convert to string format for debug purposes
465 std::string to_string() const;
469 * A command class to delete TAP interfaces in VPP
472 : public rpc_cmd<HW::item<handle_t>, rc_t, vapi::Sw_interface_tag_add_del>
476 * Constructor taking the HW::item to update
478 set_tag(HW::item<handle_t>& item, const std::string& name);
481 * Issue the command to VPP/HW
483 rc_t issue(connection& con);
486 * convert to string format for debug purposes
488 std::string to_string() const;
491 * Comparison operator - only used for UT
493 bool operator==(const set_tag& i) const;
499 const std::string m_name;
503 * A cmd class that changes the admin state
505 class state_change_cmd : public rpc_cmd<HW::item<admin_state_t>,
507 vapi::Sw_interface_set_flags>
511 * Constructor taking the HW::item to update
512 * and the name handle of the interface whose state is to change
514 state_change_cmd(HW::item<admin_state_t>& s, const HW::item<handle_t>& h);
517 * Issue the command to VPP/HW
519 rc_t issue(connection& con);
521 * convert to string format for debug purposes
523 std::string to_string() const;
526 * Comparison operator - only used for UT
528 bool operator==(const state_change_cmd& i) const;
532 * the handle of the interface to update
534 const HW::item<handle_t>& m_hdl;
538 * A command class that binds an interface to an L3 table
540 class set_table_cmd : public rpc_cmd<HW::item<route::table_id_t>,
542 vapi::Sw_interface_set_table>
546 * Constructor taking the HW::item to update
547 * and the name handle of the interface whose table is to change
549 set_table_cmd(HW::item<route::table_id_t>& item,
550 const l3_proto_t& proto,
551 const HW::item<handle_t>& h);
554 * Issue the command to VPP/HW
556 rc_t issue(connection& con);
559 * convert to string format for debug purposes
561 std::string to_string() const;
564 * Comparison operator - only used for UT
566 bool operator==(const set_table_cmd& i) const;
570 * the handle of the interface to update
572 const HW::item<handle_t>& m_hdl;
575 * The L3 protocol of the table
581 * A command class that binds an interface to an L3 table
583 class set_mac_cmd : public rpc_cmd<HW::item<l2_address_t>,
585 vapi::Sw_interface_set_mac_address>
589 * Constructor taking the HW::item to update
590 * and the handle of the interface
592 set_mac_cmd(HW::item<l2_address_t>& item, const HW::item<handle_t>& h);
595 * Issue the command to VPP/HW
597 rc_t issue(connection& con);
600 * convert to string format for debug purposes
602 std::string to_string() const;
605 * Comparison operator - only used for UT
607 bool operator==(const set_mac_cmd& i) const;
611 * the handle of the interface to update
613 const HW::item<handle_t>& m_hdl;
617 * Forward declaration of the Event command
622 * A class that listens to interface Events
628 * Default Constructor
633 * Virtual function called on the listener when the command has data
636 virtual void handle_interface_event(events_cmd* cmd) = 0;
639 * Return the HW::item representing the status
641 HW::item<bool>& status();
645 * The status of the subscription
647 HW::item<bool> m_status;
651 * A command class represents our desire to recieve interface events
654 : public event_cmd<vapi::Want_interface_events, vapi::Sw_interface_event>
658 * Constructor taking the listner to notify
660 events_cmd(event_listener& el);
663 * Issue the command to VPP/HW
665 rc_t issue(connection& con);
668 * Retires the command - unsubscribe from the events.
670 void retire(connection& con);
673 * convert to string format for debug purposes
675 std::string to_string() const;
678 * Comparison operator - only used for UT
680 bool operator==(const events_cmd& i) const;
683 * Called when it's time to poke the listeners
689 * The listeners to notify when data/events arrive
691 event_listener& m_listener;
695 * Forward declaration of the stat command
700 * A class that listens to interface Stats
706 * Default Constructor
711 * Virtual function called on the listener when the command has data
714 virtual void handle_interface_stat(stats_cmd* cmd) = 0;
717 * Return the HW::item representing the status
719 HW::item<bool>& status();
723 * The status of the subscription
725 HW::item<bool> m_status;
729 * A command class represents our desire to recieve interface stats
731 class stats_cmd : public event_cmd<vapi::Want_per_interface_combined_stats,
732 vapi::Vnet_per_interface_combined_counters>
736 * Constructor taking the listner to notify
738 stats_cmd(stat_listener& el, const std::vector<handle_t>& interfaces);
741 * Issue the command to VPP/HW
743 rc_t issue(connection& con);
746 * Retires the command - unsubscribe from the stats.
748 void retire(connection& con);
751 * convert to string format for debug purposes
753 std::string to_string() const;
756 * Comparison operator - only used for UT
758 bool operator==(const stats_cmd& i) const;
761 * Called when it's time to poke the listeners
767 * The listeners to notify when data/stats arrive
769 stat_listener& m_listener;
771 std::vector<handle_t> m_swifindex;
775 * A cmd class that Dumps all the Vpp interfaces
777 class dump_cmd : public VOM::dump_cmd<vapi::Sw_interface_dump>
781 * Default Constructor
786 * Issue the command to VPP/HW
788 rc_t issue(connection& con);
790 * convert to string format for debug purposes
792 std::string to_string() const;
795 * Comparison operator - only used for UT
797 bool operator==(const dump_cmd& i) const;
801 * The the singular instance of the interface in the object_base-Model
803 static std::shared_ptr<interface> find(const interface& temp);
806 * The the singular instance of the interface in the object_base-Model
809 static std::shared_ptr<interface> find(const handle_t& h);
812 * The the singular instance of the interface in the object_base-Model
815 static std::shared_ptr<interface> find(const std::string& s);
818 * Dump all interfaces into the stream provided
820 static void dump(std::ostream& os);
823 * Factory method to construct a new interface from the VPP record
825 static std::unique_ptr<interface> new_interface(
826 const vapi_payload_sw_interface_details& vd);
830 * Construct an interface object with a handle and a HW address
832 interface(const handle_t& handle,
833 const l2_address_t& l2_address,
834 const std::string& name,
836 admin_state_t state);
839 * The SW interface handle VPP has asigned to the interface
841 HW::item<handle_t> m_hdl;
844 * Return the matching 'singular' of the interface
846 virtual std::shared_ptr<interface> singular_i() const;
849 * release/remove an interface form the singular store
854 * Virtual functions to construct an interface create commands.
855 * Overridden in derived classes like the sub_interface
857 virtual std::queue<cmd*>& mk_create_cmd(std::queue<cmd*>& cmds);
860 * Virtual functions to construct an interface delete commands.
861 * Overridden in derived classes like the sub_interface
863 virtual std::queue<cmd*>& mk_delete_cmd(std::queue<cmd*>& cmds);
866 * Sweep/reap the object if still stale
868 virtual void sweep(void);
871 * A map of all interfaces key against the interface's name
873 static singular_db<const std::string, interface> m_db;
876 * Add an interface to the DB keyed on handle
878 static void add(const std::string& name, const HW::item<handle_t>& item);
881 * remove an interface from the DB keyed on handle
883 static void remove(const HW::item<handle_t>& item);
887 * Class definition for listeners to OM events
889 class event_handler : public OM::listener, public inspect::command_handler
893 virtual ~event_handler() = default;
896 * Handle a populate event
898 void handle_populate(const client_db::key_t& key);
901 * Handle a replay event
903 void handle_replay();
906 * Show the object in the Singular DB
908 void show(std::ostream& os);
911 * Get the sortable Id of the listener
913 dependency_t order() const;
916 static event_handler m_evh;
919 * Commit the acculmulated changes into VPP. i.e. to a 'HW" write.
921 void update(const interface& obj);
924 * It's the OM class that calls singular()
929 * It's the singular_db class that calls replay()
931 friend class singular_db<const std::string, interface>;
934 * The interfaces name
936 const std::string m_name;
939 * The interface type. clearly this cannot be changed
940 * once the interface has been created.
945 * shared pointer to the routeDoamin the interface is in.
946 * NULL is not mapped - i.e. in eht default table
948 const std::shared_ptr<route_domain> m_rd;
951 * The state of the interface
953 HW::item<admin_state_t> m_state;
956 * HW state of the VPP table mapping
958 HW::item<route::table_id_t> m_table_id;
961 * HW state of the L2 address
963 HW::item<l2_address_t> m_l2_address;
966 * Operational state of the interface
971 * A map of all interfaces keyed against VPP's handle
973 static std::map<handle_t, std::weak_ptr<interface>> m_hdl_db;
976 * replay the object to create it in hardware
978 virtual void replay(void);
981 * Create commands are firends so they can add interfaces to the
984 template <typename MSG>
985 friend class create_cmd;
988 * Create commands are firends so they can remove interfaces from the
991 template <typename MSG>
992 friend class delete_cmd;
996 * fd.io coding-style-patch-verification: ON
999 * eval: (c-set-style "mozilla")