Skip to content

Commit 811976d

Browse files
authored
Merge pull request #171 from polycube-network/pr/fix_align_ifaces
fix align interfaces logic
2 parents f0a08a9 + 893bb2d commit 811976d

File tree

4 files changed

+81
-85
lines changed

4 files changed

+81
-85
lines changed

src/polycubed/src/port.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,22 @@ void Port::set_peer(const std::string &peer) {
134134
if (peer_ == peer) {
135135
return;
136136
}
137+
138+
// if previous peer was an iface, remove subscriptions
139+
if (auto extiface_old = dynamic_cast<ExtIface*>(peer_port_)) {
140+
// Subscribe to the list of events
141+
for (auto &it : subscription_list)
142+
extiface_old->unsubscribe_parameter(uuid().str(), it.first);
143+
}
137144
}
145+
138146
ServiceController::set_port_peer(*this, peer);
139147

140-
{
141-
std::lock_guard<std::mutex> guard(port_mutex_);
142-
peer_ = peer;
143-
}
148+
std::lock_guard<std::mutex> guard(port_mutex_);
149+
peer_ = peer;
144150

145151
// Check if peer is a ExtIface
146-
ExtIface* extiface = dynamic_cast<ExtIface*>(get_peer_iface());
147-
if (extiface) {
148-
std::lock_guard<std::mutex> lock(subscription_list_mutex);
152+
if (auto extiface = dynamic_cast<ExtIface*>(peer_port_)) {
149153
// Subscribe to the list of events
150154
for (auto &it : subscription_list)
151155
extiface->subscribe_parameter(uuid().str(), it.first, it.second);
@@ -308,33 +312,34 @@ void Port::unconnect(PeerIface &p1, PeerIface &p2) {
308312

309313
void Port::subscribe_peer_parameter(const std::string &param_name,
310314
ParameterEventCallback &callback) {
311-
std::lock_guard<std::mutex> lock(subscription_list_mutex);
315+
std::lock_guard<std::mutex> lock(port_mutex_);
312316
// Add event to the list
313317
subscription_list.emplace(param_name, callback);
314318

315319
// Check if the port already has a peer (of type ExtIface)
316320
// Subscribe to the peer parameter only if the peer is an netdev
317321
// (we are not interested in align different cubes' ports).
318-
ExtIface* extiface = dynamic_cast<ExtIface*>(get_peer_iface());
322+
ExtIface* extiface = dynamic_cast<ExtIface*>(peer_port_);
319323
if (extiface)
320324
extiface->subscribe_parameter(uuid().str(), param_name, callback);
321325
}
322326

323327
void Port::unsubscribe_peer_parameter(const std::string &param_name) {
324-
std::lock_guard<std::mutex> lock(subscription_list_mutex);
328+
std::lock_guard<std::mutex> lock(port_mutex_);
325329
// Remove event from the list
326330
subscription_list.erase(param_name);
327331

328332
// Only unsubscribe if peer is ExtIface
329-
ExtIface* extiface = dynamic_cast<ExtIface*>(get_peer_iface());
333+
ExtIface* extiface = dynamic_cast<ExtIface*>(peer_port_);
330334
if (extiface)
331335
extiface->unsubscribe_parameter(uuid().str(), param_name);
332336
}
333337

334338
void Port::set_peer_parameter(const std::string &param_name,
335339
const std::string &value) {
340+
std::lock_guard<std::mutex> lock(port_mutex_);
336341
// Check if peer is a ExtIface
337-
ExtIface* extiface = dynamic_cast<ExtIface*>(get_peer_iface());
342+
ExtIface* extiface = dynamic_cast<ExtIface*>(peer_port_);
338343
if (extiface)
339344
extiface->set_parameter(param_name, value);
340345
}

src/polycubed/src/port.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ class Port : public polycube::service::PortIface, public PeerIface {
122122
uint16_t calculate_index() const;
123123

124124
std::unordered_map<std::string, ParameterEventCallback> subscription_list;
125-
std::mutex subscription_list_mutex;
126125
};
127126

128127
} // namespace polycubed

src/polycubed/src/utils/netlink.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,10 @@ class Netlink {
110110

111111
void notify(const Event &event, int ifindex, const std::string &ifname) {
112112
std::map<int, std::function<void(int, const std::string &)>> ob_copy;
113-
std::lock_guard<std::mutex> lock(notify_mutex);
114-
ob_copy.insert(observers_[event].begin(), observers_[event].end());
113+
{
114+
std::lock_guard<std::mutex> lock(notify_mutex);
115+
ob_copy.insert(observers_[event].begin(), observers_[event].end());
116+
}
115117

116118
for (const auto &it : ob_copy) {
117119
auto obs = it.second;

src/services/pcn-router/src/Ports.cpp

Lines changed: 60 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -92,72 +92,64 @@ Ports::Ports(polycube::service::Cube<Ports> &parent,
9292

9393
// lambda function to align IP and Netmask between Port and ExtIface
9494
ParameterEventCallback f_ip;
95-
f_ip = [&](const std::string name_iface, const std::string cidr) {
96-
if (peer() == name_iface) {
97-
try {
98-
if (cidr.empty()) {
99-
// set the ip address of the port on the netdev
100-
std::string ip = getIp();
101-
int prefix = utils::get_netmask_length(getNetmask());
102-
parent_.netlink_instance_router_.add_iface_ip(peer(), ip, prefix);
103-
} else {
104-
// set the ip address of the netdev on the port
105-
// cidr = ip_address/prefix
106-
std::istringstream split(cidr);
107-
std::vector<std::string> info;
108-
109-
char split_char = '/';
110-
for (std::string each; std::getline(split, each, split_char);
111-
info.push_back(each));
112-
std::string new_ip = info[0];
113-
std::string new_netmask =
114-
utils::get_netmask_from_CIDR(std::stoi(info[1]));
115-
116-
std::string old_ip = getIp();
117-
std::string old_netmask = getNetmask();
118-
119-
logger()->debug(
120-
"Align ip and netmask of port {0} with those of interface {1}",
121-
name(), name_iface);
122-
123-
if (old_ip != new_ip)
124-
setIp_Netlink(new_ip);
125-
if (old_netmask != new_netmask)
126-
setNetmask_Netlink(new_netmask);
127-
}
128-
} catch (std::exception &e) {
129-
logger()->trace("iface_ip_notification - False ip notification: {0}",
130-
e.what());
95+
f_ip = [&](const std::string param_name, const std::string cidr) {
96+
try {
97+
if (!cidr.empty()) {
98+
// set the ip address of the netdev on the port
99+
// cidr = ip_address/prefix
100+
std::istringstream split(cidr);
101+
std::vector<std::string> info;
102+
103+
char split_char = '/';
104+
for (std::string each; std::getline(split, each, split_char);
105+
info.push_back(each))
106+
;
107+
std::string new_ip = info[0];
108+
std::string new_netmask =
109+
utils::get_netmask_from_CIDR(std::stoi(info[1]));
110+
111+
std::string old_ip = getIp();
112+
std::string old_netmask = getNetmask();
113+
114+
logger()->debug("Align ip and netmask of port {0}", name());
115+
116+
if (old_ip != new_ip)
117+
setIp_Netlink(new_ip);
118+
if (old_netmask != new_netmask)
119+
setNetmask_Netlink(new_netmask);
131120
}
121+
} catch (std::exception &e) {
122+
logger()->trace("iface_ip_notification - False ip notification: {0}",
123+
e.what());
132124
}
133125
};
134126

135127
// lambda function to align MAC between Port and ExtIface
136128
ParameterEventCallback f_mac;
137-
f_mac = [&](const std::string name_iface, const std::string mac) {
138-
if (peer() == name_iface) {
139-
try {
140-
std::string old_mac = getMac();
141-
if (old_mac != mac) {
142-
logger()->debug("Align mac of port {0} with those of interface {1}",
143-
name(), name_iface);
144-
doSetMac(mac);
145-
}
146-
} catch (std::exception &e) {
147-
logger()->trace("iface_mac_notification - False mac notification: {0}",
148-
e.what());
129+
f_mac = [&](const std::string param_name, const std::string mac) {
130+
try {
131+
if (mac_ != mac) {
132+
logger()->debug("Align mac of port {0}", name());
133+
doSetMac(mac);
149134
}
135+
} catch (std::exception &e) {
136+
logger()->trace("iface_mac_notification - False mac notification: {0}",
137+
e.what());
150138
}
151139
};
152140

153-
// Register the new port to IP and MAC notifications arriving from ExtIface
154-
subscribe_peer_parameter("IP", f_ip);
155-
subscribe_peer_parameter("MAC", f_mac);
141+
if (!parent_.get_shadow()) {
142+
// Register the new port to IP and MAC notifications arriving from ExtIface
143+
subscribe_peer_parameter("IP", f_ip);
144+
subscribe_peer_parameter("MAC", f_mac);
145+
}
156146
}
157147

158148
Ports::~Ports() {
159-
unsubscribe_peer_parameter("IP");
160-
unsubscribe_peer_parameter("MAC");
149+
if (!parent_.get_shadow()) {
150+
unsubscribe_peer_parameter("IP");
151+
unsubscribe_peer_parameter("MAC");
152+
}
161153
}
162154

163155
void Ports::update(const PortsJsonObject &conf) {
@@ -355,26 +347,24 @@ void Ports::setMac(const std::string &value) {
355347
set_peer_parameter("MAC", value);
356348
}
357349

358-
void Ports::doSetMac(const std::string &value) {
359-
if (mac_ != value) {
360-
std::string new_mac = value;
361-
/* Update the port in the datapath */
362-
uint16_t index = this->index();
363-
auto router_port = parent_.get_hash_table<uint16_t, r_port>("router_port");
350+
void Ports::doSetMac(const std::string &new_mac) {
351+
if (mac_ == new_mac) {
352+
return;
353+
}
364354

365-
try {
366-
r_port value = router_port.get(index);
367-
value.mac = utils::mac_string_to_be_uint(new_mac);
368-
} catch (...) {
369-
logger()->error("Port {0} not found in the data path", this->name());
370-
}
355+
/* Update the port in the datapath */
356+
uint16_t index = this->index();
357+
auto router_port = parent_.get_hash_table<uint16_t, r_port>("router_port");
371358

372-
logger()->debug(
373-
"Updated mac port: {0} (index: {4}) [mac: {1} - ip: {2} - netmask: {3}]",
374-
getName(), new_mac, getIp(), getNetmask(), index);
359+
r_port map_value = router_port.get(index);
360+
map_value.mac = utils::mac_string_to_be_uint(new_mac);
361+
router_port.set(index, map_value);
375362

376-
mac_ = new_mac;
377-
}
363+
logger()->debug(
364+
"Updated mac port: {0} (index: {4}) [mac: {1} - ip: {2} - netmask: {3}]",
365+
getName(), new_mac, getIp(), getNetmask(), index);
366+
367+
mac_ = new_mac;
378368
}
379369

380370
std::shared_ptr<spdlog::logger> Ports::logger() {

0 commit comments

Comments
 (0)