15 #include "rofl/common/ciosrv.h"
16 #include "rofl/common/crofsock.h"
17 #include "rofl/common/openflow/cofhelloelems.h"
18 #include "rofl/common/openflow/cofhelloelemversionbitmap.h"
19 #include "rofl/common/crandom.h"
20 #include "rofl/common/csegmentation.h"
21 #include "rofl/common/ctimerid.h"
22 #include "rofl/common/cauxid.h"
23 #include "rofl/common/cthread.h"
24 #include "rofl/common/crofqueue.h"
41 static std::set<crofconn_env*> rofconn_envs;
49 if (crofconn_env::rofconn_envs.find(env) == crofconn_env::rofconn_envs.end()) {
60 return (not (crofconn_env::rofconn_envs.find(env) == crofconn_env::rofconn_envs.end()));
69 crofconn_env::rofconn_envs.insert(
this);
76 crofconn_env::rofconn_envs.erase(
this);
87 handle_connect_refused(
crofconn& conn) = 0;
93 handle_connect_failed(
crofconn& conn) = 0;
99 handle_connected(
crofconn& conn, uint8_t ofp_version) = 0;
129 get_sync_xid(
crofconn& conn, uint8_t msg_type = 0, uint16_t msg_sub_type = 0) = 0;
135 release_sync_xid(
crofconn& conn, uint32_t xid) = 0;
150 enum outqueue_type_t {
161 OFPT_ECHO_REQUEST = 2,
163 OFPT_FEATURES_REPLY = 6,
164 OFPT_MULTIPART_REQUEST = 18,
165 OFPT_MULTIPART_REPLY = 19,
168 enum crofconn_event_t {
171 EVENT_TCP_CONNECTED = 2,
172 EVENT_DISCONNECTED = 3,
173 EVENT_HELLO_RCVD = 4,
174 EVENT_HELLO_EXPIRED = 5,
175 EVENT_FEATURES_RCVD = 6,
176 EVENT_FEATURES_EXPIRED = 7,
178 EVENT_ECHO_EXPIRED = 9,
179 EVENT_NEED_LIFE_CHECK = 10,
182 EVENT_CONNECT_FAILED = 13,
183 EVENT_CONNECT_REFUSED = 14,
184 EVENT_LOCAL_DISCONNECT = 15,
185 EVENT_CONGESTION_SOLVED = 16,
186 EVENT_PEER_DISCONNECTED = 17,
189 enum crofconn_state_t {
191 STATE_DISCONNECTED = 1,
192 STATE_CONNECT_PENDING = 2,
193 STATE_ACCEPT_PENDING = 3,
194 STATE_WAIT_FOR_HELLO = 4,
195 STATE_WAIT_FOR_FEATURES = 5,
199 enum crofconn_timer_t {
200 TIMER_NEXT_RECONNECT = 1,
201 TIMER_WAIT_FOR_HELLO = 2,
202 TIMER_WAIT_FOR_FEATURES = 3,
203 TIMER_NEED_LIFE_CHECK = 4,
204 TIMER_WAIT_FOR_ECHO = 5,
207 enum crofconn_flags_t {
209 FLAGS_CONNECT_REFUSED = 2,
210 FLAGS_CONNECT_FAILED = 3,
211 FLAGS_LOCAL_DISCONNECT = 4,
212 FLAGS_RECONNECTING = 5,
213 FLAGS_RXQUEUE_CONSUMING = 6,
215 FLAGS_PEER_DISCONNECTED = 8,
220 enum crofconn_flavour_t {
221 FLAVOUR_UNSPECIFIED = 0,
245 enum crofconn_flavour_t
254 enum rofl::csocket::socket_type_t socket_type,
257 enum crofconn_flavour_t flavour);
265 enum rofl::csocket::socket_type_t socket_type,
273 bool reset_backoff_timer =
false);
286 {
return (STATE_CONNECTED == state); }
293 {
return not flags.test(FLAGS_PASSIVE); };
300 {
return flags.test(FLAGS_CONGESTED); };
307 {
return versionbitmap; };
314 {
return versionbitmap_peer; };
321 {
return ofp_version; };
335 {
return auxiliary_id; };
341 get_rofsocket()
const
342 {
return *rofsock; };
350 {
return fragment_and_send_message(msg); };
358 { this->env = env; };
365 const ctimespec& timespec);
378 handle_connect_refused(
380 rofl::logging::warn <<
"[rofl-common][crofconn] transport connection: connect refused " << std::endl;
385 handle_connect_failed(
387 rofl::logging::debug <<
"[rofl-common][crofconn] transport connection: connect failed " << std::endl;
394 rofl::logging::debug <<
"[rofl-common][crofconn] transport connection established " << std::endl;
401 rofl::logging::debug <<
"[rofl-common][crofconn] transport connection closed " << std::endl;
408 rofl::logging::debug <<
"[rofl-common][crofconn] transport connection congested " << std::endl;
438 void *data = (
void*)0);
446 switch (ev.get_cmd()) {
447 case EVENT_RXQUEUE: {
450 case EVENT_TCP_CONNECTED: {
451 flags.reset(FLAGS_RECONNECTING);
452 run_engine(EVENT_TCP_CONNECTED);
454 case EVENT_CONNECT_FAILED: {
455 flags.set(FLAGS_CONNECT_FAILED);
456 run_engine(EVENT_DISCONNECTED);
458 case EVENT_CONNECT_REFUSED: {
459 flags.set(FLAGS_CONNECT_REFUSED);
460 run_engine(EVENT_DISCONNECTED);
462 case EVENT_LOCAL_DISCONNECT: {
463 flags.set(FLAGS_LOCAL_DISCONNECT);
464 run_engine(EVENT_DISCONNECTED);
466 case EVENT_CONGESTION_SOLVED: {
467 flags.reset(FLAGS_CONGESTED);
468 crofconn_env::set_env(env).handle_write(*
this);
470 case EVENT_PEER_DISCONNECTED: {
471 flags.set(FLAGS_PEER_DISCONNECTED);
472 run_engine(EVENT_DISCONNECTED);
482 enum crofconn_event_t event = EVENT_NONE);
494 event_tcp_connected();
500 event_disconnected();
512 event_hello_expired();
518 event_features_rcvd();
524 event_features_expired();
536 event_echo_expired();
542 event_need_life_check();
548 action_send_hello_message();
554 action_send_features_request();
566 action_send_echo_request();
573 bool reset_timeout =
false);
616 fragment_and_send_message(
623 fragment_table_features_stats_request(
630 fragment_flow_stats_reply(
637 fragment_table_stats_reply(
644 fragment_port_stats_reply(
651 fragment_queue_stats_reply(
658 fragment_group_stats_reply(
665 fragment_group_desc_stats_reply(
672 fragment_table_features_stats_reply(
679 fragment_port_desc_stats_reply(
686 fragment_meter_stats_reply(
693 fragment_meter_config_stats_reply(
701 crofconn_timer_t type,
const ctimespec& timespec);
708 crofconn_timer_t type);
714 timer_start_next_reconnect() {
715 timer_start(TIMER_NEXT_RECONNECT, reconnect_timespec);
722 timer_stop_next_reconnect() {
723 timer_stop(TIMER_NEXT_RECONNECT);
730 timer_start_life_check() {
731 timer_start(TIMER_NEED_LIFE_CHECK, echo_interval);
738 timer_stop_life_check() {
739 timer_stop(TIMER_NEED_LIFE_CHECK);
746 timer_start_wait_for_hello() {
747 timer_start(TIMER_WAIT_FOR_HELLO, hello_timeout);
754 timer_stop_wait_for_hello() {
755 timer_stop(TIMER_WAIT_FOR_HELLO);
762 timer_start_wait_for_features() {
763 timer_start(TIMER_WAIT_FOR_FEATURES, echo_interval);
770 timer_stop_wait_for_features() {
771 timer_stop(TIMER_WAIT_FOR_FEATURES);
778 timer_start_wait_for_echo() {
779 timer_start(TIMER_WAIT_FOR_ECHO, echo_timeout);
786 timer_stop_wait_for_echo() {
787 timer_stop(TIMER_WAIT_FOR_ECHO);
793 operator<< (std::ostream& os,
const crofconn& conn) {
794 os << indent(0) <<
"<crofconn ofp-version:" << (int)conn.ofp_version
795 <<
" OFP-transport-connection-established: " << (
bool)(conn.state == STATE_CONNECTED)
796 <<
" >" << std::endl;
798 if (conn.state == STATE_DISCONNECTED) {
799 os << indent(2) <<
"<state: -DISCONNECTED- >" << std::endl;
801 else if (conn.state == STATE_CONNECT_PENDING) {
802 os << indent(2) <<
"<state: -CONNECT-PENDING- >" << std::endl;
804 else if (conn.state == STATE_ACCEPT_PENDING) {
805 os << indent(2) <<
"<state: -ACCEPT-PENDING- >" << std::endl;
807 else if (conn.state == STATE_WAIT_FOR_HELLO) {
808 os << indent(2) <<
"<state: -WAIT-FOR-HELLO- >" << std::endl;
810 else if (conn.state == STATE_WAIT_FOR_FEATURES) {
811 os << indent(2) <<
"<state: -WAIT-FOR-FEATURES- >" << std::endl;
813 else if (conn.state == STATE_CONNECTED) {
814 os << indent(2) <<
"<state: -ESTABLISHED- >" << std::endl;
819 os << indent(2) <<
"<versionbitmap-local: >" << std::endl;
820 { indent i(4); os << conn.versionbitmap; }
821 os << indent(2) <<
"<versionbitmap-remote: >" << std::endl;
822 { indent i(4); os << conn.versionbitmap_peer; }
829 std::stringstream ss;
830 if (state == STATE_DISCONNECTED) {
831 ss <<
"state: -DISCONNECTED- ";
833 else if (state == STATE_CONNECT_PENDING) {
834 ss <<
"state: -CONNECT-PENDING- ";
835 ss <<
"backoff: " << reconnect_timespec.str();
837 else if (state == STATE_ACCEPT_PENDING) {
838 ss <<
"state: -ACCEPT-PENDING- ";
840 else if (state == STATE_WAIT_FOR_HELLO) {
841 ss <<
"state: -WAIT-FOR-HELLO- ";
843 else if (state == STATE_WAIT_FOR_FEATURES) {
844 ss <<
"state: -WAIT-FOR-FEATURES- ";
846 else if (state == STATE_CONNECTED) {
847 ss <<
"state: -ESTABLISHED- ";
863 std::bitset<32> flags;
865 size_t fragmentation_threshold;
867 static unsigned int const
868 DEFAULT_FRAGMENTATION_THRESHOLD = 65535;
869 static unsigned int const
870 DEFAULT_ETHERNET_MTU_SIZE = 1500;
871 ctimespec max_backoff;
872 ctimespec reconnect_start_timeout;
873 ctimespec reconnect_timespec;
874 ctimespec reconnect_variance;
875 int reconnect_counter;
877 static const int CROFCONN_RECONNECT_START_TIMEOUT_IN_NSECS = 10000000;
878 static const int CROFCONN_RECONNECT_VARIANCE_IN_NSECS = 10000000;
880 enum crofconn_flavour_t
882 enum rofl::csocket::socket_type_t
887 std::deque<enum crofconn_event_t>
889 enum crofconn_state_t
891 std::map<crofconn_timer_t, ctimerid>
894 std::vector<crofqueue>
897 std::vector<unsigned int>
902 static const int DEFAULT_HELLO_TIMEOUT = 5;
903 static const int DEFAULT_ECHO_TIMEOUT = 60;
904 static const int DEFAULT_ECHO_INTERVAL = 60;
908 unsigned int hello_timeout;
909 unsigned int echo_timeout;
910 unsigned int echo_interval;
Definition: cofmsg_meter_stats.h:146
cauxid const & get_aux_id() const
Return auxialiary_id.
Definition: crofconn.h:334
Definition: cofmsg_flow_stats.h:164
Definition: cofmsg_port_stats.h:156
Definition: cofhelloelemversionbitmap.h:22
A socket capable of talking OpenFlow via TCP and vice versa.
Definition: crofsock.h:111
bool is_established() const
Returns whether this connection is established.
Definition: crofconn.h:285
void notify(const cevent &event)
Sends a notification to this ciosrv instance.
Definition: ciosrv.h:529
unsigned int send_message(rofl::openflow::cofmsg *msg)
Send OFP message via socket.
Definition: crofconn.h:348
void close()
Instruct crofsock instance to close connection to peer.
Definition: crofconn.cc:159
rofl::openflow::cofhello_elem_versionbitmap & get_versionbitmap()
Returns a reference to the versionbitmap announced by this entity.
Definition: crofconn.h:306
Definition: cofmsg_table_features_stats.h:22
Definition: cofmsg_table_features_stats.h:161
Definition: cofmsg_queue_stats.h:144
Definition: crofconn.h:31
A single OpenFlow control connection.
Definition: crofconn.h:145
Definition: cofmsg_group_stats.h:152
uint8_t get_version() const
Returns the negotiated OFP version (or OFP_UNKNOWN)
Definition: crofconn.h:320
Definition: cofmsg_port_desc_stats.h:123
void connect(const cauxid &aux_id, enum rofl::csocket::socket_type_t socket_type, const cparams &socket_params)
Instruct crofsock instance to connect to peer using specified parameters.
Definition: crofconn.cc:136
Definition: crofconn.h:28
Environment expected by a rofl::crofconn instance.
Definition: crofconn.h:40
Single event used internally by class crofl::cioloop.
Definition: cevent.h:20
bool is_actively_established() const
Returns true when this connection has been actively established.
Definition: crofconn.h:292
Definition: crofqueue.h:20
Base class for IO services.
Definition: ciosrv.h:491
uint64_t get_dpid() const
Returns data path id assigned to this connection.
Definition: crofconn.h:327
Definition: cofmsg_group_desc_stats.h:123
crofconn(crofconn_env *env, const rofl::openflow::cofhello_elem_versionbitmap &versionbitmap)
Definition: crofconn.cc:14
bool is_congested() const
Returns true, when the underlying TCP connection is congested.
Definition: crofconn.h:299
Definition: cofmsg_table_stats.h:132
rofl::openflow::cofhello_elem_versionbitmap & get_versionbitmap_peer()
Returns a reference to the versionbitmap seen from the peer.
Definition: crofconn.h:313
Definition: cofmsg_meter_config_stats.h:147
Environment expected by a rofl::crofsock instance.
Definition: crofsock.h:76
Definition: crofconn.h:29
void reconnect(bool reset_backoff_timer=false)
Instruct crofsock instance to reconnect to previously connected peer.
Definition: crofconn.cc:127
Definition: crofconn.h:30
Definition: croflexception.h:27