From ca7c063666c038d104082542f04ead6062e79246 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sun, 25 Jun 2023 20:09:31 +0200 Subject: bcast-relay: T5313: verify() relay interfaces have IPv4 address configured --- python/vyos/validate.py | 20 +++++++++++++++++++- src/conf_mode/bcast_relay.py | 16 ++++++++-------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/python/vyos/validate.py b/python/vyos/validate.py index d18785aaf..e5d8c6043 100644 --- a/python/vyos/validate.py +++ b/python/vyos/validate.py @@ -98,7 +98,7 @@ def is_intf_addr_assigned(intf, address) -> bool: return False def is_addr_assigned(ip_address, vrf=None) -> bool: - """ Verify if the given IPv4/IPv6 address is assigned to any interfac """ + """ Verify if the given IPv4/IPv6 address is assigned to any interface """ from netifaces import interfaces from vyos.util import get_interface_config from vyos.util import dict_search @@ -115,6 +115,24 @@ def is_addr_assigned(ip_address, vrf=None) -> bool: return False +def is_afi_configured(interface, afi): + """ Check if given address family is configured, or in other words - an IP + address is assigned to the interface. """ + from netifaces import ifaddresses + from netifaces import AF_INET + from netifaces import AF_INET6 + + if afi not in [AF_INET, AF_INET6]: + raise ValueError('Address family must be in [AF_INET, AF_INET6]') + + try: + addresses = ifaddresses(interface) + except ValueError as e: + print(e) + return False + + return afi in addresses + def is_loopback_addr(addr): """ Check if supplied IPv4/IPv6 address is a loopback address """ from ipaddress import ip_address diff --git a/src/conf_mode/bcast_relay.py b/src/conf_mode/bcast_relay.py index 39a2971ce..459e4cdd4 100755 --- a/src/conf_mode/bcast_relay.py +++ b/src/conf_mode/bcast_relay.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2017-2022 VyOS maintainers and contributors +# Copyright (C) 2017-2023 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -17,12 +17,14 @@ import os from glob import glob -from netifaces import interfaces +from netifaces import AF_INET from sys import exit from vyos.config import Config -from vyos.util import call +from vyos.configverify import verify_interface_exists from vyos.template import render +from vyos.util import call +from vyos.validate import is_afi_configured from vyos import ConfigError from vyos import airbag airbag.enable() @@ -52,16 +54,14 @@ def verify(relay): if 'port' not in config: raise ConfigError(f'Port number mandatory for udp broadcast relay "{instance}"') - # if only oone interface is given it's a string -> move to list - if isinstance(config.get('interface', []), str): - config['interface'] = [ config['interface'] ] # Relaying data without two interface is kinda senseless ... if len(config.get('interface', [])) < 2: raise ConfigError('At least two interfaces are required for udp broadcast relay "{instance}"') for interface in config.get('interface', []): - if interface not in interfaces(): - raise ConfigError('Interface "{interface}" does not exist!') + verify_interface_exists(interface) + if not is_afi_configured(interface, AF_INET): + raise ConfigError(f'Interface "{interface}" has no IPv4 address configured!') return None -- cgit v1.2.3