Commit 0cdd2a70 authored by Pedro Oliveira's avatar Pedro Oliveira

Configuration file support

parent 3896b38d
......@@ -55,6 +55,20 @@ If `-uvrf` is not defined, the default unicast table id will be used (table id 2
After starting the protocol process, if the default multicast table is not used, the following commands (for adding interfaces and listing state) need to have the argument `-mvrf` defined to specify the corresponding daemon process.
#### Multi daemon support
Multiple daemons are supported, each bind to a given multicast routing table id.
To perform configurations on one of these daemons use `-mvrf` command and define the daemon by its multicast table id.
To see all daemons that are currently running:
```
sudo pim-dm -instances
```
#### Add interface
After starting the protocol process you can enable the protocol in specific interfaces. You need to specify which interfaces will have IGMP enabled and which interfaces will have PIM-DM enabled.
......@@ -149,18 +163,33 @@ We have built some list commands that can be used to check the "internals" of th
sudo pim-dm -mr [-4 | -6] [-mvrf MULTICAST_TABLE_ID]
```
## Config File
## Help command
In order to determine which commands and corresponding arguments are available you can call the help command:
It is possible to configure the protocol using a YAML file. This configuration file can be used to set all interfaces that will have PIM-DM/IGMP/MLD enabled, as well to fine tune these protocols by setting their timers. Currently the settings are shared by all interfaces. In a future release it will be possible to set timers per interface.
To use this feature you need to manually install PyYaml. PyYaml is not automatically installed with `pim-dm` to support older Python versions (as of now PyYaml requires at least Python v3.5).
[This YAML file](https://github.com/pedrofran12/pim_dm/tree/master/config/config_example.yml) is a configuration file example.
It it also possible to get an YAML configuration file from the current settings of the daemon. This will output an YAML template that can be used later for enabling the daemon with the same settings (enabled interfaces and timers). The command for this matter is the following:
```
pim-dm -h
sudo pim-dm -get_config [-mvrf MULTICAST_TABLE_ID]
```
To input an YAML configuration file to the daemon:
```
sudo pim-dm -config CONFIGURATION_FILE_PATH
```
## Change settings
## Help command
In order to determine which commands and corresponding arguments are available you can call the help command:
Files tree/pim_globals.py, igmp/igmp_globals.py and mld/mld_globals.py store all timer values and some configurations regarding PIM-DM, IGMP and MLD. If you want to tune the implementation, you can change the values of these files. These configurations are used by all interfaces, meaning that there is no tuning per interface.
```
pim-dm -h
```
## Tests
......
MulticastVRF: 0
UnicastVRF: 254
PIM-DM:
DefaultTimers:
ASSERT_TIME: 180
GRAFT_RETRY_PERIOD: 3
JP_OVERRIDE_INTERVAL: 3.0
OVERRIDE_INTERVAL: 2.5
PROPAGATION_DELAY: 0.5
REFRESH_INTERVAL: 60
SOURCE_LIFETIME: 210
T_LIMIT: 210
Interfaces:
eth0:
ipv4:
enabled: true
ipv6:
enabled: true
eth1:
ipv4:
enabled: true
ipv6:
enabled: true
eth2:
ipv4:
enabled: true
ipv6:
enabled: true
IGMP:
Settings:
GROUP_MEMBERSHIP_INTERVAL: 260
LAST_MEMBER_QUERY_COUNT: 2
LAST_MEMBER_QUERY_INTERVAL: 1
MAX_RESPONSE_TIME_LAST_MEMBER_QUERY_INTERVAL: 10
MAX_RESPONSE_TIME_QUERY_RESPONSE_INTERVAL: 100
OTHER_QUERIER_PRESENT_INTERVAL: 255.0
QUERY_INTERVAL: 125
QUERY_RESPONSE_INTERVAL: 10
ROBUSTNESS_VARIABLE: 2
STARTUP_QUERY_COUNT: 2
STARTUP_QUERY_INTERVAL: 31.25
UNSOLICITED_REPORT_INTERVAL: 10
VERSION_1_ROUTER_PRESENT_TIMEOUT: 400
Interfaces:
eth0:
enabled: true
eth1:
enabled: true
eth2:
enabled: true
MLD:
Settings:
LAST_LISTENER_QUERY_COUNT: 2
LAST_LISTENER_QUERY_INTERVAL: 1
MULTICAST_LISTENER_INTERVAL: 260
OTHER_QUERIER_PRESENT_INTERVAL: 255.0
QUERY_INTERVAL: 125
QUERY_RESPONSE_INTERVAL: 10
ROBUSTNESS_VARIABLE: 2
STARTUP_QUERY_COUNT: 2
STARTUP_QUERY_INTERVAL: 31.25
UNSOLICITED_REPORT_INTERVAL: 10
Interfaces:
eth0:
enabled: true
eth1:
enabled: true
eth2:
enabled: true
This diff is collapsed.
......@@ -78,6 +78,8 @@ class InterfacePim(Interface):
# don't receive outgoing packets
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
#self.drop_packet_type = None
super().__init__(interface_name, s, s, vif_index)
super()._enable()
self.force_send_hello()
......@@ -107,6 +109,10 @@ class InterfacePim(Interface):
"""
Send a new packet destined to group_ip IP
"""
#if self.drop_packet_type is not None and data.payload.get_pim_type() == self.drop_packet_type:
# self.drop_packet_type = None
# return
super().send(data=data, group_ip=group_ip)
#Random interval for initial Hello message on bootup or triggered Hello message to a rebooting neighbor
......
......@@ -217,6 +217,33 @@ def test(router_name, server_logger_ip):
logger.addHandler(socketHandler)
def get_config():
"""
Get live configuration of PIM-DM process
"""
try:
from . import Config
return Config.get_yaml_file()
except ModuleNotFoundError:
return "PYYAML needs to be installed. Execute \"pip3 install pyyaml\""
def set_config(file_path):
"""
Set configuration of PIM-DM process
"""
from . import Config
try:
Config.parse_config_file(file_path)
except:
import traceback
traceback.print_exc()
def drop(interface_name, packet_type):
interfaces.get(interface_name).drop_packet_type = packet_type
def enable_ipv6_kernel():
"""
Function to explicitly enable IPv6 Multicast Routing stack.
......
......@@ -2,9 +2,11 @@
import os
import sys
import time
import glob
import socket
import argparse
import threading
import traceback
import _pickle as pickle
from prettytable import PrettyTable
......@@ -13,7 +15,7 @@ from pimdm import Main
from pimdm.tree import pim_globals
from pimdm.daemon.Daemon import Daemon
VERSION = "1.1.1.4"
VERSION = "1.2"
def client_socket(data_to_send, print_output=True):
......@@ -21,7 +23,7 @@ def client_socket(data_to_send, print_output=True):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = '/tmp/pim_uds_socket' + str(pim_globals.MULTICAST_TABLE_ID)
server_address = pim_globals.DAEMON_SOCKET.format(pim_globals.MULTICAST_TABLE_ID)
#print('connecting to %s' % server_address)
try:
sock.connect(server_address)
......@@ -42,7 +44,7 @@ def client_socket(data_to_send, print_output=True):
class MyDaemon(Daemon):
def run(self):
Main.main()
server_address = '/tmp/pim_uds_socket' + str(pim_globals.MULTICAST_TABLE_ID)
server_address = pim_globals.DAEMON_SOCKET.format(pim_globals.MULTICAST_TABLE_ID)
# Make sure the socket does not already exist
try:
......@@ -102,15 +104,24 @@ class MyDaemon(Daemon):
elif 'stop' in args and args.stop:
Main.stop()
connection.shutdown(socket.SHUT_RDWR)
break
elif 'test' in args and args.test:
Main.test(args.test[0], args.test[1])
connection.shutdown(socket.SHUT_RDWR)
elif 'config' in args and args.config:
Main.set_config(args.config[0])
connection.shutdown(socket.SHUT_RDWR)
elif 'get_config' in args and args.get_config:
connection.sendall(pickle.dumps(Main.get_config()))
elif 'drop' in args and args.drop:
Main.drop(args.drop[0], int(args.drop[1]))
except Exception:
connection.shutdown(socket.SHUT_RDWR)
traceback.print_exc()
finally:
# Clean up the connection
connection.close()
sock.close()
def main():
......@@ -144,6 +155,11 @@ def main():
group.add_argument("-rimld", "--remove_interface_mld", nargs=1, metavar='INTERFACE_NAME', help="Remove MLD interface")
group.add_argument("-v", "--verbose", action="store_true", default=False, help="Verbose (print all debug messages)")
group.add_argument("-t", "--test", nargs=2, metavar=('ROUTER_NAME', 'SERVER_LOG_IP'), help="Tester... send log information to SERVER_LOG_IP. Set the router name to ROUTER_NAME")
group.add_argument("-config", "--config", nargs=1, metavar='CONFIG_FILE_PATH', type=str,
help="File path for configuration file. This command should only be used with -start")
group.add_argument("-get_config", "--get_config", action="store_true", default=False,
help="Get configuration file of live daemon.")
#group.add_argument("-drop", "--drop", nargs=2, metavar=('INTERFACE_NAME', 'PACKET_TYPE'), type=str)
group.add_argument("--version", action='version', version='%(prog)s ' + VERSION)
group_ipversion = parser.add_mutually_exclusive_group(required=False)
group_ipversion.add_argument("-4", "--ipv4", action="store_true", default=False, help="Setting for IPv4")
......@@ -184,7 +200,7 @@ def main():
pim_globals.MULTICAST_TABLE_ID = args.multicast_vrf[0]
pim_globals.UNICAST_TABLE_ID = args.unicast_vrf[0]
daemon = MyDaemon('/tmp/Daemon-pim' + str(pim_globals.MULTICAST_TABLE_ID) + '.pid')
daemon = MyDaemon(pim_globals.DAEMON_PROCESS_FILE.format(pim_globals.MULTICAST_TABLE_ID))
if args.start:
print("start")
daemon.start()
......@@ -196,8 +212,25 @@ def main():
elif args.restart:
daemon.restart()
sys.exit(0)
elif args.config:
try:
from pimdm import Config
args.config[0] = os.path.abspath(args.config[0])
[pim_globals.MULTICAST_TABLE_ID, pim_globals.UNICAST_TABLE_ID] = Config.get_vrfs(args.config[0])
daemon = MyDaemon(pim_globals.DAEMON_PROCESS_FILE.format(pim_globals.MULTICAST_TABLE_ID))
if not daemon.is_running():
x = threading.Thread(target=daemon.start, args=())
x.start()
x.join()
while not daemon.is_running():
time.sleep(1)
except ModuleNotFoundError:
print("PYYAML needs to be installed. Execute \"pip3 install pyyaml\"")
sys.exit(0)
elif args.verbose:
os.system("tail -f /var/log/pimdm/stdout" + str(pim_globals.MULTICAST_TABLE_ID))
os.system("tail -f {}".format(pim_globals.DAEMON_LOG_STDOUT_FILE.format(pim_globals.MULTICAST_TABLE_ID)))
sys.exit(0)
elif args.multicast_routes:
if args.ipv4 or not args.ipv6:
......
# Protocol files
DAEMON_PROCESS_FILE = '/tmp/Daemon-pim{}.pid'
DAEMON_SOCKET = '/tmp/pim_uds_socket{}'
DAEMON_LOG_FOLDER = '/var/log/pimdm/'
DAEMON_LOG_STDOUT_FILE = DAEMON_LOG_FOLDER + 'stdout{}'
# PIM-DM TIMER VARIABLES
ASSERT_TIME = 180
GRAFT_RETRY_PERIOD = 3
......
......@@ -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.4",
version="1.2",
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