This update add two arguments to voltha when it gets started:
1) inter-core-subnet: the subnet to connect to for inter core communication
2) pon-subnet: the subnet to connect to for PON communication
This requires that the voltha_net is created with a specified subnet and that
subnet is specified in the docker compose file, e.g.:
docker network create --driver overlay --subnet 10.0.1.0/24 voltha_net
And in the compose.yml file add the following options:
- --inter-core-subnet=10.0.1.0/24
- --pon-subnet=10.0.1.0/24
This update guarantees that the voltha instance is connected to the correct
network.
Change-Id: I5d29ab54282c4ba9aff5ba165fdb37352cfaa0fd
diff --git a/common/utils/nethelpers.py b/common/utils/nethelpers.py
index a082eeb..a4610a2 100644
--- a/common/utils/nethelpers.py
+++ b/common/utils/nethelpers.py
@@ -21,8 +21,17 @@
from netifaces import AF_INET
import netifaces as ni
+import netaddr
-def get_my_primary_interface():
+
+def _get_all_interfaces():
+ m_interfaces = []
+ for iface in ni.interfaces():
+ m_interfaces.append((iface, ni.ifaddresses(iface)))
+ return m_interfaces
+
+
+def _get_my_primary_interface():
gateways = ni.gateways()
assert 'default' in gateways, \
("No default gateway on host/container, "
@@ -34,7 +43,33 @@
return interface_name
-def get_my_primary_local_ipv4(ifname=None):
+def get_my_primary_local_ipv4(inter_core_subnet=None, ifname=None):
+ if not inter_core_subnet:
+ return _get_my_primary_local_ipv4(ifname)
+ # My IP should belong to the specified subnet
+ for iface in ni.interfaces():
+ m_ip = ni.ifaddresses(iface)[AF_INET][0]['addr']
+ _ip = netaddr.IPAddress(m_ip).value
+ m_network = netaddr.IPNetwork(inter_core_subnet)
+ if _ip >= m_network.first and _ip <= m_network.last:
+ return m_ip
+ return None
+
+
+def get_my_primary_interface(pon_subnet=None):
+ if not pon_subnet:
+ return _get_my_primary_interface()
+ # My interface should have an IP that belongs to the specified subnet
+ for iface in ni.interfaces():
+ m_ip = ni.ifaddresses(iface)[AF_INET][0]['addr']
+ m_ip = netaddr.IPAddress(m_ip).value
+ m_network = netaddr.IPNetwork(pon_subnet)
+ if m_ip >= m_network.first and m_ip <= m_network.last:
+ return iface
+ return None
+
+
+def _get_my_primary_local_ipv4(ifname=None):
try:
ifname = get_my_primary_interface() if ifname is None else ifname
addresses = ni.ifaddresses(ifname)
@@ -43,6 +78,5 @@
except Exception as e:
return None
-
if __name__ == '__main__':
print get_my_primary_local_ipv4()
diff --git a/compose/docker-compose-voltha-swarm.yml b/compose/docker-compose-voltha-swarm.yml
index 39532f7..ff03c67 100644
--- a/compose/docker-compose-voltha-swarm.yml
+++ b/compose/docker-compose-voltha-swarm.yml
@@ -15,6 +15,9 @@
- --instance-id-is-container-name
- --interface=eth2
- --backend=consul
+ - --inter-core-subnet=10.0.1.0/24
+ - --pon-subnet=10.0.1.0/24
+
networks:
- net
ports:
@@ -26,5 +29,6 @@
networks:
net:
- external:
- name: voltha_net
+ external:
+ name: voltha_net
+
diff --git a/requirements.txt b/requirements.txt
index 7009e4e..bb31099 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -15,6 +15,7 @@
jsonpatch>=1.14
kafka_python>=1.3.1
klein>=15.3.1
+netaddr>=0.7.18
networkx>=1.11
nose>=1.3.7
nose-exclude>=0.5.0
diff --git a/voltha/main.py b/voltha/main.py
index 9eb12d4..c5cb300 100755
--- a/voltha/main.py
+++ b/voltha/main.py
@@ -52,11 +52,15 @@
defs = dict(
config=os.environ.get('CONFIG', './voltha.yml'),
consul=os.environ.get('CONSUL', 'localhost:8500'),
- external_host_address=os.environ.get('EXTERNAL_HOST_ADDRESS', None),
+ inter_core_subnet=os.environ.get('INTER_CORE_SUBNET', None),
+ pon_subnet=os.environ.get('PON_SUBNET', None),
+ external_host_address=os.environ.get('EXTERNAL_HOST_ADDRESS',
+ get_my_primary_local_ipv4()),
fluentd=os.environ.get('FLUENTD', None),
grpc_port=os.environ.get('GRPC_PORT', 50055),
instance_id=os.environ.get('INSTANCE_ID', os.environ.get('HOSTNAME', '1')),
- internal_host_address=os.environ.get('INTERNAL_HOST_ADDRESS', None),
+ internal_host_address=os.environ.get('INTERNAL_HOST_ADDRESS',
+ get_my_primary_local_ipv4()),
interface=os.environ.get('INTERFACE', get_my_primary_interface()),
rest_port=os.environ.get('REST_PORT', 8880),
kafka=os.environ.get('KAFKA', 'localhost:9092'),
@@ -83,6 +87,23 @@
default=defs['consul'],
help=_help)
+
+ _help = ('<inter_core_subnet> is the subnet connecting all the voltha '
+ 'instances in a cluster (default: %s)' % defs['inter_core_subnet'])
+ parser.add_argument('-V', '--inter-core-subnet',
+ dest='inter_core_subnet',
+ action='store',
+ default=defs['inter_core_subnet'],
+ help=_help)
+
+ _help = ('<pon subnet> is the subnet connecting the voltha instances'
+ 'with the PON network (default: %s)' % defs['pon_subnet'])
+ parser.add_argument('-P', '--pon-subnet',
+ dest='pon_subnet',
+ action='store',
+ default=defs['pon_subnet'],
+ help=_help)
+
_help = ('<hostname> or <ip> at which Voltha is reachable from outside '
'the cluster (default: %s)' % defs['external_host_address'])
parser.add_argument('-E', '--external-host-address',
@@ -204,14 +225,21 @@
if args.instance_id_is_container_name:
args.instance_id = get_my_containers_name()
- m_ip = get_my_primary_local_ipv4(args.interface)
- if not m_ip:
- m_ip = get_my_primary_local_ipv4()
- if not args.external_host_address:
+ """
+ The container external, internal IP and PON interface needs to be
+ set based on the subnet data. At this time the internal IP is not used.
+ The external IP is used for inter-core communications. If the subnets are
+ set then they take precedence over the other relevant arguments (
+ external and internal host as well as interface
+ """
+ if args.inter_core_subnet:
+ m_ip = get_my_primary_local_ipv4(inter_core_subnet=args.inter_core_subnet)
args.external_host_address = m_ip
- if not args.internal_host_address:
args.internal_host_address = m_ip
+ if args.pon_subnet:
+ args.interface = get_my_primary_interface(args.pon_subnet)
+
return args
@@ -291,7 +319,9 @@
try:
self.log.info('starting-internal-components',
internal_host=self.args.internal_host_address,
- external_host=self.args.external_host_address)
+ external_host=self.args.external_host_address,
+ interface=self.args.interface,
+ consul=self.args.consul)
registry.register('main', self)