diff --git a/tests-1.3/bundle.py b/tests-1.3/bundle.py
new file mode 100644
index 0000000..b1251bc
--- /dev/null
+++ b/tests-1.3/bundle.py
@@ -0,0 +1,216 @@
+# Distributed under the OpenFlow Software License (see LICENSE)
+# Copyright (c) 2014 Big Switch Networks, Inc.
+"""
+Bundle test cases
+"""
+
+import logging
+
+from oftest import config
+import oftest.base_tests as base_tests
+import ofp
+import loxi.of14 as of14
+
+from oftest.testutils import *
+
+class Commit(base_tests.SimpleProtocol):
+    """
+    Verify that messages added to a bundle are executed only after a commit
+    """
+    def runTest(self):
+        request = of14.message.bundle_ctrl_msg(
+            bundle_ctrl_type=of14.OFPBCT_OPEN_REQUEST,
+            bundle_id=1)
+
+        response, _ = self.controller.transact(request)
+        self.assertIsInstance(response, of14.message.bundle_ctrl_msg)
+        self.assertEqual(response.bundle_ctrl_type, of14.OFPBCT_OPEN_REPLY)
+        self.assertEqual(response.bundle_id, 1)
+
+        for i in xrange(0, 10):
+            request = of14.message.bundle_add_msg(
+                xid=i,
+                bundle_id=1,
+                data=ofp.message.echo_request(xid=i).pack())
+            self.controller.message_send(request)
+
+        # Make sure the messages aren't executed
+        msg, _ = self.controller.poll(ofp.message.echo_reply)
+        self.assertIsNone(msg)
+
+        request = of14.message.bundle_ctrl_msg(
+            bundle_ctrl_type=of14.OFPBCT_COMMIT_REQUEST,
+            bundle_id=1)
+
+        response, _ = self.controller.transact(request)
+        self.assertIsInstance(response, of14.message.bundle_ctrl_msg)
+        self.assertEqual(response.bundle_ctrl_type, of14.OFPBCT_COMMIT_REPLY)
+        self.assertEqual(response.bundle_id, 1)
+
+        for i in xrange(0, 10):
+            response, _ = self.controller.poll(ofp.message.echo_reply)
+            self.assertIsNotNone(response)
+            self.assertEquals(response.xid, i)
+
+class Discard(base_tests.SimpleProtocol):
+    """
+    Verify that messages in a discarded bundle are not executed
+    """
+    def runTest(self):
+        request = of14.message.bundle_ctrl_msg(
+            bundle_ctrl_type=of14.OFPBCT_OPEN_REQUEST,
+            bundle_id=1)
+
+        response, _ = self.controller.transact(request)
+        self.assertIsInstance(response, of14.message.bundle_ctrl_msg)
+        self.assertEqual(response.bundle_ctrl_type, of14.OFPBCT_OPEN_REPLY)
+        self.assertEqual(response.bundle_id, 1)
+
+        for i in xrange(0, 10):
+            request = of14.message.bundle_add_msg(
+                xid=i,
+                bundle_id=1,
+                data=ofp.message.echo_request(xid=i).pack())
+            self.controller.message_send(request)
+
+        # Make sure the messages aren't executed
+        msg, _ = self.controller.poll(ofp.message.echo_reply)
+        self.assertIsNone(msg)
+
+        request = of14.message.bundle_ctrl_msg(
+            bundle_ctrl_type=of14.OFPBCT_DISCARD_REQUEST,
+            bundle_id=1)
+
+        response, _ = self.controller.transact(request)
+        self.assertIsInstance(response, of14.message.bundle_ctrl_msg)
+        self.assertEqual(response.bundle_ctrl_type, of14.OFPBCT_DISCARD_REPLY)
+        self.assertEqual(response.bundle_id, 1)
+
+        # Make sure the messages aren't executed
+        msg, _ = self.controller.poll(ofp.message.echo_reply)
+        self.assertIsNone(msg)
+
+class Disconnect(base_tests.SimpleProtocol):
+    """
+    Disconnect without explicitly discarding the bundle
+    """
+    def runTest(self):
+        request = of14.message.bundle_ctrl_msg(
+            bundle_ctrl_type=of14.OFPBCT_OPEN_REQUEST,
+            bundle_id=1)
+
+        response, _ = self.controller.transact(request)
+        self.assertIsInstance(response, of14.message.bundle_ctrl_msg)
+        self.assertEqual(response.bundle_ctrl_type, of14.OFPBCT_OPEN_REPLY)
+        self.assertEqual(response.bundle_id, 1)
+
+        for i in xrange(0, 10):
+            request = of14.message.bundle_add_msg(
+                xid=i,
+                bundle_id=1,
+                data=ofp.message.echo_request(xid=i).pack())
+            self.controller.message_send(request)
+
+        # Disconnect without committing/discarding
+
+class TooManyMsgs(base_tests.SimpleProtocol):
+    """
+    Verify that exactly 262144 messages can be added to a bundle
+
+    This is tied to the limit in Indigo.
+    """
+    def runTest(self):
+        request = of14.message.bundle_ctrl_msg(
+            bundle_ctrl_type=of14.OFPBCT_OPEN_REQUEST,
+            bundle_id=1)
+
+        response, _ = self.controller.transact(request)
+        self.assertIsInstance(response, of14.message.bundle_ctrl_msg)
+        self.assertEqual(response.bundle_ctrl_type, of14.OFPBCT_OPEN_REPLY)
+        self.assertEqual(response.bundle_id, 1)
+
+        request = of14.message.bundle_add_msg(
+            xid=0,
+            bundle_id=1,
+            data=ofp.message.echo_request(xid=0).pack())
+
+        buf = request.pack()
+
+        logging.debug("Sending bundle-add messages")
+
+        count = 0
+        for i in xrange(0, 256*1024):
+            with self.controller.tx_lock:
+                if self.controller.switch_socket.sendall(buf) is not None:
+                    raise AssertionError("failed to send message to switch")
+            count += 1
+
+        logging.debug("Sent %d bundle-add messages", count)
+
+        do_barrier(self.controller)
+        verify_no_errors(self.controller)
+
+        request = of14.message.bundle_add_msg(
+            xid=1,
+            bundle_id=1,
+            data=ofp.message.echo_request(xid=1).pack())
+        self.controller.message_send(request)
+
+        do_barrier(self.controller)
+
+        msg, _ = self.controller.poll(exp_msg=of14.message.error_msg)
+        self.assertIsNotNone(msg)
+
+class TooManyBytes(base_tests.SimpleProtocol):
+    """
+    Verify that 50 MB of messages can be added to a bundle
+
+    This is tied to the limit in Indigo.
+    """
+    def runTest(self):
+        request = of14.message.bundle_ctrl_msg(
+            bundle_ctrl_type=of14.OFPBCT_OPEN_REQUEST,
+            bundle_id=1)
+
+        response, _ = self.controller.transact(request)
+        self.assertIsInstance(response, of14.message.bundle_ctrl_msg)
+        self.assertEqual(response.bundle_ctrl_type, of14.OFPBCT_OPEN_REPLY)
+        self.assertEqual(response.bundle_id, 1)
+
+        echo_buf = ofp.message.echo_request(xid=0, data="\x00" * 1016).pack()
+        self.assertEquals(len(echo_buf), 1024)
+
+        request = of14.message.bundle_add_msg(
+            xid=0,
+            bundle_id=1,
+            data=echo_buf)
+
+        buf = request.pack()
+
+        max_bytes = 50*1024*1024
+        num_msgs = max_bytes / len(echo_buf)
+
+        logging.debug("Sending bundle-add messages")
+
+        count = 0
+        for i in xrange(0, num_msgs):
+            with self.controller.tx_lock:
+                if self.controller.switch_socket.sendall(buf) is not None:
+                    raise AssertionError("failed to send message to switch")
+            count += 1
+
+        logging.debug("Sent %d bundle-add messages", count)
+
+        do_barrier(self.controller)
+        verify_no_errors(self.controller)
+
+        request = of14.message.bundle_add_msg(
+            xid=1,
+            bundle_id=1,
+            data=ofp.message.echo_request(xid=1).pack())
+        self.controller.message_send(request)
+
+        do_barrier(self.controller)
+
+        msg, _ = self.controller.poll(exp_msg=of14.message.error_msg)
+        self.assertIsNotNone(msg)
