def __setitem__(self, key, value): # ignore blacklisted attributes if key in self.blacklist: return # there must be no "None" values in the request if value is None: return # all the values must be in ascii try: if isinstance(value, unicode): value = value.encode("ascii") except NameError: pass # set up specific keys if key == "kind": self["IFLA_LINKINFO"] = {"attrs": []} linkinfo = self["IFLA_LINKINFO"]["attrs"] linkinfo.append(["IFLA_INFO_KIND", value]) if value in ("vlan", "bond", "tuntap", "veth", "vxlan", "macvlan", "macvtap", "gre"): linkinfo.append(["IFLA_INFO_DATA", {"attrs": []}]) elif key == "vlan_id": nla = ["IFLA_VLAN_ID", value] # FIXME: we need to replace, not add self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "vlan") elif key == "gid": nla = ["IFTUN_UID", value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "tuntap") elif key == "uid": nla = ["IFTUN_UID", value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "tuntap") elif key == "mode": nla = ["IFTUN_MODE", value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "tuntap") nla = ["IFLA_BOND_MODE", value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "bond") elif key == "ifr": nla = ["IFTUN_IFR", value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "tuntap") elif key.startswith("macvtap"): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "macvtap") elif key.startswith("macvlan"): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "macvlan") elif key.startswith("gre"): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "gre") elif key.startswith("vxlan"): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "vxlan") elif key == "peer": nla = ["VETH_INFO_PEER", {"attrs": [["IFLA_IFNAME", value]]}] self.defer_nla(nla, ("IFLA_LINKINFO", "IFLA_INFO_DATA"), lambda x: x.get("kind", None) == "veth") dict.__setitem__(self, key, value) if self.deferred: self.flush_deferred()
def set_specific(self, key, value): # FIXME: vlan hack if self.kind == 'vlan' and key == 'vlan_flags': if isinstance(value, (list, tuple)): if len(value) == 2 and \ all((isinstance(x, int) for x in value)): value = {'flags': value[0], 'mask': value[1]} else: ret = 0 for x in value: ret |= vlan_flags.get(x, 1) value = {'flags': ret, 'mask': ret} elif isinstance(value, int): value = {'flags': value, 'mask': value} elif isinstance(value, basestring): value = vlan_flags.get(value, 1) value = {'flags': value, 'mask': value} elif not isinstance(value, dict): raise ValueError() # the kind is known: lookup the NLA if key in self.specific: self.info_data.append((self.specific[key], value)) return True elif key == 'peer' and self.kind == 'veth': # FIXME: veth hack if isinstance(value, dict): attrs = [] for k, v in value.items(): attrs.append([ifinfmsg.name2nla(k), v]) else: attrs = [['IFLA_IFNAME', value], ] nla = ['VETH_INFO_PEER', {'attrs': attrs}] self.info_data.append(nla) return True elif key == 'mode': # FIXME: ipvlan / tuntap / bond hack if self.kind == 'tuntap': nla = ['IFTUN_MODE', value] else: nla = ['IFLA_%s_MODE' % self.kind.upper(), value] self.info_data.append(nla) return True return False
def set_specific(self, key, value): # the kind is known: lookup the NLA if key in self.specific: self.info_data.append((self.specific[key], value)) return True elif key == 'peer' and self.kind == 'veth': # FIXME: veth hack if isinstance(value, dict): attrs = [] for k, v in value.items(): attrs.append([ifinfmsg.name2nla(k), v]) else: attrs = [ ['IFLA_IFNAME', value], ] nla = ['VETH_INFO_PEER', {'attrs': attrs}] self.info_data.append(nla) return True elif key == 'mode': # FIXME: ipvlan / tuntap / bond hack if self.kind == 'ipvlan': nla = ['IFLA_IPVLAN_MODE', value] elif self.kind == 'tuntap': nla = ['IFTUN_MODE', value] elif self.kind == 'bond': nla = ['IFLA_BOND_MODE', value] self.info_data.append(nla) return True elif key == 'vlan_flags': # FIXME: vlan hack if isinstance(value, (list, tuple)): nla = [ 'IFLA_VLAN_FLAGS', { 'flags': value[0], 'mask': value[1] } ] else: nla = ['IFLA_VLAN_FLAGS', {'flags': value, 'mask': value}] self.info_data.append(nla) return True return False
def __setitem__(self, key, value): # ignore blacklisted attributes if key in self.blacklist: return # there must be no "None" values in the request if value is None: return # all the values must be in ascii try: if isinstance(value, unicode): value = value.encode('ascii') except NameError: pass # set up specific keys if key == 'kind': self['IFLA_LINKINFO'] = {'attrs': []} linkinfo = self['IFLA_LINKINFO']['attrs'] linkinfo.append(['IFLA_INFO_KIND', value]) if value in ('vlan', 'bond', 'tuntap', 'veth', 'vxlan', 'macvlan', 'macvtap', 'gre', 'gretap', 'ipvlan', 'bridge', 'vrf', 'ip6gre', 'ip6gretap'): linkinfo.append(['IFLA_INFO_DATA', {'attrs': []}]) elif key == 'vlan_id': nla = ['IFLA_VLAN_ID', value] # FIXME: we need to replace, not add self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'vlan') elif key == 'gid': nla = ['IFTUN_UID', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'tuntap') elif key == 'uid': nla = ['IFTUN_UID', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'tuntap') elif key == 'mode': nla = ['IFLA_IPVLAN_MODE', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'ipvlan') nla = ['IFTUN_MODE', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'tuntap') nla = ['IFLA_BOND_MODE', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'bond') elif key == 'stp_state': nla = ['IFLA_BRIDGE_STP_STATE', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'bridge') elif key == 'ifr': nla = ['IFTUN_IFR', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'tuntap') elif key.startswith('macvtap_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'macvtap') elif key.startswith('macvlan_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'macvlan') elif key.startswith('gre_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'gre' or x.get('kind', None) == 'gretap') elif key.startswith('ip6gre_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'ip6gre' or x.get('kind', None) == 'ip6gretap') elif key.startswith('vxlan_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'vxlan') elif key.startswith('vrf_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'vrf') elif key.startswith('br_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'bridge') elif key.startswith('bond_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'bond') elif key == 'peer': if isinstance(value, dict): attrs = [] for k, v in value.items(): attrs.append([ifinfmsg.name2nla(k), v]) else: attrs = [['IFLA_IFNAME', value], ] nla = ['VETH_INFO_PEER', {'attrs': attrs}] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'veth') dict.__setitem__(self, key, value) if self.deferred: self.flush_deferred()
def link(self, command, **kwarg): ''' Link operations. * command -- set, add or delete * index -- device index * \*\*kwarg -- keywords, NLA Example:: x = 62 # interface index ip.link("set", index=x, state="down") ip.link("set", index=x, address="00:11:22:33:44:55", name="bala") ip.link("set", index=x, mtu=1000, txqlen=2000) ip.link("set", index=x, state="up") Keywords "state", "flags" and "mask" are reserved. State can be "up" or "down", it is a shortcut:: state="up": flags=1, mask=1 state="down": flags=0, mask=0 For more flags grep IFF in the kernel code, until we write human-readable flag resolver. Other keywords are from ifinfmsg.nla_map, look into the corresponding module. You can use the form "ifname" as well as "IFLA_IFNAME" and so on, so that's equal:: ip.link("set", index=x, mtu=1000) ip.link("set", index=x, IFLA_MTU=1000) You can also delete interface with:: ip.link("delete", index=x) ''' commands = {'set': RTM_SETLINK, # almost all operations 'add': RTM_NEWLINK, # no idea, how to use it :) 'delete': RTM_DELLINK} # remove interface command = commands.get(command, command) msg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL msg = ifinfmsg() # index is required msg['index'] = kwarg.get('index') flags = kwarg.pop('flags', 0) or 0 mask = kwarg.pop('mask', 0) or kwarg.pop('change', 0) or 0 if 'state' in kwarg: mask = 1 # IFF_UP mask if kwarg['state'].lower() == 'up': flags = 1 # 0 (down) or 1 (up) del kwarg['state'] msg['flags'] = flags msg['change'] = mask for key in kwarg: nla = ifinfmsg.name2nla(key) if kwarg[key] is not None: msg['attrs'].append([nla, kwarg[key]]) return self.nlm_request(msg, msg_type=command, msg_flags=msg_flags)
def __setitem__(self, key, value): # ignore blacklisted attributes if key in self.blacklist: return # there must be no "None" values in the request if value is None: return # all the values must be in ascii try: if isinstance(value, unicode): value = value.encode('ascii') except NameError: pass # set up specific keys if key == 'kind': self['IFLA_LINKINFO'] = {'attrs': []} linkinfo = self['IFLA_LINKINFO']['attrs'] linkinfo.append(['IFLA_INFO_KIND', value]) if value in ('vlan', 'bond', 'tuntap', 'veth', 'vxlan', 'macvlan', 'macvtap', 'gre', 'gretap', 'ipvlan', 'bridge', 'vrf', 'ip6gre', 'ip6gretap'): linkinfo.append(['IFLA_INFO_DATA', {'attrs': []}]) elif key == 'vlan_id': nla = ['IFLA_VLAN_ID', value] # FIXME: we need to replace, not add self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'vlan') elif key == 'gid': nla = ['IFTUN_UID', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'tuntap') elif key == 'uid': nla = ['IFTUN_UID', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'tuntap') elif key == 'mode': nla = ['IFLA_IPVLAN_MODE', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'ipvlan') nla = ['IFTUN_MODE', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'tuntap') nla = ['IFLA_BOND_MODE', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'bond') elif key == 'stp_state': nla = ['IFLA_BRIDGE_STP_STATE', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'bridge') elif key == 'ifr': nla = ['IFTUN_IFR', value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'tuntap') elif key.startswith('macvtap_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'macvtap') elif key.startswith('macvlan_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'macvlan') elif key.startswith('gre_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla( nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get( 'kind', None) == 'gre' or x.get('kind', None) == 'gretap') elif key.startswith('ip6gre_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla( nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'ip6gre' or x.get( 'kind', None) == 'ip6gretap') elif key.startswith('vxlan_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'vxlan') elif key.startswith('vrf_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'vrf') elif key.startswith('br_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'bridge') elif key.startswith('bond_'): nla = [ifinfmsg.name2nla(key), value] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'bond') elif key == 'peer': if isinstance(value, dict): attrs = [] for k, v in value.items(): attrs.append([ifinfmsg.name2nla(k), v]) else: attrs = [ ['IFLA_IFNAME', value], ] nla = ['VETH_INFO_PEER', {'attrs': attrs}] self.defer_nla(nla, ('IFLA_LINKINFO', 'IFLA_INFO_DATA'), lambda x: x.get('kind', None) == 'veth') dict.__setitem__(self, key, value) if self.deferred: self.flush_deferred()
def link(self, command, **kwarg): ''' Link operations. * command -- set, add or delete * index -- device index * \*\*kwarg -- keywords, NLA Example:: x = 62 # interface index ip.link("set", index=x, state="down") ip.link("set", index=x, address="00:11:22:33:44:55", name="bala") ip.link("set", index=x, mtu=1000, txqlen=2000) ip.link("set", index=x, state="up") Keywords "state", "flags" and "mask" are reserved. State can be "up" or "down", it is a shortcut:: state="up": flags=1, mask=1 state="down": flags=0, mask=0 For more flags grep IFF in the kernel code, until we write human-readable flag resolver. Other keywords are from ifinfmsg.nla_map, look into the corresponding module. You can use the form "ifname" as well as "IFLA_IFNAME" and so on, so that's equal:: ip.link("set", index=x, mtu=1000) ip.link("set", index=x, IFLA_MTU=1000) You can also delete interface with:: ip.link("delete", index=x) ''' commands = { 'set': RTM_SETLINK, # almost all operations 'add': RTM_NEWLINK, # no idea, how to use it :) 'delete': RTM_DELLINK } # remove interface command = commands.get(command, command) msg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL msg = ifinfmsg() # index is required msg['index'] = kwarg.get('index') flags = kwarg.pop('flags', 0) or 0 mask = kwarg.pop('mask', 0) or kwarg.pop('change', 0) or 0 if 'state' in kwarg: mask = 1 # IFF_UP mask if kwarg['state'].lower() == 'up': flags = 1 # 0 (down) or 1 (up) del kwarg['state'] msg['flags'] = flags msg['change'] = mask for key in kwarg: nla = ifinfmsg.name2nla(key) if kwarg[key] is not None: msg['attrs'].append([nla, kwarg[key]]) return self.nlm_request(msg, msg_type=command, msg_flags=msg_flags)