Add tap support to TunInterface.

This allows callers to create a tap interface instead of a tun.
Also specify IFF_NO_PI in order to make it easier for users of
this class to read data from the tun. No existing users actually
check the data, so this is safe.

Bug: 150736748
Test: atest netd_integration_test
Change-Id: Ic2e46bb864978b969ae5c1b8c2bdc5379d298f5a
diff --git a/tests/tun_interface.cpp b/tests/tun_interface.cpp
index ffb10b5..93b669f 100644
--- a/tests/tun_interface.cpp
+++ b/tests/tun_interface.cpp
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * tun_interface.cpp - creates tun interfaces for testing purposes
+ * tun_interface.cpp - creates tun or tap interfaces for testing purposes
  */
 
 #include <string>
@@ -48,7 +48,7 @@
 namespace android {
 namespace net {
 
-int TunInterface::init(const std::string& ifName) {
+int TunInterface::init(const std::string& ifName, bool isTap) {
     // Generate a random ULA address pair.
     arc4random_buf(&mSrcAddr, sizeof(mSrcAddr));
     mSrcAddr.s6_addr[0] = 0xfd;
@@ -80,8 +80,9 @@
     }
     mIfName.resize(9);
 
+    flags = IFF_NO_PI | (isTap ? IFF_TAP : IFF_TUN);
     struct ifreq ifr = {
-        .ifr_ifru = { .ifru_flags = IFF_TUN },
+            .ifr_ifru = {.ifru_flags = static_cast<short>(flags)},
     };
     strlcpy(ifr.ifr_name, mIfName.c_str(), sizeof(ifr.ifr_name));
 
@@ -106,6 +107,7 @@
     if (int ret = ifc_enable(ifr.ifr_name)) {
         return ret;
     }
+
     return 0;
 }
 
diff --git a/tests/tun_interface.h b/tests/tun_interface.h
index 0af43b1..ae2c330 100644
--- a/tests/tun_interface.h
+++ b/tests/tun_interface.h
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * tun_interface.h - creates tun interfaces for testing purposes
+ * tun_interface.h - creates tun or tap interfaces for testing purposes
  */
 
 #ifndef _SYSTEM_NETD_TESTS_TUN_INTERACE_H
@@ -27,9 +27,14 @@
     TunInterface() = default;
     ~TunInterface() { destroy(); }
 
-    // Creates a tun interface. Returns 0 on success or -errno on failure. Must succeed before it is
-    // legal to call any of the other methods in this class.
-    int init(const std::string& ifName = "");
+    // Creates a tun or tap interface. Returns 0 on success or -errno on failure. Must succeed
+    // before it is legal to call any of the other methods in this class.
+    int init(const std::string& ifName, bool isTap);
+
+    // Convenience overloads.
+    int init() { return init("", false); }
+    int init(const std::string& ifName) { return init(ifName, false); }
+    int init(bool isTap) { return init("", isTap); }
     void destroy();
 
     const std::string& name() const { return mIfName; }