Configure the Bonnet's bootstrapping process in a Kubernetes pod. Should do the following:

TODO: Need to handle graceful handoff of connections between bonnets on restart. As it is now, the old Bonnet being connected causes the new one to be blocked (and the old one isn't killed by the kubemaster until the new one initializes...).

1) Start Bonnet as an init container, configuring the TUN device and setting permissions to allow the Bonnet sidecar to pick up the TUN without NET_ADMIN permissions.
2) Have the init container shut down upon successful configuration (should we forcefully terminate after some number of failed initial attempts?).
3) Start Bonnet again as a sidecar (without NET_ADMIN), allowing the primary task within the pod to run without requiring any privileges.

gfe-relnote: n/a (QBONE-only change)
PiperOrigin-RevId: 285281727
Change-Id: Ie78ffb1d441f605e41ead80c16069271fbe102f3
diff --git a/quic/qbone/bonnet/tun_device.cc b/quic/qbone/bonnet/tun_device.cc
index e266654..6fa3cc3 100644
--- a/quic/qbone/bonnet/tun_device.cc
+++ b/quic/qbone/bonnet/tun_device.cc
@@ -22,10 +22,12 @@
 TunDevice::TunDevice(const string& interface_name,
                      int mtu,
                      bool persist,
+                     bool setup_tun,
                      KernelInterface* kernel)
     : interface_name_(interface_name),
       mtu_(mtu),
       persist_(persist),
+      setup_tun_(setup_tun),
       file_descriptor_(kInvalidFd),
       kernel_(*kernel) {}
 
@@ -56,7 +58,7 @@
 // TODO(pengg): might be better to use netlink socket, once we have a library to
 // use
 bool TunDevice::Up() {
-  if (!is_interface_up_) {
+  if (setup_tun_ && !is_interface_up_) {
     struct ifreq if_request;
     memset(&if_request, 0, sizeof(if_request));
     // copy does not zero-terminate the result string, but we've memset the
@@ -75,7 +77,7 @@
 // TODO(pengg): might be better to use netlink socket, once we have a library to
 // use
 bool TunDevice::Down() {
-  if (is_interface_up_) {
+  if (setup_tun_ && is_interface_up_) {
     struct ifreq if_request;
     memset(&if_request, 0, sizeof(if_request));
     // copy does not zero-terminate the result string, but we've memset the
@@ -145,6 +147,10 @@
 // TODO(pengg): might be better to use netlink socket, once we have a library to
 // use
 bool TunDevice::ConfigureInterface() {
+  if (!setup_tun_) {
+    return true;
+  }
+
   struct ifreq if_request;
   memset(&if_request, 0, sizeof(if_request));
   // copy does not zero-terminate the result string, but we've memset the entire
diff --git a/quic/qbone/bonnet/tun_device.h b/quic/qbone/bonnet/tun_device.h
index 1828b81..f4b901f 100644
--- a/quic/qbone/bonnet/tun_device.h
+++ b/quic/qbone/bonnet/tun_device.h
@@ -35,6 +35,7 @@
   TunDevice(const string& interface_name,
             int mtu,
             bool persist,
+            bool setup_tun,
             KernelInterface* kernel);
 
   ~TunDevice() override;
@@ -72,6 +73,7 @@
   const string interface_name_;
   const int mtu_;
   const bool persist_;
+  const bool setup_tun_;
   int file_descriptor_;
   KernelInterface& kernel_;
   bool is_interface_up_ = false;
diff --git a/quic/qbone/bonnet/tun_device_test.cc b/quic/qbone/bonnet/tun_device_test.cc
index e9ae4d3..e44f499 100644
--- a/quic/qbone/bonnet/tun_device_test.cc
+++ b/quic/qbone/bonnet/tun_device_test.cc
@@ -123,7 +123,7 @@
 // A TunDevice can be initialized and up
 TEST_F(TunDeviceTest, BasicWorkFlow) {
   SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
-  TunDevice tun_device(kDeviceName, 1500, false, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, false, true, &mock_kernel_);
   EXPECT_TRUE(tun_device.Init());
   EXPECT_GT(tun_device.GetFileDescriptor(), -1);
 
@@ -136,7 +136,7 @@
   SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
   EXPECT_CALL(mock_kernel_, open(StrEq("/dev/net/tun"), _))
       .WillOnce(Return(-1));
-  TunDevice tun_device(kDeviceName, 1500, false, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, false, true, &mock_kernel_);
   EXPECT_FALSE(tun_device.Init());
   EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
 }
@@ -144,7 +144,7 @@
 TEST_F(TunDeviceTest, FailToCheckFeature) {
   SetInitExpectations(/* mtu = */ 1500, /* persist = */ false);
   EXPECT_CALL(mock_kernel_, ioctl(_, TUNGETFEATURES, _)).WillOnce(Return(-1));
-  TunDevice tun_device(kDeviceName, 1500, false, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, false, true, &mock_kernel_);
   EXPECT_FALSE(tun_device.Init());
   EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
 }
@@ -157,7 +157,7 @@
         *actual_features = IFF_TUN | IFF_ONE_QUEUE;
         return 0;
       }));
-  TunDevice tun_device(kDeviceName, 1500, false, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, false, true, &mock_kernel_);
   EXPECT_FALSE(tun_device.Init());
   EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
 }
@@ -165,7 +165,7 @@
 TEST_F(TunDeviceTest, FailToSetFlag) {
   SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
   EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETIFF, _)).WillOnce(Return(-1));
-  TunDevice tun_device(kDeviceName, 1500, true, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, true, true, &mock_kernel_);
   EXPECT_FALSE(tun_device.Init());
   EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
 }
@@ -173,7 +173,7 @@
 TEST_F(TunDeviceTest, FailToPersistDevice) {
   SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
   EXPECT_CALL(mock_kernel_, ioctl(_, TUNSETPERSIST, _)).WillOnce(Return(-1));
-  TunDevice tun_device(kDeviceName, 1500, true, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, true, true, &mock_kernel_);
   EXPECT_FALSE(tun_device.Init());
   EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
 }
@@ -181,7 +181,7 @@
 TEST_F(TunDeviceTest, FailToOpenSocket) {
   SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
   EXPECT_CALL(mock_kernel_, socket(AF_INET6, _, _)).WillOnce(Return(-1));
-  TunDevice tun_device(kDeviceName, 1500, true, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, true, true, &mock_kernel_);
   EXPECT_FALSE(tun_device.Init());
   EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
 }
@@ -189,14 +189,14 @@
 TEST_F(TunDeviceTest, FailToSetMtu) {
   SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
   EXPECT_CALL(mock_kernel_, ioctl(_, SIOCSIFMTU, _)).WillOnce(Return(-1));
-  TunDevice tun_device(kDeviceName, 1500, true, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, true, true, &mock_kernel_);
   EXPECT_FALSE(tun_device.Init());
   EXPECT_EQ(tun_device.GetFileDescriptor(), -1);
 }
 
 TEST_F(TunDeviceTest, FailToUp) {
   SetInitExpectations(/* mtu = */ 1500, /* persist = */ true);
-  TunDevice tun_device(kDeviceName, 1500, true, &mock_kernel_);
+  TunDevice tun_device(kDeviceName, 1500, true, true, &mock_kernel_);
   EXPECT_TRUE(tun_device.Init());
   EXPECT_GT(tun_device.GetFileDescriptor(), -1);