aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xend/lib/netif.py
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-05-07 14:53:28 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-05-07 14:53:28 +0000
commit1de448f4c54eac94a966d65e72b15bcbef3a7e5d (patch)
treecc2a452db9507208580071b8676288d9b1dde5ea /tools/xend/lib/netif.py
parent747a8d04495070f12d625e2047b07eb3967ca9b8 (diff)
downloadxen-1de448f4c54eac94a966d65e72b15bcbef3a7e5d.tar.gz
xen-1de448f4c54eac94a966d65e72b15bcbef3a7e5d.tar.bz2
xen-1de448f4c54eac94a966d65e72b15bcbef3a7e5d.zip
bitkeeper revision 1.891.1.5 (409ba2e8A6F60eP06BqyZUGapsn8XA)
Network interface for new IO model is now completed.
Diffstat (limited to 'tools/xend/lib/netif.py')
-rw-r--r--tools/xend/lib/netif.py144
1 files changed, 144 insertions, 0 deletions
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)