diff --git a/ovn/utilities/automake.mk b/ovn/utilities/automake.mk
index d84368c..c78a07f 100644
--- a/ovn/utilities/automake.mk
+++ b/ovn/utilities/automake.mk
@@ -1,5 +1,7 @@
 scripts_SCRIPTS += \
-    ovn/utilities/ovn-ctl
+    ovn/utilities/ovn-ctl \
+    ovn/utilities/ovn-nbread \
+    ovn/utilities/ovn-sbread
 
 man_MANS += \
     ovn/utilities/ovn-ctl.8 \
@@ -18,7 +20,9 @@ EXTRA_DIST += \
     ovn/utilities/ovn-ctl.8.xml \
     ovn/utilities/ovn-docker-overlay-driver \
     ovn/utilities/ovn-docker-underlay-driver \
-    ovn/utilities/ovn-nbctl.8.xml
+    ovn/utilities/ovn-nbctl.8.xml \
+    ovn/utilities/ovn-nbread \
+    ovn/utilities/ovn-sbread
 
 DISTCLEANFILES += \
     ovn/utilities/ovn-ctl.8 \
diff --git a/ovn/utilities/ovn-nbread b/ovn/utilities/ovn-nbread
new file mode 100755
index 0000000..27c9b71
--- /dev/null
+++ b/ovn/utilities/ovn-nbread
@@ -0,0 +1,2 @@
+#! /bin/sh
+exec ovn-nbctl --dry-run "$@"
diff --git a/ovn/utilities/ovn-sbread b/ovn/utilities/ovn-sbread
new file mode 100755
index 0000000..d5c3f44
--- /dev/null
+++ b/ovn/utilities/ovn-sbread
@@ -0,0 +1,2 @@
+#! /bin/sh
+exec ovn-sbctl --dry-run "$@"
diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at
index 5357ced..615e0fc 100644
--- a/tests/ovn-nbctl.at
+++ b/tests/ovn-nbctl.at
@@ -485,3 +485,106 @@ IPv6 Routes
 
 OVN_NBCTL_TEST_STOP
 AT_CLEANUP
