diff options
-rw-r--r-- | config/bgp_configs.go | 8 | ||||
-rw-r--r-- | server/dumper.go | 71 | ||||
-rw-r--r-- | server/server.go | 37 | ||||
-rw-r--r-- | tools/pyang_plugins/gobgp.yang | 13 |
4 files changed, 128 insertions, 1 deletions
diff --git a/config/bgp_configs.go b/config/bgp_configs.go index 03e719fd..a4a6c0ff 100644 --- a/config/bgp_configs.go +++ b/config/bgp_configs.go @@ -764,6 +764,12 @@ type Neighbors struct { NeighborList []Neighbor } +//struct for container gobgp:mrt +type Mrt struct { + // original -> gobgp:file-name + FileName string +} + //struct for container bgp-mp:l2vpn-evpn type L2vpnEvpn struct { // original -> bgp-mp:prefix-limit @@ -1300,6 +1306,8 @@ type Global struct { AfiSafis AfiSafis // original -> rpol:apply-policy ApplyPolicy ApplyPolicy + // original -> gobgp:mrt + Mrt Mrt } //struct for container bgp:bgp diff --git a/server/dumper.go b/server/dumper.go new file mode 100644 index 00000000..46281ca6 --- /dev/null +++ b/server/dumper.go @@ -0,0 +1,71 @@ +// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + log "github.com/Sirupsen/logrus" + "github.com/osrg/gobgp/packet" + "os" + "time" +) + +type dumper struct { + ch chan *broadcastBGPMsg +} + +func (d *dumper) sendCh() chan *broadcastBGPMsg { + return d.ch +} + +func newDumper(filename string) (*dumper, error) { + f, err := os.Create(filename) + if err != nil { + return nil, err + } + + ch := make(chan *broadcastBGPMsg, 16) + + go func() { + for { + m := <-ch + subtype := bgp.MESSAGE_AS4 + mp := bgp.NewBGP4MPMessage(m.peerAS, m.localAS, 0, m.peerAddress.String(), m.localAddress.String(), m.fourBytesAs, m.message) + if m.fourBytesAs == false { + subtype = bgp.MESSAGE + } + bm, err := bgp.NewMRTMessage(uint32(time.Now().Unix()), bgp.BGP4MP, subtype, mp) + if err != nil { + log.WithFields(log.Fields{ + "Topic": "mrt", + "Data": m, + }).Warn(err) + continue + } + buf, err := bm.Serialize() + if err != nil { + log.WithFields(log.Fields{ + "Topic": "mrt", + "Data": m, + }).Warn(err) + } else { + f.Write(buf) + } + } + }() + return &dumper{ + ch: ch, + }, nil +} diff --git a/server/server.go b/server/server.go index 2cb0d29e..c1ba5206 100644 --- a/server/server.go +++ b/server/server.go @@ -69,6 +69,20 @@ func (m *broadcastGrpcMsg) send() { } } +type broadcastBGPMsg struct { + message *bgp.BGPMessage + peerAS uint32 + localAS uint32 + peerAddress net.IP + localAddress net.IP + fourBytesAs bool + ch chan *broadcastBGPMsg +} + +func (m *broadcastBGPMsg) send() { + m.ch <- m +} + type BgpServer struct { bgpConfig config.Bgp globalTypeCh chan config.Global @@ -76,6 +90,7 @@ type BgpServer struct { deletedPeerCh chan config.Neighbor updatedPeerCh chan config.Neighbor rpkiConfigCh chan config.RpkiServers + dumper *dumper GrpcReqCh chan *GrpcRequest listenPort int @@ -138,6 +153,15 @@ func (server *BgpServer) Serve() { g := <-server.globalTypeCh server.bgpConfig.Global = g + if g.Mrt.FileName != "" { + d, err := newDumper(g.Mrt.FileName) + if err != nil { + log.Warn(err) + } else { + server.dumper = d + } + } + senderCh := make(chan *SenderMsg, 1<<16) go func(ch chan *SenderMsg) { for { @@ -772,6 +796,19 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *fsmMsg, incoming chan * server.roaClient.validate(pathList) } } + if m.Header.Type == bgp.BGP_MSG_UPDATE && server.dumper != nil { + _, y := peer.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER] + bm := &broadcastBGPMsg{ + message: m, + peerAS: peer.peerInfo.AS, + localAS: peer.peerInfo.LocalAS, + peerAddress: peer.peerInfo.Address, + localAddress: peer.fsm.LocalAddr(), + fourBytesAs: y, + ch: server.dumper.sendCh(), + } + server.broadcastMsgs = append(server.broadcastMsgs, bm) + } msgs = append(msgs, server.propagateUpdate(peer, pathList)...) default: log.WithFields(log.Fields{ diff --git a/tools/pyang_plugins/gobgp.yang b/tools/pyang_plugins/gobgp.yang index 2fa51887..ad8f24b8 100644 --- a/tools/pyang_plugins/gobgp.yang +++ b/tools/pyang_plugins/gobgp.yang @@ -554,7 +554,18 @@ module bgp-gobgp { augment "/bgp:bgp" { description "additional rpki configuration and state"; uses gobgp-rpki-servers; - } + augment "/bgp:bgp/bgp:global" { + description "additional mrt configuration"; + container mrt { + description + "Configure dump bgp messages in the mrt format"; + leaf file-name { + type string; + description + "Configures a file name to be written."; + } + } + } } |