diff --git a/Makefile.am b/Makefile.am
index 788972804acd..ff472ad81baa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -102,6 +102,7 @@ dist_pkgdata_SCRIPTS =
 dist_sbin_SCRIPTS =
 dist_scripts_SCRIPTS =
 dist_scripts_DATA =
+EXTRA_PROGRAMS =
 INSTALL_DATA_LOCAL =
 UNINSTALL_LOCAL =
 man_MANS =
diff --git a/tests/automake.mk b/tests/automake.mk
index 49ceb415ddc6..b29a37ec840a 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -477,3 +477,5 @@ clean-pki:
 	rm -f tests/pki/stamp
 	rm -rf tests/pki
 endif
+
+include tests/oss-fuzz/automake.mk
diff --git a/tests/oss-fuzz/automake.mk b/tests/oss-fuzz/automake.mk
new file mode 100644
index 000000000000..9f46de6d05e2
--- /dev/null
+++ b/tests/oss-fuzz/automake.mk
@@ -0,0 +1,30 @@
+OSS_FUZZ_TARGETS = \
+	tests/oss-fuzz/flow_extract_target \
+	tests/oss-fuzz/json_parser_target \
+	tests/oss-fuzz/ofp_print_target
+EXTRA_PROGRAMS += $(OSS_FUZZ_TARGETS)
+oss-fuzz-targets: $(OSS_FUZZ_TARGETS)
+
+tests_oss_fuzz_flow_extract_target_SOURCES = \
+	tests/oss-fuzz/flow_extract_target.c \
+	tests/oss-fuzz/fuzzer.h
+tests_oss_fuzz_flow_extract_target_LDADD = lib/libopenvswitch.la
+tests_oss_fuzz_flow_extract_target_LDFLAGS = $(LIB_FUZZING_ENGINE) -lc++
+
+tests_oss_fuzz_json_parser_target_SOURCES = \
+	tests/oss-fuzz/json_parser_target.c \
+	tests/oss-fuzz/fuzzer.h
+tests_oss_fuzz_json_parser_target_LDADD = lib/libopenvswitch.la
+tests_oss_fuzz_json_parser_target_LDFLAGS = $(LIB_FUZZING_ENGINE) -lc++
+
+tests_oss_fuzz_ofp_print_target_SOURCES = \
+	tests/oss-fuzz/ofp_print_target.c \
+	tests/oss-fuzz/fuzzer.h
+tests_oss_fuzz_ofp_print_target_LDADD = lib/libopenvswitch.la
+tests_oss_fuzz_ofp_print_target_LDFLAGS = $(LIB_FUZZING_ENGINE) -lc++
+
+EXTRA_DIST += \
+	tests/oss-fuzz/config/flow_extract_target.options \
+	tests/oss-fuzz/config/json_parser_target.options \
+	tests/oss-fuzz/config/ofp_print_target.options \
+	tests/oss-fuzz/config/ovs.dict
diff --git a/tests/oss-fuzz/config/flow_extract_target.options b/tests/oss-fuzz/config/flow_extract_target.options
new file mode 100644
index 000000000000..7a77aaf0462a
--- /dev/null
+++ b/tests/oss-fuzz/config/flow_extract_target.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+dict = ovs.dict
diff --git a/tests/oss-fuzz/config/json_parser_target.options b/tests/oss-fuzz/config/json_parser_target.options
new file mode 100644
index 000000000000..8d3739a53fa2
--- /dev/null
+++ b/tests/oss-fuzz/config/json_parser_target.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+dict = json.dict
diff --git a/tests/oss-fuzz/config/ofp_print_target.options b/tests/oss-fuzz/config/ofp_print_target.options
new file mode 100644
index 000000000000..7f117292e62d
--- /dev/null
+++ b/tests/oss-fuzz/config/ofp_print_target.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+close_fd_mask = 3
+dict = ovs.dict
diff --git a/tests/oss-fuzz/config/ovs.dict b/tests/oss-fuzz/config/ovs.dict
new file mode 100644
index 000000000000..243b243ab42a
--- /dev/null
+++ b/tests/oss-fuzz/config/ovs.dict
@@ -0,0 +1,293 @@
+"0.2"
+"ADD_SUBSCRIBE"
+"-cbc"
+"CLEARSUB"
+"CLIENT"
+"GIMME"
+"GIMMEDEFS"
+"GIMMESTATS"
+"HM"
+"-hmac96"
+"HM_CTL"
+"HM_STAT"
+"HMST_CLIENT"
+"LOGIN"
+"\\MAILSLOT\\BROWSE"
+"NET-ANNOUNCED"
+"NET-VISIBLE"
+"-nodefs"
+"NONE"
+"OPSTAFF"
+"\\PIPE\\LANMAN"
+"public"
+"REALM"
+"REALM-ANNOUNCED"
+"REALM-VISIBLE"
+"REQ_SUBSCRIBE"
+"RLM_SUBSCRIBE"
+"RLM_UNSUBSCRIBE"
+"SENT"
+" %ssub%s"
+"SUBSCRIBE"
+"SUBSCRIBE_NODEFS"
+"un"
+"UNSUBSCRIBE"
+"USER_FLUSH"
+"USER_HIDE"
+"USER_LOCATE"
+"USER_UNHIDE"
+"WG_CTL"
+"\x01\x00"
+"\x01\x00\x00"
+"\x01\x00\x01"
+"\x01\x00\x02"
+"\x01\x00\x03"
+"\x01\x00\x05"
+"\x01\x01"
+"\x01\x02"
+"\x01\x03"
+"\x01\x04"
+"\x01\x05"
+"\x01\x07"
+"\x01\x0B"
+"\x01\x0C"
+"\x01\x10"
+"\x01\x11"
+"\x01\x12"
+"\x01\x13"
+"\x01\x14"
+"\x01\x15"
+"\x01\x16"
+"\x01\xE8\x48"
+"\x01\xF4"
+"\x01\xF5"
+"\x01\xF6"
+"\x01\xF7"
+"\x01\xF8"
+"\x01\xF9"
+"\x01\xFA"
+"\x01\xFB"
+"\x01\xFC"
+"\x01\xFD"
+"\x01\xFE"
+"\x01\xFF"
+"\x02\x00"
+"\x02\x00\x00"
+"\x02\x01"
+"\x02\x02"
+"\x02\x03"
+"\x02\x04"
+"\x02\x05"
+"\x02\x06"
+"\x02\x07"
+"\x02\x08"
+"\x02\x09"
+"\x02\x0C"
+"\x02\x0E"
+"\x02\x0F"
+"\x02\x11"
+"\x02\x12"
+"\x02\x58"
+"\x02\x81"
+"\x02\x83"
+"\x03\x00"
+"\x03\x01"
+"\x03\x02"
+"\x03\x03"
+"\x03\x06"
+"\x03\xE8"
+"\x03\xE9"
+"\x03\xEA"
+"\x03\xEB"
+"\x03\xEC"
+"\x03\xED"
+"\x03\xEE"
+"\x03\xEF"
+"\x03\xF0"
+"\x03\xF1"
+"\x03\xF2"
+"\x03\xF3"
+"\x03\xF4"
+"\x03\xFF\xFF\xFF"
+"\x04\x00"
+"\x04\x00\x00"
+"\x04\x01"
+"\x04\x02"
+"\x04\x03"
+"\x04\x04"
+"\x04\x51"
+"\x04\x52"
+"\x04\x53"
+"\x04\x55"
+"\x04\x56"
+"\x05\x00"
+"\x05\x01"
+"\x05\x02"
+"\x05\x03"
+"\x05\x53"
+"\x05\xCC"
+"\x05\xDC"
+"\x06\x00"
+"\x06\x01"
+"\x06\xCF"
+"\x07\x07"
+"\x07\xC1"
+"\x07\xFF"
+"\x08\x00"
+"\x08\x00\x00\x00"
+"\x08\x00\x07"
+"\x08\x01"
+"\x08\x06"
+"\x08\x38\x00\x00"
+"\x0A\x00\xB1"
+"\x0C\x01"
+"\x0C\x02"
+"\x0C\x03"
+"\x0C\x04"
+"\x0C\x05"
+"\x0C\x06"
+"\x0C\x08"
+"\x0D\x80"
+"\x0E\x00"
+"\x0E\x10"
+"\x0E\xC8"
+"\x0E\xC9"
+"\x0F\x42\x40"
+"\x0F\xFF"
+"\x10\x00"
+"\x11\x11"
+"\x11\xD7"
+"\x12\x0F"
+"\x12\xBB"
+"\x1A\x30"
+"\x1A\x31"
+"\x1A\x32"
+"\x1B\x21"
+"\x1B\x58"
+"\x1B\x59"
+"\x1B\x5A"
+"\x1B\x5B"
+"\x1B\x5C"
+"\x1B\x5D"
+"\x1B\x5F"
+"\x1B\x61"
+"\x1F\x00"
+"\x1F\x40"
+"\x1F\xFF"
+"\x1F\xFF\xFF"
+"\x20\x00"
+"\x20\x03"
+"\x20\x04"
+"\x27\x10"
+"\x27\x13"
+"\x2F\xBF"
+"\x35\x00\x00"
+"\x3C\x13"
+"\x40\x00"
+"\x40\x04"
+"\x40\x80"
+"\x47\x00\x06\x01"
+"\x4E\x20"
+"\x4E\x21"
+"\x4E\x22"
+"\x4E\x23"
+"\x4E\x24"
+"\x4E\x25"
+"\x4E\x26"
+"\x4E\x27"
+"\x4E\x28"
+"\x4E\x29"
+"\x4E\x2A"
+"\x4E\x2C"
+"\x60\x00"
+"\x60\x01"
+"\x60\x02"
+"\x60\x03"
+"\x60\x04"
+"\x60\x07"
+"\x7F\xFF"
+"\x7F\xFF\xFF"
+"\x80\x00"
+"\x80\x00\x00\x00"
+"\x80\x01"
+"\x80\x05"
+"\x80\x0A"
+"\x80\x21"
+"\x80\x21\x10\x01"
+"\x80\x21\x10\x02"
+"\x80\x23"
+"\x80\x35"
+"\x80\x57"
+"\x80\x9B"
+"\x80\xC2"
+"\x80\xF3"
+"\x80\xFD"
+"\x81\x00"
+"\x81\x37"
+"\x82\x81"
+"\x83\xAA\x7E\x80"
+"\x85\xBE"
+"\x86\xDD"
+"\x88\x08"
+"\x88\x09"
+"\x88\x0B"
+"\x88\x47"
+"\x88\x48"
+"\x88\x63"
+"\x88\x64"
+"\x88\x6F"
+"\x88\x70"
+"\x88\x8E"
+"\x88\x99"
+"\x88\xA2"
+"\x88\xA8"
+"\x88\xCA"
+"\x88\xCC"
+"\x89\x02"
+"\x89\x3A"
+"\x89\x47"
+"\x90\x00"
+"\x91\x00"
+"\xA0\x00"
+"\xAB\xCD"
+"\xB0\x00"
+"\xC0\x00\x00\x00"
+"\xC0\x21"
+"\xC0\x23"
+"\xC0\x25"
+"\xC0\x27"
+"\xC0\x2B"
+"\xC0\x2D"
+"\xC1\x23"
+"\xC2\x23"
+"\xC2\x27"
+"\xDA\xDA"
+"\xE0\x00"
+"\xE0\x00\x00\x00"
+"\xF0\x00\x00\x00"
+"\xF1\x0A"
+"\xF9\x89"
+"\xFC\x00"
+"\xFD\xE9"
+"\xFE\xFE"
+"\xFF\x00"
+"\xFF\x00\x00"
+"\xFF\x00\x00\x00"
+"\xFF\xF0"
+"\xFF\xF8"
+"\xFF\xFD"
+"\xFF\xFE"
+"\xFF\xFF"
+"\xFF\xFF\x00\x00"
+"\xFF\xFF\xF0\x00"
+"\xFF\xFF\xFF\x00"
+"\xFF\xFF\xFF\x01"
+"\xFF\xFF\xFF\x02"
+"\xFF\xFF\xFF\x03"
+"\xFF\xFF\xFF\xEF"
+"\xFF\xFF\xFF\xFD"
+"\xFF\xFF\xFF\xFE"
+"\xFF\xFF\xFF\xFF"
+"ZEPH"
+"ZEPHYR_ADMIN"
+"ZEPHYR_CTL"
diff --git a/tests/oss-fuzz/flow_extract_target.c b/tests/oss-fuzz/flow_extract_target.c
new file mode 100644
index 000000000000..e03cf136cf3f
--- /dev/null
+++ b/tests/oss-fuzz/flow_extract_target.c
@@ -0,0 +1,15 @@
+#include <config.h>
+#include "fuzzer.h"
+#include "dp-packet.h"
+#include "flow.h"
+
+int
+LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    struct dp_packet packet;
+    struct flow flow;
+
+    dp_packet_use_const(&packet, data, size);
+    flow_extract(&packet, &flow);
+    return 0;
+}
diff --git a/tests/oss-fuzz/fuzzer.h b/tests/oss-fuzz/fuzzer.h
new file mode 100644
index 000000000000..f87ae59e9185
--- /dev/null
+++ b/tests/oss-fuzz/fuzzer.h
@@ -0,0 +1,9 @@
+#ifndef FUZZER_H
+#define FUZZER_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+#endif  /* fuzzer.h */
diff --git a/tests/oss-fuzz/json_parser_target.c b/tests/oss-fuzz/json_parser_target.c
new file mode 100644
index 000000000000..e39e04a0d70a
--- /dev/null
+++ b/tests/oss-fuzz/json_parser_target.c
@@ -0,0 +1,42 @@
+#include <config.h>
+#include "fuzzer.h"
+#include "jsonrpc.h"
+#include "openvswitch/json.h"
+#include "ovsdb-error.h"
+#include "ovsdb/table.h"
+#include <assert.h>
+#include <string.h>
+
+int
+LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    if (!size || data[size - 1]) {
+        return 0;
+    }
+
+    struct json *j1 = json_from_string((const char *)data);
+    if (j1->type == JSON_STRING) {
+        json_destroy(j1);
+        return 0;
+    }
+
+    free(json_to_string(j1, JSSF_SORT | JSSF_PRETTY));
+
+    struct jsonrpc_msg *msg;
+    char *error = jsonrpc_msg_from_json(j1, &msg); /* Frees 'j1'. */
+    if (error) {
+        free(error);
+        return 0;
+    }
+
+    struct json *j2 = jsonrpc_msg_to_json(msg); /* Frees 'msg'. */
+    if (j2->type == JSON_STRING) {
+        json_destroy(j2);
+        return 0;
+    }
+
+    free(json_to_string(j2, JSSF_SORT | JSSF_PRETTY));
+    json_destroy(j2);
+
+    return 0;
+}
diff --git a/tests/oss-fuzz/ofp_print_target.c b/tests/oss-fuzz/ofp_print_target.c
new file mode 100644
index 000000000000..126f2623fe3e
--- /dev/null
+++ b/tests/oss-fuzz/ofp_print_target.c
@@ -0,0 +1,47 @@
+#include <config.h>
+#include "fuzzer.h"
+#include "dp-packet.h"
+#include "openvswitch/ofp-print.h"
+#include "openvswitch/ofpbuf.h"
+#include "openvswitch/vlog.h"
+
+int
+LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    if (size < sizeof(struct ofp_header)) {
+        return 0;
+    }
+
+    static bool isInit = false;
+    if (!isInit) {
+        vlog_set_verbosity("off");
+        isInit = true;
+    }
+
+    struct ofpbuf b;
+    ofpbuf_use_const(&b, data, size);
+    for (;;) {
+        /* Check if ofpbuf contains ofp header. */
+        struct ofp_header *oh = ofpbuf_at(&b, 0, sizeof *oh);
+        if (!oh) {
+            break;
+        }
+
+        /* Check if length is geq than lower bound. */
+        size_t length = ntohs(oh->length);
+        if (length < sizeof *oh) {
+            break;
+        }
+
+        /* Check if ofpbuf contains payload. */
+        size_t tail_len = length - sizeof *oh;
+        void *tail = ofpbuf_at(&b, sizeof *oh, tail_len);
+        if (!tail) {
+            break;
+        }
+
+        ofp_print(stdout, ofpbuf_pull(&b, length), length, NULL, NULL, 2);
+    }
+    ofpbuf_uninit(&b);
+    return 0;
+}
