From 5ecbc83cc2435faeb002f7a708889118418b9d7f Mon Sep 17 00:00:00 2001
From: Daniel Czerwonk <daniel@dan-nrw.de>
Date: Sun, 1 Jul 2018 13:55:17 +0200
Subject: [PATCH] added MP_UNREACH_NLRI

---
 protocols/bgp/packet/helper.go               | 21 +++++++++++
 protocols/bgp/packet/mp_reach_nlri.go        | 19 +---------
 protocols/bgp/packet/mp_reach_nlri_test.go   |  2 +-
 protocols/bgp/packet/mp_unreach_nlri.go      | 26 +++++++++++++
 protocols/bgp/packet/mp_unreach_nlri_test.go | 39 ++++++++++++++++++++
 5 files changed, 89 insertions(+), 18 deletions(-)
 create mode 100644 protocols/bgp/packet/helper.go
 create mode 100644 protocols/bgp/packet/mp_unreach_nlri.go
 create mode 100644 protocols/bgp/packet/mp_unreach_nlri_test.go

diff --git a/protocols/bgp/packet/helper.go b/protocols/bgp/packet/helper.go
new file mode 100644
index 00000000..1fd55ffe
--- /dev/null
+++ b/protocols/bgp/packet/helper.go
@@ -0,0 +1,21 @@
+package packet
+
+import (
+	"math"
+
+	bnet "github.com/bio-routing/bio-rd/net"
+)
+
+func serializePrefix(pfx bnet.Prefix) []byte {
+	if pfx.Pfxlen() == 0 {
+		return []byte{}
+	}
+
+	numBytes := uint8(math.Ceil(float64(pfx.Pfxlen()) / float64(8)))
+
+	b := make([]byte, numBytes+1)
+	b[0] = pfx.Pfxlen()
+	copy(b[1:numBytes+1], pfx.Addr().Bytes()[0:numBytes])
+
+	return b
+}
diff --git a/protocols/bgp/packet/mp_reach_nlri.go b/protocols/bgp/packet/mp_reach_nlri.go
index 82205b5f..64c76066 100644
--- a/protocols/bgp/packet/mp_reach_nlri.go
+++ b/protocols/bgp/packet/mp_reach_nlri.go
@@ -2,14 +2,13 @@ package packet
 
 import (
 	"bytes"
-	"math"
 
 	"github.com/taktv6/tflow2/convert"
 
 	bnet "github.com/bio-routing/bio-rd/net"
 )
 
-// MultiProtocolReachNLRI represents Network Layer Reachability Information for one prefix of an IP address family (rfc4760)
+// MultiProtocolReachNLRI represents network layer reachability information for one prefix of an IP address family (rfc4760)
 type MultiProtocolReachNLRI struct {
 	AFI     uint16
 	SAFI    uint8
@@ -26,23 +25,9 @@ func (n *MultiProtocolReachNLRI) serialize(buf *bytes.Buffer) uint8 {
 	tempBuf.WriteByte(uint8(len(nextHop))) // NextHop length
 	tempBuf.Write(nextHop)
 	tempBuf.WriteByte(0) // RESERVED
-	tempBuf.Write(n.serializePrefix())
+	tempBuf.Write(serializePrefix(n.Prefix))
 
 	buf.Write(tempBuf.Bytes())
 
 	return uint8(tempBuf.Len())
 }
-
-func (n *MultiProtocolReachNLRI) serializePrefix() []byte {
-	if n.Prefix.Pfxlen() == 0 {
-		return []byte{}
-	}
-
-	numBytes := uint8(math.Ceil(float64(n.Prefix.Pfxlen()) / float64(8)))
-
-	b := make([]byte, numBytes+1)
-	b[0] = n.Prefix.Pfxlen()
-	copy(b[1:numBytes+1], n.Prefix.Addr().Bytes()[0:numBytes])
-
-	return b
-}
diff --git a/protocols/bgp/packet/mp_reach_nlri_test.go b/protocols/bgp/packet/mp_reach_nlri_test.go
index 935c6661..2bbb9d2e 100644
--- a/protocols/bgp/packet/mp_reach_nlri_test.go
+++ b/protocols/bgp/packet/mp_reach_nlri_test.go
@@ -8,7 +8,7 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-func TestSerializeMultiProtocolNLRI(t *testing.T) {
+func TestSerializeMultiProtocolReachNLRI(t *testing.T) {
 	tests := []struct {
 		name     string
 		nlri     MultiProtocolReachNLRI
diff --git a/protocols/bgp/packet/mp_unreach_nlri.go b/protocols/bgp/packet/mp_unreach_nlri.go
new file mode 100644
index 00000000..1c025093
--- /dev/null
+++ b/protocols/bgp/packet/mp_unreach_nlri.go
@@ -0,0 +1,26 @@
+package packet
+
+import (
+	"bytes"
+
+	bnet "github.com/bio-routing/bio-rd/net"
+	"github.com/taktv6/tflow2/convert"
+)
+
+// MultiProtocolUnreachNLRI represents network layer withdraw information for one prefix of an IP address family (rfc4760)
+type MultiProtocolUnreachNLRI struct {
+	AFI    uint16
+	SAFI   uint8
+	Prefix bnet.Prefix
+}
+
+func (n *MultiProtocolUnreachNLRI) serialize(buf *bytes.Buffer) uint8 {
+	tempBuf := bytes.NewBuffer(nil)
+	tempBuf.Write(convert.Uint16Byte(n.AFI))
+	tempBuf.WriteByte(n.SAFI)
+	tempBuf.Write(serializePrefix(n.Prefix))
+
+	buf.Write(tempBuf.Bytes())
+
+	return uint8(tempBuf.Len())
+}
diff --git a/protocols/bgp/packet/mp_unreach_nlri_test.go b/protocols/bgp/packet/mp_unreach_nlri_test.go
new file mode 100644
index 00000000..7e132acc
--- /dev/null
+++ b/protocols/bgp/packet/mp_unreach_nlri_test.go
@@ -0,0 +1,39 @@
+package packet
+
+import (
+	"bytes"
+	"testing"
+
+	bnet "github.com/bio-routing/bio-rd/net"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestSerializeMultiProtocolUnreachNLRI(t *testing.T) {
+	tests := []struct {
+		name     string
+		nlri     MultiProtocolUnreachNLRI
+		expected []byte
+	}{
+		{
+			name: "Simple IPv6 prefix",
+			nlri: MultiProtocolUnreachNLRI{
+				AFI:    IPv6AFI,
+				SAFI:   UnicastSAFI,
+				Prefix: bnet.NewPfx(bnet.IPv6FromBlocks(0x2620, 0x110, 0x9000, 0, 0, 0, 0, 0), 44),
+			},
+			expected: []byte{
+				0x00, 0x02, // AFI
+				0x01,                                     // SAFI
+				0x2c, 0x26, 0x20, 0x01, 0x10, 0x90, 0x00, // Prefix
+			},
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			buf := &bytes.Buffer{}
+			test.nlri.serialize(buf)
+			assert.Equal(t, test.expected, buf.Bytes())
+		})
+	}
+}
-- 
GitLab