Commit 1a64d22c authored by Pedro Oliveira's avatar Pedro Oliveira

Add command to list instances && fix issue of -mvr and -uvrf being mutually...

Add command to list instances && fix issue of -mvr and -uvrf being mutually exclusive && fix state refresh deadlock && include originator state on -ls
parent 4f60a67a
......@@ -46,7 +46,7 @@ In order to start the protocol you first need to explicitly start it. This will
IPv4 and IPv6 multicast is supported. By default all commands will be executed on IPv4 daemon. To execute a command on the IPv6 daemon use `-6`.
We support multiple tables. Each daemon process will be bind to a given multicast and unicast table id, with can be defined at startup with `-mvrf` and `-uvrf`.
We support multiple tables. Each daemon process will be bind to a given multicast and unicast table id, which can be defined at startup with `-mvrf` and `-uvrf`.
If `-mvrf` is not defined, the default multicast table id will be used (table id 0).
......
......@@ -228,15 +228,14 @@ class InterfacePim(Interface):
"""
Check StateRefresh capability of interface neighbors
"""
with self.neighbors_lock.genWlock():
if len(self.neighbors) == 0:
return False
if len(self.neighbors) == 0:
return False
state_refresh_capable = True
for neighbor in list(self.neighbors.values()):
state_refresh_capable &= neighbor.state_refresh_capable
state_refresh_capable = True
for neighbor in list(self.neighbors.values()):
state_refresh_capable &= neighbor.state_refresh_capable
return state_refresh_capable
return state_refresh_capable
'''
def change_interface(self):
......
......@@ -4,6 +4,7 @@ import netifaces
import logging
import logging.handlers
from prettytable import PrettyTable
from pimdm.tree import pim_globals
from pimdm import UnicastRouting
from pimdm.TestLogger import RootFilter
......@@ -158,7 +159,7 @@ def list_routing_state(ipv4=False, ipv6=False):
for b in list(a.values()):
routing_entries.append(b)
t = PrettyTable(['SourceIP', 'GroupIP', 'Interface', 'PruneState', 'AssertState', 'LocalMembership', "Is Forwarding?"])
t = PrettyTable(['SourceIP', 'GroupIP', 'Interface', 'OriginatorState', 'PruneState', 'AssertState', 'LocalMembership', "Is Forwarding?"])
for entry in routing_entries:
ip = entry.source_ip
group = entry.group_ip
......@@ -172,16 +173,29 @@ def list_routing_state(ipv4=False, ipv6=False):
assert_state = type(interface_state._assert_state).__name__
if index != upstream_if_index:
prune_state = type(interface_state._prune_state).__name__
originator_state = "-"
is_forwarding = interface_state.is_forwarding()
else:
prune_state = type(interface_state._graft_prune_state).__name__
is_forwarding = "upstream"
originator_state = type(interface_state._originator_state).__name__
except:
originator_state = "-"
prune_state = "-"
assert_state = "-"
is_forwarding = "-"
t.add_row([ip, group, interface_name, prune_state, assert_state, local_membership, is_forwarding])
t.add_row([ip, group, interface_name, originator_state, prune_state, assert_state, local_membership, is_forwarding])
return str(t)
def list_instances():
"""
List instance information
"""
t = PrettyTable(['Instance PID', 'Multicast VRF', 'Unicast VRF'])
import os
t.add_row([os.getpid(), pim_globals.MULTICAST_TABLE_ID, pim_globals.UNICAST_TABLE_ID])
return str(t)
......
......@@ -2,19 +2,21 @@
import os
import sys
import glob
import socket
import argparse
import traceback
import _pickle as pickle
from prettytable import PrettyTable
from pimdm import Main
from pimdm.tree import pim_globals
from pimdm.daemon.Daemon import Daemon
VERSION = "1.1.1.2"
VERSION = "1.1.1.3"
def client_socket(data_to_send):
def client_socket(data_to_send, print_output=True):
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
......@@ -26,7 +28,10 @@ def client_socket(data_to_send):
sock.sendall(pickle.dumps(data_to_send))
data_rcv = sock.recv(1024 * 256)
if data_rcv:
print(pickle.loads(data_rcv))
if print_output:
print(pickle.loads(data_rcv))
else:
return pickle.loads(data_rcv)
except socket.error:
pass
finally:
......@@ -92,6 +97,8 @@ class MyDaemon(Daemon):
elif 'remove_interface_mld' in args and args.remove_interface_mld:
Main.remove_interface(args.remove_interface_mld[0], membership=True, ipv4=False, ipv6=True)
connection.shutdown(socket.SHUT_RDWR)
elif 'list_instances' in args and args.list_instances:
connection.sendall(pickle.dumps(Main.list_instances()))
elif 'stop' in args and args.stop:
Main.stop()
connection.shutdown(socket.SHUT_RDWR)
......@@ -121,6 +128,8 @@ def main():
"Use -4 or -6 to specify IPv4 or IPv6 PIM neighbors.")
group.add_argument("-ls", "--list_state", action="store_true", default=False, help="List IGMP/MLD and PIM-DM state machines."
" Use -4 or -6 to specify IPv4 or IPv6 state respectively.")
group.add_argument("-instances", "--list_instances", action="store_true", default=False,
help="List running PIM-DM daemon processes.")
group.add_argument("-mr", "--multicast_routes", action="store_true", default=False, help="List Multicast Routing table. "
"Use -4 or -6 to specify IPv4 or IPv6 multicast routing table.")
group.add_argument("-ai", "--add_interface", nargs=1, metavar='INTERFACE_NAME', help="Add PIM interface. "
......@@ -139,7 +148,7 @@ def main():
group_ipversion = parser.add_mutually_exclusive_group(required=False)
group_ipversion.add_argument("-4", "--ipv4", action="store_true", default=False, help="Setting for IPv4")
group_ipversion.add_argument("-6", "--ipv6", action="store_true", default=False, help="Setting for IPv6")
group_vrf = parser.add_mutually_exclusive_group(required=False)
group_vrf = parser.add_argument_group()
group_vrf.add_argument("-mvrf", "--multicast_vrf", nargs=1, default=[pim_globals.MULTICAST_TABLE_ID],
metavar='MULTICAST_VRF_NUMBER', type=int,
help="Define multicast table id. This can be used on -start to explicitly start the daemon"
......@@ -157,6 +166,21 @@ def main():
if os.geteuid() != 0:
sys.exit('PIM-DM must be run as root!')
if args.list_instances:
pid_files = glob.glob("/tmp/Daemon-pim*.pid")
t = PrettyTable(['Instance PID', 'Multicast VRF', 'Unicast VRF'])
for pid_file in pid_files:
d = MyDaemon(pid_file)
pim_globals.MULTICAST_TABLE_ID = pid_file[15:-4]
if not d.is_running():
continue
t_new = client_socket(args, print_output=False)
t.add_row(t_new.replace(" ", "").split("\n")[3].split("|")[1:4])
print(t)
return
pim_globals.MULTICAST_TABLE_ID = args.multicast_vrf[0]
pim_globals.UNICAST_TABLE_ID = args.unicast_vrf[0]
......
......@@ -149,7 +149,7 @@ class KernelEntry:
return
# refresh limit
timestamp = time()
if (timestamp - self.timestamp_of_last_state_refresh_message_received) < interval:
if (timestamp - self.timestamp_of_last_state_refresh_message_received) < interval - 5:
return
self.timestamp_of_last_state_refresh_message_received = timestamp
if ttl == 0:
......
......@@ -114,6 +114,7 @@ class TreeInterfaceDownstream(TreeInterface):
# Send messages
######################################
def send_state_refresh(self, state_refresh_msg_received):
print("send state refresh")
if state_refresh_msg_received is None:
return
......
......@@ -13,7 +13,7 @@ setup(
long_description=open("README.md", "r").read(),
long_description_content_type="text/markdown",
keywords="PIM-DM Multicast Routing Protocol PIM Dense-Mode Router RFC3973 IPv4 IPv6",
version="1.1.1.2",
version="1.1.1.3",
url="http://github.com/pedrofran12/pim_dm",
author="Pedro Oliveira",
author_email="pedro.francisco.oliveira@tecnico.ulisboa.pt",
......
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