+
+dnl ---------------------------------------------------------------------
+
+AT_SETUP([ovn-nbread - negative tests])
+OVN_NBCTL_TEST_START
+ovn-nbctl ls-add base
+ovn-nbctl ls-list > expout
+ovn-nbread init
+AT_CHECK([ovn-nbread ls-list], [0], [expout])
+ovn-nbread ls-add canary
+AT_CHECK([ovn-nbread ls-list], [0], [expout])
+ovn-nbread ls-del base
+AT_CHECK([ovn-nbread ls-list], [0], [expout])
+
+ovn-nbread acl-add base to-lport 100 1 allow
+AT_CHECK([ovn-nbread acl-list base], [0], [])
+ovn-nbread acl-del base
+AT_CHECK([ovn-nbread acl-list base], [0], [])
+
+ovn-nbctl lsp-add base base-port
+ovn-nbctl lsp-list base > expout
+ovn-nbread lsp-add base canary
+AT_CHECK([ovn-nbread lsp-list base], [0], [expout])
+ovn-nbread lsp-del base-port
+AT_CHECK([ovn-nbread lsp-list base], [0], [expout])
+
+ovn-nbread lsp-get-addresses base-port > expout
+ovn-nbread lsp-set-addresses base-port "01:23:45:67:89:ab"
+AT_CHECK([ovn-nbread lsp-get-addresses base-port], [0], [expout])
+
+ovn-nbread lsp-get-port-security base-port > expout
+ovn-nbread lsp-set-port-security base-port "01:23:45:67:89:ab"
+AT_CHECK([ovn-nbread lsp-get-port-security base-port], [0], [expout])
+
+ovn-nbctl lsp-set-enabled base-port disabled
+ovn-nbread lsp-set-enabled base-port enabled
+AT_CHECK([ovn-nbctl lsp-get-enabled base-port], [0], [disabled
+])
+ovn-nbctl lsp-set-type base-port patch
+ovn-nbread lsp-set-type base-port gateway
+AT_CHECK([ovn-nbread lsp-get-type base-port], [0], [patch
+])
+ovn-nbread lsp-get-options base-port > expout
+ovn-nbread lsp-set-options base-port key=value
+AT_CHECK([ovn-nbread lsp-get-options base-port], [0], [expout])
+
+ovn-nbread lsp-get-dhcpv4-options base-port > expout
+ovn-nbread lsp-set-dhcpv4-options base-port 00000000-0000-0000-0000-000000001234
+AT_CHECK([ovn-nbread lsp-get-dhcpv4-options base-port], [0], [expout])
+
+ovn-nbctl lr-add baserouter
+ovn-nbctl lr-list > expout
+ovn-nbread lr-add canary
+AT_CHECK([ovn-nbctl lr-list], [0], [expout])
+ovn-nbread lr-del baserouter
+AT_CHECK([ovn-nbctl lr-list], [0], [expout])
+
+ovn-nbctl lrp-add baserouter brp 01:23:45:67:89:EF 1.1.1.2
+ovn-nbctl lrp-list baserouter > expout
+ovn-nbread lrp-add baserouter canary 12:34:56:78:90:AB 1.1.1.1
+AT_CHECK([ovn-nbread lrp-list baserouter], [0], [expout])
+ovn-nbread lrp-del brp
+AT_CHECK([ovn-nbread lrp-list baserouter], [0], [expout])
+
+ovn-nbctl lrp-set-enabled brp disabled
+ovn-nbread lrp-set-enabled brp enabled
+AT_CHECK([ovn-nbread lrp-get-enabled brp], [0], [disabled
+])
+
+ovn-nbctl lr-route-add baserouter 1.1.1.0/24 1.1.2.1
+ovn-nbread lr-route-list baserouter > expout
+ovn-nbread lr-route-add baserouter 2.2.2.0/24 1.1.2.2
+AT_CHECK([ovn-nbread lr-route-list baserouter], [0], [expout])
+ovn-nbread lr-route-del baserouter 1.1.1.0/24
+AT_CHECK([ovn-nbread lr-route-list baserouter], [0], [expout])
+
+ovn-nbctl  dhcp-options-create 3.3.3.0/24
+ovn-nbread dhcp-options-list > expout
+ovn-nbread dhcp-options-create 4.4.4.0/24
+AT_CHECK([ovn-nbread dhcp-options-list], [0], [expout])
+ovn-nbread dhcp-options-del `ovn-nbread dhcp-options-list`
+AT_CHECK([ovn-nbread dhcp-options-list], [0], [expout])
+ovn-nbread dhcp-options-set-options `ovn-nbread dhcp-options-list` key=value
+AT_CHECK([ovn-nbread dhcp-options-get-options `ovn-nbread dhcp-options-list`], [0], [])
+
+ovn-nbread list Logical_Switch > expout
+ovn-nbread add Logical_Switch base external_ids ovn-bridge-mappings="test"
+AT_CHECK([ovn-nbread list Logical_Switch], [0], [expout])
+ovn-nbread set Logical_Switch base external_ids='ovn-bridge-mappings="test"'
+AT_CHECK([ovn-nbread list Logical_Switch], [0], [expout])
+ovn-nbctl add Logical_Switch base external_ids ovn-bridge-mappings="test"
+ovn-nbread list Logical_Switch > expout
+ovn-nbread remove Logical_Switch base external_ids ovn-bridge-mappings="test"
+AT_CHECK([ovn-nbread list Logical_Switch], [0], [expout])
+ovn-nbread clear Logical_Switch base external_ids
+AT_CHECK([ovn-nbread list Logical_Switch], [0], [expout])
+ovn-nbread create Logical_Switch name=canary
+AT_CHECK([ovn-nbread list Logical_Switch], [0], [expout])
+ovn-nbread destroy Logical_Switch base
+AT_CHECK([ovn-nbread list Logical_Switch], [0], [expout])
+
+OVN_NBCTL_TEST_STOP
+AT_CLEANUP
diff --git a/tests/ovn-sbctl.at b/tests/ovn-sbctl.at
index 72dc441..89cc6a8 100644
--- a/tests/ovn-sbctl.at
+++ b/tests/ovn-sbctl.at
@@ -141,3 +141,49 @@ options             : {vtep_logical_switch="l0", vtep_physical_switch="p0"}
 
 OVN_SBCTL_TEST_STOP
 AT_CLEANUP
