1# 2# Copyright (c) 2013 Nicolas PLANEL <[email protected]> 3# 4 5"""BRIDGE network link 6 7""" 8 9from __future__ import absolute_import 10from __future__ import print_function 11 12from ... import core as netlink 13from .. import capi as capi 14 15 16class BRIDGELink(object): 17 def __init__(self, link): 18 self._link = link 19 self._has_ext_info = capi.rtnl_link_bridge_has_ext_info(self._link) 20 self._port_state_values = [ 21 "disabled", 22 "listening", 23 "learning", 24 "forwarding", 25 "blocking", 26 ] 27 28 def bridge_assert_ext_info(self): 29 if not self._has_ext_info: 30 print( 31 """ 32 Please update your kernel to be able to call this method. 33 Your current kernel bridge version is too old to support this extention. 34 """ 35 ) 36 raise RuntimeWarning() 37 38 def port_state2str(self, state): 39 return self._port_state_values[state] 40 41 def str2port_state(self, str): 42 for value, port in enumerate(self._port_state_values): 43 if str.lower() == port: 44 return value 45 raise ValueError() 46 47 @property 48 @netlink.nlattr(type=int) 49 def port_state(self): 50 """bridge state : 51 %s 52 """ % ( 53 self.port_state 54 ) 55 return capi.rtnl_link_bridge_get_state(self._link) 56 57 @port_state.setter 58 def port_state(self, state): 59 capi.rtnl_link_bridge_set_state(self._link, int(state)) 60 61 @property 62 @netlink.nlattr(type=int) 63 def priority(self): 64 """bridge prio""" 65 self.bridge_assert_ext_info() 66 return capi.rtnl_link_bridge_get_prio(self._link) 67 68 @priority.setter 69 def priority(self, prio): 70 self.bridge_assert_ext_info() 71 if prio < 0 or prio >= 2**16: 72 raise ValueError() 73 capi.rtnl_link_bridge_set_prio(self._link, int(prio)) 74 75 @property 76 @netlink.nlattr(type=int) 77 def cost(self): 78 """bridge prio""" 79 self.bridge_assert_ext_info() 80 return capi.rtnl_link_bridge_get_cost(self._link) 81 82 @cost.setter 83 def cost(self, cost): 84 self.bridge_assert_ext_info() 85 if cost < 0 or cost >= 2**32: 86 raise ValueError() 87 capi.rtnl_link_bridge_set_cost(self._link, int(cost)) 88 89 @property 90 @netlink.nlattr(type=str) 91 def flags(self): 92 """BRIDGE flags 93 Setting this property will *Not* reset flags to value you supply in 94 Examples: 95 link.flags = '+xxx' # add xxx flag 96 link.flags = 'xxx' # exactly the same 97 link.flags = '-xxx' # remove xxx flag 98 link.flags = [ '+xxx', '-yyy' ] # list operation 99 """ 100 self.bridge_assert_ext_info() 101 flags = capi.rtnl_link_bridge_get_flags(self._link) 102 return capi.rtnl_link_bridge_flags2str(flags, 256)[0].split(",") 103 104 def _set_flag(self, flag): 105 if flag.startswith("-"): 106 i = capi.rtnl_link_bridge_str2flags(flag[1:]) 107 capi.rtnl_link_bridge_unset_flags(self._link, i) 108 elif flag.startswith("+"): 109 i = capi.rtnl_link_bridge_str2flags(flag[1:]) 110 capi.rtnl_link_bridge_set_flags(self._link, i) 111 else: 112 i = capi.rtnl_link_bridge_str2flags(flag) 113 capi.rtnl_link_bridge_set_flags(self._link, i) 114 115 @flags.setter 116 def flags(self, value): 117 self.bridge_assert_ext_info() 118 if type(value) is list: 119 for flag in value: 120 self._set_flag(flag) 121 else: 122 self._set_flag(value) 123 124 def brief(self): 125 return "bridge-has-ext-info {0}".format(self._has_ext_info) 126 127 128def init(link): 129 link.bridge = BRIDGELink(link._rtnl_link) 130 return link.bridge 131