aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/examples/xc_dom_create.py13
-rw-r--r--tools/xenctl/lib/utils.py10
-rw-r--r--tools/xend/lib/domain_controller.h1
-rwxr-xr-xtools/xend/lib/main.py25
-rw-r--r--tools/xend/lib/manager.py39
-rw-r--r--tools/xend/lib/netif.py144
6 files changed, 222 insertions, 10 deletions
diff --git a/tools/examples/xc_dom_create.py b/tools/examples/xc_dom_create.py
index 22479a9d14..19bb2ac9df 100755
--- a/tools/examples/xc_dom_create.py
+++ b/tools/examples/xc_dom_create.py
@@ -333,7 +333,18 @@ def make_domain():
xc.domain_destroy ( dom=id )
sys.exit()
- if not new_io_world:
+ if new_io_world:
+ cmsg = 'new_network_interface(dom='+str(id)+')'
+ xend_response = xenctl.utils.xend_control_message(cmsg)
+ if not xend_response['success']:
+ print "Error creating network interface"
+ print "Error type: " + xend_response['error_type']
+ if xend_response['error_type'] == 'exception':
+ print "Exception type: " + xend_response['exception_type']
+ print "Exception val: " + xend_response['exception_value']
+ xc.domain_destroy ( dom=id )
+ sys.exit()
+ else:
# setup virtual firewall rules for all aliases
for ip in vfr_ipaddr:
xenctl.utils.setup_vfr_rules_for_vif( id, 0, ip )
diff --git a/tools/xenctl/lib/utils.py b/tools/xenctl/lib/utils.py
index 3f0914f73f..11aadb4f08 100644
--- a/tools/xenctl/lib/utils.py
+++ b/tools/xenctl/lib/utils.py
@@ -54,15 +54,13 @@ def get_current_ipmask(dev='eth0'):
return m.group(1)
return None
-def get_current_ipgw(dev='eth0'):
- """Return a string containing the IP gateway for the given
- network interface (default 'eth0').
- """
+def get_current_ipgw():
+ """Return a string containing the default IP gateway."""
fd = os.popen( '/sbin/route -n' )
lines = fd.readlines()
for line in lines:
- m = re.search( '^\S+\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' +
- '\s+\S+\s+\S*G.*' + dev + '.*', line )
+ m = re.search( '^0.0.0.0+\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' +
+ '\s+0.0.0.0+\s+\S*G.*', line )
if m:
return m.group(1)
return None
diff --git a/tools/xend/lib/domain_controller.h b/tools/xend/lib/domain_controller.h
index d5c397fe96..566967dc38 100644
--- a/tools/xend/lib/domain_controller.h
+++ b/tools/xend/lib/domain_controller.h
@@ -468,7 +468,6 @@ typedef struct {
unsigned int evtchn; /* Event channel for notifications. */
unsigned long tx_shmem_frame; /* Page cont. tx shared comms window. */
unsigned long rx_shmem_frame; /* Page cont. rx shared comms window. */
- unsigned long shmem_frame;
/* OUT */
unsigned int status;
} netif_be_connect_t;
diff --git a/tools/xend/lib/main.py b/tools/xend/lib/main.py
index 7b5adbab83..0056783d7f 100755
--- a/tools/xend/lib/main.py
+++ b/tools/xend/lib/main.py
@@ -5,7 +5,7 @@
###########################################################
import errno, re, os, pwd, select, signal, socket, struct, sys, time
-import xend.blkif, xend.console, xend.manager, xend.utils, Xc
+import xend.blkif, xend.netif, xend.console, xend.manager, xend.utils, Xc
# The following parameters could be placed in a configuration file.
@@ -19,6 +19,8 @@ UNIX_SOCK = 'management_sock' # relative to CONTROL_DIR
CMSG_CONSOLE = 0
CMSG_BLKIF_BE = 1
CMSG_BLKIF_FE = 2
+CMSG_NETIF_BE = 3
+CMSG_NETIF_FE = 4
def port_from_dom(dom):
@@ -162,6 +164,10 @@ def daemon_loop():
if xend.blkif.interface.list.has_key(idx):
blk_if = xend.blkif.interface.list[idx]
+ net_if = False
+ if xend.netif.interface.list.has_key(idx):
+ net_if = xend.netif.interface.list[idx]
+
# If we pick up a disconnect notification then we do any necessary
# cleanup.
if type == notifier.EXCEPTION:
@@ -175,6 +181,9 @@ def daemon_loop():
if blk_if:
blk_if.destroy()
del blk_if
+ if net_if:
+ net_if.destroy()
+ del net_if
continue
# Process incoming requests.
@@ -188,6 +197,10 @@ def daemon_loop():
blk_if.ctrlif_rx_req(port, msg)
elif type == CMSG_BLKIF_BE and port == dom0_port:
xend.blkif.backend_rx_req(port, msg)
+ elif type == CMSG_NETIF_FE and net_if:
+ net_if.ctrlif_rx_req(port, msg)
+ elif type == CMSG_NETIF_BE and port == dom0_port:
+ xend.netif.backend_rx_req(port, msg)
else:
port.write_response(msg)
@@ -198,6 +211,8 @@ def daemon_loop():
type = (msg.get_header())['type']
if type == CMSG_BLKIF_BE and port == dom0_port:
xend.blkif.backend_rx_rsp(port, msg)
+ elif type == CMSG_NETIF_BE and port == dom0_port:
+ xend.netif.backend_rx_rsp(port, msg)
# Send console data.
if con_if and con_if.ctrlif_transmit_work(port):
@@ -207,10 +222,18 @@ def daemon_loop():
if blk_if and blk_if.ctrlif_transmit_work(port):
work_done = True
+ # Send netif messages.
+ if net_if and net_if.ctrlif_transmit_work(port):
+ work_done = True
+
# Back-end block-device work.
if port == dom0_port and xend.blkif.backend_do_work(port):
work_done = True
+ # Back-end network-device work.
+ if port == dom0_port and xend.netif.backend_do_work(port):
+ work_done = True
+
# Finally, notify the remote end of any work that we did.
if work_done:
port.notify()
diff --git a/tools/xend/lib/manager.py b/tools/xend/lib/manager.py
index ea7398cd4c..2f15683d66 100644
--- a/tools/xend/lib/manager.py
+++ b/tools/xend/lib/manager.py
@@ -4,7 +4,7 @@
## Copyright (c) 2004, K A Fraser (University of Cambridge)
#############################################################
-import xend.blkif, xend.console, xend.main, xend.utils
+import xend.blkif, xend.netif, xend.console, xend.main, xend.utils
##
@@ -113,3 +113,40 @@ def new_block_device(dom, handle, vdev, pdev, start_sect, nr_sect, readonly):
# Response is deferred until back-end driver sends acknowledgement.
return None
+
+
+##
+## new_network_interface:
+## Create a new network interface for the specified domain @dom.
+##
+def new_network_interface(dom, handle=-1):
+ # By default we create an interface with handle zero.
+ if handle < 0:
+ handle = 0
+
+ # We only support one interface per domain, which must have handle zero.
+ if handle != 0:
+ response = { 'success': False }
+ response['error_type'] = 'Bad handle %d (only handle 0 ' + \
+ 'is supported)' % handle
+ return response
+
+ # Find local event-channel port associated with the specified domain.
+ port = xend.main.port_from_dom(dom)
+ if not port:
+ response = { 'success': False }
+ response['error_type'] = 'Unknown domain %d' % dom
+ return response
+
+ # The interface must not already exist.
+ if xend.netif.interface.list.has_key(port.local_port):
+ response = { 'success': False }
+ response['error_type'] = 'Interface (dom=%d,handle=%d) already ' + \
+ 'exists' % (dom, handle)
+ return response
+
+ # Create the new interface. Initially no virtual devices are attached.
+ xend.netif.interface(dom, port.local_port)
+
+ # Response is deferred until back-end driver sends acknowledgement.
+ return None
diff --git a/tools/xend/lib/netif.py b/tools/xend/lib/netif.py
new file mode 100644
index 0000000000..11756c5e56
--- /dev/null
+++ b/tools/xend/lib/netif.py
@@ -0,0 +1,144 @@
+
+###################################################################
+## xend/netif.py -- Network-interface management functions for Xend
+## Copyright (c) 2004, K A Fraser (University of Cambridge)
+###################################################################
+
+import errno, random, re, os, select, signal, socket, struct, sys
+import xend.main, xend.console, xend.manager, xend.utils, Xc
+
+CMSG_NETIF_BE = 3
+CMSG_NETIF_FE = 4
+CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED = 0
+CMSG_NETIF_FE_DRIVER_STATUS_CHANGED = 32
+CMSG_NETIF_FE_INTERFACE_CONNECT = 33
+CMSG_NETIF_FE_INTERFACE_DISCONNECT = 34
+CMSG_NETIF_BE_CREATE = 0
+CMSG_NETIF_BE_DESTROY = 1
+CMSG_NETIF_BE_CONNECT = 2
+CMSG_NETIF_BE_DISCONNECT = 3
+
+pendmsg = None
+pendaddr = None
+
+def backend_tx_req(msg):
+ port = xend.main.dom0_port
+ if port.space_to_write_request():
+ port.write_request(msg)
+ port.notify()
+ else:
+ xend.netif.pendmsg = msg
+
+def backend_rx_req(port, msg):
+ port.write_response(msg)
+
+def backend_rx_rsp(port, msg):
+ subtype = (msg.get_header())['subtype']
+ print "Received netif-be response, subtype %d" % subtype
+ if subtype == CMSG_NETIF_BE_CREATE:
+ rsp = { 'success': True }
+ xend.main.send_management_response(rsp, xend.netif.pendaddr)
+ elif subtype == CMSG_NETIF_BE_CONNECT:
+ (dom,hnd,evtchn,tx_frame,rx_frame,st) = \
+ struct.unpack("QIILLI", msg.get_payload())
+ netif = interface.list[xend.main.port_from_dom(dom).local_port]
+ msg = xend.utils.message(CMSG_NETIF_FE, \
+ CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, 0)
+ msg.append_payload(struct.pack("IIIBBBBBBBB",0,2, \
+ netif.evtchn['port2'], \
+ netif.mac[0],netif.mac[1], \
+ netif.mac[2],netif.mac[3], \
+ netif.mac[4],netif.mac[5], \
+ 0,0))
+ netif.ctrlif_tx_req(xend.main.port_list[netif.key], msg)
+
+def backend_do_work(port):
+ global pendmsg
+ if pendmsg and port.space_to_write_request():
+ port.write_request(pendmsg)
+ pendmsg = None
+ return True
+ return False
+
+
+class interface:
+
+ # Dictionary of all network-device interfaces.
+ list = {}
+
+
+ # NB. 'key' is an opaque value that has no meaning in this class.
+ def __init__(self, dom, key):
+ self.dom = dom
+ self.key = key
+ self.pendmsg = None
+
+ # VIFs get a random MAC address with a "special" vendor id.
+ #
+ # NB. The vendor is currently an "obsolete" one that used to belong
+ # to DEC (AA-00-00). Using it is probably a bit rude :-)
+ #
+ # NB2. The first bit of the first random octet is set to zero for
+ # all dynamic MAC addresses. This may allow us to manually specify
+ # MAC addresses for some VIFs with no fear of clashes.
+ self.mac = [ 0xaa, 0x00, 0x00 ]
+ self.mac.append(int(random.random()*128))
+ self.mac.append(int(random.random()*256))
+ self.mac.append(int(random.random()*256))
+
+ interface.list[key] = self
+ msg = xend.utils.message(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE, 0)
+ msg.append_payload(struct.pack("QIBBBBBBBBI",dom,0, \
+ self.mac[0],self.mac[1], \
+ self.mac[2],self.mac[3], \
+ self.mac[4],self.mac[5], \
+ 0,0,0))
+ xend.netif.pendaddr = xend.main.mgmt_req_addr
+ backend_tx_req(msg)
+
+
+ # Completely destroy this interface.
+ def destroy(self):
+ del interface.list[self.key]
+ msg = xend.utils.message(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY, 0)
+ msg.append_payload(struct.pack("QII",self.dom,0,0))
+ backend_tx_req(msg)
+
+
+ # The parameter @port is the control-interface event channel. This method
+ # returns True if messages were written to the control interface.
+ def ctrlif_transmit_work(self, port):
+ if self.pendmsg and port.space_to_write_request():
+ port.write_request(self.pendmsg)
+ self.pendmsg = None
+ return True
+ return False
+
+ def ctrlif_tx_req(self, port, msg):
+ if port.space_to_write_request():
+ port.write_request(msg)
+ port.notify()
+ else:
+ self.pendmsg = msg
+
+ def ctrlif_rx_req(self, port, msg):
+ port.write_response(msg)
+ subtype = (msg.get_header())['subtype']
+ if subtype == CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
+ msg = xend.utils.message(CMSG_NETIF_FE, \
+ CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, 0)
+ msg.append_payload(struct.pack("IIIBBBBBBBB",0,1,0,self.mac[0], \
+ self.mac[1],self.mac[2], \
+ self.mac[3],self.mac[4], \
+ self.mac[5],0,0))
+ self.ctrlif_tx_req(port, msg)
+ elif subtype == CMSG_NETIF_FE_INTERFACE_CONNECT:
+ (hnd,tx_frame,rx_frame) = struct.unpack("ILL", msg.get_payload())
+ xc = Xc.new()
+ self.evtchn = xc.evtchn_bind_interdomain(dom1=0,dom2=self.dom)
+ msg = xend.utils.message(CMSG_NETIF_BE, \
+ CMSG_NETIF_BE_CONNECT, 0)
+ msg.append_payload(struct.pack("QIILLI",self.dom,0, \
+ self.evtchn['port1'],tx_frame, \
+ rx_frame,0))
+ backend_tx_req(msg)