+
+dnl ---------------------------------------------------------------------
+
+AT_SETUP([ovn-sbread - negative tests])
+OVN_SBCTL_TEST_START
+
+ovn-sbctl chassis-add base geneve 10.10.10.10
+ovn-sbread list Chassis > expout
+ovn-sbread init
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+ovn-sbread chassis-add canary geneve 20.20.20.20
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+ovn-sbread chassis-del base
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+
+AT_CHECK([ovn-nbctl ls-add br-test])
+AT_CHECK([ovn-nbctl lsp-add br-test vif0])
+ovn-sbread list Port_Binding > expout
+ovn-sbread lsp-bind vif0 base
+AT_CHECK([ovn-sbread list Port_Binding], [0], [expout])
+
+ovn-sbctl lsp-bind vif0 base
+ovn-sbread list Port_Binding > expout
+ovn-sbread lsp-unbind vif0
+AT_CHECK([ovn-sbread list Port_Binding], [0], [expout])
+
+ovn-sbctl add Chassis base external_ids ovn-bridge-mappings="test"
+
+ovn-sbread list Chassis > expout
+ovn-sbread add Chassis base external_ids ovn-bridge-mappings="test"
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+ovn-sbread set Chassis base hostname=test
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+ovn-sbctl add Chassis base external_ids ovn-bridge-mappings="test"
+ovn-sbread list Chassis > expout
+ovn-sbread remove Chassis base external_ids ovn-bridge-mappings="test"
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+ovn-sbread clear Chassis base external_ids
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+ovn-sbread create Chassis name=canary
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+ovn-sbread destroy Chassis base
+AT_CHECK([ovn-sbread list Chassis], [0], [expout])
+
+OVN_SBCTL_TEST_STOP
+AT_CLEANUP
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index 00db247..c7e77b6 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -3042,3 +3042,36 @@ vconn|DBG|unix: sent (Success): OFPST_FLOW reply (OF1.4):
 
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
+AT_SETUP([ovs-ofread - negative tests])
+AT_KEYWORDS([ovs-ofread])
+AT_DATA([allflows.txt], [[
+priority=4,in_port=23213 actions=output:42
+priority=5,in_port=1029 actions=output:43
+priority=7,in_port=1029 actions=output:43
+priority=3,in_port=1028 actions=output:44
+priority=1,in_port=1026 actions=output:45
+priority=6,in_port=1027 actions=output:64
+priority=2,in_port=1025 actions=output:47
+priority=8,tcp,tp_src=5 actions=drop
+priority=9,tcp,tp_src=6 actions=drop
+]])
+OVS_VSWITCHD_START
+
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip > expout])
+AT_CHECK([ovs-ofread add-flow br0 'ip actions=mod_tp_dst:1234'])
+AT_CHECK([ovs-ofread dump-flows br0 | ofctl_strip], [0], [expout])
+AT_CHECK([ovs-ofread add-flows br0 allflows.txt])
+AT_CHECK([ovs-ofread dump-flows br0 | ofctl_strip], [0], [expout])
+AT_CHECK([ovs-ofread replace-flows br0 allflows.txt])
+AT_CHECK([ovs-ofread dump-flows br0 | ofctl_strip], [0], [expout])
+AT_CHECK([ovs-ofctl add-flows br0 allflows.txt
+], [0], [ignore])
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip > expout])
+AT_CHECK([ovs-ofread mod-flows br0 "priority=9,tcp,tp_src=6 actions=output:48"])
+AT_CHECK([ovs-ofread dump-flows br0 | ofctl_strip], [0], [expout])
+AT_CHECK([ovs-ofread del-flows br0])
+AT_CHECK([ovs-ofread dump-flows br0 | ofctl_strip], [0], [expout])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at
index 5171786..c4bec27 100644
--- a/tests/ovs-vsctl.at
+++ b/tests/ovs-vsctl.at
@@ -1361,3 +1361,93 @@ AT_CHECK([ovs-vsctl -t 5 --no-wait --db=ssl:127.0.0.1:$SSL_PORT --private-key=$P
 
 OVS_VSCTL_CLEANUP
 AT_CLEANUP
+
+dnl RUN_OVS_VSREAD(COMMAND, ...)
+dnl
+dnl Executes each ovs-vsread COMMAND.
+m4_define([RUN_OVS_VSREAD],
+  [m4_foreach([command], [$@], [ovs-vsread --no-wait -vreconnect:emer --db=unix:socket command
+])])
+
+AT_SETUP([ovs-vsread - negative tests])
+AT_KEYWORDS([ovs-vsread])
+OVS_VSCTL_SETUP
+RUN_OVS_VSCTL([add-br a])
+RUN_OVS_VSCTL([list-br > expout])
+AT_CHECK([RUN_OVS_VSREAD([list-br])], [0], [expout])
+RUN_OVS_VSREAD([init])
+AT_CHECK([RUN_OVS_VSREAD([list-br])], [0], [expout])
+RUN_OVS_VSREAD([add-br b])
+AT_CHECK([RUN_OVS_VSREAD([list-br])], [0], [expout])
+RUN_OVS_VSREAD([del-br a])
+AT_CHECK([RUN_OVS_VSREAD([list-br])], [0], [expout])
+
+RUN_OVS_VSCTL([br-get-external-id a > expout])
+RUN_OVS_VSREAD([br-set-external-id a key0 value0])
+AT_CHECK([RUN_OVS_VSREAD([br-get-external-id a])], [0], [expout])
+
+RUN_OVS_VSCTL([add-port a a1])
+RUN_OVS_VSCTL([list-ports a > expout])
+RUN_OVS_VSREAD([ add-port a a2])
+AT_CHECK([RUN_OVS_VSREAD([list-ports a])], [0], [expout])
+RUN_OVS_VSREAD([ add-bond a bond0 a1 a2 a3])
+AT_CHECK([RUN_OVS_VSREAD([list-ports a])], [0], [expout])
+RUN_OVS_VSREAD([ del-port a])
+AT_CHECK([RUN_OVS_VSREAD([list-ports a])], [0], [expout])
+
+RUN_OVS_VSCTL([get-controller a > expout])
+RUN_OVS_VSREAD([set-controller a tcp:4.5.6.7])
+AT_CHECK([RUN_OVS_VSREAD([get-controller a])], [0], [expout])
+RUN_OVS_VSCTL([set-controller a tcp:4.5.6.7])
+RUN_OVS_VSCTL([get-controller a > expout])
+RUN_OVS_VSREAD([del-controller a])
+AT_CHECK([RUN_OVS_VSREAD([get-controller a])], [0], [expout])
+
+RUN_OVS_VSCTL([set-fail-mode a closed])
+RUN_OVS_VSCTL([get-fail-mode a > expout])
+RUN_OVS_VSREAD([set-fail-mode a open])
+AT_CHECK([RUN_OVS_VSREAD([get-fail-mode a])], [0], [expout])
+RUN_OVS_VSREAD([del-fail-mode a])
+AT_CHECK([RUN_OVS_VSREAD([get-fail-mode a])], [0], [expout])
+
+RUN_OVS_VSCTL([set-manager tcp:1.2.3.4])
+RUN_OVS_VSCTL([get-manager > expout])
+RUN_OVS_VSREAD([set-manager tcp:5.6.7.8])
+AT_CHECK([RUN_OVS_VSREAD([get-manager])], [0], [expout])
+RUN_OVS_VSREAD([del-manager])
+AT_CHECK([RUN_OVS_VSREAD([get-manager])], [0], [expout])
+
+RUN_OVS_VSCTL([set-ssl a b c])
+RUN_OVS_VSCTL([get-ssl > expout])
+RUN_OVS_VSREAD([set-ssl d e f])
+AT_CHECK([RUN_OVS_VSREAD([get-ssl])], [0], [expout])
+RUN_OVS_VSREAD([del-ssl])
+AT_CHECK([RUN_OVS_VSREAD([get-ssl])], [0], [expout])
+
+RUN_OVS_VSCTL([set-aa-mapping a b 10])
+RUN_OVS_VSCTL([get-aa-mapping a > expout])
+RUN_OVS_VSREAD([set-aa-mapping a c 20])
+AT_CHECK([RUN_OVS_VSREAD([get-aa-mapping a])], [0], [expout])
+RUN_OVS_VSREAD([del-aa-mapping a b 10])
+AT_CHECK([RUN_OVS_VSREAD([get-aa-mapping a])], [0], [expout])
+
+RUN_OVS_VSREAD([emer-reset])
+AT_CHECK([RUN_OVS_VSREAD([get-aa-mapping a])], [0], [expout])
+
+RUN_OVS_VSCTL([set Bridge a external_ids="bridge-id=test"])
+RUN_OVS_VSCTL([list Bridge > expout])
+RUN_OVS_VSREAD([set Bridge a datapath_type=test])
+AT_CHECK([RUN_OVS_VSREAD([list Bridge])], [0], [expout])
+RUN_OVS_VSREAD([add Bridge a datapath_type=test])
+AT_CHECK([RUN_OVS_VSREAD([list Bridge])], [0], [expout])
+RUN_OVS_VSREAD([remove Bridge a external_ids="bridge-id=test"])
+AT_CHECK([RUN_OVS_VSREAD([list Bridge])], [0], [expout])
+RUN_OVS_VSREAD([clear Bridge a external_ids])
+AT_CHECK([RUN_OVS_VSREAD([list Bridge])], [0], [expout])
+RUN_OVS_VSREAD([create Bridge b])
+AT_CHECK([RUN_OVS_VSREAD([list Bridge])], [0], [expout])
+RUN_OVS_VSREAD([destroy Bridge a])
+AT_CHECK([RUN_OVS_VSREAD([list Bridge])], [0], [expout])
+
+OVS_VSCTL_CLEANUP
+AT_CLEANUP
diff --git a/tests/vtep-ctl.at b/tests/vtep-ctl.at
index f0511ad..163cf82 100644
--- a/tests/vtep-ctl.at
+++ b/tests/vtep-ctl.at
@@ -942,3 +942,148 @@ AT_CHECK([vtep-ctl --timeout=5 -vreconnect:emer --db=unix:socket show | tail -n+
 
 VTEP_CTL_CLEANUP
 AT_CLEANUP
+
+dnl RUN_VTEP_READ(COMMAND, ...)
+dnl
+dnl Executes each vtep-read COMMAND.
+m4_define([RUN_VTEP_READ],
+  [m4_foreach([command], [$@], [vtep-read --timeout=5 -vreconnect:emer --db=unix:socket command
+])])
+AT_SETUP([vtep-read -- negative tests])
+AT_KEYWORDS([vtep-read])
+VTEP_CTL_SETUP
+AT_CHECK([RUN_VTEP_CTL([add-ps a])], [0], [], [], [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_READ([add-ps b])])
+CHECK_PSWITCHES([a])
+AT_CHECK([RUN_VTEP_READ([del-ps a])])
+CHECK_PSWITCHES([a])
+
+AT_CHECK([RUN_VTEP_CTL([add-port a a1])], [0], [], [], [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_READ([add-port a a2])])
+CHECK_PORTS([a], [a1])
+AT_CHECK([RUN_VTEP_READ([del-port a a1])])
+CHECK_PORTS([a], [a1])
+
+AT_CHECK([RUN_VTEP_CTL([add-ls ls1])], [0], [], [], [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_READ([add-ls b])])
+CHECK_LSWITCHES([ls1])
+AT_CHECK([RUN_VTEP_READ([del-ls ls1])])
+CHECK_LSWITCHES([ls1])
+
+AT_CHECK([RUN_VTEP_READ([bind-ls a a1 300 ls1])])
+AT_CHECK([RUN_VTEP_CTL([list-bindings a a1])], [0],
+   [], [], [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_CTL([bind-ls a a1 300 ls1])])
+AT_CHECK([RUN_VTEP_READ([unbind-ls a a1 300])])
+AT_CHECK([RUN_VTEP_CTL([list-bindings a a1])], [0],
+   [0300 ls1
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_READ([set-replication-mode ls1 source_node])])
+AT_CHECK([RUN_VTEP_CTL(
+  [get-replication-mode ls1])],
+  [0], [[(null)]
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_CTL([add-lr lr1])])
+AT_CHECK([RUN_VTEP_READ([add-lr lr2])])
+AT_CHECK([RUN_VTEP_CTL([list-lr])], [0], [lr1
+], [], [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_READ([del-lr lr1])])
+AT_CHECK([RUN_VTEP_CTL([list-lr])], [0], [lr1
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_CTL(
+   [add-ucast-local ls1 00:11:22:33:44:55 10.0.0.10])], [0], [], [],
+   [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_READ([add-ucast-local ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11])])
+AT_CHECK([RUN_VTEP_READ([del-ucast-local ls1 00:11:22:33:44:55])])
+AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
+   [ucast-mac-local
+  00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
+
+mcast-mac-local
+
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_CTL(
+   [add-mcast-local ls1 01:11:22:33:44:55 10.0.0.12])
+], [0], [], [], [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_READ([add-mcast-local ls1 01:11:22:33:44:55 10.0.0.10])])
+AT_CHECK([RUN_VTEP_READ([del-mcast-local ls1 01:11:22:33:44:55 10.0.0.12])])
+AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
+   [ucast-mac-local
+  00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
+
+mcast-mac-local
+  01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
+
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_READ([clear-local-macs ls1])])
+AT_CHECK([RUN_VTEP_CTL([list-local-macs ls1])], [0],
+   [ucast-mac-local
+  00:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
+
+mcast-mac-local
+  01:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
+
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_CTL(
+   [add-ucast-remote ls1 02:11:22:33:44:55 10.0.0.10])], [0], [], [],
+   [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_READ(
+   [add-ucast-remote ls1 00:11:22:33:44:66 vxlan_over_ipv4 10.0.0.11])])
+AT_CHECK([RUN_VTEP_READ([del-ucast-remote ls1 02:11:22:33:44:55])])
+AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
+   [ucast-mac-remote
+  02:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
+
+mcast-mac-remote
+
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_CTL(
+   [add-mcast-remote ls1 03:11:22:33:44:55 10.0.0.12])
+], [0], [], [], [VTEP_CTL_CLEANUP])
+AT_CHECK([RUN_VTEP_READ([add-mcast-remote ls1 03:11:22:33:44:55 10.0.0.14])])
+AT_CHECK([RUN_VTEP_READ([del-mcast-remote ls1 03:11:22:33:44:55 10.0.0.12])])
+AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
+   [ucast-mac-remote
+  02:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
+
+mcast-mac-remote
+  03:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
+
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_READ([clear-remote-macs ls1])])
+AT_CHECK([RUN_VTEP_CTL([list-remote-macs ls1])], [0],
+   [ucast-mac-remote
+  02:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.10
+
+mcast-mac-remote
+  03:11:22:33:44:55 -> vxlan_over_ipv4/10.0.0.12
+
+], [], [VTEP_CTL_CLEANUP])
+
+AT_CHECK([RUN_VTEP_CTL([set-manager tcp:4.5.6.7])])
+AT_CHECK([RUN_VTEP_CTL([get-manager > expout])])
+AT_CHECK([RUN_VTEP_READ([set-manager tcp:4.5.6.8])])
+AT_CHECK([RUN_VTEP_READ([del-manager])])
+AT_CHECK([RUN_VTEP_CTL([get-manager])], [0], [expout])
+
+AT_CHECK([RUN_VTEP_CTL([set Physical_Switch a management_ips=[[4.3.2.1]] tunnel_ips=[[1.2.3.4]]])])
+AT_CHECK([RUN_VTEP_CTL([list Physical_Switch > expout])])
+AT_CHECK([RUN_VTEP_READ([set Physical_Switch a management_ips=[[4.3.2.2]]])])
+AT_CHECK([RUN_VTEP_READ([add Physical_Switch a management_ips [[4.3.2.3]]])])
+AT_CHECK([RUN_VTEP_READ([remove Physical_Switch a management_ips [[4.3.2.1]]])])
+AT_CHECK([RUN_VTEP_CTL([list Physical_Switch])], [0], [expout])
+AT_CHECK([RUN_VTEP_READ([clear Physical_Switch a management_ips])])
+AT_CHECK([RUN_VTEP_CTL([list Physical_Switch])], [0], [expout])
+AT_CHECK([RUN_VTEP_READ([destroy Physical_Switch a])])
+AT_CHECK([RUN_VTEP_CTL([list Physical_Switch])], [0], [expout])
+
+VTEP_CTL_CLEANUP
+AT_CLEANUP
diff --git a/utilities/automake.mk b/utilities/automake.mk
index 9d5b425..6eb7164 100644
--- a/utilities/automake.mk
+++ b/utilities/automake.mk
@@ -5,7 +5,11 @@ bin_PROGRAMS += \
 	utilities/ovs-ofctl \
 	utilities/ovs-vsctl
 bin_SCRIPTS += utilities/ovs-docker \
