def delete_service_instance(serv_name): ''' Precondition: check on serv_name existence has been performed Deletes the last entry in the list of services. This could change later to a random entry or something else. ''' if len(_service_table[serv_name]) == 0: return packed_multiaddr = _service_table[serv_name][-1:][0] nh.shutdown_instance(packed_multiaddr) address = ma.get_address(packed_multiaddr) _delete_serv_instance_entry(address) _service_table[serv_name] = _service_table[serv_name][:-1] # delete any connection tracks which this service has initiated if ma.get_type(packed_multiaddr) == ma.IPV4: flows = _check_flow_existence('*', v4=address) if flows: for flow_id in flows: _del_flow(address, \ flow_id, \ _which_service_is_instance( \ ma.ip_to_packed_multiaddr( _flow_id_to_ip(flow_id) )\ )) elif ma.get_type(packed_multiaddr) == ma.IPV6: pass
def _netns_resolvconf(netns): ''' Each network namespace will now send dns requests to the bridge ''' ret = os.system('mkdir -p /etc/netns/' + netns) with open('/etc/netns/' + netns + '/resolv.conf', 'w+') as f: f.write('nameserver ' + ma.get_address(bridge_ipv4_multiaddr))
def _connect_netns_to_bridge(netns, \ packed_multiaddr): ''' Function to connect a given network namespace to the orchestrator bridge. ''' #TODO # error handle veth1, veth2 = _create_veth_pair() # move one veth end to the proper namespace _conn_ns_bridge(netns, veth1) # assign the other veth end to the bridge _slave_veth(veth2) # bring everything up _bring_up_if(bridge_netns, veth2) _bring_up_if(netns, veth1) _bring_up_if(netns, 'lo') # assign ip address to netns addr = ma.get_address(packed_multiaddr) _assign_addr(netns, veth1, addr) _def_route(netns, addr)
def serv_instance_exists(multi_addr, ip=None): if ip: if ip in _service_instances: return True else: instance = ma.pack(multi_addr) if ma.get_address(instance) in _service_instances: return True return False
def add_service_instance(serv_name, multi_addr): ''' Precondition: checks on serv_name existence and multi_addr validity have been performed ''' packed_multiaddr = ma.pack(multi_addr) _service_table[serv_name].append(packed_multiaddr) _add_serv_instance_entry(ma.get_address(packed_multiaddr), multi_addr) #TODO # error handle ret = nh.instantiate_service(multi_addr)
def network_init(): ''' Return None if unable to complete. ''' #TODO # error handle # some failures aren't critical and probably shoudl accommodate for that if # i have time print("Creating netns for the orchestrator.") ret = os.system('ip netns add ' + bridge_netns) print("Creating the linux bridge.") ret = os.system('ip netns exec ' + bridge_netns + ' \ ip link add ' + bridge_name + ' type bridge') print("Adding IP address to bridge.") # assign IPv4 address _assign_addr(bridge_netns, \ bridge_name, \ ma.get_address(bridge_ipv4_multiaddr)) # assign IPv6 address #ret = os.system('ip netns exec '+bridge_netns+' \ # ip address add '+ma.get_address(bridge_ipv6_multiaddr)+' \ # dev '+bridge_name) print("Setting the devices for the bridge netns to be up.") _bring_up_if(bridge_netns, 'lo') _bring_up_if(bridge_netns, bridge_name) print("Network namespace initialised.") print("Orchestrator bridge resides on "\ +ma.get_address(bridge_ipv4_multiaddr)+subnet_mask) print( "For your namespaces to be able to communicate with each other, they \ need to be on the same subnet as the bridge.") # initialise random number generator random.seed(time.time())
''' DNS Code heavily pulled from https://github.com/pathes/fakedns/blob/master/fakedns.py Cheers pathes Modified as needed by ramwan <*****@*****.**> ''' ''' Variable definitions ''' _dns_active = False _dns_ipv4 = None #_dns_ipv6 = None _dns4_thread = None #_dns6_thread = None dns_ipv4_addr = ma.get_address(bridge_ipv4_multiaddr) #dns_ipv6_addr = ma.get_address(bridge_ipv6_multiaddr) dns_header_length = 12 def listen(): ''' Initialises sockets in the orchestrator/bridge netns and starts separate threads to listen on them. ''' global _dns_active global _dns_ipv4 #global dns_ipv6 global _dns4_thread #global _dns6_thread _dns_active = True
def get_flow_id(serv_name, v4=None, v6=None): ''' Adds a flow entry to the flow bi-map. Checks for the existence of the a flow between the sender and receiver first. If a flow already exists then that flow id will be returned. Returns None on error NOTE: doesn't support one automaton needing to talk to multiple automatons of the same type. ''' if v4: exists = _check_flow_existence(serv_name, v4=v4) # if the flow already exists we return the same flow ID if exists == _FLOW_EXISTS: return _conn_flow_id(_conn_key(v4, serv_name)) # if the flow exists but the receiving server is dead, we need to # find a new receiver if there is one elif exists == _FLOW_DEAD: fid = _conn_flow_id(_conn_key(v4, serv_name)) # we don't need to call del() right now due to the implementation # of the flow table. However it probably would be good to call it to # make it clearer so I'm going to leave it here. # #_del_flow_id_to_ip(fid) #_del_conn( _conn_key(v4, serv_name) ) instance = _get_random_instance(serv_name) if instance == None: return None instance_addr = ma.get_address(instance) # do iptables nat mappings with nh.Namespace( nh.get_ns_name( \ nh.ma.ip_to_packed_multiaddr(v4) \ )): ih.edit_nat_mapping(fid, new_source=v4,\ old_source=v4,\ new_dest=instance_addr,\ old_dest=_flow_id_to_ip[fid]) _add_flow_id_to_ip(instance_addr, fid) _add_conn(v4, serv_name, fid) return fid # create new flow elif exists == _FLOW_NOEXISTS: instance = _get_random_instance(serv_name) if instance == None: return None fid = _generate_flow_id() instance_addr = ma.get_address(instance) _add_ip_to_flow_id(v4, fid) _add_flow_id_to_ip(instance_addr, fid) # create connection tracking information _add_conn(v4, serv_name, fid) # do iptables nat mappings with nh.Namespace( nh.get_ns_name( \ ma.ip_to_packed_multiaddr(v4) \ )): ih.create_nat_mapping(fid, v4, instance_addr) return fid elif v6: # TODO return None return None