diff --git a/protocols/bgp/packet/community.go b/protocols/bgp/packet/community.go
index e97d67885461b8a7e2a14405d5741ae8019cdccf..e00ae204898511c50788a4654b734ac9547e158d 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 06a226892765a9e30988fcdca973752d7f1bfcec..f2dced9a4749cfb9d9aeabbe06ed1497595f1cc9 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 8a13ec64391ef9b90aab0ae5635a1c1228c2bbfe..c4d672055c9eb448b9aa08ddc02a7a40a6781d76 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 70599584438c49efd1c28b59895afb3318ffe905..54cfefd9edef5b619adb1ff93d145b2cea385770 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 1d83b2d39819e429d9d32b557df9d97d28e07bac..b1d1f745127941582b1f4c422acc45f9f7e0573e 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 a19c4cde94873f5761fd579737bacde3fd240729..d0eaf2955df44ee15dc0d4a6ecb63d924093ce45 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
 }