diff --git a/pyroute2/netlink/rtnl/ifinfmsg.py b/pyroute2/netlink/rtnl/ifinfmsg.py index 798ae91a7..ad71bc842 100644 --- a/pyroute2/netlink/rtnl/ifinfmsg.py +++ b/pyroute2/netlink/rtnl/ifinfmsg.py @@ -23,6 +23,8 @@ IFF_DORMANT = 0x20000 # driver signals dormant IFF_ECHO = 0x40000 # echo sent packets +(IFF_NAMES, IFF_VALUES) = map_namespace('IFF', globals()) + IFF_MASK = IFF_UP |\ IFF_DEBUG |\ IFF_NOTRAILERS |\ @@ -40,8 +42,6 @@ IFF_LOWER_UP |\ IFF_DORMANT -(IFF_NAMES, IFF_VALUES) = map_namespace('IFF', globals()) - states = ('UNKNOWN', 'NOTPRESENT', 'DOWN', @@ -131,24 +131,29 @@ class ifinfmsg(nlmsg): ('IFLA_NUM_RX_QUEUES', 'uint32')) @staticmethod - def flags2names(flags): + def flags2names(flags, mask=0xffffffff): ret = [] for flag in IFF_VALUES: - if flag & flags: + if (flag & mask & flags) == flag: ret.append(IFF_VALUES[flag]) return ret @staticmethod def names2flags(flags): ret = 0 + mask = 0 for flag in flags: - ret |= IFF_NAMES[flag] - return ret + if flag[0] == '!': + flag = flag[1:] + else: + ret |= IFF_NAMES[flag] + mask |= IFF_NAMES[flag] + return (ret, mask) def encode(self): # convert flags if isinstance(self['flags'], (set, tuple, list)): - self['flags'] = self.names2flags(self['flags']) + self['flags'], self['change'] = self.names2flags(self['flags']) return nlmsg.encode(self) class wireless(iw_event): diff --git a/tests/test_ipr.py b/tests/test_ipr.py index 761012df6..e59394ec0 100644 --- a/tests/test_ipr.py +++ b/tests/test_ipr.py @@ -279,6 +279,14 @@ def test_route_table_2048(self): pattern='172.16.1.0/24.*172.16.0.1') remove_link('bala') + def test_symbolic_flags(self): + require_user('root') + dev = self.dev[0] + self.ip.link('set', index=dev, flags=['IFF_UP']) + assert self.ip.get_links(dev)[0]['flags'] & 1 + self.ip.link('set', index=dev, flags=['!IFF_UP']) + assert not (self.ip.get_links(dev)[0]['flags'] & 1) + def test_updown_link(self): require_user('root') dev = self.dev[0]