summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-08-15 09:24:49 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-08-15 09:24:49 +0900
commit2c12fa2b92c3372d8639e84be6ee89a9ab581158 (patch)
tree22de5e752ecb359f319d790bb838eee91123e315
parentcdca8b5ceffd12ff702903e3369f3cafff2787ae (diff)
mrt: support per-peer table dump with route server configuration
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--config/bgp_configs.go5
-rw-r--r--docs/sources/mrt.md72
-rw-r--r--server/mrt.go12
-rw-r--r--server/server.go23
-rw-r--r--tools/pyang_plugins/gobgp.yang7
5 files changed, 112 insertions, 7 deletions
diff --git a/config/bgp_configs.go b/config/bgp_configs.go
index d144b47c..2ecaae86 100644
--- a/config/bgp_configs.go
+++ b/config/bgp_configs.go
@@ -1038,6 +1038,8 @@ type MrtConfig struct {
DumpType MrtType `mapstructure:"dump-type"`
// original -> gobgp:file-name
FileName string `mapstructure:"file-name"`
+ // original -> gobgp:table-name
+ TableName string `mapstructure:"table-name"`
// original -> gobgp:dump-interval
DumpInterval uint64 `mapstructure:"dump-interval"`
// original -> gobgp:rotation-interval
@@ -1054,6 +1056,9 @@ func (lhs *MrtConfig) Equal(rhs *MrtConfig) bool {
if lhs.FileName != rhs.FileName {
return false
}
+ if lhs.TableName != rhs.TableName {
+ return false
+ }
if lhs.DumpInterval != rhs.DumpInterval {
return false
}
diff --git a/docs/sources/mrt.md b/docs/sources/mrt.md
index 99f92afc..85a311f1 100644
--- a/docs/sources/mrt.md
+++ b/docs/sources/mrt.md
@@ -22,9 +22,7 @@ $ gobgp mrt inject global <dumpfile> [<number of prefix to inject>]
### <a name="section1.1"> Configuration
With the following configuration, gobgpd continuously dumps BGP update
-messages to `/tmp/updates.dump` file in the BGP4MP format and dumps
-routes in the global rib to `/tmp/table.dump` file in the TABLE_DUMPv2
-format every 60 seconds.
+messages to `/tmp/updates.dump` file in the BGP4MP format.
```toml
[global.config]
@@ -72,4 +70,72 @@ router-id = "10.0.255.254"
rotation-interval = 180
```
+## <a name="section1"> Dump the RIB in MRT TABLE_DUMPv2 format
+### <a name="section1.1"> Configuration
+
+With the following configuration, gobgpd continuously dumps routes in
+the global rib to `/tmp/table.dump` file in the TABLE_DUMPv2 format
+every 60 seconds.
+
+
+```toml
+[global.config]
+as = 64512
+router-id = "10.0.255.254"
+
+[[neighbors]]
+ [neighbors.config]
+ peer-as = 65001
+ neighbor-address = "10.0.255.1"
+
+[[mrt-dump]]
+ [mrt-dump.config]
+ dump-type = "table"
+ file-name = "/tmp/table.dump"
+ dump-interval = 60
+```
+
+With a route server configuration, gobgpd can dump routes in each
+peer's RIB.
+
+
+```toml
+[global.config]
+ as = 64512
+ router-id = "192.168.255.1"
+
+[[neighbors]]
+ [neighbors.config]
+ neighbor-address = "10.0.255.1"
+ peer-as = 65001
+ auth-password = "hoge1"
+ [neighbors.transport.config]
+ passive-mode = true
+ [neighbors.route-server.config]
+ route-server-client = true
+
+[[neighbors]]
+ [neighbors.config]
+ neighbor-address = "10.0.255.2"
+ peer-as = 65002
+ auth-password = "hoge2"
+ [neighbors.transport.config]
+ passive-mode = true
+ [neighbors.route-server.config]
+ route-server-client = true
+
+[[mrt-dump]]
+ [mrt-dump.config]
+ dump-type = "table"
+ file-name = "/tmp/table-1.dump"
+ table-name = "10.0.255.1"
+ dump-interval = 60
+
+[[mrt-dump]]
+ [mrt-dump.config]
+ dump-type = "table"
+ file-name = "/tmp/table-2.dump"
+ table-name = "10.0.255.2"
+ dump-interval = 60
+```
diff --git a/server/mrt.go b/server/mrt.go
index 605d6fe0..b92ce293 100644
--- a/server/mrt.go
+++ b/server/mrt.go
@@ -32,6 +32,7 @@ type mrtWriter struct {
dead chan struct{}
s *BgpServer
filename string
+ tablename string
file *os.File
rotationInterval uint64
dumpInterval uint64
@@ -48,6 +49,9 @@ func (m *mrtWriter) loop() error {
case config.MRT_TYPE_UPDATES:
ops = append(ops, WatchUpdate(false))
case config.MRT_TYPE_TABLE:
+ if len(m.tablename) > 0 {
+ ops = append(ops, WatchTableName(m.tablename))
+ }
}
w := m.s.Watch(ops...)
rotator := func() *time.Ticker {
@@ -258,7 +262,7 @@ func mrtFileOpen(filename string, interval uint64) (*os.File, error) {
return file, err
}
-func newMrtWriter(s *BgpServer, dumpType config.MrtType, filename string, rInterval, dInterval uint64) (*mrtWriter, error) {
+func newMrtWriter(s *BgpServer, dumpType config.MrtType, filename, tablename string, rInterval, dInterval uint64) (*mrtWriter, error) {
file, err := mrtFileOpen(filename, rInterval)
if err != nil {
return nil, err
@@ -268,6 +272,7 @@ func newMrtWriter(s *BgpServer, dumpType config.MrtType, filename string, rInter
s: s,
filename: filename,
file: file,
+ tablename: tablename,
rotationInterval: rInterval,
dumpInterval: dInterval,
}
@@ -298,9 +303,12 @@ func (m *mrtManager) enable(c *config.MrtConfig) error {
}
} else if c.DumpType == config.MRT_TYPE_UPDATES {
dInterval = 0
+ if len(c.TableName) > 0 {
+ return fmt.Errorf("can't specify the table name with the update dump type")
+ }
}
- w, err := newMrtWriter(m.bgpServer, c.DumpType, c.FileName, rInterval, dInterval)
+ w, err := newMrtWriter(m.bgpServer, c.DumpType, c.FileName, c.TableName, rInterval, dInterval)
if err == nil {
m.writer[c.FileName] = w
}
diff --git a/server/server.go b/server/server.go
index c0ac7c7c..81950c91 100644
--- a/server/server.go
+++ b/server/server.go
@@ -2417,6 +2417,7 @@ type watchOptions struct {
initUpdate bool
initPostUpdate bool
initPeerState bool
+ tableName string
}
type WatchOption func(*watchOptions)
@@ -2454,6 +2455,12 @@ func WatchPeerState(current bool) WatchOption {
}
}
+func WatchTableName(name string) WatchOption {
+ return func(o *watchOptions) {
+ o.tableName = name
+ }
+}
+
type Watcher struct {
opts watchOptions
realCh chan WatchEvent
@@ -2480,11 +2487,25 @@ func (w *Watcher) Generate(t WatchEventType) (err error) {
}
w.notify(&WatchEventAdjIn{PathList: clonePathList(pathList)})
case WATCH_EVENT_TYPE_TABLE:
+ id := table.GLOBAL_RIB_NAME
+ if len(w.opts.tableName) > 0 {
+ peer, ok := w.s.neighborMap[w.opts.tableName]
+ if !ok {
+ err = fmt.Errorf("Neighbor that has %v doesn't exist.", w.opts.tableName)
+ break
+ }
+ if !peer.isRouteServerClient() {
+ err = fmt.Errorf("Neighbor %v doesn't have local rib", w.opts.tableName)
+ return
+ }
+ id = peer.ID()
+ }
+
pathList := func() map[string][]*table.Path {
pathList := make(map[string][]*table.Path)
for _, t := range w.s.globalRib.Tables {
for _, dst := range t.GetSortedDestinations() {
- if paths := dst.GetKnownPathList(table.GLOBAL_RIB_NAME); len(paths) > 0 {
+ if paths := dst.GetKnownPathList(id); len(paths) > 0 {
pathList[dst.GetNlri().String()] = clonePathList(paths)
}
}
diff --git a/tools/pyang_plugins/gobgp.yang b/tools/pyang_plugins/gobgp.yang
index 3293d9d6..a7b78b95 100644
--- a/tools/pyang_plugins/gobgp.yang
+++ b/tools/pyang_plugins/gobgp.yang
@@ -828,7 +828,12 @@ module gobgp {
leaf file-name {
type string;
description
- "Configures a file name to be written.";
+ "Configures a file name to be written";
+ }
+ leaf table-name {
+ type string;
+ description
+ "specify the table name with route server setup";
}
leaf dump-interval {
type uint64;