Skip to content

Commit d12204d

Browse files
Shadow Router:
This commit register a Shadow router to the netlink events and implements the functions to handle netlink notifications - Route added to the namespace - Route removed from the namespace - Interface removed - New Address on the interface Local traffic and ARP traffic of a Shadow router is managed by the namespace. The setIP, setNetmask and setMac methods have been implemented on the router. Signed-off-by: francescomessina <francescomessina92@hotmail.com>
1 parent 7305045 commit d12204d

6 files changed

Lines changed: 400 additions & 11 deletions

File tree

src/services/pcn-router/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ aux_source_directory(default-src SRC_SOURCES)
77
include_directories(serializer)
88
include_directories(interface)
99
include_directories(default-src)
10+
include_directories(/usr/include/libnl3)
1011

1112
# Needed to load files as variables
1213
include_directories(${CMAKE_CURRENT_BINARY_DIR})

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

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
#include "Router.h"
2121
#include "UtilityMethods.h"
2222

23+
#include "../../../polycubed/src/utils/netlink.h"
24+
#include "../../../polycubed/src/utils/ns.h"
25+
2326
Ports::Ports(polycube::service::Cube<Ports> &parent,
2427
std::shared_ptr<polycube::service::PortIface> port,
2528
const PortsJsonObject &conf)
@@ -142,7 +145,52 @@ std::string Ports::getIp() {
142145

143146
void Ports::setIp(const std::string &value) {
144147
// This method set the ip value.
145-
throw std::runtime_error("[Ports]: Method setIp not implemented");
148+
if (ip_ != value) {
149+
// unset old ip
150+
if (parent_.get_shadow()) {
151+
int prefix = get_netmask_length(getNetmask());
152+
std::function<void()> doThis = [&]{parent_.netlink_instance_router_.unset_iface_ip(getName(), ip_, prefix);};
153+
polycube::polycubed::Namespace namespace_ = polycube::polycubed::Namespace::open("pcn-" + parent_.get_name());
154+
namespace_.execute(doThis);
155+
}
156+
157+
setIp_Netlink(value);
158+
159+
// set new ip
160+
if (parent_.get_shadow()) {
161+
int prefix = get_netmask_length(getNetmask());
162+
std::function<void()> doThis = [&]{parent_.netlink_instance_router_.set_iface_ip(getName(), value, prefix);};
163+
polycube::polycubed::Namespace namespace_ = polycube::polycubed::Namespace::open("pcn-" + parent_.get_name());
164+
namespace_.execute(doThis);
165+
}
166+
}
167+
}
168+
169+
void Ports::setIp_Netlink(const std::string &value) {
170+
// This method set the ip value.
171+
if (ip_ != value) {
172+
std::string new_ip = value;
173+
/* Update the port in the datapath */
174+
uint16_t index = this->index();
175+
auto router_port = parent_.get_hash_table<uint16_t, r_port>("router_port");
176+
177+
try {
178+
r_port value = router_port.get(index);
179+
value.ip = utils::ip_string_to_be_uint(new_ip);
180+
} catch (...) {
181+
logger()->error("Port {0} not found in the data path", this->name());
182+
}
183+
184+
logger()->debug(
185+
"Updated IP port: {0} (index: {4}) [mac: {1} - ip: {2} - netmask: {3}]",
186+
getName(), getMac(), new_ip, getNetmask(), index);
187+
188+
/* Update routes in the routing table */
189+
parent_.remove_local_route(ip_, getNetmask(), getName());
190+
parent_.add_local_route(new_ip, getNetmask(), getName(), index);
191+
192+
ip_ = new_ip;
193+
}
146194
}
147195

148196
std::string Ports::getNetmask() {
@@ -152,7 +200,52 @@ std::string Ports::getNetmask() {
152200

153201
void Ports::setNetmask(const std::string &value) {
154202
// This method set the netmask value.
155-
throw std::runtime_error("[Ports]: Method setNetmask not implemented");
203+
if (netmask_ != value) {
204+
// unset old netmask
205+
if (parent_.get_shadow()) {
206+
int prefix = get_netmask_length(netmask_);
207+
std::function<void()> doThis = [&]{parent_.netlink_instance_router_.unset_iface_ip(getName(), ip_, prefix);};
208+
polycube::polycubed::Namespace namespace_ = polycube::polycubed::Namespace::open("pcn-" + parent_.get_name());
209+
namespace_.execute(doThis);
210+
}
211+
212+
setNetmask_Netlink(value);
213+
214+
// set new netmask
215+
if (parent_.get_shadow()) {
216+
int prefix = get_netmask_length(value);
217+
std::function<void()> doThis = [&]{parent_.netlink_instance_router_.set_iface_ip(getName(), getIp(), prefix);};
218+
polycube::polycubed::Namespace namespace_ = polycube::polycubed::Namespace::open("pcn-" + parent_.get_name());
219+
namespace_.execute(doThis);
220+
}
221+
}
222+
}
223+
224+
void Ports::setNetmask_Netlink(const std::string &value) {
225+
// This method set the netmask value.
226+
if (netmask_ != value) {
227+
std::string new_netmask = value;
228+
/* Update the port in the datapath */
229+
uint16_t index = this->index();
230+
auto router_port = parent_.get_hash_table<uint16_t, r_port>("router_port");
231+
232+
try {
233+
r_port value = router_port.get(index);
234+
value.netmask = utils::ip_string_to_be_uint(new_netmask);
235+
} catch (...) {
236+
logger()->error("Port {0} not found in the data path", this->name());
237+
}
238+
239+
logger()->debug(
240+
"Updated netmask port: {0} (index: {4}) [mac: {1} - ip: {2} - netmask: {3}]",
241+
getName(), getMac(), getIp(), new_netmask, index);
242+
243+
/* Update routes in the routing table */
244+
parent_.remove_local_route(getIp(), netmask_, getName());
245+
parent_.add_local_route(getIp(), new_netmask, getName(), index);
246+
247+
netmask_ = new_netmask;
248+
}
156249
}
157250

158251
std::string Ports::getMac() {
@@ -162,7 +255,30 @@ std::string Ports::getMac() {
162255

163256
void Ports::setMac(const std::string &value) {
164257
// This method set the mac value.
165-
throw std::runtime_error("[Ports]: Method setMac not implemented");
258+
if (mac_ != value) {
259+
std::string new_mac = value;
260+
/* Update the port in the datapath */
261+
uint16_t index = this->index();
262+
auto router_port = parent_.get_hash_table<uint16_t, r_port>("router_port");
263+
264+
try {
265+
r_port value = router_port.get(index);
266+
value.mac = utils::mac_string_to_be_uint(new_mac);
267+
} catch (...) {
268+
logger()->error("Port {0} not found in the data path", this->name());
269+
}
270+
271+
logger()->debug(
272+
"Updated mac port: {0} (index: {4}) [mac: {1} - ip: {2} - netmask: {3}]",
273+
getName(), new_mac, getIp(), getNetmask(), index);
274+
275+
mac_ = new_mac;
276+
}
277+
if (parent_.get_shadow()) {
278+
std::function<void()> doThis = [&]{parent_.netlink_instance_router_.set_iface_mac(getName(), mac_);};
279+
polycube::polycubed::Namespace namespace_ = polycube::polycubed::Namespace::open("pcn-" + parent_.get_name());
280+
namespace_.execute(doThis);
281+
}
166282
}
167283

168284
std::shared_ptr<spdlog::logger> Ports::logger() {
@@ -259,4 +375,4 @@ void Ports::delSecondaryipList() {
259375
std::string netmask = tmp->getNetmask();
260376
delSecondaryip(ip, netmask);
261377
}
262-
}
378+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ class Ports : public polycube::service::Port, public PortsInterface {
6060
/// </summary>
6161
std::string getIp() override;
6262
void setIp(const std::string &value) override;
63+
void setIp_Netlink(const std::string &value);
6364

6465
/// <summary>
6566
/// Netmask of the port
6667
/// </summary>
6768
std::string getNetmask() override;
6869
void setNetmask(const std::string &value) override;
70+
void setNetmask_Netlink(const std::string &value);
6971

7072
/// <summary>
7173
/// MAC address of the port

0 commit comments

Comments
 (0)