1#!/usr/bin/env python3 2# 3# Copyright 2017 - Google, Inc. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import logging 18import time 19from acts.libs.proc import job 20 21_BRCTL = 'brctl' 22BRIDGE_NAME = 'br-lan' 23CREATE_BRIDGE = '%s addbr %s' % (_BRCTL, BRIDGE_NAME) 24DELETE_BRIDGE = '%s delbr %s' % (_BRCTL, BRIDGE_NAME) 25BRING_DOWN_BRIDGE = 'ifconfig %s down' % BRIDGE_NAME 26 27 28class BridgeInterfaceConfigs(object): 29 """Configs needed for creating bridge interface between LAN and WLAN. 30 31 """ 32 def __init__(self, iface_wlan, iface_lan, bridge_ip): 33 """Set bridge interface configs based on the channel info. 34 35 Args: 36 iface_wlan: the wlan interface as part of the bridge 37 iface_lan: the ethernet LAN interface as part of the bridge 38 bridge_ip: the ip address assigned to the bridge interface 39 """ 40 self.iface_wlan = iface_wlan 41 self.iface_lan = iface_lan 42 self.bridge_ip = bridge_ip 43 44 45class BridgeInterface(object): 46 """Class object for bridge interface betwen WLAN and LAN 47 48 """ 49 def __init__(self, ap): 50 """Initialize the BridgeInterface class. 51 52 Bridge interface will be added between ethernet LAN port and WLAN port. 53 Args: 54 ap: AP object within ACTS 55 """ 56 self.ssh = ap.ssh 57 58 def startup(self, brconfigs): 59 """Start up the bridge interface. 60 61 Args: 62 brconfigs: the bridge interface config, type BridgeInterfaceConfigs 63 """ 64 65 logging.info('Create bridge interface between LAN and WLAN') 66 # Create the bridge 67 try: 68 self.ssh.run(CREATE_BRIDGE) 69 except job.Error: 70 logging.warning( 71 'Bridge interface {} already exists, no action needed'.format( 72 BRIDGE_NAME)) 73 74 # Enable 4addr mode on for the wlan interface 75 ENABLE_4ADDR = 'iw dev %s set 4addr on' % (brconfigs.iface_wlan) 76 try: 77 self.ssh.run(ENABLE_4ADDR) 78 except job.Error: 79 logging.warning('4addr is already enabled on {}'.format( 80 brconfigs.iface_wlan)) 81 82 # Add both LAN and WLAN interfaces to the bridge interface 83 for interface in [brconfigs.iface_lan, brconfigs.iface_wlan]: 84 ADD_INTERFACE = '%s addif %s %s' % (_BRCTL, BRIDGE_NAME, interface) 85 try: 86 self.ssh.run(ADD_INTERFACE) 87 except job.Error: 88 logging.warning('{} has already been added to {}'.format( 89 interface, BRIDGE_NAME)) 90 time.sleep(5) 91 92 # Set IP address on the bridge interface to bring it up 93 SET_BRIDGE_IP = 'ifconfig %s %s' % (BRIDGE_NAME, brconfigs.bridge_ip) 94 self.ssh.run(SET_BRIDGE_IP) 95 time.sleep(2) 96 97 # Bridge interface is up 98 logging.info('Bridge interface is up and running') 99 100 def teardown(self, brconfigs): 101 """Tear down the bridge interface. 102 103 Args: 104 brconfigs: the bridge interface config, type BridgeInterfaceConfigs 105 """ 106 logging.info('Bringing down the bridge interface') 107 # Delete the bridge interface 108 self.ssh.run(BRING_DOWN_BRIDGE) 109 time.sleep(1) 110 self.ssh.run(DELETE_BRIDGE) 111 112 # Bring down wlan interface and disable 4addr mode 113 BRING_DOWN_WLAN = 'ifconfig %s down' % brconfigs.iface_wlan 114 self.ssh.run(BRING_DOWN_WLAN) 115 time.sleep(2) 116 DISABLE_4ADDR = 'iw dev %s set 4addr off' % (brconfigs.iface_wlan) 117 self.ssh.run(DISABLE_4ADDR) 118 time.sleep(1) 119 logging.info('Bridge interface is down') 120