Commit 4cab6eca authored by Federico Sismondi's avatar Federico Sismondi

Merge branch 'support_router_mode' into 'master'

agent can bootstrap automatically through the agent's cli, see options --force-bootstrap     --ipv6-prefix bbbb     --ipv6-host 100

See merge request !28
parents 40775c2f 3f8c2669
......@@ -60,14 +60,46 @@ class Agent(object):
"""
header = """
F-interop agent and management tool.
Agent (~VPN client) for connecting your implementation under test (IUT) to the private network of the remote interop
session.
Please use the following format to connect to the f-interop server:
Some examples on the different modes of running the agent (depending on the cabling and networking of your IUT):
Note: We assume that a session was a already created and user has url
1. user runs an IPv6 based implementation (e.g. coap_client) which runs in same PC where agent runs (default mode):
command:
```
sudo python -m agent connect
--url amqp://alfredo:zitarrosa@exampleRmqHost[:port]/sessionXX
--name coap_client
```
expected result:
agent is connected to f-interop and now awaits bootstrap command from backend
2. user runs an IPv6 based implementation (e.g. coap_client) which runs in same PC where agent runs, but wants to force
bootstrap ( virtual interface creation, and forced IP assignation)
sudo python -m agent connect
--url amqp://alfredo:zitarrosa@exampleRmqHost[:port]/sessionXX
--exchange myExchange
--name coap_client
--force-bootstrap
--ipv6-prefix bbbb
--ipv6-host 100
expected result:
agent is connected to f-interop, bootstrapped, and has an assigned IPv6 (check interface with ifconfig)
continue writing this...
TODO document --serial for 802.15.4 probes
TODO document --router-mode for re-routing the packets to another interface
For more information, visit: http://doc.f-interop.eu
""",
......@@ -103,14 +135,33 @@ For more information, visit: http://doc.f-interop.eu
param_decls=["--dump"],
default=False,
required=False,
help="[NOT YET SUPPORTED] Dump automatically data packets from event bus into pcap files.",
help="[NOT YET SUPPORTED] Dump automatically data packets from event bus into pcap files",
is_flag=True)
self.force_bootstrap = click.Option(
param_decls=["--force-bootstrap"],
default=False,
required=False,
help="Force agent's bootstrap",
is_flag=True)
self.ipv6_prefix = click.Option(
param_decls=["--ipv6-prefix"],
default="bbbb",
required=False,
help="Prefix of IPv6 address, used only if --force-bootstrap")
self.ipv6_host = click.Option(
param_decls=["--ipv6-host"],
default="1",
required=False,
help="Host IPv6 address, used only if --force-bootstrap")
self.serial_option = click.Option(
param_decls=["--serial"],
default=False,
required=False,
help="Run agent bound to serial injector/forwarder of 802.15.4 frames .",
help="Run agent bound to serial injector/forwarder of 802.15.4 frames",
is_flag=True)
# Commands
......@@ -123,16 +174,19 @@ For more information, visit: http://doc.f-interop.eu
self.session_amqp_exchange,
self.name_option,
self.dump_option,
self.serial_option
self.force_bootstrap,
self.ipv6_host,
self.ipv6_prefix,
self.serial_option,
],
short_help="Connect with authentication AMQP_URL, and some other basic agent configurations."
short_help="Connect with authentication AMQP_URL, and some other basic agent configurations"
)
self.cli.add_command(self.connect_command)
self.plugins = {}
def handle_connect(self, url, exchange, name, dump, serial):
def handle_connect(self, url, exchange, name, dump, force_bootstrap, ipv6_host, ipv6_prefix, serial):
"""
Authenticate USER and create agent connection to f-interop.
......@@ -159,9 +213,13 @@ For more information, visit: http://doc.f-interop.eu
if serial:
self.plugins["serial"] = SerialConnector(**data)
else:
# pass some extra kwargs specific to the TunConnector
data['force_bootstrap'] = force_bootstrap
data['ipv6_host'] = ipv6_host
data['ipv6_prefix'] = ipv6_prefix
self.plugins["tun"] = TunConnector(**data)
# self.plugins["http"] = HTTPConnector(**data)
for p in self.plugins.values():
p.start()
......
......@@ -5,7 +5,7 @@ import json
import logging
from multiprocessing import Process
from utils.messages import Message as EventBusMessage, MsgTestingToolComponentReady as EventBusMessageComponentReady
from utils.messages import Message as EventBusMessage
from amqp.exceptions import UnexpectedFrame
from kombu import Connection, Queue, Exchange, Consumer
......@@ -62,7 +62,7 @@ class BaseConsumer(ConsumerMixin):
def subscribe_to_topics(self, topic_list):
for t in topic_list:
queue = Queue(
name="consumer:{name}.{consumer_name}::RKey:{rkey}".format(
name="consumer: {name}.{consumer_name}::RKey:{rkey}".format(
name=self.name,
consumer_name=self.consumer_name,
rkey=t
......
......@@ -22,11 +22,12 @@ class TunConsumer(BaseConsumer):
"""
Tun interface consumer:
- creates tunnel interface (RAW_IP)
- inyects IPv6 packets comming from event bus into tun interaface
- sniffs and forwards packets from tun to event bus
- injects IPv6 packets coming from event bus into tun interface
- captures and forwards packets from tun interface to event bus
"""
def __init__(self, user, password, session, server, exchange, name, consumer_name):
def __init__(self, user, password, session, server, exchange, name, consumer_name, force_bootstrap, ipv6_host,
ipv6_prefix):
self.dispatcher = {
MsgAgentTunStart: self.handle_start,
MsgPacketInjectRaw: self.handle_raw_packet_to_inject,
......@@ -35,12 +36,24 @@ class TunConsumer(BaseConsumer):
self.packet_count = 0
subscriptions = [
MsgAgentTunStart.routing_key.replace('*', name),
MsgAgentTunStart.routing_key.replace('*', name), # default rkey is "toAgent.*.ip.tun.start"
MsgPacketInjectRaw.routing_key.replace('*', name)
]
super(TunConsumer, self).__init__(user, password, session, server, exchange, name, consumer_name, subscriptions)
if force_bootstrap:
self.handle_start(
MsgAgentTunStart(
ipv6_host=ipv6_host,
ipv6_prefix=ipv6_prefix,
ipv6_no_forwarding=False,
ipv4_host=None,
ipv4_network=None,
ipv4_netmask=None,
)
)
def _on_message(self, message):
msg_type = type(message)
assert msg_type in self.dispatcher.keys(), 'Event message couldnt be dispatched %s' % repr(message)
......@@ -52,13 +65,29 @@ class TunConsumer(BaseConsumer):
)
self.dispatcher[msg_type](message)
def _publish_agent_tun_started_message(self):
assert self.tun is not None
# get config from tun
conf = self.tun.get_tun_configuration()
conf.update({'name': self.name})
# publish message in event bus
msg = MsgAgentTunStarted(**conf)
producer = Producer(self.connection, serializer='json')
producer.publish(
body=msg.to_dict(),
exchange=self.exchange,
routing_key='fromAgent.{0}.ip.tun.started'.format(self.name)
)
def handle_start(self, msg):
"""
Function that will handle tun start event emitted coming from backend
"""
if self.tun is not None:
self.log.warning('Received open tun control message, but TUN already created')
return
else:
self.log.info('starting tun interface')
try:
......@@ -102,23 +131,8 @@ class TunConsumer(BaseConsumer):
self.log.error('Agent TunTap not yet supported for: {0}'.format(sys.platform))
sys.exit(1)
msg = MsgAgentTunStarted(
name=self.name,
ipv6_host=ipv6_host,
ipv6_prefix=ipv6_prefix,
ipv4_host=ipv4_host,
ipv4_network=ipv4_network,
ipv4_netmask=ipv4_netmask,
ipv6_no_forwarding=ipv6_no_forwarding,
)
self.log.info("Tun started. Publishing msg: %s" % repr(msg))
producer = Producer(self.connection, serializer='json')
producer.publish(
body=msg.to_dict(),
exchange=self.exchange,
routing_key='fromAgent.{0}.ip.tun.started'.format(self.name)
)
self.log.info("Tun is up. Publishing msg: %s" % repr(msg))
self._publish_agent_tun_started_message()
def handle_raw_packet_to_inject(self, message):
"""
......
......@@ -385,6 +385,18 @@ class OpenTunLinux(object):
# ======================== public ==========================================
def get_tun_configuration(self):
return {
'ipv6_prefix': self.ipv6_prefix,
'ipv6_host': self.ipv6_host,
'ipv6_no_forwarding': self.ipv6_no_forwarding,
'ipv4_host': self.ipv4_host,
'ipv4_network': self.ipv4_network,
'ipv4_netmask': self.ipv4_netmask,
}
# def close(self):
# if self.tunReadThread:
......@@ -606,6 +618,17 @@ class OpenTunMACOS(object):
# ======================== public ==========================================
def get_tun_configuration(self):
return {
'ipv6_prefix': self.ipv6_prefix,
'ipv6_host': self.ipv6_host,
'ipv6_no_forwarding': self.ipv6_no_forwarding,
'ipv4_host': self.ipv4_host,
'ipv4_network': self.ipv4_network,
'ipv4_netmask': self.ipv4_netmask,
}
# ======================== private =========================================
def _getNetworkPrefix_notif(self, sender, signal, data):
......
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