diff --git a/protocols/isis/packet/BUILD.bazel b/protocols/isis/packet/BUILD.bazel
index a81bca313da316e6ebd6165feb7296340c8e6947..51b35c52bfa922705c255ddcf13b41c039a46f9a 100644
--- a/protocols/isis/packet/BUILD.bazel
+++ b/protocols/isis/packet/BUILD.bazel
@@ -4,13 +4,11 @@ go_library(
     name = "go_default_library",
     srcs = [
         "csnp.go",
-        "decoder.go",
         "header.go",
         "hello.go",
         "isis.go",
         "lsp.go",
         "lsp_entry.go",
-        "math.go",
         "psnp.go",
         "tlv.go",
         "tlv_area_addresses.go",
@@ -25,13 +23,15 @@ go_library(
         "tlv_p2p_adj_state.go",
         "tlv_padding.go",
         "tlv_protocols_supported.go",
+        "tlv_unknown.go",
     ],
     importpath = "github.com/bio-routing/bio-rd/protocols/isis/packet",
     visibility = ["//visibility:public"],
     deps = [
         "//protocols/isis/types:go_default_library",
+        "//util/decode:go_default_library",
+        "//util/math:go_default_library",
         "//vendor/github.com/FMNSSun/libhash/fletcher:go_default_library",
-        "//vendor/github.com/sirupsen/logrus:go_default_library",
         "//vendor/github.com/taktv6/tflow2/convert:go_default_library",
     ],
 )
@@ -40,10 +40,14 @@ go_test(
     name = "go_default_test",
     srcs = [
         "csnp_test.go",
+        "header_test.go",
         "hello_test.go",
         "isis_test.go",
         "lsp_test.go",
         "psnp_test.go",
+        "tlv_area_addresses_test.go",
+        "tlv_padding_test.go",
+        "tlv_unknown_test.go",
     ],
     embed = [":go_default_library"],
     deps = [
diff --git a/protocols/isis/packet/csnp.go b/protocols/isis/packet/csnp.go
index 58aa5ad2b8c120d92d0de88519d4395e06b37d33..c528a8fb3031446f8a85d80f0ac6e1e0912aa204 100644
--- a/protocols/isis/packet/csnp.go
+++ b/protocols/isis/packet/csnp.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/bio-routing/bio-rd/protocols/isis/types"
 	"github.com/bio-routing/bio-rd/util/decode"
+	umath "github.com/bio-routing/bio-rd/util/math"
 	"github.com/taktv6/tflow2/convert"
 )
 
@@ -68,7 +69,7 @@ func NewCSNPs(sourceID types.SystemID, lspEntries []LSPEntry, maxPDULen int) []C
 
 	for i := 0; i < numCSNPs; i++ {
 		start := i * lspsPerCSNP
-		end := min(lspsPerCSNP, left)
+		end := umath.Min(lspsPerCSNP, left)
 
 		slice := lspEntries[start : start+end]
 		csnp := newCSNP(sourceID, slice)
diff --git a/protocols/isis/packet/lsp.go b/protocols/isis/packet/lsp.go
index d0c70ed13ecb9b53d8def682eac37587439737c5..0fe4b689344dd58585013829d795b5072df51ae1 100644
--- a/protocols/isis/packet/lsp.go
+++ b/protocols/isis/packet/lsp.go
@@ -15,16 +15,19 @@ const (
 	LSPDUMinLen = 19
 )
 
+// LSPID represents a Link State Packet ID
 type LSPID struct {
 	SystemID     types.SystemID
 	PseudonodeID uint16
 }
 
+// Serialize serializes an LSPID
 func (l *LSPID) Serialize(buf *bytes.Buffer) {
 	buf.Write(l.SystemID[:])
 	buf.Write(convert.Uint16Byte(l.PseudonodeID))
 }
 
+// LSPDU represents a link state PDU
 type LSPDU struct {
 	Length            uint16
 	RemainingLifetime uint16
@@ -35,6 +38,7 @@ type LSPDU struct {
 	TLVs              []TLV
 }
 
+// SetChecksum sets the checksum of an LSPDU
 func (l *LSPDU) SetChecksum() {
 	buf := bytes.NewBuffer(nil)
 	l.Serialize(buf)
@@ -46,6 +50,7 @@ func (l *LSPDU) SetChecksum() {
 	l.Checksum = uint16(csum[0])*256 + uint16(csum[1])
 }
 
+// Serialize serializes a linke state PDU
 func (l *LSPDU) Serialize(buf *bytes.Buffer) {
 	buf.Write(convert.Uint16Byte(l.Length))
 	buf.Write(convert.Uint16Byte(l.RemainingLifetime))
@@ -59,6 +64,7 @@ func (l *LSPDU) Serialize(buf *bytes.Buffer) {
 	}
 }
 
+// DecodeLSPDU decodes an LSPDU
 func DecodeLSPDU(buf *bytes.Buffer) (*LSPDU, error) {
 	pdu := &LSPDU{}
 
diff --git a/protocols/isis/packet/math.go b/protocols/isis/packet/math.go
deleted file mode 100644
index d8dab68edf88ca21aa861fbd1481cfb9f0bc51f1..0000000000000000000000000000000000000000
--- a/protocols/isis/packet/math.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package packet
-
-func min(a, b int) int {
-	if a < b {
-		return a
-	}
-	return b
-}
diff --git a/protocols/isis/packet/psnp.go b/protocols/isis/packet/psnp.go
index 0299ade07ebbdc2e65b689e5e72e5392b705227a..0686a6b8ccaaef29581bcfb71052f92a7f60cb64 100644
--- a/protocols/isis/packet/psnp.go
+++ b/protocols/isis/packet/psnp.go
@@ -7,10 +7,12 @@ import (
 
 	"github.com/bio-routing/bio-rd/protocols/isis/types"
 	"github.com/bio-routing/bio-rd/util/decode"
+	umath "github.com/bio-routing/bio-rd/util/math"
 	"github.com/taktv6/tflow2/convert"
 )
 
 const (
+	// PSNPMinLen is the minimal length of PSNP PDU
 	PSNPMinLen = 8
 )
 
@@ -30,7 +32,7 @@ func NewPSNPs(sourceID types.SystemID, lspEntries []LSPEntry, maxPDULen int) []P
 
 	for i := 0; i < numPSNPs; i++ {
 		start := i * lspsPerPSNP
-		end := min(lspsPerPSNP, left)
+		end := umath.Min(lspsPerPSNP, left)
 
 		slice := lspEntries[start : start+end]
 		PSNP := newPSNP(sourceID, slice)
diff --git a/util/math/BUILD.bazel b/util/math/BUILD.bazel
new file mode 100644
index 0000000000000000000000000000000000000000..863ccd06fbf3be0f67b3e25565707640f053d3bb
--- /dev/null
+++ b/util/math/BUILD.bazel
@@ -0,0 +1,15 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+    name = "go_default_library",
+    srcs = ["min.go"],
+    importpath = "github.com/bio-routing/bio-rd/util/math",
+    visibility = ["//visibility:public"],
+)
+
+go_test(
+    name = "go_default_test",
+    srcs = ["min_test.go"],
+    embed = [":go_default_library"],
+    deps = ["//vendor/github.com/stretchr/testify/assert:go_default_library"],
+)
diff --git a/util/math/min.go b/util/math/min.go
new file mode 100644
index 0000000000000000000000000000000000000000..f76c898aa81d17a892aeb1085c3f78e19984d0b5
--- /dev/null
+++ b/util/math/min.go
@@ -0,0 +1,9 @@
+package math
+
+// Min returns the minimum of a and b
+func Min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
diff --git a/util/math/min_test.go b/util/math/min_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..12ef418f01e72191994d0869aa70bedd18a48c03
--- /dev/null
+++ b/util/math/min_test.go
@@ -0,0 +1,34 @@
+package math
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestMin(t *testing.T) {
+	tests := []struct {
+		name     string
+		a        int
+		b        int
+		expected int
+	}{
+		{
+			name:     "A",
+			a:        100,
+			b:        200,
+			expected: 100,
+		},
+		{
+			name:     "A",
+			a:        200,
+			b:        100,
+			expected: 100,
+		},
+	}
+
+	for _, test := range tests {
+		res := Min(test.a, test.b)
+		assert.Equalf(t, test.expected, res, "Test %q", test.name)
+	}
+}