site_linux_system: delete ifbX for -pcap devices too

-pcap devices also have ifb0/ifb1 and (very, very slowly, over a long
time) the log noise from Shill needlessly bringing these interfaces up
and down (crbug.com/960551 -- resolved, but still requires an AP image
update) fills either the disk (logs) or tmpfs (bootstat entries).

Apply this hack to both pcap and router.

BUG=chromium:1076166, chromium:1005443
TEST=run a WiFi test on a lab -pcap/-router, see the -pcap's ifb0/ifb1
     deleted

Change-Id: I256f5de1b1c0626e9e5f5c615557d04650078b9d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2199894
Tested-by: Brian Norris <[email protected]>
Commit-Queue: Brian Norris <[email protected]>
Reviewed-by: Shuo-Peng Liao <[email protected]>
Reviewed-by: Matthew Wang <[email protected]>
Reviewed-by: Harpreet Grewal <[email protected]>
diff --git a/server/site_linux_system.py b/server/site_linux_system.py
index d80c3ad..0433a00 100644
--- a/server/site_linux_system.py
+++ b/server/site_linux_system.py
@@ -41,6 +41,7 @@
     CAPABILITY_SME = 'sme'
     CAPABILITY_SUPPLICANT_ROAMING = "supplicant_roaming"
     BRIDGE_INTERFACE_NAME = 'br0'
+    HOSTAP_BRIDGE_INTERFACE_PREFIX = 'hostapbr'
     IFB_INTERFACE_PREFIX = 'ifb'
     MIN_SPATIAL_STREAMS = 2
     MAC_BIT_LOCAL = 0x2  # Locally administered.
@@ -136,6 +137,19 @@
             self.host.run('truncate -s 0 %s' % self._UMA_EVENTS,
                           ignore_status=True)
 
+        # Tear down hostapbr bridge and intermediate functional block
+        # interfaces. Run this even for pcaps, because pcap devices sometimes
+        # are run as APs too.
+        # TODO(crbug.com/1005443): drop the ifb hack when we deploy an AP OS
+        # image that has fixes for crbug.com/960551.
+        result = self.host.run('ls -d /sys/class/net/%s* /sys/class/net/%s*'
+                               ' 2>/dev/null' %
+                               (self.HOSTAP_BRIDGE_INTERFACE_PREFIX,
+                                self.IFB_INTERFACE_PREFIX),
+                               ignore_status=True)
+        for path in result.stdout.splitlines():
+            self.delete_link(path.split('/')[-1])
+
 
     @property
     def phy_list(self):
@@ -267,6 +281,16 @@
                 break
 
 
+    def delete_link(self, name):
+        """Delete link using the `ip` command.
+
+        @param name string link name.
+
+        """
+        self.host.run('%s link del %s' % (self.cmd_ip, name),
+                      ignore_status=True)
+
+
     def close(self):
         """Close global resources held by this system."""
         logging.debug('Cleaning up host object for %s', self.role)