forked from ishidawataru/openair-cn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOpenflowController.cpp
124 lines (112 loc) · 3.81 KB
/
OpenflowController.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
*/
#include "OpenflowController.h"
extern "C" {
#include "log.h"
}
using namespace fluid_base;
using namespace fluid_msg;
namespace openflow {
OpenflowController::OpenflowController(
const char* address,
const int port,
const int n_workers,
bool secure,
std::shared_ptr<OpenflowMessenger> messenger) :
OFServer(
address,
port,
n_workers,
secure,
OFServerSettings()
.supported_version(OF_13_VERSION) // OF 1.3
.use_hello_elements(true) // bitmask version negotiation
.keep_data_ownership(false)),
running_(true), messenger_(messenger) {}
OpenflowController::OpenflowController(
const char* address,
const int port,
const int n_workers,
bool secure)
: OpenflowController(
address,
port,
n_workers,
secure,
std::shared_ptr<DefaultMessenger>(new DefaultMessenger())) {}
void OpenflowController::register_for_event(
Application* app,
ControllerEventType event_type) {
event_listeners[event_type].push_back(app);
}
void OpenflowController::stop() {
running_ = false;
OFServer::stop();
}
void OpenflowController::message_callback(
OFConnection* ofconn,
uint8_t type,
void* data,
size_t len) {
if (type == OFPT_PACKET_IN_TYPE) {
OAILOG_DEBUG(LOG_GTPV1U, "Openflow controller got packet-in message\n");
dispatch_event(PacketInEvent(ofconn, *this, data, len));
}
else if (type == OFPT_FEATURES_REPLY_TYPE) {
OAILOG_DEBUG(LOG_GTPV1U, "Openflow controller connected to switch\n");
// Save OF connection for external events
latest_ofconn_ = ofconn;
dispatch_event(SwitchUpEvent(ofconn, *this, data, len));
} else if (type == OFPT_ERROR) {
dispatch_event(ErrorEvent(
ofconn,
reinterpret_cast<struct ofp_error_msg*>(data)));
}
}
void OpenflowController::connection_callback(
OFConnection* ofconn,
OFConnection::Event type) {
if (type == OFConnection::EVENT_CLOSED || type == OFConnection::EVENT_DEAD) {
OAILOG_ERROR(LOG_GTPV1U, "Openflow controller lost connection to switch\n");
dispatch_event(SwitchDownEvent(ofconn));
}
}
void OpenflowController::dispatch_event(const ControllerEvent& ev) {
if (not running_) {
throw std::runtime_error(
"Openflow controller needs to be running beforehandling an event\n");
return;
}
std::vector<Application*> listeners = event_listeners[ev.get_type()];
for (auto it = listeners.begin(); it != listeners.end(); it++) {
((Application*) (*it))->event_callback(ev, *messenger_);
}
}
void OpenflowController::inject_external_event(
std::shared_ptr<ExternalEvent> ev,
void* (*cb)(std::shared_ptr<void>)) {
if (latest_ofconn_ == NULL) {
throw std::runtime_error("Controller not connected to switch\n");
}
ev->set_of_connection(latest_ofconn_);
latest_ofconn_->add_immediate_event(cb, ev);
}
}