X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ifupdown2%2Fifupdownaddons%2FLinkUtils.py;h=d05c0103535e2fdd61b9de72712498d8e0493b3d;hb=df106c519e61fb6989f7a7c722ae2ea85607c2d7;hp=53eefd94909a55432282cd0371c02e5e105a1824;hpb=77054f7f5f0dbd5852a85386406b9d846a44467d;p=mirror_ifupdown2.git diff --git a/ifupdown2/ifupdownaddons/LinkUtils.py b/ifupdown2/ifupdownaddons/LinkUtils.py index 53eefd9..d05c010 100644 --- a/ifupdown2/ifupdownaddons/LinkUtils.py +++ b/ifupdown2/ifupdownaddons/LinkUtils.py @@ -10,6 +10,7 @@ import re import glob import shlex import signal +import socket import subprocess from ipaddr import IPNetwork, IPv6Network @@ -544,6 +545,8 @@ class LinkUtils(utilsBase): tunattrs['ttl'] = citems[j + 1] elif citems[j] == 'dev': tunattrs['physdev'] = citems[j + 1] + elif citems[j] in ['vti', 'vti6', 'ip6gre', 'ipip6', 'ip6ip6']: + tunattrs['mode'] = citems[j] linkattrs['linkinfo'] = tunattrs break elif citems[i] == 'link/ppp': @@ -1112,7 +1115,7 @@ class LinkUtils(utilsBase): return self._cache_get('link', [ifacename, 'ifflag'], refresh=True) @staticmethod - def route_add_gateway(ifacename, gateway, vrf=None, metric=None): + def route_add_gateway(ifacename, gateway, vrf=None, metric=None, onlink=True): if not gateway: return if not vrf: @@ -1125,6 +1128,10 @@ class LinkUtils(utilsBase): if metric: cmd += 'metric %s' % metric cmd += ' dev %s' % ifacename + + if onlink: + cmd += " onlink" + utils.exec_command(cmd) @staticmethod @@ -1265,13 +1272,16 @@ class LinkUtils(utilsBase): if '6' in mode: cmd = ' -6 ' - cmd += 'tunnel add' - cmd += ' %s mode %s' %(tunnelname, mode) + if mode in ['gretap']: + cmd += 'link add %s type %s' % (tunnelname, mode) + else: + cmd += 'tunnel add %s mode %s' % (tunnelname, mode) + if attrs: for k, v in attrs.iteritems(): - cmd += ' %s' %k + cmd += ' %s' % k if v: - cmd += ' %s' %v + cmd += ' %s' % v if self.ipbatch and not self.ipbatch_pause: self.add_to_batch(cmd) else: @@ -1293,7 +1303,6 @@ class LinkUtils(utilsBase): self.add_to_batch(cmd) else: utils.exec_command('ip %s' % cmd) - self._cache_update([tunnelname], {}) def link_create_vxlan(self, name, vxlanid, localtunnelip=None, @@ -1345,6 +1354,10 @@ class LinkUtils(utilsBase): return True return os.path.exists('/sys/class/net/%s' % ifacename) + @staticmethod + def link_exists_nodryrun(ifname): + return os.path.exists('/sys/class/net/%s' % ifname) + def link_get_ifindex(self, ifacename): if ifupdownflags.flags.DRYRUN: return True @@ -1538,11 +1551,40 @@ class LinkUtils(utilsBase): if not bridgeout: return brvlaninfo try: - vlan_json_dict = json.loads(bridgeout, encoding="utf-8") + vlan_json = json.loads(bridgeout, encoding="utf-8") except Exception, e: self.logger.info('json loads failed with (%s)' % str(e)) return {} - return vlan_json_dict + + try: + if isinstance(vlan_json, list): + # newer iproute2 version changed the bridge vlan show output + # ifupdown2 relies on the previous format, we have the convert + # data into old format + bridge_port_vids = dict() + + for intf in vlan_json: + bridge_port_vids[intf["ifname"]] = intf["vlans"] + + return bridge_port_vids + else: + # older iproute2 version have different ways to dump vlans + # ifupdown2 prefers the following syntax: + # { + # "vx-1002": [{ + # "vlan": 1002, + # "flags": ["PVID", "Egress Untagged"] + # } + # ], + # "vx-1004": [{ + # "vlan": 1004, + # "flags": ["PVID", "Egress Untagged"] + # }] + # } + return vlan_json + except Exception as e: + self.logger.debug("bridge vlan show: Unknown json output: %s" % str(e)) + return vlan_json @staticmethod def get_bridge_vlan_nojson(): @@ -2590,6 +2632,31 @@ class LinkUtils(utilsBase): return mcqv4src.get(vlan) return mcqv4src + def bridge_get_mcqv4src_sysfs(self, bridge, vlan=None): + if not LinkUtils.bridge_utils_is_installed: + return {} + if not self.supported_command['showmcqv4src']: + return {} + if ifupdownflags.flags.PERFMODE: + return {} + mcqv4src = {} + try: + filename = '/sys/class/net/%s/bridge/multicast_v4_queriers' % bridge + if os.path.exists(filename): + for line in self.read_file(filename) or []: + vlan_id, ip = line.split('=') + mcqv4src[vlan_id] = ip.strip() + except Exception as e: + s = str(e).lower() + msg = ('%s showmcqv4src: skipping unsupported command' + % utils.brctl_cmd) + self.logger.info(msg) + self.supported_command['showmcqv4src'] = False + return {} + if vlan: + return mcqv4src.get(vlan) + return mcqv4src + @staticmethod def bridge_set_mclmi(bridge, mclmi): if not LinkUtils.bridge_utils_is_installed: @@ -2634,8 +2701,52 @@ class LinkUtils(utilsBase): except: return [] - def ipv6_addrgen(self, ifname, addrgen): - cmd = 'link set dev %s addrgenmode %s' % (ifname, 'eui64' if addrgen else 'none') + def reset_addr_cache(self, ifname): + try: + linkCache.links[ifname]['addrs'] = {} + self.logger.debug('%s: reset address cache' % ifname) + except: + pass + + def get_ipv6_addrgen_mode(self, ifname): + try: + return self._cache_get('link', [ifname, 'af_spec', socket.AF_INET6])[Link.IFLA_INET6_ADDR_GEN_MODE] + except: + # default to 0 (eui64) + return 0 + + def ipv6_addrgen(self, ifname, addrgen, link_created): + try: + # IFLA_INET6_ADDR_GEN_MODE values: + # 0 = eui64 + # 1 = none + if self._link_cache_get([ifname, 'af_spec', socket.AF_INET6])[Link.IFLA_INET6_ADDR_GEN_MODE] == addrgen: + self.logger.debug('%s: ipv6 addrgen already %s' % (ifname, 'off' if addrgen else 'on')) + return + + disabled_ipv6 = self.read_file_oneline('/proc/sys/net/ipv6/conf/%s/disable_ipv6' % ifname) + if not disabled_ipv6 or int(disabled_ipv6) == 1: + self.logger.info('%s: cannot set addrgen: ipv6 is disabled on this device' % ifname) + return + + if int(self._link_cache_get([ifname, 'mtu'])) < 1280: + self.logger.info('%s: ipv6 addrgen is disabled on device with MTU ' + 'lower than 1280: cannot set addrgen %s' % (ifname, 'off' if addrgen else 'on')) + return + except (KeyError, TypeError): + self.logger.debug('%s: ipv6 addrgen probably not supported or disabled on this device' % ifname) + return + except Exception: + pass + + if not link_created: + # When setting addrgenmode it is necessary to flap the macvlan + # device. After flapping the device we also need to re-add all + # the user configuration. The best way to add the user config + # is to flush our internal address cache + self.reset_addr_cache(ifname) + + cmd = 'link set dev %s addrgenmode %s' % (ifname, 'none' if addrgen else 'eui64') is_link_up = self.is_link_up(ifname)