reserve a WAN address for the VM and use it for VM root context connectivity
diff --git a/xos/services/cord/models.py b/xos/services/cord/models.py
index fe978c9..959bf19 100644
--- a/xos/services/cord/models.py
+++ b/xos/services/cord/models.py
@@ -601,13 +601,16 @@
else:
raise Exception("wan_container_ip.setter called on non-VTN CORD")
+ def ip_to_mac(self, ip):
+ (a, b, c, d) = ip.split('.')
+ return "02:42:%02x:%02x:%02x:%02x" % (int(a), int(b), int(c), int(d))
+
# Generate the MAC for the container interface connected to WAN
@property
def wan_container_mac(self):
if not self.wan_container_ip:
return None
- (a, b, c, d) = self.wan_container_ip.split('.')
- return "02:42:%02x:%02x:%02x:%02x" % (int(a), int(b), int(c), int(d))
+ return self.ip_to_mac(self.wan_container_ip)
@property
def private_ip(self):
@@ -760,24 +763,31 @@
self.bbs_account = None
super(VSGTenant, self).save()
+ def get_wan_address_from_pool(self):
+ ap = AddressPool.objects.filter(name="public_addresses")
+ if not ap:
+ raise Exception("AddressPool 'public_addresses' does not exist. Please configure it.")
+ ap = ap[0]
+
+ addr = ap.get_address()
+ if not addr:
+ raise Exception("AddressPool 'public_addresses' has run out of addresses.")
+ return addr
+
+ def put_wan_address_to_pool(self, addr):
+ AddressPool.objects.filter(name="public_addresses")[0].put_address(addr)
+
def manage_wan_container_ip(self):
if CORD_USE_VTN:
if not self.wan_container_ip:
- ap = AddressPool.objects.filter(name="public_addresses")
- if not ap:
- raise Exception("AddressPool 'public_addresses' does not exist. Please configure it.")
- ap = ap[0]
-
- addr = ap.get_address()
- if not addr:
- raise Exception("AddressPool 'public_addresses' has run out of addresses.")
+ addr = self.get_wan_address_from_pool()
self.wan_container_ip = addr
super(TenantWithContainer, self).save()
def cleanup_wan_container_ip(self):
if CORD_USE_VTN and self.wan_container_ip:
- AddressPool.objects.filter(name="public_addresses")[0].put_address(self.wan_container_ip)
+ self.put_wan_address_to_pool(self.wan_container_ip)
self.wan_container_ip = None
def find_or_make_port(self, instance, network, **kwargs):
@@ -838,6 +848,15 @@
tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag)
tag.save()
+ # VTN-CORD needs a WAN address for the VM, so that the VM can
+ # be configured.
+ if CORD_USE_VTN:
+ tags = Tag.select_by_content_object(instance).filter(name="vm_wan_addr")
+ if not tags:
+ address = self.get_wan_address_from_pool()
+ tag = Tag(service=self.provider_service, content_object=instance, name="vm_wan_addr", value="%s,%s,%s" % ("public_addresses", address, self.ip_to_mac(address)))
+ tag.save()
+
def save(self, *args, **kwargs):
if not self.creator:
if not getattr(self, "caller", None):
diff --git a/xos/synchronizers/vcpe/steps/sync_vcpetenant.py b/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
index 27b47d4..21b5bd7 100644
--- a/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
+++ b/xos/synchronizers/vcpe/steps/sync_vcpetenant.py
@@ -9,7 +9,7 @@
from synchronizers.base.syncstep import SyncStep
from synchronizers.base.ansible import run_template_ssh
from synchronizers.base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible
-from core.models import Service, Slice
+from core.models import Service, Slice, Tag
from services.cord.models import VSGService, VSGTenant, VOLTTenant
from services.hpc.models import HpcService, CDNPrefix
from xos.logger import Logger, logging
@@ -139,6 +139,19 @@
if mac:
safe_macs.append(mac)
+ wan_vm_ip=""
+ wan_vm_mac=""
+ tags = Tag.select_by_content_object(o.instance).filter(name="vm_wan_addr")
+ if tags:
+ parts=tags[0].value.split(",")
+ if len(parts)!=3:
+ raise Exception("vm_wan_addr tag is malformed: %s" % value)
+ wan_vm_ip = parts[1]
+ wan_vm_mac = parts[2]
+ else:
+ if CORD_USE_VTN:
+ raise Exception("no vm_wan_addr tag for instance %s" % instance)
+
fields = {"vlan_ids": vlan_ids, # XXX remove this
"s_tags": s_tags,
"c_tags": c_tags,
@@ -150,6 +163,8 @@
"wan_container_gateway_mac": vcpe_service.wan_container_gateway_mac,
"wan_container_gateway_ip": vcpe_service.wan_container_gateway_ip,
"wan_container_netbits": vcpe_service.wan_container_netbits,
+ "wan_vm_mac": wan_vm_mac,
+ "wan_vm_ip": wan_vm_ip,
"safe_browsing_macs": safe_macs}
# add in the sync_attributes that come from the SubscriberRoot object
diff --git a/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml b/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml
index c933f5b..26aa2ea 100644
--- a/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml
+++ b/xos/synchronizers/vcpe/steps/sync_vcpetenant_vtn.yaml
@@ -43,6 +43,8 @@
wan_container_netbits: {{ wan_container_netbits }}
wan_container_mac: {{ wan_container_mac }}
wan_container_gateway_ip: {{ wan_container_gateway_ip }}
+ wan_vm_ip: {{ wan_vm_ip }}
+ wan_vm_mac: {{ wan_vm_mac }}
wan_next_hop: 10.0.1.253 # FIX ME
private_ip: {{ private_ip }}
private_mac: {{ private_mac }}
@@ -65,8 +67,8 @@
- ifconfig eth0.500 || ip link add link eth0 eth0.500 type vlan id 500
- ifconfig eth0.500 up
- ifconfig eth0.500 0.0.0.0
- - ifconfig eth0.500 hw ether {{ wan_container_mac }}
- - ip addr add {{ wan_container_ip }}/{{ wan_container_netbits }} dev eth0.500
+ - ifconfig eth0.500 hw ether {{ wan_vm_mac }}
+ - ip addr add {{ wan_vm_ip }}/{{ wan_container_netbits }} dev eth0.500
- ip link set eth0.500 up
- ip route del default || true
- ip route add default via {{ wan_container_gateway_ip }}
diff --git a/xos/synchronizers/vtn/steps/sync_port_addresses.py b/xos/synchronizers/vtn/steps/sync_port_addresses.py
index 0659d72..6b48911 100644
--- a/xos/synchronizers/vtn/steps/sync_port_addresses.py
+++ b/xos/synchronizers/vtn/steps/sync_port_addresses.py
@@ -6,7 +6,7 @@
from django.db.models import F, Q
from xos.config import Config
from synchronizers.base.syncstep import SyncStep
-from core.models import Service, Port, Controller
+from core.models import Service, Port, Controller, Tag
from core.models.service import COARSE_KIND
from services.cord.models import VSGTenant
from services.cord.models import Tenant
@@ -68,6 +68,17 @@
if not entry in addr_pairs:
addr_pairs.append(entry)
+ # now do the VM_WAN_IP from the instance
+ if vsg.instance:
+ tags=Tag.select_by_content_object(vsg.instance).filter(name="vm_wan_addr")
+ if tags:
+ parts=tags[0].value.split(",")
+ if len(parts)!=3:
+ raise Exception("vm_wan_addr tag is malformed: %s" % value)
+ entry = {"mac_address": parts[2], "ip_address": parts[1]}
+ if not entry in addr_pairs:
+ addr_pairs.append(entry)
+
# Get all ports in all controllers
ports_by_id = {}
for controller in Controller.objects.all():