Commit 9cb1b14c authored by Léo-Paul Géneau's avatar Léo-Paul Géneau 👾

Fix: check mrule existence before deletion

Avoid message: "RTNETLINK answers: No such file or directory"
parent 56668000
...@@ -3,9 +3,11 @@ import socket ...@@ -3,9 +3,11 @@ import socket
import struct import struct
import ipaddress import ipaddress
import traceback import traceback
from socket import if_nametoindex from socket import if_nametoindex, AF_INET, AF_INET6
from threading import RLock, Thread from threading import RLock, Thread
from abc import abstractmethod, ABCMeta from abc import abstractmethod, ABCMeta
from functools import partial
from pyroute2 import IPRoute
from pimdm import UnicastRouting, Main from pimdm import UnicastRouting, Main
from pimdm.rwlock.RWLock import RWLockWrite from pimdm.rwlock.RWLock import RWLockWrite
...@@ -23,6 +25,10 @@ class Kernel(metaclass=ABCMeta): ...@@ -23,6 +25,10 @@ class Kernel(metaclass=ABCMeta):
# Max Number of Virtual Interfaces # Max Number of Virtual Interfaces
MAXVIFS = 32 MAXVIFS = 32
# Rtnetlink flags
RTNL_FAMILY_IPMR = 128
RTNL_FAMILY_IP6MR = RTNL_FAMILY_IPMR + 1
def __init__(self, kernel_socket): def __init__(self, kernel_socket):
# Kernel is running # Kernel is running
self.running = True self.running = True
...@@ -50,6 +56,12 @@ class Kernel(metaclass=ABCMeta): ...@@ -50,6 +56,12 @@ class Kernel(metaclass=ABCMeta):
self.interface_logger = Main.logger.getChild('KernelInterface') self.interface_logger = Main.logger.getChild('KernelInterface')
self.tree_logger = Main.logger.getChild('KernelTree') self.tree_logger = Main.logger.getChild('KernelTree')
# netlink interfacing
self.ipr = IPRoute()
# unformatted mrule command
self.to_format_mrule = "ip {ip_version} mrule {cmd} {selector} {interface_name} lookup {table_id}".format
# receive signals from kernel with a background thread # receive signals from kernel with a background thread
handler_thread = Thread(target=self.handler) handler_thread = Thread(target=self.handler)
handler_thread.daemon = True handler_thread.daemon = True
...@@ -258,6 +270,32 @@ class Kernel(metaclass=ABCMeta): ...@@ -258,6 +270,32 @@ class Kernel(metaclass=ABCMeta):
for entry in groups_dict.values(): for entry in groups_dict.values():
entry.new_or_reset_neighbor(vif_index, neighbor_ip) entry.new_or_reset_neighbor(vif_index, neighbor_ip)
def ex_partial_mrule(self, partial_mrule: partial, ip_family: int):
os.system(partial_mrule(ip_version='-6' if ip_family == AF_INET6 else ''))
def add_mrule(self, interface_name: str, table_id: int, ip_family=AF_INET):
partial_mrule = partial(self.to_format_mrule, cmd='add', interface_name=interface_name, table_id=table_id)
self.ex_partial_mrule(partial(partial_mrule, selector='iif'), ip_family)
self.ex_partial_mrule(partial(partial_mrule, selector='oif'), ip_family)
def delete_mrule(self, interface_name: str, table_id: int, ip_family=AF_INET):
partial_mrule = partial(self.to_format_mrule, cmd='del', interface_name=interface_name, table_id=table_id)
for rule in self.ipr.get_rules(
family=self.RTNL_FAMILY_IP6MR if ip_family == AF_INET6 else self.RTNL_FAMILY_IPMR,
table=table_id
):
for k,v in rule['attrs']:
if k == 'FRA_IIFNAME':
if v == interface_name:
self.ex_partial_mrule(partial(partial_mrule, selector='iif'), ip_family)
else:
break
elif k == 'FRA_OIFNAME':
if v == interface_name:
self.ex_partial_mrule(partial(partial_mrule, selector='oif'), ip_family)
else:
break
class Kernel4(Kernel): class Kernel4(Kernel):
# MRT # MRT
...@@ -329,11 +367,9 @@ class Kernel4(Kernel): ...@@ -329,11 +367,9 @@ class Kernel4(Kernel):
struct_mrt_add_vif = struct.pack("HBBI 4s 4s", index, flags, 1, 0, ip_interface, struct_mrt_add_vif = struct.pack("HBBI 4s 4s", index, flags, 1, 0, ip_interface,
socket.inet_aton("0.0.0.0")) socket.inet_aton("0.0.0.0"))
os.system("ip mrule del iif {}".format(interface_name)) self.delete_mrule(interface_name, 0)
os.system("ip mrule del oif {}".format(interface_name))
if pim_globals.MULTICAST_TABLE_ID != 0: if pim_globals.MULTICAST_TABLE_ID != 0:
os.system("ip mrule add iif {} lookup {}".format(interface_name, pim_globals.MULTICAST_TABLE_ID)) self.add_mrule(interface_name, pim_globals.MULTICAST_TABLE_ID)
os.system("ip mrule add oif {} lookup {}".format(interface_name, pim_globals.MULTICAST_TABLE_ID))
with self.rwlock.genWlock(): with self.rwlock.genWlock():
self.socket.setsockopt(socket.IPPROTO_IP, self.MRT_ADD_VIF, struct_mrt_add_vif) self.socket.setsockopt(socket.IPPROTO_IP, self.MRT_ADD_VIF, struct_mrt_add_vif)
self.vif_index_to_name_dic[index] = interface_name self.vif_index_to_name_dic[index] = interface_name
...@@ -350,8 +386,7 @@ class Kernel4(Kernel): ...@@ -350,8 +386,7 @@ class Kernel4(Kernel):
index = self.vif_name_to_index_dic.pop(interface_name) index = self.vif_name_to_index_dic.pop(interface_name)
struct_vifctl = struct.pack("HBBI 4s 4s", index, 0, 0, 0, socket.inet_aton("0.0.0.0"), socket.inet_aton("0.0.0.0")) struct_vifctl = struct.pack("HBBI 4s 4s", index, 0, 0, 0, socket.inet_aton("0.0.0.0"), socket.inet_aton("0.0.0.0"))
os.system("ip mrule del iif {}".format(interface_name)) self.delete_mrule(interface_name, 0)
os.system("ip mrule del oif {}".format(interface_name))
self.socket.setsockopt(socket.IPPROTO_IP, self.MRT_DEL_VIF, struct_vifctl) self.socket.setsockopt(socket.IPPROTO_IP, self.MRT_DEL_VIF, struct_vifctl)
self.stop_forwarding(index) self.stop_forwarding(index)
...@@ -563,11 +598,9 @@ class Kernel6(Kernel): ...@@ -563,11 +598,9 @@ class Kernel6(Kernel):
physical_if_index = if_nametoindex(interface_name) physical_if_index = if_nametoindex(interface_name)
struct_mrt_add_vif = struct.pack("HBBHI", index, flags, 1, physical_if_index, 0) struct_mrt_add_vif = struct.pack("HBBHI", index, flags, 1, physical_if_index, 0)
os.system("ip -6 mrule del iif {}".format(interface_name)) self.delete_mrule(interface_name, 0, AF_INET6)
os.system("ip -6 mrule del oif {}".format(interface_name))
if pim_globals.MULTICAST_TABLE_ID != 0: if pim_globals.MULTICAST_TABLE_ID != 0:
os.system("ip -6 mrule add iif {} lookup {}".format(interface_name, pim_globals.MULTICAST_TABLE_ID)) self.add_mrule(interface_name, pim_globals.MULTICAST_TABLE_ID, AF_INET6)
os.system("ip -6 mrule add oif {} lookup {}".format(interface_name, pim_globals.MULTICAST_TABLE_ID))
with self.rwlock.genWlock(): with self.rwlock.genWlock():
self.socket.setsockopt(socket.IPPROTO_IPV6, self.MRT6_ADD_MIF, struct_mrt_add_vif) self.socket.setsockopt(socket.IPPROTO_IPV6, self.MRT6_ADD_MIF, struct_mrt_add_vif)
...@@ -588,8 +621,7 @@ class Kernel6(Kernel): ...@@ -588,8 +621,7 @@ class Kernel6(Kernel):
struct_vifctl = struct.pack("HBBHI", mif_index, 0, 0, physical_if_index, 0) struct_vifctl = struct.pack("HBBHI", mif_index, 0, 0, physical_if_index, 0)
self.socket.setsockopt(socket.IPPROTO_IPV6, self.MRT6_DEL_MIF, struct_vifctl) self.socket.setsockopt(socket.IPPROTO_IPV6, self.MRT6_DEL_MIF, struct_vifctl)
os.system("ip -6 mrule del iif {}".format(interface_name)) self.delete_mrule(interface_name, 0)
os.system("ip -6 mrule del oif {}".format(interface_name))
self.stop_forwarding(mif_index) self.stop_forwarding(mif_index)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment