From fd45a9a41dc654e97a9d0f0bcc49a1c9220ea3d0 Mon Sep 17 00:00:00 2001
From: Oliver Herms <oliver.herms@exaring.de>
Date: Fri, 4 May 2018 19:05:31 +0200
Subject: [PATCH] Making routing table thread safe

---
 routingtable/routingtable/table.go | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/routingtable/routingtable/table.go b/routingtable/routingtable/table.go
index a75ba5cc..6b8bcb6b 100644
--- a/routingtable/routingtable/table.go
+++ b/routingtable/routingtable/table.go
@@ -20,6 +20,9 @@ func NewRoutingTable() *RoutingTable {
 
 // AddPath adds a path to the routing table
 func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error {
+	rt.mu.Lock()
+	defer rt.mu.Unlock()
+
 	if rt.root == nil {
 		rt.root = newNode(pfx, p, pfx.Pfxlen(), false)
 		return nil
@@ -31,12 +34,18 @@ func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error {
 
 // RemovePath removes a path from the trie
 func (rt *RoutingTable) RemovePath(pfx net.Prefix, p *route.Path) error {
+	rt.mu.Lock()
+	defer rt.mu.Unlock()
+
 	rt.root.removePath(pfx, p)
 	return nil
 }
 
 // LPM performs a longest prefix match for pfx on lpm
 func (rt *RoutingTable) LPM(pfx net.Prefix) (res []*route.Route) {
+	rt.mu.RLock()
+	defer rt.mu.RUnlock()
+
 	if rt.root == nil {
 		return nil
 	}
@@ -47,6 +56,9 @@ func (rt *RoutingTable) LPM(pfx net.Prefix) (res []*route.Route) {
 
 // Get get's the route for pfx from the LPM
 func (rt *RoutingTable) Get(pfx net.Prefix) *route.Route {
+	rt.mu.RLock()
+	defer rt.mu.RUnlock()
+
 	if rt.root == nil {
 		return nil
 	}
@@ -60,6 +72,9 @@ func (rt *RoutingTable) Get(pfx net.Prefix) *route.Route {
 
 // GetLonger get's prefix pfx and all it's more specifics from the LPM
 func (rt *RoutingTable) GetLonger(pfx net.Prefix) (res []*route.Route) {
+	rt.mu.RLock()
+	defer rt.mu.RUnlock()
+
 	if rt.root == nil {
 		return []*route.Route{}
 	}
@@ -69,6 +84,9 @@ func (rt *RoutingTable) GetLonger(pfx net.Prefix) (res []*route.Route) {
 
 // Dump dumps all routes in table rt into a slice
 func (rt *RoutingTable) Dump() []*route.Route {
+	rt.mu.RLock()
+	defer rt.mu.RUnlock()
+
 	res := make([]*route.Route, 0)
 	return rt.root.dump(res)
 }
-- 
GitLab