From 00d8bd29dd241184fe3ff8f256f2c31eb5535f8d Mon Sep 17 00:00:00 2001 From: Olivier Le Thanh Duong Date: Mon, 16 Dec 2024 11:32:07 +0100 Subject: [PATCH 1/3] Fix error Deleting network interface JIRA: ALEPH-115 **Problem**: When reusing an existing stale network interface, the following error would occasionally occur: ``` Unknown exception while deleting address 2a01:4f8:171:787:1:63fa:f8b5:db10/124 to interface vmtap... ``` See details in Sentry: [https://alephim.sentry.io/issues/5993120643/?project=4506303231819776](https://alephim.sentry.io/issues/5993120643/?project=4506303231819776) **Analysis**: This error occurred during the process of cleaning up an old interface (that was not deleted after usage for various possible reasons). The code was attempting to delete the IP addresses associated with this interface (as calculated in the code). However, when these IP addresses did not exist, an error was raised. **Solution**: Our initial approach was to use the `IPRoute` module to list the IP addresses associated with the network interface and then delete them instead of calculating their names in the Python code as is done presently. After experimentation, we determined that deleting the interface directly also removes the associated IP addresses. Therefore, it is unnecessary to delete them manually, which simplifies the code. **To test**: Create and stop Program Create network interface ```bash sudo ip tuntap add dev vmtap4 mode tap ``` and attach ip to them ```bash sudo ip addr add 1.1.1.1/30 dev vmtap4 ``` Try different combinaison and validate that everything still work correctly To check the networks interfaces use the following command to list them ```bash sudo ip link ``` and to list the ip address use: ``` sudo ip addr ``` --- src/aleph/vm/network/interfaces.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/aleph/vm/network/interfaces.py b/src/aleph/vm/network/interfaces.py index f401b507f..3d093d542 100644 --- a/src/aleph/vm/network/interfaces.py +++ b/src/aleph/vm/network/interfaces.py @@ -170,6 +170,4 @@ async def delete(self) -> None: if self.ndp_proxy: await self.ndp_proxy.delete_range(self.device_name) with IPRoute() as ipr: - delete_ip_address(ipr, self.device_name, self.host_ip) - delete_ip_address(ipr, self.device_name, self.host_ipv6) delete_tap_interface(ipr, self.device_name) From 67101e1d1ff7afa48aa6b71a8679cbdd50de0e19 Mon Sep 17 00:00:00 2001 From: Olivier Le Thanh Duong Date: Mon, 16 Dec 2024 11:58:30 +0100 Subject: [PATCH 2/3] Remove unused delete_ip_address() mainly to improve code coverage --- src/aleph/vm/network/interfaces.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/aleph/vm/network/interfaces.py b/src/aleph/vm/network/interfaces.py index 3d093d542..5f0120725 100644 --- a/src/aleph/vm/network/interfaces.py +++ b/src/aleph/vm/network/interfaces.py @@ -61,20 +61,6 @@ def add_ip_address(ipr: IPRoute, device_name: str, ip: IPv4Interface | IPv6Inter logger.error(f"Unknown exception while adding address {ip} to interface {device_name}: {e}") -def delete_ip_address(ipr: IPRoute, device_name: str, ip: IPv4Interface | IPv6Interface): - """Delete an IP address to the given interface.""" - interface_index: list[int] = ipr.link_lookup(ifname=device_name) - if not interface_index: - msg = f"Interface {device_name} does not exist, can't delete address {ip} to it." - raise MissingInterfaceError(msg) - try: - ipr.addr("del", index=interface_index[0], address=str(ip.ip), mask=ip.network.prefixlen) - except NetlinkError as e: - logger.exception(f"Unknown exception while deleting address {ip} to interface {device_name}: {e}") - except OSError as e: - logger.exception(f"Unknown exception while deleting address {ip} to interface {device_name}: {e}") - - def set_link_up(ipr: IPRoute, device_name: str): """Set the given interface up.""" interface_index: list[int] = ipr.link_lookup(ifname=device_name) From 2540724b6e21ff93d1fa1ba5bfd9fc839f354ff9 Mon Sep 17 00:00:00 2001 From: Olivier Le Thanh Duong Date: Mon, 16 Dec 2024 13:56:26 +0100 Subject: [PATCH 3/3] List all ip on interface and delete them --- src/aleph/vm/network/interfaces.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/aleph/vm/network/interfaces.py b/src/aleph/vm/network/interfaces.py index 5f0120725..8c40f5eaa 100644 --- a/src/aleph/vm/network/interfaces.py +++ b/src/aleph/vm/network/interfaces.py @@ -61,6 +61,20 @@ def add_ip_address(ipr: IPRoute, device_name: str, ip: IPv4Interface | IPv6Inter logger.error(f"Unknown exception while adding address {ip} to interface {device_name}: {e}") +def delete_ip_address(ipr: IPRoute, device_name: str, ip: str, mask: int): + """Delete an IP address to the given interface.""" + interface_index: list[int] = ipr.link_lookup(ifname=device_name) + if not interface_index: + msg = f"Interface {device_name} does not exist, can't delete address {ip} to it." + raise MissingInterfaceError(msg) + try: + ipr.addr("del", index=interface_index[0], address=ip, mask=mask) + except NetlinkError as e: + logger.exception(f"Unknown exception while deleting address {ip}/{mask} to interface {device_name}: {e}") + except OSError as e: + logger.exception(f"Unknown exception while deleting address {ip}/{mask} to interface {device_name}: {e}") + + def set_link_up(ipr: IPRoute, device_name: str): """Set the given interface up.""" interface_index: list[int] = ipr.link_lookup(ifname=device_name) @@ -156,4 +170,11 @@ async def delete(self) -> None: if self.ndp_proxy: await self.ndp_proxy.delete_range(self.device_name) with IPRoute() as ipr: + interface_index: list[int] = ipr.link_lookup(ifname=self.device_name) + for addr in ipr.get_addr(index=interface_index): + # The order of attributes in the attrs field comes from the Netlink protocol + attrs = dict(addr["attrs"]) + ip_addr: str = attrs["IFA_ADDRESS"] + mask: int = addr["prefixlen"] + delete_ip_address(ipr, self.device_name, ip_addr, mask) delete_tap_interface(ipr, self.device_name)