-	utilities/ovs-pki
+	utilities/ovs-pki \
+        utilities/ovs-appsetlog \
+	utilities/ovs-dpread \
+	utilities/ovs-ofread \
+	utilities/ovs-vsread
 if HAVE_PYTHON
 bin_SCRIPTS += \
 	utilities/ovs-dpctl-top \
@@ -40,14 +44,17 @@ utilities/ovs-lib: $(top_builddir)/config.status
 docs += utilities/ovs-command-bashcomp.INSTALL.md
 EXTRA_DIST += \
 	utilities/ovs-appctl-bashcomp.bash \
+        utilities/ovs-appsetlog \
 	utilities/ovs-check-dead-ifs.in \
 	utilities/ovs-command-bashcomp.INSTALL.md \
 	utilities/ovs-ctl.in \
 	utilities/ovs-dev.py \
 	utilities/ovs-docker \
 	utilities/ovs-dpctl-top.in \
+	utilities/ovs-dpread \
 	utilities/ovs-l3ping.in \
 	utilities/ovs-lib.in \
+	utilities/ovs-ofread \
 	utilities/ovs-parse-backtrace.in \
 	utilities/ovs-pcap.in \
 	utilities/ovs-pipegen.py \
@@ -58,6 +65,7 @@ EXTRA_DIST += \
 	utilities/ovs-test.in \
 	utilities/ovs-vlan-test.in \
 	utilities/ovs-vsctl-bashcomp.bash \
