diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-08-15 09:24:49 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-08-15 09:24:49 +0900 |
commit | 2c12fa2b92c3372d8639e84be6ee89a9ab581158 (patch) | |
tree | 22de5e752ecb359f319d790bb838eee91123e315 | |
parent | cdca8b5ceffd12ff702903e3369f3cafff2787ae (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.go | 5 | ||||
-rw-r--r-- | docs/sources/mrt.md | 72 | ||||
-rw-r--r-- | server/mrt.go | 12 | ||||
-rw-r--r-- | server/server.go | 23 | ||||
-rw-r--r-- | tools/pyang_plugins/gobgp.yang | 7 |
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; |