patchpanel: Implement ModifyPortRule API

Firewall is now moved from permission_broker to
patchpanel. Implement ModifyPortRule by calling
firewall.

BUG=b:160130580
TEST=tast run <DUT_IP> platform.Firewall
     with chromium:2291865

Change-Id: I25e1cfdf512d63b05a83a532b05798e1df2dd9a0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2291867
Commit-Queue: Jason Jeremy Iman <jasongustaman@chromium.org>
Tested-by: Jason Jeremy Iman <jasongustaman@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
Reviewed-by: Garrick Evans <garrick@chromium.org>
diff --git a/patchpanel/manager.cc b/patchpanel/manager.cc
index 3218586..784a5d3 100644
--- a/patchpanel/manager.cc
+++ b/patchpanel/manager.cc
@@ -792,7 +792,7 @@
     return dbus_response;
   }
 
-  // TODO(b/160129667): Handle ModifyPortRule request.
+  response.set_success(ModifyPortRule(request));
   writer.AppendProtoAsArrayOfBytes(response);
   return dbus_response;
 }
@@ -1026,6 +1026,57 @@
       kConnectNamespaceCheckInterval);
 }
 
+bool Manager::ModifyPortRule(const patchpanel::ModifyPortRuleRequest& request) {
+  switch (request.proto()) {
+    case patchpanel::ModifyPortRuleRequest::TCP:
+    case patchpanel::ModifyPortRuleRequest::UDP:
+      break;
+    default:
+      LOG(ERROR) << "Unknown protocol " << request.proto();
+      return false;
+  }
+
+  switch (request.op()) {
+    case patchpanel::ModifyPortRuleRequest::CREATE:
+      switch (request.type()) {
+        case patchpanel::ModifyPortRuleRequest::ACCESS:
+          return firewall_.AddAcceptRules(request.proto(),
+                                          request.input_dst_port(),
+                                          request.input_ifname());
+        case patchpanel::ModifyPortRuleRequest::LOCKDOWN:
+          return firewall_.AddLoopbackLockdownRules(request.proto(),
+                                                    request.input_dst_port());
+        case patchpanel::ModifyPortRuleRequest::FORWARDING:
+          return firewall_.AddIpv4ForwardRule(
+              request.proto(), request.input_dst_ip(), request.input_dst_port(),
+              request.input_ifname(), request.dst_ip(), request.dst_port());
+        default:
+          LOG(ERROR) << "Unknown port rule type " << request.type();
+          return false;
+      }
+    case patchpanel::ModifyPortRuleRequest::DELETE:
+      switch (request.type()) {
+        case patchpanel::ModifyPortRuleRequest::ACCESS:
+          return firewall_.DeleteAcceptRules(request.proto(),
+                                             request.input_dst_port(),
+                                             request.input_ifname());
+        case patchpanel::ModifyPortRuleRequest::LOCKDOWN:
+          return firewall_.DeleteLoopbackLockdownRules(
+              request.proto(), request.input_dst_port());
+        case patchpanel::ModifyPortRuleRequest::FORWARDING:
+          return firewall_.DeleteIpv4ForwardRule(
+              request.proto(), request.input_dst_ip(), request.input_dst_port(),
+              request.input_ifname(), request.dst_ip(), request.dst_port());
+        default:
+          LOG(ERROR) << "Unknown port rule type " << request.type();
+          return false;
+      }
+    default:
+      LOG(ERROR) << "Unknown operation " << request.op();
+      return false;
+  }
+}
+
 void Manager::SendGuestMessage(const GuestMessage& msg) {
   IpHelperMessage ipm;
   *ipm.mutable_guest_message() = msg;