Commit 66b92c8d authored by Pedro Oliveira's avatar Pedro Oliveira

fix loggers (using LoggerAdapter) & added join_prune_logger in...

fix loggers (using LoggerAdapter) & added join_prune_logger in Downstream/Upstream prune state machine & added originator_logger & fix downstream/upstream state machines
parent 5557988b
...@@ -15,7 +15,6 @@ class InterfaceIGMP(Interface): ...@@ -15,7 +15,6 @@ class InterfaceIGMP(Interface):
ETH_P_IP = 0x0800 # Internet Protocol packet ETH_P_IP = 0x0800 # Internet Protocol packet
SO_ATTACH_FILTER = 26 SO_ATTACH_FILTER = 26
# TODO filtro nao esta a funcionar bem no netkit
FILTER_IGMP = [ FILTER_IGMP = [
struct.pack('HBBI', 0x28, 0, 0, 0x0000000c), struct.pack('HBBI', 0x28, 0, 0, 0x0000000c),
struct.pack('HBBI', 0x15, 0, 3, 0x00000800), struct.pack('HBBI', 0x15, 0, 3, 0x00000800),
...@@ -36,15 +35,7 @@ class InterfaceIGMP(Interface): ...@@ -36,15 +35,7 @@ class InterfaceIGMP(Interface):
rcv_s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(InterfaceIGMP.ETH_P_IP)) rcv_s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(InterfaceIGMP.ETH_P_IP))
# receive only IGMP packets by setting a BPF filter # receive only IGMP packets by setting a BPF filter
# TODO filtro nao esta a funcionar bem no netkit bpf_filter = b''.join(InterfaceIGMP.FILTER_IGMP)
cmd = "tcpdump -ddd \"ip proto 2\""
result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
bpf_filter = b''
tmp = result.stdout.read().splitlines()
for line in tmp[1:]:
bpf_filter += struct.pack("HBBI", *tuple(map(int, line.split(b' '))))
b = create_string_buffer(bpf_filter) b = create_string_buffer(bpf_filter)
mem_addr_of_filters = addressof(b) mem_addr_of_filters = addressof(b)
fprog = struct.pack('HL', len(InterfaceIGMP.FILTER_IGMP), mem_addr_of_filters) fprog = struct.pack('HL', len(InterfaceIGMP.FILTER_IGMP), mem_addr_of_filters)
...@@ -74,8 +65,7 @@ class InterfaceIGMP(Interface): ...@@ -74,8 +65,7 @@ class InterfaceIGMP(Interface):
packet = ReceivedPacket(raw_bytes, self) packet = ReceivedPacket(raw_bytes, self)
ip_src = packet.ip_header.ip_src ip_src = packet.ip_header.ip_src
if not (ip_src == "0.0.0.0" or IPv4Address(ip_src).is_multicast): if not (ip_src == "0.0.0.0" or IPv4Address(ip_src).is_multicast):
self.PKT_FUNCTIONS[packet.payload.get_igmp_type()](self, packet) self.PKT_FUNCTIONS.get(packet.payload.get_igmp_type(), InterfaceIGMP.receive_unknown_type)(self, packet)
########################################### ###########################################
# Recv packets # Recv packets
...@@ -104,6 +94,9 @@ class InterfaceIGMP(Interface): ...@@ -104,6 +94,9 @@ class InterfaceIGMP(Interface):
if ip_dst == igmp_group or (ip_dst == "224.0.0.1" and igmp_group == "0.0.0.0"): if ip_dst == igmp_group or (ip_dst == "224.0.0.1" and igmp_group == "0.0.0.0"):
self.interface_state.receive_query(packet) self.interface_state.receive_query(packet)
def receive_unknown_type(self, packet):
return
PKT_FUNCTIONS = { PKT_FUNCTIONS = {
Version_1_Membership_Report: receive_version_1_membership_report, Version_1_Membership_Report: receive_version_1_membership_report,
Version_2_Membership_Report: receive_version_2_membership_report, Version_2_Membership_Report: receive_version_2_membership_report,
......
...@@ -185,7 +185,21 @@ class InterfacePim(Interface): ...@@ -185,7 +185,21 @@ class InterfacePim(Interface):
return state_refresh_capable return state_refresh_capable
'''
def change_interface(self):
old_ip_address = self.ip_interface
self._recv_socket.setsockopt(socket.IPPROTO_IP, socket.IP_DROP_MEMBERSHIP,
socket.inet_aton(Interface.MCAST_GRP) + socket.inet_aton(old_ip_address))
new_ip_interface = netifaces.ifaddresses(self.interface_name)[netifaces.AF_INET][0]['addr']
self._recv_socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(Interface.MCAST_GRP) + socket.inet_aton(new_ip_interface))
self._send_socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(new_ip_interface))
self.ip_interface = new_ip_interface
import Main
Main.kernel.vif_dic[new_ip_interface] = Main.kernel.vif_dic.pop(old_ip_address)
'''
########################################### ###########################################
# Recv packets # Recv packets
......
import socket import socket
import struct import struct
import netifaces from threading import Lock, Thread
from threading import Lock
import traceback import traceback
import ipaddress import ipaddress
...@@ -9,8 +8,8 @@ import ipaddress ...@@ -9,8 +8,8 @@ import ipaddress
from RWLock.RWLock import RWLockWrite from RWLock.RWLock import RWLockWrite
import Main import Main
from tree.tree_if_upstream import * from InterfacePIM import InterfacePim
from tree.tree_if_downstream import * from InterfaceIGMP import InterfaceIGMP
from tree.KernelEntry import KernelEntry from tree.KernelEntry import KernelEntry
...@@ -85,7 +84,7 @@ class Kernel: ...@@ -85,7 +84,7 @@ class Kernel:
self.tree_logger = Main.logger.getChild('KernelTree') self.tree_logger = Main.logger.getChild('KernelTree')
# receive signals from kernel with a background thread # receive signals from kernel with a background thread
handler_thread = threading.Thread(target=self.handler) handler_thread = Thread(target=self.handler)
handler_thread.daemon = True handler_thread.daemon = True
handler_thread.start() handler_thread.start()
...@@ -103,34 +102,7 @@ class Kernel: ...@@ -103,34 +102,7 @@ class Kernel:
struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */ struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */
}; };
''' '''
'''
def create_virtual_interface(self, ip_interface: str or bytes, interface_name: str, flags=0x0):
with self.interface_lock:
index = list(range(0, self.MAXVIFS) - self.vif_index_to_name_dic.keys())[0]
if type(ip_interface) is str:
ip_interface = socket.inet_aton(ip_interface)
struct_mrt_add_vif = struct.pack("HBBI 4s 4s", index, flags, 1, 0, ip_interface, socket.inet_aton("0.0.0.0"))
self.socket.setsockopt(socket.IPPROTO_IP, Kernel.MRT_ADD_VIF, struct_mrt_add_vif)
self.vif_dic[socket.inet_ntoa(ip_interface)] = index
self.vif_index_to_name_dic[index] = interface_name
self.vif_name_to_index_dic[interface_name] = index
with self.rwlock.genWlock():
for kernel_entry in list(self.routing.values()):
kernel_entry.new_interface(index)
return index
'''
######################### new create virtual if
def create_virtual_interface(self, ip_interface: str or bytes, interface_name: str, index, flags=0x0): def create_virtual_interface(self, ip_interface: str or bytes, interface_name: str, index, flags=0x0):
#with self.interface_lock:
if type(ip_interface) is str: if type(ip_interface) is str:
ip_interface = socket.inet_aton(ip_interface) ip_interface = socket.inet_aton(ip_interface)
...@@ -151,7 +123,6 @@ class Kernel: ...@@ -151,7 +123,6 @@ class Kernel:
def create_pim_interface(self, interface_name: str, state_refresh_capable:bool): def create_pim_interface(self, interface_name: str, state_refresh_capable:bool):
from InterfacePIM import InterfacePim
with self.interface_lock: with self.interface_lock:
pim_interface = self.pim_interface.get(interface_name) pim_interface = self.pim_interface.get(interface_name)
igmp_interface = self.igmp_interface.get(interface_name) igmp_interface = self.igmp_interface.get(interface_name)
...@@ -174,7 +145,6 @@ class Kernel: ...@@ -174,7 +145,6 @@ class Kernel:
self.create_virtual_interface(ip_interface=ip_interface, interface_name=interface_name, index=index) self.create_virtual_interface(ip_interface=ip_interface, interface_name=interface_name, index=index)
def create_igmp_interface(self, interface_name: str): def create_igmp_interface(self, interface_name: str):
from InterfaceIGMP import InterfaceIGMP
with self.interface_lock: with self.interface_lock:
pim_interface = self.pim_interface.get(interface_name) pim_interface = self.pim_interface.get(interface_name)
igmp_interface = self.igmp_interface.get(interface_name) igmp_interface = self.igmp_interface.get(interface_name)
...@@ -197,41 +167,6 @@ class Kernel: ...@@ -197,41 +167,6 @@ class Kernel:
self.create_virtual_interface(ip_interface=ip_interface, interface_name=interface_name, index=index) self.create_virtual_interface(ip_interface=ip_interface, interface_name=interface_name, index=index)
'''
def create_interface(self, interface_name: str, igmp:bool = False, pim:bool = False):
from InterfaceIGMP import InterfaceIGMP
from InterfacePIM import InterfacePim
if (not igmp and not pim):
return
with self.interface_lock:
pim_interface = self.pim_interface.get(interface_name)
igmp_interface = self.igmp_interface.get(interface_name)
vif_already_exists = pim_interface or igmp_interface
if pim_interface:
index = pim_interface.vif_index
elif igmp_interface:
index = igmp_interface.vif_index
else:
index = list(range(0, self.MAXVIFS) - self.vif_index_to_name_dic.keys())[0]
ip_interface = None
if pim and interface_name not in self.pim_interface:
pim_interface = InterfacePim(interface_name, index)
self.pim_interface[interface_name] = pim_interface
ip_interface = pim_interface.ip_interface
if igmp and interface_name not in self.igmp_interface:
igmp_interface = InterfaceIGMP(interface_name, index)
self.igmp_interface[interface_name] = igmp_interface
ip_interface = igmp_interface.ip_interface
if not vif_already_exists:
self.create_virtual_interface(ip_interface=ip_interface, interface_name=interface_name, index=index)
'''
def remove_interface(self, interface_name, igmp:bool=False, pim:bool=False): def remove_interface(self, interface_name, igmp:bool=False, pim:bool=False):
with self.interface_lock: with self.interface_lock:
ip_interface = None ip_interface = None
...@@ -252,10 +187,6 @@ class Kernel: ...@@ -252,10 +187,6 @@ class Kernel:
self.remove_virtual_interface(ip_interface) self.remove_virtual_interface(ip_interface)
def remove_virtual_interface(self, ip_interface): def remove_virtual_interface(self, ip_interface):
#with self.interface_lock: #with self.interface_lock:
index = self.vif_dic[ip_interface] index = self.vif_dic[ip_interface]
...@@ -292,10 +223,6 @@ class Kernel: ...@@ -292,10 +223,6 @@ class Kernel:
''' '''
def set_multicast_route(self, kernel_entry: KernelEntry): def set_multicast_route(self, kernel_entry: KernelEntry):
source_ip = socket.inet_aton(kernel_entry.source_ip) source_ip = socket.inet_aton(kernel_entry.source_ip)
print("============")
print(type(kernel_entry.group_ip))
print(kernel_entry.group_ip)
print("============")
group_ip = socket.inet_aton(kernel_entry.group_ip) group_ip = socket.inet_aton(kernel_entry.group_ip)
outbound_interfaces = kernel_entry.get_outbound_interfaces_indexes() outbound_interfaces = kernel_entry.get_outbound_interfaces_indexes()
...@@ -422,11 +349,11 @@ class Kernel: ...@@ -422,11 +349,11 @@ class Kernel:
# notify KernelEntries about changes at the unicast routing table # notify KernelEntries about changes at the unicast routing table
def notify_unicast_changes(self, subnet): def notify_unicast_changes(self, subnet):
with self.rwlock.genWlock(): with self.rwlock.genWlock():
for source_ip in self.routing.keys(): for source_ip in list(self.routing.keys()):
source_ip_obj = ipaddress.ip_address(source_ip) source_ip_obj = ipaddress.ip_address(source_ip)
if source_ip_obj not in subnet: if source_ip_obj not in subnet:
continue continue
for group_ip in self.routing[source_ip].keys(): for group_ip in list(self.routing[source_ip].keys()):
self.routing[source_ip][group_ip].network_update() self.routing[source_ip][group_ip].network_update()
......
...@@ -17,36 +17,6 @@ class RootFilter(logging.Filter): ...@@ -17,36 +17,6 @@ class RootFilter(logging.Filter):
record.tree = '' record.tree = ''
if not hasattr(record, 'vif'): if not hasattr(record, 'vif'):
record.vif = '' record.vif = ''
if not hasattr(record, 'interfacename'):
return True record.interfacename = ''
class NonRootFilter(logging.Filter):
"""
This is a filter which injects contextual information into the log.
Rather than use actual contextual information, we just use random
data in this demo.
"""
def __init__(self, tree):
super().__init__()
self.tree = tree
def filter(self, record):
record.tree = self.tree
return True
class InterfaceFilter(logging.Filter):
"""
This is a filter which injects contextual information into the log.
Rather than use actual contextual information, we just use random
data in this demo.
"""
def __init__(self, vif):
super().__init__()
self.vif = vif
def filter(self, record):
record.vif = self.vif
return True return True
...@@ -101,7 +101,19 @@ class UnicastRouting(object): ...@@ -101,7 +101,19 @@ class UnicastRouting(object):
Main.kernel.notify_unicast_changes(subnet) Main.kernel.notify_unicast_changes(subnet)
elif action == "RTM_NEWADDR" or action == "RTM_DELADDR": elif action == "RTM_NEWADDR" or action == "RTM_DELADDR":
# TODO ALTERACOES NA INTERFACE # TODO ALTERACOES NA INTERFACE
print("a") '''
print(msg)
attrs = msg["attrs"]
for (key, value) in attrs:
print((key, value))
if key == "IFA_LABEL":
interface_name = value
break
pim_interface = Main.kernel.pim_interface.get(interface_name)
pim_interface.change_interface()
igmp_interface = Main.kernel.igmp_interface.get(interface_name)
'''
pass
def stop(self): def stop(self):
......
import Main
import socket
from tree.originator import OriginatorState
from tree.tree_if_upstream import TreeInterfaceUpstream from tree.tree_if_upstream import TreeInterfaceUpstream
from tree.tree_if_downstream import TreeInterfaceDownstream from tree.tree_if_downstream import TreeInterfaceDownstream
from .tree_interface import TreeInterface from .tree_interface import TreeInterface
...@@ -10,20 +6,16 @@ from tree.metric import AssertMetric ...@@ -10,20 +6,16 @@ from tree.metric import AssertMetric
import UnicastRouting import UnicastRouting
from time import time from time import time
import Main import Main
from TestLogger import NonRootFilter, logging import logging
class KernelEntry: class KernelEntry:
TREE_TIMEOUT = 180 TREE_TIMEOUT = 180
KERNEL_LOGGER = logging.getLogger('pim.KernelEntry')
def __init__(self, source_ip: str, group_ip: str, inbound_interface_index: int): def __init__(self, source_ip: str, group_ip: str, inbound_interface_index: int):
self.kernel_entry_logger = Main.logger.getChild('KernelEntry') self.kernel_entry_logger = logging.LoggerAdapter(KernelEntry.KERNEL_LOGGER, {'tree': '(' + source_ip + ',' + group_ip + ')'})
ch = logging.NullHandler()
ch.addFilter(NonRootFilter('(' + source_ip + ',' + group_ip + ')'))
self.kernel_entry_logger.addHandler(ch)
self.kernel_entry_logger.debug('Create KernelEntry') self.kernel_entry_logger.debug('Create KernelEntry')
self.source_ip = source_ip self.source_ip = source_ip
self.group_ip = group_ip self.group_ip = group_ip
...@@ -50,24 +42,27 @@ class KernelEntry: ...@@ -50,24 +42,27 @@ class KernelEntry:
# (S,G) starts IG state # (S,G) starts IG state
self._was_olist_null = False self._was_olist_null = False
# Locks
self._multicast_change = Lock()
self._lock_test2 = RLock()
self.CHANGE_STATE_LOCK = RLock()
# decide inbound interface based on rpf check # decide inbound interface based on rpf check
self.inbound_interface_index = Main.kernel.vif_dic[self.check_rpf()] self.inbound_interface_index = Main.kernel.vif_dic[self.check_rpf()]
self.interface_state = {} # type: Dict[int, TreeInterface] self.interface_state = {} # type: Dict[int, TreeInterface]
for i in Main.kernel.vif_index_to_name_dic.keys(): with self.CHANGE_STATE_LOCK:
try: for i in Main.kernel.vif_index_to_name_dic.keys():
if i == self.inbound_interface_index: try:
self.interface_state[i] = TreeInterfaceUpstream(self, i, False) if i == self.inbound_interface_index:
else: self.interface_state[i] = TreeInterfaceUpstream(self, i, False)
self.interface_state[i] = TreeInterfaceDownstream(self, i) else:
except: self.interface_state[i] = TreeInterfaceDownstream(self, i)
import traceback except:
print(traceback.print_exc()) import traceback
continue print(traceback.print_exc())
continue
self._multicast_change = Lock()
self._lock_test2 = RLock()
self.CHANGE_STATE_LOCK = RLock()
self.change() self.change()
self.evaluate_olist_change() self.evaluate_olist_change()
self.timestamp_of_last_state_refresh_message_received = 0 self.timestamp_of_last_state_refresh_message_received = 0
...@@ -213,9 +208,10 @@ class KernelEntry: ...@@ -213,9 +208,10 @@ class KernelEntry:
old_downstream_interface.delete(change_type_interface=True) old_downstream_interface.delete(change_type_interface=True)
# atualizar tabela de encaminhamento multicast # atualizar tabela de encaminhamento multicast
self._was_olist_null = False #self._was_olist_null = False
self.change() self.change()
self.evaluate_olist_change() self.evaluate_olist_change()
new_upstream_interface.change_on_unicast_routing(interface_change=True)
elif self.rpf_node != rpf_node: elif self.rpf_node != rpf_node:
self.rpf_node = rpf_node self.rpf_node = rpf_node
self.interface_state[self.inbound_interface_index].change_on_unicast_routing() self.interface_state[self.inbound_interface_index].change_on_unicast_routing()
......
...@@ -96,7 +96,8 @@ class NoInfo(DownstreamStateABS): ...@@ -96,7 +96,8 @@ class NoInfo(DownstreamStateABS):
interface.set_prune_pending_timer(time) interface.set_prune_pending_timer(time)
print("receivedPrune, NI -> PP") #print("receivedPrune, NI -> PP")
interface.join_prune_logger.debug("receivedPrune, NI -> PP")
@staticmethod @staticmethod
def receivedJoin(interface: "TreeInterfaceDownstream"): def receivedJoin(interface: "TreeInterfaceDownstream"):
...@@ -107,7 +108,8 @@ class NoInfo(DownstreamStateABS): ...@@ -107,7 +108,8 @@ class NoInfo(DownstreamStateABS):
""" """
# Do nothing # Do nothing
print("receivedJoin, NI -> NI") #print("receivedJoin, NI -> NI")
interface.join_prune_logger.debug("receivedJoin, NI -> NI")
@staticmethod @staticmethod
def receivedGraft(interface: "TreeInterfaceDownstream", source_ip): def receivedGraft(interface: "TreeInterfaceDownstream", source_ip):
...@@ -118,7 +120,8 @@ class NoInfo(DownstreamStateABS): ...@@ -118,7 +120,8 @@ class NoInfo(DownstreamStateABS):
""" """
interface.send_graft_ack(source_ip) interface.send_graft_ack(source_ip)
print('receivedGraft, NI -> NI') #print('receivedGraft, NI -> NI')
interface.join_prune_logger.debug('receivedGraft, NI -> NI')
@staticmethod @staticmethod
def PPTexpires(interface: "TreeInterfaceDownstream"): def PPTexpires(interface: "TreeInterfaceDownstream"):
...@@ -127,7 +130,7 @@ class NoInfo(DownstreamStateABS): ...@@ -127,7 +130,7 @@ class NoInfo(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
#assert False #assert False, "PPTexpires in state NI"
return return
@staticmethod @staticmethod
...@@ -137,7 +140,7 @@ class NoInfo(DownstreamStateABS): ...@@ -137,7 +140,7 @@ class NoInfo(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
#assert False #assert False, "PTexpires in state NI"
return return
@staticmethod @staticmethod
...@@ -147,9 +150,8 @@ class NoInfo(DownstreamStateABS): ...@@ -147,9 +150,8 @@ class NoInfo(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
pass
# Do nothing # Do nothing
return
@staticmethod @staticmethod
def send_state_refresh(interface: "TreeInterfaceDownstream"): def send_state_refresh(interface: "TreeInterfaceDownstream"):
...@@ -158,9 +160,12 @@ class NoInfo(DownstreamStateABS): ...@@ -158,9 +160,12 @@ class NoInfo(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
pass
# Do nothing # Do nothing
return
def __str__(self):
return "NI"
class PrunePending(DownstreamStateABS): class PrunePending(DownstreamStateABS):
...@@ -181,7 +186,9 @@ class PrunePending(DownstreamStateABS): ...@@ -181,7 +186,9 @@ class PrunePending(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
print('receivedPrune, PP -> PP') #print('receivedPrune, PP -> PP')
interface.join_prune_logger.debug('receivedPrune, PP -> PP')
@staticmethod @staticmethod
def receivedJoin(interface: "TreeInterfaceDownstream"): def receivedJoin(interface: "TreeInterfaceDownstream"):
...@@ -190,13 +197,12 @@ class PrunePending(DownstreamStateABS): ...@@ -190,13 +197,12 @@ class PrunePending(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
#interface.get_ppt().stop()
interface.clear_prune_pending_timer() interface.clear_prune_pending_timer()
interface.set_prune_state(DownstreamState.NoInfo) interface.set_prune_state(DownstreamState.NoInfo)
print('receivedJoin, PP -> NI') #print('receivedJoin, PP -> NI')
interface.join_prune_logger.debug('receivedJoin, PP -> NI')
@staticmethod @staticmethod
def receivedGraft(interface: "TreeInterfaceDownstream", source_ip): def receivedGraft(interface: "TreeInterfaceDownstream", source_ip):
...@@ -210,7 +216,8 @@ class PrunePending(DownstreamStateABS): ...@@ -210,7 +216,8 @@ class PrunePending(DownstreamStateABS):
interface.set_prune_state(DownstreamState.NoInfo) interface.set_prune_state(DownstreamState.NoInfo)
interface.send_graft_ack(source_ip) interface.send_graft_ack(source_ip)
print('receivedGraft, PP -> NI') #print('receivedGraft, PP -> NI')
interface.join_prune_logger.debug('receivedGraft, PP -> NI')
@staticmethod @staticmethod
def PPTexpires(interface: "TreeInterfaceDownstream"): def PPTexpires(interface: "TreeInterfaceDownstream"):
...@@ -225,7 +232,8 @@ class PrunePending(DownstreamStateABS): ...@@ -225,7 +232,8 @@ class PrunePending(DownstreamStateABS):
if len(interface.get_interface().neighbors) > 1: if len(interface.get_interface().neighbors) > 1:
interface.send_pruneecho() interface.send_pruneecho()
print('PPTexpires, PP -> P') #print('PPTexpires, PP -> P')
interface.join_prune_logger.debug('PPTexpires, PP -> P')
@staticmethod @staticmethod
def PTexpires(interface: "TreeInterfaceDownstream"): def PTexpires(interface: "TreeInterfaceDownstream"):
...@@ -235,7 +243,7 @@ class PrunePending(DownstreamStateABS): ...@@ -235,7 +243,7 @@ class PrunePending(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
#assert False #assert False, "PTexpires in state PP"
return return
@staticmethod @staticmethod
...@@ -245,8 +253,6 @@ class PrunePending(DownstreamStateABS): ...@@ -245,8 +253,6 @@ class PrunePending(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
# todo understand better
interface.clear_prune_pending_timer() interface.clear_prune_pending_timer()
interface.set_prune_state(DownstreamState.NoInfo) interface.set_prune_state(DownstreamState.NoInfo)
...@@ -260,8 +266,10 @@ class PrunePending(DownstreamStateABS): ...@@ -260,8 +266,10 @@ class PrunePending(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
pass return
def __str__(self):
return "PP"
class Pruned(DownstreamStateABS): class Pruned(DownstreamStateABS):
''' '''
...@@ -279,10 +287,11 @@ class Pruned(DownstreamStateABS): ...@@ -279,10 +287,11 @@ class Pruned(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
if interface.get_received_prune_holdtime() > interface.remaining_prune_timer(): if holdtime > interface.remaining_prune_timer():
interface.set_prune_timer(holdtime) interface.set_prune_timer(holdtime)
print('receivedPrune, P -> P') #print('receivedPrune, P -> P')
interface.join_prune_logger.debug('receivedPrune, P -> P')
@staticmethod @staticmethod
def receivedJoin(interface: "TreeInterfaceDownstream"): def receivedJoin(interface: "TreeInterfaceDownstream"):
...@@ -295,7 +304,8 @@ class Pruned(DownstreamStateABS): ...@@ -295,7 +304,8 @@ class Pruned(DownstreamStateABS):
interface.set_prune_state(DownstreamState.NoInfo) interface.set_prune_state(DownstreamState.NoInfo)
print('receivedPrune, P -> NI') #print('receivedPrune, P -> NI')
interface.join_prune_logger.debug('receivedPrune, P -> NI')
@staticmethod @staticmethod
def receivedGraft(interface: "TreeInterfaceDownstream", source_ip): def receivedGraft(interface: "TreeInterfaceDownstream", source_ip):
...@@ -308,7 +318,8 @@ class Pruned(DownstreamStateABS): ...@@ -308,7 +318,8 @@ class Pruned(DownstreamStateABS):
interface.set_prune_state(DownstreamState.NoInfo) interface.set_prune_state(DownstreamState.NoInfo)
interface.send_graft_ack(source_ip) interface.send_graft_ack(source_ip)
print('receivedGraft, P -> NI') #print('receivedGraft, P -> NI')
interface.join_prune_logger.debug('receivedGraft, P -> NI')
@staticmethod @staticmethod
def PPTexpires(interface: "TreeInterfaceDownstream"): def PPTexpires(interface: "TreeInterfaceDownstream"):
...@@ -317,7 +328,7 @@ class Pruned(DownstreamStateABS): ...@@ -317,7 +328,7 @@ class Pruned(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
#assert False #assert False, "PPTexpires in state P"
return return
@staticmethod @staticmethod
...@@ -327,10 +338,10 @@ class Pruned(DownstreamStateABS): ...@@ -327,10 +338,10 @@ class Pruned(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
interface.set_prune_state(DownstreamState.NoInfo) interface.set_prune_state(DownstreamState.NoInfo)
print('PTexpires, P -> NI') #print('PTexpires, P -> NI')
interface.join_prune_logger.debug('PTexpires, P -> NI')
@staticmethod @staticmethod
def is_now_RPF_Interface(interface: "TreeInterfaceDownstream"): def is_now_RPF_Interface(interface: "TreeInterfaceDownstream"):
...@@ -339,8 +350,6 @@ class Pruned(DownstreamStateABS): ...@@ -339,8 +350,6 @@ class Pruned(DownstreamStateABS):
@type interface: TreeInterfaceDownstreamDownstream @type interface: TreeInterfaceDownstreamDownstream
""" """
# todo ver melhor
#interface.get_pt().stop()
interface.clear_prune_timer() interface.clear_prune_timer()
interface.set_prune_state(DownstreamState.NoInfo) interface.set_prune_state(DownstreamState.NoInfo)
...@@ -356,8 +365,11 @@ class Pruned(DownstreamStateABS): ...@@ -356,8 +365,11 @@ class Pruned(DownstreamStateABS):
if interface.get_interface().is_state_refresh_capable(): if interface.get_interface().is_state_refresh_capable():
interface.set_prune_timer(interface.get_received_prune_holdtime()) interface.set_prune_timer(interface.get_received_prune_holdtime())
print('send_state_refresh, P -> P') #print('send_state_refresh, P -> P')
interface.join_prune_logger.debug('send_state_refresh, P -> P')
def __str__(self):
return "P"
class DownstreamState(): class DownstreamState():
NoInfo = NoInfo() NoInfo = NoInfo()
......
...@@ -30,26 +30,28 @@ class Originator(OriginatorStateABC): ...@@ -30,26 +30,28 @@ class Originator(OriginatorStateABC):
''' '''
@type tree: Tree @type tree: Tree
''' '''
print('SRT expired, O to O')
tree.set_state_refresh_timer() tree.set_state_refresh_timer()
tree.create_state_refresh_msg() tree.create_state_refresh_msg()
#print('SRT expired, O to O')
tree.originator_logger.debug('SRT expired, O -> O')
@staticmethod @staticmethod
def SATexpires(tree): def SATexpires(tree):
print('SAT expired, O to NO')
tree.clear_state_refresh_timer() tree.clear_state_refresh_timer()
tree.set_originator_state(OriginatorState.NotOriginator) tree.set_originator_state(OriginatorState.NotOriginator)
#print('SAT expired, O to NO')
tree.originator_logger.debug('SAT expired, O -> NO')
@staticmethod @staticmethod
def SourceNotConnected(tree): def SourceNotConnected(tree):
print('Source no longer directly connected, O to NO')
tree.clear_state_refresh_timer() tree.clear_state_refresh_timer()
tree.clear_source_active_timer() tree.clear_source_active_timer()
tree.set_originator_state(OriginatorState.NotOriginator) tree.set_originator_state(OriginatorState.NotOriginator)
#print('Source no longer directly connected, O to NO')
tree.originator_logger.debug('Source no longer directly connected, O -> NO')
class NotOriginator(OriginatorStateABC): class NotOriginator(OriginatorStateABC):
@staticmethod @staticmethod
...@@ -62,15 +64,16 @@ class NotOriginator(OriginatorStateABC): ...@@ -62,15 +64,16 @@ class NotOriginator(OriginatorStateABC):
tree.set_state_refresh_timer() tree.set_state_refresh_timer()
tree.set_source_active_timer() tree.set_source_active_timer()
print('new DataMsg from Source, NO to O') #print('new DataMsg from Source, NO to O')
tree.originator_logger.debug('new DataMsg from Source, NO -> O')
@staticmethod @staticmethod
def SRTexpires(tree): def SRTexpires(tree):
assert False assert False, "SRTexpires in NO"
@staticmethod @staticmethod
def SATexpires(tree): def SATexpires(tree):
assert False assert False, "SATexpires in NO"
@staticmethod @staticmethod
def SourceNotConnected(tree): def SourceNotConnected(tree):
......
...@@ -12,14 +12,20 @@ from Packet.PacketPimStateRefresh import PacketPimStateRefresh ...@@ -12,14 +12,20 @@ from Packet.PacketPimStateRefresh import PacketPimStateRefresh
from Packet.Packet import Packet from Packet.Packet import Packet
from Packet.PacketPimHeader import PacketPimHeader from Packet.PacketPimHeader import PacketPimHeader
import traceback import traceback
import logging
import Main
class TreeInterfaceDownstream(TreeInterface): class TreeInterfaceDownstream(TreeInterface):
LOGGER = logging.getLogger('pim.KernelEntry.DownstreamInterface')
def __init__(self, kernel_entry, interface_id): def __init__(self, kernel_entry, interface_id):
logger = kernel_entry.kernel_entry_logger.getChild('DownstreamInterface') extra_dict_logger = kernel_entry.kernel_entry_logger.extra.copy()
extra_dict_logger['vif'] = interface_id
extra_dict_logger['interfacename'] = Main.kernel.vif_index_to_name_dic[interface_id]
logger = logging.LoggerAdapter(TreeInterfaceDownstream.LOGGER, extra_dict_logger)
TreeInterface.__init__(self, kernel_entry, interface_id, logger) TreeInterface.__init__(self, kernel_entry, interface_id, logger)
self.logger.debug('Created DownstreamInterface') self.logger.debug('Created DownstreamInterface')
self.join_prune_logger.debug(str(self._prune_state))
########################################## ##########################################
# Set state # Set state
...@@ -28,6 +34,7 @@ class TreeInterfaceDownstream(TreeInterface): ...@@ -28,6 +34,7 @@ class TreeInterfaceDownstream(TreeInterface):
with self.get_state_lock(): with self.get_state_lock():
if new_state != self._prune_state: if new_state != self._prune_state:
self._prune_state = new_state self._prune_state = new_state
self.join_prune_logger.debug(str(new_state))
self.change_tree() self.change_tree()
self.evaluate_ingroup() self.evaluate_ingroup()
...@@ -121,11 +128,6 @@ class TreeInterfaceDownstream(TreeInterface): ...@@ -121,11 +128,6 @@ class TreeInterfaceDownstream(TreeInterface):
if self.is_pruned(): if self.is_pruned():
prune_indicator_bit = 1 prune_indicator_bit = 1
# TODO set timer
# todo maybe ja feito na maquina de estados Prune downstream
# if state_refresh_capable
# set PT....
import UnicastRouting import UnicastRouting
(metric_preference, metric, mask) = UnicastRouting.get_metric(state_refresh_msg_received.source_address) (metric_preference, metric, mask) = UnicastRouting.get_metric(state_refresh_msg_received.source_address)
......
...@@ -6,6 +6,7 @@ Created on Jul 16, 2015 ...@@ -6,6 +6,7 @@ Created on Jul 16, 2015
from .tree_interface import TreeInterface from .tree_interface import TreeInterface
from .upstream_prune import UpstreamState from .upstream_prune import UpstreamState
from threading import Timer from threading import Timer
from CustomTimer.RemainingTimer import RemainingTimer
from .globals import * from .globals import *
import random import random
from .metric import AssertMetric from .metric import AssertMetric
...@@ -14,11 +15,18 @@ from Packet.PacketPimStateRefresh import PacketPimStateRefresh ...@@ -14,11 +15,18 @@ from Packet.PacketPimStateRefresh import PacketPimStateRefresh
import traceback import traceback
from . import DataPacketsSocket from . import DataPacketsSocket
import threading import threading
import logging
import Main
class TreeInterfaceUpstream(TreeInterface): class TreeInterfaceUpstream(TreeInterface):
LOGGER = logging.getLogger('pim.KernelEntry.UpstreamInterface')
def __init__(self, kernel_entry, interface_id, is_originater: bool): def __init__(self, kernel_entry, interface_id, is_originater: bool):
logger = kernel_entry.kernel_entry_logger.getChild('UpstreamInterface') extra_dict_logger = kernel_entry.kernel_entry_logger.extra.copy()
extra_dict_logger['vif'] = interface_id
extra_dict_logger['interfacename'] = Main.kernel.vif_index_to_name_dic[interface_id]
logger = logging.LoggerAdapter(TreeInterfaceUpstream.LOGGER, extra_dict_logger)
TreeInterface.__init__(self, kernel_entry, interface_id, logger) TreeInterface.__init__(self, kernel_entry, interface_id, logger)
# Graft/Prune State: # Graft/Prune State:
...@@ -27,12 +35,14 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -27,12 +35,14 @@ class TreeInterfaceUpstream(TreeInterface):
self._override_timer = None self._override_timer = None
self._prune_limit_timer = None self._prune_limit_timer = None
self._last_rpf = self.get_neighbor_RPF() self._last_rpf = self.get_neighbor_RPF()
self.join_prune_logger.debug(str(self._graft_prune_state))
# Originator state # Originator state
self._originator_state = OriginatorState.NotOriginator self._originator_state = OriginatorState.NotOriginator
self._state_refresh_timer = None self._state_refresh_timer = None
self._source_active_timer = None self._source_active_timer = None
self._prune_now_counter = 0 self._prune_now_counter = 0
self.originator_logger = logging.LoggerAdapter(TreeInterfaceUpstream.LOGGER, extra_dict_logger)
if self.is_S_directly_conn(): if self.is_S_directly_conn():
self._graft_prune_state.sourceIsNowDirectConnect(self) self._graft_prune_state.sourceIsNowDirectConnect(self)
...@@ -71,6 +81,7 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -71,6 +81,7 @@ class TreeInterfaceUpstream(TreeInterface):
with self.get_state_lock(): with self.get_state_lock():
if new_state != self._graft_prune_state: if new_state != self._graft_prune_state:
self._graft_prune_state = new_state self._graft_prune_state = new_state
self.join_prune_logger.debug(str(new_state))
self.change_tree() self.change_tree()
self.evaluate_ingroup() self.evaluate_ingroup()
...@@ -91,6 +102,9 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -91,6 +102,9 @@ class TreeInterfaceUpstream(TreeInterface):
def is_prune_limit_timer_running(self): def is_prune_limit_timer_running(self):
return self._prune_limit_timer is not None and self._prune_limit_timer.is_alive() return self._prune_limit_timer is not None and self._prune_limit_timer.is_alive()
def remaining_prune_limit_timer(self):
return 0 if not self._prune_limit_timer else self._prune_limit_timer.time_remaining()
########################################## ##########################################
# Set timers # Set timers
########################################## ##########################################
...@@ -114,7 +128,7 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -114,7 +128,7 @@ class TreeInterfaceUpstream(TreeInterface):
def set_prune_limit_timer(self, time=T_LIMIT): def set_prune_limit_timer(self, time=T_LIMIT):
self.clear_prune_limit_timer() self.clear_prune_limit_timer()
self._prune_limit_timer = Timer(time, self.prune_limit_timeout) self._prune_limit_timer = RemainingTimer(time, self.prune_limit_timeout)
self._prune_limit_timer.start() self._prune_limit_timer.start()
def clear_prune_limit_timer(self): def clear_prune_limit_timer(self):
...@@ -177,6 +191,7 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -177,6 +191,7 @@ class TreeInterfaceUpstream(TreeInterface):
def recv_prune_msg(self, upstream_neighbor_address, holdtime): def recv_prune_msg(self, upstream_neighbor_address, holdtime):
super().recv_prune_msg(upstream_neighbor_address, holdtime) super().recv_prune_msg(upstream_neighbor_address, holdtime)
self.set_receceived_prune_holdtime(holdtime)
self._graft_prune_state.seePrune(self) self._graft_prune_state.seePrune(self)
def recv_graft_ack_msg(self, source_ip_of_graft_ack): def recv_graft_ack_msg(self, source_ip_of_graft_ack):
...@@ -232,13 +247,13 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -232,13 +247,13 @@ class TreeInterfaceUpstream(TreeInterface):
self.change_rpf(self.is_olist_null()) self.change_rpf(self.is_olist_null())
# caused by unicast routing table: # caused by unicast routing table:
def change_on_unicast_routing(self): def change_on_unicast_routing(self, interface_change=False):
self.change_rpf(self.is_olist_null()) self.change_rpf(self.is_olist_null(), interface_change)
def change_rpf(self, olist_is_null): def change_rpf(self, olist_is_null, interface_change=False):
current_rpf = self.get_neighbor_RPF() current_rpf = self.get_neighbor_RPF()
if self._last_rpf != current_rpf: if interface_change or self._last_rpf != current_rpf:
self._last_rpf = current_rpf self._last_rpf = current_rpf
if olist_is_null: if olist_is_null:
self._graft_prune_state.RPFnbrChanges_olistIsNull(self) self._graft_prune_state.RPFnbrChanges_olistIsNull(self)
......
...@@ -24,18 +24,15 @@ from .metric import AssertMetric ...@@ -24,18 +24,15 @@ from .metric import AssertMetric
from threading import Timer from threading import Timer
from .local_membership import LocalMembership from .local_membership import LocalMembership
from .globals import * from .globals import *
from TestLogger import InterfaceFilter, logging import logging
class TreeInterface(metaclass=ABCMeta): class TreeInterface(metaclass=ABCMeta):
def __init__(self, kernel_entry, interface_id, logger): def __init__(self, kernel_entry, interface_id, logger: logging.LoggerAdapter):
self._kernel_entry = kernel_entry self._kernel_entry = kernel_entry
self._interface_id = interface_id self._interface_id = interface_id
self.logger = logger self.logger = logger
ch = logging.NullHandler() self.assert_logger = logging.LoggerAdapter(logger.logger.getChild('Assert'), logger.extra)
ch.addFilter(InterfaceFilter(interface_id)) self.join_prune_logger = logging.LoggerAdapter(logger.logger.getChild('JoinPrune'), logger.extra)
self.logger.addHandler(ch)
self.assert_logger = logger.getChild('Assert')
self.join_prune_logger = logger.getChild('JoinPrune')
# Local Membership State # Local Membership State
try: try:
...@@ -58,6 +55,7 @@ class TreeInterface(metaclass=ABCMeta): ...@@ -58,6 +55,7 @@ class TreeInterface(metaclass=ABCMeta):
self._assert_state = AssertState.NoInfo self._assert_state = AssertState.NoInfo
self._assert_winner_metric = AssertMetric() self._assert_winner_metric = AssertMetric()
self._assert_timer = None self._assert_timer = None
self.assert_logger.debug("NI")
# Received prune hold time # Received prune hold time
self._received_prune_holdtime = None self._received_prune_holdtime = None
...@@ -265,9 +263,6 @@ class TreeInterface(metaclass=ABCMeta): ...@@ -265,9 +263,6 @@ class TreeInterface(metaclass=ABCMeta):
def is_forwarding(self): def is_forwarding(self):
pass pass
def nbr_died(self):
pass
def nbr_connected(self): def nbr_connected(self):
pass pass
...@@ -331,9 +326,6 @@ class TreeInterface(metaclass=ABCMeta): ...@@ -331,9 +326,6 @@ class TreeInterface(metaclass=ABCMeta):
with self._igmp_lock: with self._igmp_lock:
return self._local_membership_state.has_members() return self._local_membership_state.has_members()
def __str__(self):
return '{}<{}>'.format(self.__class__, self._interface.get_link())
def get_interface(self): def get_interface(self):
kernel = Main.kernel kernel = Main.kernel
interface_name = kernel.vif_index_to_name_dic[self._interface_id] interface_name = kernel.vif_index_to_name_dic[self._interface_id]
...@@ -377,12 +369,6 @@ class TreeInterface(metaclass=ABCMeta): ...@@ -377,12 +369,6 @@ class TreeInterface(metaclass=ABCMeta):
else: else:
return self._kernel_entry.rpf_node return self._kernel_entry.rpf_node
def i_am_assert_loser(self):
return self._assert_state == AssertState.Loser
def is_assert_winner(self):
return not self.is_downstream() and not self._assert_state == AssertState.Loser
def is_S_directly_conn(self): def is_S_directly_conn(self):
return self._kernel_entry.rpf_node == self._kernel_entry.source_ip return self._kernel_entry.rpf_node == self._kernel_entry.source_ip
...@@ -404,6 +390,9 @@ class TreeInterface(metaclass=ABCMeta): ...@@ -404,6 +390,9 @@ class TreeInterface(metaclass=ABCMeta):
return not self._assert_winner_metric.i_am_assert_winner(self) and \ return not self._assert_winner_metric.i_am_assert_winner(self) and \
self._assert_winner_metric.is_better_than(AssertMetric.spt_assert_metric(self)) self._assert_winner_metric.is_better_than(AssertMetric.spt_assert_metric(self))
def i_am_assert_loser(self):
return self._assert_state == AssertState.Loser
def could_assert(self): def could_assert(self):
return self.is_downstream() return self.is_downstream()
......
This diff is collapsed.
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