From f48a4b5ae35d311f09f9301ac146853cfc49a472 Mon Sep 17 00:00:00 2001
From: Daniel Czerwonk <daniel@dan-nrw.de>
Date: Thu, 31 May 2018 20:58:21 +0200
Subject: [PATCH] added community string

---
 protocols/bgp/packet/community.go            |  2 +-
 protocols/bgp/packet/community_test.go       |  4 +--
 protocols/bgp/packet/path_attributes.go      |  9 +++++++
 protocols/bgp/packet/path_attributes_test.go | 27 +++++++++++++++++++-
 protocols/bgp/server/fsm.go                  |  2 ++
 route/bgp.go                                 |  1 +
 6 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/protocols/bgp/packet/community.go b/protocols/bgp/packet/community.go
index e97d6788..e00ae204 100644
--- a/protocols/bgp/packet/community.go
+++ b/protocols/bgp/packet/community.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 )
 
-func CommunityString(v uint32) string {
+func CommunityStringForUint32(v uint32) string {
 	e1 := v >> 16
 	e2 := v - e1<<16
 
diff --git a/protocols/bgp/packet/community_test.go b/protocols/bgp/packet/community_test.go
index 06a22689..f2dced9a 100644
--- a/protocols/bgp/packet/community_test.go
+++ b/protocols/bgp/packet/community_test.go
@@ -6,7 +6,7 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-func TestCommunityString(t *testing.T) {
+func TestCommunityStringFromUint32(t *testing.T) {
 	tests := []struct {
 		name     string
 		value    uint32
@@ -31,7 +31,7 @@ func TestCommunityString(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(te *testing.T) {
-			assert.Equal(te, test.expected, CommunityString(test.value))
+			assert.Equal(te, test.expected, CommunityStringForUint32(test.value))
 		})
 	}
 }
diff --git a/protocols/bgp/packet/path_attributes.go b/protocols/bgp/packet/path_attributes.go
index 8a13ec64..c4d67205 100644
--- a/protocols/bgp/packet/path_attributes.go
+++ b/protocols/bgp/packet/path_attributes.go
@@ -396,6 +396,15 @@ func (pa *PathAttribute) ASPathLen() (ret uint16) {
 	return
 }
 
+func (a *PathAttribute) CommunityString() string {
+	s := ""
+	for _, com := range a.Value.([]uint32) {
+		s += CommunityStringForUint32(com) + " "
+	}
+
+	return strings.TrimRight(s, " ")
+}
+
 func (a *PathAttribute) LargeCommunityString() string {
 	s := ""
 	for _, com := range a.Value.([]LargeCommunity) {
diff --git a/protocols/bgp/packet/path_attributes_test.go b/protocols/bgp/packet/path_attributes_test.go
index 70599584..54cfefd9 100644
--- a/protocols/bgp/packet/path_attributes_test.go
+++ b/protocols/bgp/packet/path_attributes_test.go
@@ -674,7 +674,7 @@ func TestDecodeCommunity(t *testing.T) {
 			expected: &PathAttribute{
 				Length: 8,
 				Value: []uint32{
-					131080, 16777216 + 1025,
+					131080, 16778241,
 				},
 			},
 		},
@@ -917,6 +917,31 @@ func TestLargeCommunityString(t *testing.T) {
 	}
 }
 
+func TestCommunityString(t *testing.T) {
+	tests := []struct {
+		name     string
+		pa       *PathAttribute
+		expected string
+	}{
+		{
+			name: "two attributes",
+			pa: &PathAttribute{
+				Value: []uint32{
+					131080, 16778241,
+				},
+			},
+			expected: "(2,8) (256,1025)",
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(te *testing.T) {
+			res := test.pa.CommunityString()
+			assert.Equal(te, test.expected, res)
+		})
+	}
+}
+
 func TestSetOptional(t *testing.T) {
 	tests := []struct {
 		name     string
diff --git a/protocols/bgp/server/fsm.go b/protocols/bgp/server/fsm.go
index 1d83b2d3..b1d1f745 100644
--- a/protocols/bgp/server/fsm.go
+++ b/protocols/bgp/server/fsm.go
@@ -845,6 +845,8 @@ func (fsm *FSM) established() int {
 						case packet.ASPathAttr:
 							path.BGPPath.ASPath = pa.ASPathString()
 							path.BGPPath.ASPathLen = pa.ASPathLen()
+						case packet.CommunitiesAttr:
+							path.BGPPath.Communities = pa.CommunityString()
 						case packet.LargeCommunityAttr:
 							path.BGPPath.LargeCommunities = pa.LargeCommunityString()
 						}
diff --git a/route/bgp.go b/route/bgp.go
index a19c4cde..d0eaf295 100644
--- a/route/bgp.go
+++ b/route/bgp.go
@@ -20,6 +20,7 @@ type BGPPath struct {
 	EBGP             bool
 	BGPIdentifier    uint32
 	Source           uint32
+	Communities      string
 	LargeCommunities string
 }
 
-- 
GitLab