+	utilities/ovs-vsread \
 	utilities/qemu-wrap.py \
 	utilities/checkpatch.py
 MAN_ROOTS += \
diff --git a/utilities/ovs-appsetlog b/utilities/ovs-appsetlog
new file mode 100755
index 0000000..80c8943
--- /dev/null
+++ b/utilities/ovs-appsetlog
@@ -0,0 +1,37 @@
+#! /bin/sh
+
+case $1 in
+    ovsdb-server)
+        ;;
+    ovn-northd)
+        ;;
+    ovn-controller)
+        ;;
+    ovn-controller-vtep)
+        ;;
+    *)
+        echo "Invalid target"
+        exit 1;
+        ;;
+esac
+
+case $2 in
+    off)
+        ;;
+    emer)
+        ;;
+    err)
+        ;;
+    warn)
+        ;;
+    info)
+        ;;
+    dbg)
+        ;;
+    *)
+        echo "Invalid log level"
+        exit 1;
+        ;;
+esac
+
+exec ovs-appctl vlog/set "$1:$2"
diff --git a/utilities/ovs-dpread b/utilities/ovs-dpread
new file mode 100755
index 0000000..a560edf
--- /dev/null
+++ b/utilities/ovs-dpread
@@ -0,0 +1,2 @@
+#! /bin/sh
+exec ovs-dpctl --dry-run "$@"
diff --git a/utilities/ovs-ofread b/utilities/ovs-ofread
new file mode 100755
index 0000000..fd8bf82
--- /dev/null
+++ b/utilities/ovs-ofread
@@ -0,0 +1,2 @@
+#! /bin/sh
+exec ovs-ofctl --dry-run "$@"
diff --git a/utilities/ovs-vsread b/utilities/ovs-vsread
new file mode 100755
index 0000000..39b156e
--- /dev/null
+++ b/utilities/ovs-vsread
@@ -0,0 +1,2 @@
+#! /bin/sh
+exec ovs-vsctl --dry-run "$@"
diff --git a/vtep/automake.mk b/vtep/automake.mk
index 2645f30..05387fd 100644
--- a/vtep/automake.mk
+++ b/vtep/automake.mk
@@ -38,10 +38,11 @@ vtep_vtep_ctl_LDADD = vtep/libvtep.la lib/libopenvswitch.la
 
 # ovs-vtep
 scripts_SCRIPTS += \
-    vtep/ovs-vtep
+    vtep/ovs-vtep \
+    vtep/vtep-read
 
 docs += vtep/README.ovs-vtep.md
-EXTRA_DIST += vtep/ovs-vtep
+EXTRA_DIST += vtep/ovs-vtep vtep/vtep-read
 
 FLAKE8_PYFILES += vtep/ovs-vtep
 
diff --git a/vtep/vtep-read b/vtep/vtep-read
new file mode 100755
index 0000000..4f0f919
--- /dev/null
+++ b/vtep/vtep-read
@@ -0,0 +1,2 @@
+#! /bin/sh
+exec vtep-ctl --dry-run "$@"
