diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/server.go | 29 | ||||
-rw-r--r-- | server/zapi.go | 89 |
2 files changed, 118 insertions, 0 deletions
diff --git a/server/server.go b/server/server.go index a2f25391..ef0b2ce3 100644 --- a/server/server.go +++ b/server/server.go @@ -23,10 +23,12 @@ import ( "github.com/osrg/gobgp/packet" "github.com/osrg/gobgp/policy" "github.com/osrg/gobgp/table" + zebra "github.com/osrg/gozebra" "gopkg.in/tomb.v2" "net" "os" "strconv" + "strings" "time" ) @@ -76,6 +78,7 @@ type BgpServer struct { broadcastMsgs []broadcastMsg neighborMap map[string]*Peer localRibMap map[string]*LocalRib + zclient *zebra.Client } func NewBgpServer(port int) *BgpServer { @@ -191,6 +194,11 @@ func (server *BgpServer) Serve() { incoming := make(chan *fsmMsg, 4096) var senderMsgs []*SenderMsg + + var zapiMsgCh chan *zebra.Message + if server.zclient != nil { + zapiMsgCh = server.zclient.Recieve() + } for { var firstMsg *SenderMsg var sCh chan *SenderMsg @@ -206,6 +214,8 @@ func (server *BgpServer) Serve() { } select { + case zmsg := <-zapiMsgCh: + handleZapiMsg(zmsg) case conn := <-acceptCh: remoteAddr, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) peer, found := server.neighborMap[remoteAddr] @@ -472,6 +482,11 @@ func applyPolicies(peer *Peer, loc *LocalRib, d Direction, pathList []*table.Pat func (server *BgpServer) broadcastBests(bests []*table.Path) { for _, path := range bests { + z := newBroadcastZapiBestMsg(server.zclient, path) + if z != nil { + server.broadcastMsgs = append(server.broadcastMsgs, z) + } + result := &GrpcResponse{ Data: path.ToApiStruct(), } @@ -2032,3 +2047,17 @@ func (server *BgpServer) mkMrtRibMsgs(rf bgp.RouteFamily, t uint32) ([]*bgp.MRTM } return msgs, nil } + +func (server *BgpServer) NewZclient(url string) error { + l := strings.SplitN(url, ":", 2) + if len(l) != 2 { + return fmt.Errorf("unsupported url: %s", url) + } + cli, err := zebra.NewClient(l[0], l[1], zebra.ROUTE_BGP) + if err != nil { + return err + } + cli.SendHello() + server.zclient = cli + return nil +} diff --git a/server/zapi.go b/server/zapi.go new file mode 100644 index 00000000..bd80dba9 --- /dev/null +++ b/server/zapi.go @@ -0,0 +1,89 @@ +// 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 ( + "github.com/osrg/gobgp/packet" + "github.com/osrg/gobgp/table" + zebra "github.com/osrg/gozebra" + "net" + "strconv" + "strings" +) + +type broadcastZapiMsg struct { + client *zebra.Client + msg *zebra.Message +} + +func (m *broadcastZapiMsg) send() { + m.client.Send(m.msg) +} + +func newIPRouteMessage(path *table.Path) *zebra.Message { + var command zebra.API_TYPE + switch path.GetRouteFamily() { + case bgp.RF_IPv4_UC: + if path.IsWithdraw == true { + command = zebra.IPV4_ROUTE_DELETE + } else { + command = zebra.IPV4_ROUTE_ADD + } + case bgp.RF_IPv6_UC: + if path.IsWithdraw == true { + command = zebra.IPV6_ROUTE_DELETE + } else { + command = zebra.IPV6_ROUTE_ADD + } + default: + return nil + } + + l := strings.SplitN(path.GetNlri().String(), "/", 2) + plen, _ := strconv.Atoi(l[1]) + med, _ := path.GetMed() + return &zebra.Message{ + Header: zebra.Header{ + Command: command, + }, + Body: &zebra.IPv4RouteBody{ + Type: zebra.ROUTE_BGP, + SAFI: zebra.SAFI_UNICAST, + Message: zebra.MESSAGE_NEXTHOP, + Prefix: net.ParseIP(l[0]), + PrefixLength: uint8(plen), + Nexthops: []net.IP{path.GetNexthop()}, + Metric: med, + }, + } +} + +func newBroadcastZapiBestMsg(cli *zebra.Client, path *table.Path) *broadcastZapiMsg { + if cli == nil { + return nil + } + m := newIPRouteMessage(path) + if m == nil { + return nil + } + return &broadcastZapiMsg{ + client: cli, + msg: m, + } +} + +func handleZapiMsg(msg *zebra.Message) { +} |