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;
diff --git a/patchpanel/manager.h b/patchpanel/manager.h
index 5b83543..70f5a54 100644
--- a/patchpanel/manager.h
+++ b/patchpanel/manager.h
@@ -21,6 +21,7 @@
 #include "patchpanel/address_manager.h"
 #include "patchpanel/arc_service.h"
 #include "patchpanel/crostini_service.h"
+#include "patchpanel/firewall.h"
 #include "patchpanel/helper_process.h"
 #include "patchpanel/network_monitor_service.h"
 #include "patchpanel/routing_service.h"
@@ -156,6 +157,8 @@
   // fd found.
   void CheckConnectedNamespaces();
 
+  bool ModifyPortRule(const patchpanel::ModifyPortRuleRequest& request);
+
   // Dispatch |msg| to child processes.
   void SendGuestMessage(const GuestMessage& msg);
 
@@ -171,6 +174,9 @@
   // DBus service.
   dbus::ExportedObject* dbus_svc_path_;  // Owned by |bus_|.
 
+  // Firewall service.
+  Firewall firewall_;
+
   // Other services.
   brillo::ProcessReaper process_reaper_;
   std::unique_ptr<HelperProcess> adb_proxy_;