Pass rule modification errors back to CommandListener.
Change-Id: If01334dccad8b6230648713a57fd58be180ac66b
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 9dbd021..af5df04 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -123,8 +123,10 @@
// + If |mask| is non-zero, the rule matches the specified fwmark and mask. Otherwise, |fwmark| is
// ignored.
// + If |interface| is non-NULL, the rule matches the specified outgoing interface.
-bool modifyIpRule(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark,
- uint32_t mask, const char* interface) {
+//
+// Returns 0 on success or negative errno on failure.
+int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table, uint32_t fwmark, uint32_t mask,
+ const char* interface) {
// The interface name must include exactly one terminating NULL and be properly padded, or older
// kernels will refuse to delete rules.
uint8_t padding[RTA_ALIGNTO] = {0, 0, 0, 0};
@@ -172,12 +174,11 @@
rule.family = family[i];
int ret = sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov));
if (ret) {
- errno = -ret;
- return false;
+ return ret;
}
}
- return true;
+ return 0;
}
// Adds or deletes an IPv4 or IPv6 route.
@@ -247,14 +248,15 @@
return sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov));
}
-bool modifyPerNetworkRules(unsigned netId, const char* interface, Permission permission, bool add,
- bool modifyIptables) {
+int modifyPerNetworkRules(unsigned netId, const char* interface, Permission permission, bool add,
+ bool modifyIptables) {
uint32_t table = getRouteTableForInterface(interface);
if (!table) {
- return false;
+ return -ESRCH;
}
uint16_t action = add ? RTM_NEWRULE : RTM_DELRULE;
+ int ret;
Fwmark fwmark;
fwmark.permission = permission;
@@ -266,9 +268,9 @@
//
// Supports apps that use SO_BINDTODEVICE or IP_PKTINFO options and the kernel that already
// knows the outgoing interface (typically for link-local communications).
- if (!modifyIpRule(action, RULE_PRIORITY_PER_NETWORK_INTERFACE, table, fwmark.intValue,
- mask.intValue, interface)) {
- return false;
+ if ((ret = modifyIpRule(action, RULE_PRIORITY_PER_NETWORK_INTERFACE, table, fwmark.intValue,
+ mask.intValue, interface)) != 0) {
+ return ret;
}
// A rule to route traffic based on the chosen network.
@@ -278,9 +280,9 @@
// network stay on that network even if the default network changes.
fwmark.netId = netId;
mask.netId = FWMARK_NET_ID_MASK;
- if (!modifyIpRule(action, RULE_PRIORITY_PER_NETWORK_NORMAL, table, fwmark.intValue,
- mask.intValue, NULL)) {
- return false;
+ if ((ret = modifyIpRule(action, RULE_PRIORITY_PER_NETWORK_NORMAL, table, fwmark.intValue,
+ mask.intValue, NULL)) != 0) {
+ return ret;
}
// A rule to route traffic based on an explicitly chosen network.
@@ -291,9 +293,9 @@
// checked at the time the netId was set into the fwmark, but we do so to be consistent.
fwmark.explicitlySelected = true;
mask.explicitlySelected = true;
- if (!modifyIpRule(action, RULE_PRIORITY_PER_NETWORK_EXPLICIT, table, fwmark.intValue,
- mask.intValue, NULL)) {
- return false;
+ if ((ret = modifyIpRule(action, RULE_PRIORITY_PER_NETWORK_EXPLICIT, table, fwmark.intValue,
+ mask.intValue, NULL)) != 0) {
+ return ret;
}
// An iptables rule to mark incoming packets on a network with the netId of the network.
@@ -309,17 +311,17 @@
snprintf(markString, sizeof(markString), "0x%x", netId);
if (execIptables(V4V6, "-t", "mangle", iptablesAction, "INPUT", "-i", interface,
"-j", "MARK", "--set-mark", markString, NULL)) {
- return false;
+ return -EREMOTEIO;
}
}
- return true;
+ return 0;
}
-bool modifyDefaultNetworkRules(const char* interface, Permission permission, uint16_t action) {
+int modifyDefaultNetworkRules(const char* interface, Permission permission, uint16_t action) {
uint32_t table = getRouteTableForInterface(interface);
if (!table) {
- return false;
+ return -ESRCH;
}
Fwmark fwmark;
@@ -454,29 +456,29 @@
#endif
}
-bool RouteController::addInterfaceToNetwork(unsigned netId, const char* interface,
- Permission permission) {
+int RouteController::addInterfaceToNetwork(unsigned netId, const char* interface,
+ Permission permission) {
return modifyPerNetworkRules(netId, interface, permission, true, true);
}
-bool RouteController::removeInterfaceFromNetwork(unsigned netId, const char* interface,
- Permission permission) {
+int RouteController::removeInterfaceFromNetwork(unsigned netId, const char* interface,
+ Permission permission) {
return modifyPerNetworkRules(netId, interface, permission, false, true) &&
flushRoutes(interface);
}
-bool RouteController::modifyNetworkPermission(unsigned netId, const char* interface,
- Permission oldPermission, Permission newPermission) {
+int RouteController::modifyNetworkPermission(unsigned netId, const char* interface,
+ Permission oldPermission, Permission newPermission) {
// Add the new rules before deleting the old ones, to avoid race conditions.
return modifyPerNetworkRules(netId, interface, newPermission, true, false) &&
modifyPerNetworkRules(netId, interface, oldPermission, false, false);
}
-bool RouteController::addToDefaultNetwork(const char* interface, Permission permission) {
+int RouteController::addToDefaultNetwork(const char* interface, Permission permission) {
return modifyDefaultNetworkRules(interface, permission, RTM_NEWRULE);
}
-bool RouteController::removeFromDefaultNetwork(const char* interface, Permission permission) {
+int RouteController::removeFromDefaultNetwork(const char* interface, Permission permission) {
return modifyDefaultNetworkRules(interface, permission, RTM_DELRULE);
}