Commit a890f223 authored by Pedro Oliveira's avatar Pedro Oliveira

react to new neighbors (resend state refresh msg/clear prune limit timer <-...

react to new neighbors (resend state refresh msg/clear prune limit timer <- based on downstream/upstream neighbor) & fix originator logger & remove dead code
parent 66b92c8d
...@@ -44,6 +44,7 @@ class InterfaceIGMP(Interface): ...@@ -44,6 +44,7 @@ class InterfaceIGMP(Interface):
# bind to interface # bind to interface
rcv_s.bind((interface_name, 0x0800)) rcv_s.bind((interface_name, 0x0800))
super().__init__(interface_name=interface_name, recv_socket=rcv_s, send_socket=snd_s, vif_index=vif_index) super().__init__(interface_name=interface_name, recv_socket=rcv_s, send_socket=snd_s, vif_index=vif_index)
self.interface_enabled = True
from igmp.RouterState import RouterState from igmp.RouterState import RouterState
self.interface_state = RouterState(self) self.interface_state = RouterState(self)
super()._enable() super()._enable()
......
...@@ -145,6 +145,9 @@ class InterfacePim(Interface): ...@@ -145,6 +145,9 @@ class InterfacePim(Interface):
self._had_neighbors = has_neighbors self._had_neighbors = has_neighbors
Main.kernel.interface_change_number_of_neighbors() Main.kernel.interface_change_number_of_neighbors()
def new_or_reset_neighbor(self, neighbor_ip):
Main.kernel.new_or_reset_neighbor(self.vif_index, neighbor_ip)
''' '''
def add_neighbor(self, ip, random_number, hello_hold_time): def add_neighbor(self, ip, random_number, hello_hold_time):
with self.neighbors_lock.genWlock(): with self.neighbors_lock.genWlock():
...@@ -187,18 +190,21 @@ class InterfacePim(Interface): ...@@ -187,18 +190,21 @@ class InterfacePim(Interface):
''' '''
def change_interface(self): def change_interface(self):
# check if ip change was already applied to interface
old_ip_address = self.ip_interface old_ip_address = self.ip_interface
new_ip_interface = netifaces.ifaddresses(self.interface_name)[netifaces.AF_INET][0]['addr']
if old_ip_address == new_ip_interface:
return
self._send_socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(new_ip_interface))
self._recv_socket.setsockopt(socket.IPPROTO_IP, socket.IP_DROP_MEMBERSHIP, self._recv_socket.setsockopt(socket.IPPROTO_IP, socket.IP_DROP_MEMBERSHIP,
socket.inet_aton(Interface.MCAST_GRP) + socket.inet_aton(old_ip_address)) 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, self._recv_socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(Interface.MCAST_GRP) + socket.inet_aton(new_ip_interface)) 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 self.ip_interface = new_ip_interface
import Main
Main.kernel.vif_dic[new_ip_interface] = Main.kernel.vif_dic.pop(old_ip_address)
''' '''
########################################### ###########################################
...@@ -220,11 +226,14 @@ class InterfacePim(Interface): ...@@ -220,11 +226,14 @@ class InterfacePim(Interface):
with self.neighbors_lock.genWlock(): with self.neighbors_lock.genWlock():
if ip not in self.neighbors: if ip not in self.neighbors:
if hello_hold_time == 0:
return
print("ADD NEIGHBOR") print("ADD NEIGHBOR")
from Neighbor import Neighbor from Neighbor import Neighbor
self.neighbors[ip] = Neighbor(self, ip, generation_id, hello_hold_time, state_refresh_capable) self.neighbors[ip] = Neighbor(self, ip, generation_id, hello_hold_time, state_refresh_capable)
self.force_send_hello() self.force_send_hello()
self.check_number_of_neighbors() self.check_number_of_neighbors()
self.new_or_reset_neighbor(ip)
return return
else: else:
neighbor = self.neighbors[ip] neighbor = self.neighbors[ip]
......
...@@ -337,7 +337,7 @@ class Kernel: ...@@ -337,7 +337,7 @@ class Kernel:
if ip_src in self.routing and ip_dst in self.routing[ip_src]: if ip_src in self.routing and ip_dst in self.routing[ip_src]:
return self.routing[ip_src][ip_dst] return self.routing[ip_src][ip_dst]
elif create_if_not_existent: elif create_if_not_existent:
kernel_entry = KernelEntry(ip_src, ip_dst, 0) kernel_entry = KernelEntry(ip_src, ip_dst)
if ip_src not in self.routing: if ip_src not in self.routing:
self.routing[ip_src] = {} self.routing[ip_src] = {}
...@@ -357,9 +357,38 @@ class Kernel: ...@@ -357,9 +357,38 @@ class Kernel:
self.routing[source_ip][group_ip].network_update() self.routing[source_ip][group_ip].network_update()
# notify about changes at the interface (IP)
'''
def notify_interface_change(self, interface_name):
with self.interface_lock:
# check if interface was already added
if interface_name not in self.vif_name_to_index_dic:
return
print("trying to change ip")
pim_interface = self.pim_interface.get(interface_name)
if pim_interface:
old_ip = pim_interface.get_ip()
pim_interface.change_interface()
new_ip = pim_interface.get_ip()
if old_ip != new_ip:
self.vif_dic[new_ip] = self.vif_dic.pop(old_ip)
igmp_interface = self.igmp_interface.get(interface_name)
if igmp_interface:
igmp_interface.change_interface()
'''
# When interface changes number of neighbors verify if olist changes and prune/forward respectively # When interface changes number of neighbors verify if olist changes and prune/forward respectively
def interface_change_number_of_neighbors(self): def interface_change_number_of_neighbors(self):
with self.rwlock.genWlock(): with self.rwlock.genRlock():
for groups_dict in self.routing.values(): for groups_dict in self.routing.values():
for entry in groups_dict.values(): for entry in groups_dict.values():
entry.change_at_number_of_neighbors() entry.change_at_number_of_neighbors()
# When new neighbor connects try to resend last state refresh msg (if AssertWinner)
def new_or_reset_neighbor(self, vif_index, neighbor_ip):
with self.rwlock.genRlock():
for groups_dict in self.routing.values():
for entry in groups_dict.values():
entry.new_or_reset_neighbor(vif_index, neighbor_ip)
import netifaces import netifaces
import time import time
from prettytable import PrettyTable from prettytable import PrettyTable
import sys
import logging, logging.handlers
from TestLogger import RootFilter
#from InterfacePIM import InterfacePim
#from InterfaceIGMP import InterfaceIGMP
from Kernel import Kernel from Kernel import Kernel
#from threading import Lock
import UnicastRouting import UnicastRouting
interfaces = {} # interfaces with multicast routing enabled interfaces = {} # interfaces with multicast routing enabled
...@@ -160,8 +160,6 @@ def stop(): ...@@ -160,8 +160,6 @@ def stop():
def test(router_name, server_logger_ip): def test(router_name, server_logger_ip):
global logger global logger
import logging.handlers
from TestLogger import RootFilter
socketHandler = logging.handlers.SocketHandler(server_logger_ip, socketHandler = logging.handlers.SocketHandler(server_logger_ip,
logging.handlers.DEFAULT_TCP_LOGGING_PORT) logging.handlers.DEFAULT_TCP_LOGGING_PORT)
# don't bother with a formatter, since a socket handler sends the event as # don't bother with a formatter, since a socket handler sends the event as
...@@ -173,8 +171,6 @@ def test(router_name, server_logger_ip): ...@@ -173,8 +171,6 @@ def test(router_name, server_logger_ip):
def main(): def main():
# logging # logging
global logger global logger
import sys
import logging, logging.handlers
logger = logging.getLogger('pim') logger = logging.getLogger('pim')
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler(sys.stdout)) logger.addHandler(logging.StreamHandler(sys.stdout))
......
...@@ -45,7 +45,7 @@ class Neighbor: ...@@ -45,7 +45,7 @@ class Neighbor:
# neighbor restarted # neighbor restarted
if self.generation_id != generation_id: if self.generation_id != generation_id:
self.generation_id = generation_id self.generation_id = generation_id
self.contact_interface.send_hello() self.contact_interface.force_send_hello()
self.reset() self.reset()
""" """
...@@ -74,7 +74,7 @@ class Neighbor: ...@@ -74,7 +74,7 @@ class Neighbor:
def reset(self): def reset(self):
return self.contact_interface.new_or_reset_neighbor(self.ip)
def receive_hello(self, generation_id, hello_hold_time, state_refresh_capable): def receive_hello(self, generation_id, hello_hold_time, state_refresh_capable):
......
...@@ -26,8 +26,8 @@ class PacketPimHelloOptions(metaclass=ABCMeta): ...@@ -26,8 +26,8 @@ class PacketPimHelloOptions(metaclass=ABCMeta):
def parse_bytes(data: bytes, type:int = None, length:int = None): def parse_bytes(data: bytes, type:int = None, length:int = None):
(type, length) = struct.unpack(PacketPimHelloOptions.PIM_HDR_OPTS, (type, length) = struct.unpack(PacketPimHelloOptions.PIM_HDR_OPTS,
data[:PacketPimHelloOptions.PIM_HDR_OPTS_LEN]) data[:PacketPimHelloOptions.PIM_HDR_OPTS_LEN])
print("TYPE:", type) #print("TYPE:", type)
print("LENGTH:", length) #print("LENGTH:", length)
data = data[PacketPimHelloOptions.PIM_HDR_OPTS_LEN:] data = data[PacketPimHelloOptions.PIM_HDR_OPTS_LEN:]
#return PIM_MSG_TYPES[type](data) #return PIM_MSG_TYPES[type](data)
return PIM_MSG_TYPES.get(type, PacketPimHelloUnknown).parse_bytes(data, type, length) return PIM_MSG_TYPES.get(type, PacketPimHelloUnknown).parse_bytes(data, type, length)
...@@ -114,7 +114,7 @@ class PacketPimHelloHoldtime(PacketPimHelloOptions): ...@@ -114,7 +114,7 @@ class PacketPimHelloHoldtime(PacketPimHelloOptions):
raise Exception raise Exception
(holdtime, ) = struct.unpack(PacketPimHelloHoldtime.PIM_HDR_OPT, (holdtime, ) = struct.unpack(PacketPimHelloHoldtime.PIM_HDR_OPT,
data[:PacketPimHelloHoldtime.PIM_HDR_OPT_LEN]) data[:PacketPimHelloHoldtime.PIM_HDR_OPT_LEN])
print("HOLDTIME:", holdtime) #print("HOLDTIME:", holdtime)
return PacketPimHelloHoldtime(holdtime=holdtime) return PacketPimHelloHoldtime(holdtime=holdtime)
...@@ -142,7 +142,7 @@ class PacketPimHelloGenerationID(PacketPimHelloOptions): ...@@ -142,7 +142,7 @@ class PacketPimHelloGenerationID(PacketPimHelloOptions):
raise Exception raise Exception
(generation_id, ) = struct.unpack(PacketPimHelloGenerationID.PIM_HDR_OPT, (generation_id, ) = struct.unpack(PacketPimHelloGenerationID.PIM_HDR_OPT,
data[:PacketPimHelloGenerationID.PIM_HDR_OPT_LEN]) data[:PacketPimHelloGenerationID.PIM_HDR_OPT_LEN])
print("GenerationID:", generation_id) #print("GenerationID:", generation_id)
return PacketPimHelloGenerationID(generation_id=generation_id) return PacketPimHelloGenerationID(generation_id=generation_id)
...@@ -158,7 +158,7 @@ class PacketPimHelloUnknown(PacketPimHelloOptions): ...@@ -158,7 +158,7 @@ class PacketPimHelloUnknown(PacketPimHelloOptions):
''' '''
def __init__(self, type, length): def __init__(self, type, length):
super().__init__(type=type, length=length) super().__init__(type=type, length=length)
print("PIM Hello Option Unknown... TYPE=", type, "LENGTH=", length) #print("PIM Hello Option Unknown... TYPE=", type, "LENGTH=", length)
def bytes(self) -> bytes: def bytes(self) -> bytes:
raise Exception raise Exception
......
...@@ -64,7 +64,7 @@ class PacketPimStateRefresh: ...@@ -64,7 +64,7 @@ class PacketPimStateRefresh:
msg = multicast_group_adress + source_address + originator_adress + \ msg = multicast_group_adress + source_address + originator_adress + \
struct.pack(self.PIM_HDR_STATE_REFRESH_WITHOUT_ADDRESSES, 0x7FFFFFFF & self.metric_preference, struct.pack(self.PIM_HDR_STATE_REFRESH_WITHOUT_ADDRESSES, 0x7FFFFFFF & self.metric_preference,
self.metric, self.mask_len, self.ttl, prune_and_assert_flags, self. interval) self.metric, self.mask_len, self.ttl, prune_and_assert_flags, self.interval)
return msg return msg
......
...@@ -102,16 +102,17 @@ class UnicastRouting(object): ...@@ -102,16 +102,17 @@ class UnicastRouting(object):
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(action)
print(msg) print(msg)
interface_name = None
attrs = msg["attrs"] attrs = msg["attrs"]
for (key, value) in attrs: for (key, value) in attrs:
print((key, value)) print((key, value))
if key == "IFA_LABEL": if key == "IFA_LABEL":
interface_name = value interface_name = value
break break
pim_interface = Main.kernel.pim_interface.get(interface_name)
pim_interface.change_interface() Main.kernel.notify_interface_change(interface_name)
igmp_interface = Main.kernel.igmp_interface.get(interface_name)
''' '''
pass pass
......
...@@ -12,7 +12,7 @@ class KernelEntry: ...@@ -12,7 +12,7 @@ class KernelEntry:
TREE_TIMEOUT = 180 TREE_TIMEOUT = 180
KERNEL_LOGGER = logging.getLogger('pim.KernelEntry') 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):
self.kernel_entry_logger = logging.LoggerAdapter(KernelEntry.KERNEL_LOGGER, {'tree': '(' + source_ip + ',' + group_ip + ')'}) self.kernel_entry_logger = logging.LoggerAdapter(KernelEntry.KERNEL_LOGGER, {'tree': '(' + source_ip + ',' + group_ip + ')'})
self.kernel_entry_logger.debug('Create KernelEntry') self.kernel_entry_logger.debug('Create KernelEntry')
...@@ -55,7 +55,7 @@ class KernelEntry: ...@@ -55,7 +55,7 @@ class KernelEntry:
for i in Main.kernel.vif_index_to_name_dic.keys(): for i in Main.kernel.vif_index_to_name_dic.keys():
try: try:
if i == self.inbound_interface_index: if i == self.inbound_interface_index:
self.interface_state[i] = TreeInterfaceUpstream(self, i, False) self.interface_state[i] = TreeInterfaceUpstream(self, i)
else: else:
self.interface_state[i] = TreeInterfaceDownstream(self, i) self.interface_state[i] = TreeInterfaceDownstream(self, i)
except: except:
...@@ -199,7 +199,7 @@ class KernelEntry: ...@@ -199,7 +199,7 @@ class KernelEntry:
# change type of interfaces # change type of interfaces
new_downstream_interface = TreeInterfaceDownstream(self, self.inbound_interface_index) new_downstream_interface = TreeInterfaceDownstream(self, self.inbound_interface_index)
self.interface_state[self.inbound_interface_index] = new_downstream_interface self.interface_state[self.inbound_interface_index] = new_downstream_interface
new_upstream_interface = TreeInterfaceUpstream(self, new_inbound_interface_index, False) new_upstream_interface = TreeInterfaceUpstream(self, new_inbound_interface_index)
self.interface_state[new_inbound_interface_index] = new_upstream_interface self.interface_state[new_inbound_interface_index] = new_upstream_interface
self.inbound_interface_index = new_inbound_interface_index self.inbound_interface_index = new_inbound_interface_index
...@@ -223,6 +223,10 @@ class KernelEntry: ...@@ -223,6 +223,10 @@ class KernelEntry:
self.change() self.change()
self.evaluate_olist_change() self.evaluate_olist_change()
def new_or_reset_neighbor(self, if_index, neighbor_ip):
# todo maybe lock de interfaces
self.interface_state[if_index].new_or_reset_neighbor(neighbor_ip)
def is_olist_null(self): def is_olist_null(self):
for interface in self.interface_state.values(): for interface in self.interface_state.values():
if interface.is_forwarding(): if interface.is_forwarding():
...@@ -248,7 +252,6 @@ class KernelEntry: ...@@ -248,7 +252,6 @@ class KernelEntry:
return self.group_ip return self.group_ip
def change(self): def change(self):
# todo: changes on unicast routing or multicast routing...
with self._multicast_change: with self._multicast_change:
Main.kernel.set_multicast_route(self) Main.kernel.set_multicast_route(self)
......
...@@ -52,6 +52,8 @@ class Originator(OriginatorStateABC): ...@@ -52,6 +52,8 @@ class Originator(OriginatorStateABC):
#print('Source no longer directly connected, O to NO') #print('Source no longer directly connected, O to NO')
tree.originator_logger.debug('Source no longer directly connected, O -> NO') tree.originator_logger.debug('Source no longer directly connected, O -> NO')
def __str__(self):
return 'O'
class NotOriginator(OriginatorStateABC): class NotOriginator(OriginatorStateABC):
@staticmethod @staticmethod
...@@ -79,6 +81,9 @@ class NotOriginator(OriginatorStateABC): ...@@ -79,6 +81,9 @@ class NotOriginator(OriginatorStateABC):
def SourceNotConnected(tree): def SourceNotConnected(tree):
return return
def __str__(self):
return 'NO'
class OriginatorState(): class OriginatorState():
NotOriginator = NotOriginator() NotOriginator = NotOriginator()
......
...@@ -27,6 +27,9 @@ class TreeInterfaceDownstream(TreeInterface): ...@@ -27,6 +27,9 @@ class TreeInterfaceDownstream(TreeInterface):
self.logger.debug('Created DownstreamInterface') self.logger.debug('Created DownstreamInterface')
self.join_prune_logger.debug(str(self._prune_state)) self.join_prune_logger.debug(str(self._prune_state))
# Last state refresh message sent (resend in case of new neighbors)
self._last_state_refresh_message = None
########################################## ##########################################
# Set state # Set state
########################################## ##########################################
...@@ -116,6 +119,10 @@ class TreeInterfaceDownstream(TreeInterface): ...@@ -116,6 +119,10 @@ class TreeInterfaceDownstream(TreeInterface):
# Send messages # Send messages
###################################### ######################################
def send_state_refresh(self, state_refresh_msg_received): def send_state_refresh(self, state_refresh_msg_received):
if state_refresh_msg_received is None:
return
self._last_state_refresh_message = state_refresh_msg_received
if self.lost_assert() or not self.get_interface().is_state_refresh_enabled(): if self.lost_assert() or not self.get_interface().is_state_refresh_enabled():
return return
...@@ -167,9 +174,10 @@ class TreeInterfaceDownstream(TreeInterface): ...@@ -167,9 +174,10 @@ class TreeInterfaceDownstream(TreeInterface):
# self._assert_winner_metric.is_better_than(AssertMetric.spt_assert_metric(self)) # self._assert_winner_metric.is_better_than(AssertMetric.spt_assert_metric(self))
# Override # Override
def nbr_connected(self): # When new neighbor connects, send last state refresh msg
# TODO resend last state refresh messages def new_or_reset_neighbor(self, neighbor_ip):
return self.send_state_refresh(self._last_state_refresh_message)
# Override # Override
def delete(self, change_type_interface=False): def delete(self, change_type_interface=False):
......
...@@ -22,7 +22,7 @@ import Main ...@@ -22,7 +22,7 @@ import Main
class TreeInterfaceUpstream(TreeInterface): class TreeInterfaceUpstream(TreeInterface):
LOGGER = logging.getLogger('pim.KernelEntry.UpstreamInterface') LOGGER = logging.getLogger('pim.KernelEntry.UpstreamInterface')
def __init__(self, kernel_entry, interface_id, is_originater: bool): def __init__(self, kernel_entry, interface_id):
extra_dict_logger = kernel_entry.kernel_entry_logger.extra.copy() extra_dict_logger = kernel_entry.kernel_entry_logger.extra.copy()
extra_dict_logger['vif'] = interface_id extra_dict_logger['vif'] = interface_id
extra_dict_logger['interfacename'] = Main.kernel.vif_index_to_name_dic[interface_id] extra_dict_logger['interfacename'] = Main.kernel.vif_index_to_name_dic[interface_id]
...@@ -42,7 +42,8 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -42,7 +42,8 @@ class TreeInterfaceUpstream(TreeInterface):
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) self.originator_logger = logging.LoggerAdapter(TreeInterfaceUpstream.LOGGER.getChild('Originator'), extra_dict_logger)
self.originator_logger.debug(str(self._originator_state))
if self.is_S_directly_conn(): if self.is_S_directly_conn():
self._graft_prune_state.sourceIsNowDirectConnect(self) self._graft_prune_state.sourceIsNowDirectConnect(self)
...@@ -89,6 +90,7 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -89,6 +90,7 @@ class TreeInterfaceUpstream(TreeInterface):
def set_originator_state(self, new_state: OriginatorStateABC): def set_originator_state(self, new_state: OriginatorStateABC):
if new_state != self._originator_state: if new_state != self._originator_state:
self._originator_state = new_state self._originator_state = new_state
self.originator_logger.debug(str(new_state))
########################################## ##########################################
# Check timers # Check timers
...@@ -250,6 +252,12 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -250,6 +252,12 @@ class TreeInterfaceUpstream(TreeInterface):
def change_on_unicast_routing(self, interface_change=False): def change_on_unicast_routing(self, interface_change=False):
self.change_rpf(self.is_olist_null(), interface_change) self.change_rpf(self.is_olist_null(), interface_change)
'''
if self.is_S_directly_conn():
self._graft_prune_state.sourceIsNowDirectConnect(self)
else:
self._originator_state.SourceNotConnected(self)
'''
def change_rpf(self, olist_is_null, interface_change=False): def change_rpf(self, olist_is_null, interface_change=False):
current_rpf = self.get_neighbor_RPF() current_rpf = self.get_neighbor_RPF()
...@@ -266,6 +274,11 @@ class TreeInterfaceUpstream(TreeInterface): ...@@ -266,6 +274,11 @@ class TreeInterfaceUpstream(TreeInterface):
def is_forwarding(self): def is_forwarding(self):
return False return False
# If new/reset neighbor is RPF neighbor => clear prune limit timer
def new_or_reset_neighbor(self, neighbor_ip):
if neighbor_ip == self.get_neighbor_RPF():
self.clear_prune_limit_timer()
#Override #Override
def delete(self, change_type_interface=False): def delete(self, change_type_interface=False):
self.socket_is_enabled = False self.socket_is_enabled = False
......
...@@ -5,7 +5,7 @@ Created on Jul 16, 2015 ...@@ -5,7 +5,7 @@ Created on Jul 16, 2015
''' '''
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
import Main import Main
from threading import Lock, RLock from threading import RLock
import traceback import traceback
from .downstream_prune import DownstreamState from .downstream_prune import DownstreamState
...@@ -263,16 +263,12 @@ class TreeInterface(metaclass=ABCMeta): ...@@ -263,16 +263,12 @@ class TreeInterface(metaclass=ABCMeta):
def is_forwarding(self): def is_forwarding(self):
pass pass
def nbr_connected(self):
pass
def assert_winner_nlt_expires(self): def assert_winner_nlt_expires(self):
self._assert_state.winnerLivelinessTimerExpires(self) self._assert_state.winnerLivelinessTimerExpires(self)
@abstractmethod
#@abstractmethod def new_or_reset_neighbor(self, neighbor_ip):
def is_now_root(self): raise NotImplementedError()
pass
@abstractmethod @abstractmethod
def delete(self, change_type_interface=False): def delete(self, change_type_interface=False):
......
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