Skip to content

Commit deb455c

Browse files
pcn-nat: update masquerade rules when attached
The masquerade rules should be updated with the new external IP if they are enabled when the nat is attached to a cube's port. This commit also fixes two small problems when creating a nat with the full configuration in a single operation: - objects in rule were created after the call to update (segfault) - masquerade enabled was not taken into consideration Signed-off-by: Mauricio Vasquez B <mauriciovasquezbernal@gmail.com>
1 parent 6dc7211 commit deb455c

4 files changed

Lines changed: 54 additions & 27 deletions

File tree

src/services/pcn-nat/src/Nat.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ void Nat::attach() {
8383
auto temp = get_parent_parameter("ip");
8484
external_ip_ = temp.substr(1, temp.length() - 2); // remove qoutes
8585
logger()->info("external ip is : {}", external_ip_);
86+
// if masquerare is enabled we need to update the IP address
87+
// TODO: this action should also be performed when the IP address on the
88+
// parent changes (it needs the subscription mechanishm)
89+
if (rule_->getMasquerade()->getEnabled()) {
90+
rule_->getMasquerade()->inject(utils::ip_string_to_be_uint(external_ip_));
91+
}
8692
} catch (...) {
8793
logger()->warn("External IP not found. Is this enabled on a router?");
8894
}

src/services/pcn-nat/src/Rule.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
#include "Nat.h"
2121

2222
Rule::Rule(Nat &parent, const RuleJsonObject &conf) : parent_(parent) {
23-
update(conf);
2423
snat_ = std::make_shared<RuleSnat>(*this);
2524
dnat_ = std::make_shared<RuleDnat>(*this);
2625
portforwarding_ = std::make_shared<RulePortForwarding>(*this);
2726
masquerade_ = std::make_shared<RuleMasquerade>(*this);
27+
update(conf);
2828
}
2929

3030
Rule::~Rule() {

src/services/pcn-nat/src/RuleMasquerade.cpp

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,8 @@ RuleMasqueradeJsonObject RuleMasquerade::toJsonObject() {
5050
return conf;
5151
}
5252

53-
RuleMasqueradeEnableOutputJsonObject RuleMasquerade::enable() {
54-
RuleMasqueradeEnableOutputJsonObject output;
55-
if (enabled) {
56-
// Already enabled
57-
output.setResult(true);
58-
return output;
59-
}
60-
try {
53+
bool RuleMasquerade::inject(uint32_t ip) {
54+
try {
6155
// Inject rule in the datapath table
6256
auto sm_rules = parent_.getParent().get_hash_table<sm_k, sm_v>(
6357
"sm_rules", 0, ProgramType::EGRESS);
@@ -66,50 +60,75 @@ RuleMasqueradeEnableOutputJsonObject RuleMasquerade::enable() {
6660
};
6761

6862
sm_v value{
69-
.external_ip = utils::ip_string_to_be_uint(
70-
parent_.getParent().getExternalIpString()),
63+
.external_ip = ip,
7164
.entry_type = (uint8_t)NattingTableOriginatingRuleEnum::MASQUERADE,
7265
};
7366
sm_rules.set(key, value);
74-
enabled = true;
67+
} catch (std::exception &e) {
68+
logger()->error("Error injecting masquerate rule " + std::string(e.what()));
69+
return false;
70+
}
71+
72+
return true;
73+
}
74+
75+
RuleMasqueradeEnableOutputJsonObject RuleMasquerade::enable() {
76+
RuleMasqueradeEnableOutputJsonObject output;
77+
if (enabled) {
78+
// Already enabled
7579
output.setResult(true);
80+
return output;
81+
}
82+
83+
uint32_t ip = 0;
84+
85+
try {
86+
ip = utils::ip_string_to_be_uint(
87+
parent_.getParent().getExternalIpString());
88+
} catch(...) {
89+
output.setResult(false);
90+
return output;
91+
}
92+
93+
bool result = inject(ip);
94+
output.setResult(result);
95+
if (result) {
96+
enabled = true;
7697
logger()->info("Enabled masquerade: 0.0.0.0 -> {0}",
7798
parent_.getParent().getExternalIpString());
78-
} catch (std::exception &e) {
79-
logger()->info("Could not enable masquerade: " + std::string(e.what()));
80-
output.setResult(false);
8199
}
100+
82101
return output;
83102
}
103+
84104
RuleMasqueradeDisableOutputJsonObject RuleMasquerade::disable() {
85105
RuleMasqueradeDisableOutputJsonObject output;
86106
if (!enabled) {
87107
// Already disabled
88108
output.setResult(true);
89109
return output;
90110
}
91-
try {
92-
auto sm_rules = parent_.getParent().get_hash_table<sm_k, sm_v>(
93-
"sm_rules", 0, ProgramType::EGRESS);
94-
sm_k key{
95-
.internal_netmask_len = 0, .internal_ip = 0,
96-
};
97-
98-
sm_rules.remove(key);
99111

112+
bool result = inject(0);
113+
output.setResult(result);
114+
if (result) {
100115
enabled = false;
101-
output.setResult(true);
102116
logger()->info("Disabled masquerade");
103-
} catch (std::exception &e) {
104-
logger()->info("Could not disable masquerade: " + std::string(e.what()));
105-
output.setResult(false);
106117
}
118+
107119
return output;
108120
}
109121

110122
void RuleMasquerade::setEnabled(const bool &value) {
123+
if (value) {
124+
enable();
125+
} else {
126+
disable();
127+
}
128+
111129
enabled = value;
112130
}
131+
113132
bool RuleMasquerade::getEnabled() {
114133
return enabled;
115134
}

src/services/pcn-nat/src/RuleMasquerade.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Rule;
2525
using namespace io::swagger::server::model;
2626

2727
class RuleMasquerade : public RuleMasqueradeInterface {
28+
friend class Nat;
2829
public:
2930
RuleMasquerade(Rule &parent);
3031
RuleMasquerade(Rule &parent, const RuleMasqueradeJsonObject &conf);
@@ -41,6 +42,7 @@ class RuleMasquerade : public RuleMasqueradeInterface {
4142
void setEnabled(const bool &value) override;
4243

4344
private:
45+
bool inject(uint32_t ip); // injects the rule in datapath
4446
Rule &parent_;
4547
bool enabled;
4648
};

0 commit comments

Comments
 (0)