Used: $ flynt -a -tc . vppcfg Execution time: 0.216s Files checked: 24 Files modified: 13 Character count reduction: 632 (0.36%) Per expression type: Old style (`%`) expressions attempted: 209/211 (99.1%) No `.format(...)` calls attempted. No concatenations attempted. F-string expressions created: 205 Ran an integration test before and after. No diffs.
		
			
				
	
	
		
			102 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#
 | 
						|
# Copyright (c) 2022 Pim van Pelt
 | 
						|
#
 | 
						|
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
# you may not use this file except in compliance with the License.
 | 
						|
# You may obtain a copy of the License at:
 | 
						|
#     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
# Unless required by applicable law or agreed to in writing, software
 | 
						|
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
# See the License for the specific language governing permissions and
 | 
						|
# limitations under the License.
 | 
						|
#
 | 
						|
import logging
 | 
						|
import config.mac as mac
 | 
						|
 | 
						|
def get_taps(yaml):
 | 
						|
    """ Return a list of all taps. """
 | 
						|
    ret = []
 | 
						|
    if 'taps' in yaml:
 | 
						|
        for ifname, iface in yaml['taps'].items():
 | 
						|
            ret.append(ifname)
 | 
						|
    return ret
 | 
						|
 | 
						|
 | 
						|
def get_by_name(yaml, ifname):
 | 
						|
    """ Return the tap by name, if it exists. Return None otherwise. """
 | 
						|
    try:
 | 
						|
        if ifname in yaml['taps']:
 | 
						|
            return ifname, yaml['taps'][ifname]
 | 
						|
    except:
 | 
						|
        pass
 | 
						|
    return None, None
 | 
						|
 | 
						|
 | 
						|
def is_tap(yaml, ifname):
 | 
						|
    """ Returns True if the interface name is an existing tap in the config.
 | 
						|
        The TAP has to be explicitly named in the configuration, and notably
 | 
						|
        a TAP belonging to a Linux Control Plane (LCP) will return False.
 | 
						|
    """
 | 
						|
    ifname, iface = get_by_name(yaml, ifname)
 | 
						|
    return not iface == None
 | 
						|
 | 
						|
 | 
						|
def is_host_name_unique(yaml, hostname):
 | 
						|
    """ Returns True if there is at most one occurence of the given ifname amonst all host-names of TAPs. """
 | 
						|
    if not 'taps' in yaml:
 | 
						|
        return True
 | 
						|
    host_names = []
 | 
						|
    for tap_ifname, tap_iface in yaml['taps'].items():
 | 
						|
        host_names.append(tap_iface['host']['name'])
 | 
						|
    return host_names.count(hostname) < 2
 | 
						|
 | 
						|
 | 
						|
def validate_taps(yaml):
 | 
						|
    result = True
 | 
						|
    msgs = []
 | 
						|
    logger = logging.getLogger('vppcfg.config')
 | 
						|
    logger.addHandler(logging.NullHandler())
 | 
						|
 | 
						|
    if not 'taps' in yaml:
 | 
						|
        return result, msgs
 | 
						|
 | 
						|
    for ifname, iface in yaml['taps'].items():
 | 
						|
        logger.debug(f"tap {iface}")
 | 
						|
        instance = int(ifname[3:])
 | 
						|
 | 
						|
        ## NOTE(pim): 1024 is not off-by-one, tap1024 is precisely the highest permissible id
 | 
						|
        if instance > 1024:
 | 
						|
            msgs.append(f"tap {ifname} has instance {int(instance)} which is too large")
 | 
						|
            result = False
 | 
						|
 | 
						|
        if not is_host_name_unique(yaml, iface['host']['name']):
 | 
						|
            msgs.append(f"tap {ifname} does not have a unique host name {iface['host']['name']}")
 | 
						|
            result = False
 | 
						|
 | 
						|
        if 'rx-ring-size' in iface:
 | 
						|
            n = iface['rx-ring-size']
 | 
						|
            if n & (n-1) != 0:
 | 
						|
                msgs.append(f"tap {ifname} rx-ring-size must be a power of two")
 | 
						|
                result = False
 | 
						|
 | 
						|
        if 'tx-ring-size' in iface:
 | 
						|
            n = iface['tx-ring-size']
 | 
						|
            if n & (n-1) != 0:
 | 
						|
                msgs.append(f"tap {ifname} tx-ring-size must be a power of two")
 | 
						|
                result = False
 | 
						|
 | 
						|
        if 'namespace-create' in iface['host'] and iface['host']['namespace-create'] and not 'namespace' in iface['host']:
 | 
						|
            msgs.append(f"tap {ifname} namespace-create can only be set if namespace is set")
 | 
						|
            result = False
 | 
						|
 | 
						|
        if 'bridge-create' in iface['host'] and iface['host']['bridge-create'] and not 'bridge' in iface['host']:
 | 
						|
            msgs.append(f"tap {ifname} bridge-create can only be set if bridge is set")
 | 
						|
            result = False
 | 
						|
 | 
						|
        if 'mac' in iface['host'] and mac.is_multicast(iface['host']['mac']):
 | 
						|
            msgs.append(f"tap {ifname} host MAC address {iface['host']['mac']} cannot be multicast")
 | 
						|
            result = False
 | 
						|
 | 
						|
    return result, msgs
 |