summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/grpc_server.go21
-rw-r--r--server/rpki.go121
-rw-r--r--server/server.go8
3 files changed, 149 insertions, 1 deletions
diff --git a/server/grpc_server.go b/server/grpc_server.go
index 4a652c4f..a4e61be7 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -83,6 +83,7 @@ const (
REQ_MONITOR_GLOBAL_BEST_CHANGED
REQ_MONITOR_NEIGHBOR_PEER_STATE
REQ_MRT_GLOBAL_RIB
+ REQ_RPKI
)
const GRPC_PORT = 8080
@@ -621,6 +622,26 @@ END:
return err
}
+func (s *Server) GetRPKI(arg *api.Arguments, stream api.Grpc_GetRPKIServer) error {
+ rf, err := convertAf2Rf(arg.Af)
+ if err != nil {
+ return err
+ }
+ req := NewGrpcRequest(REQ_RPKI, "", rf, nil)
+ s.bgpServerCh <- req
+
+ for res := range req.ResponseCh {
+ if err := res.Err(); err != nil {
+ log.Debug(err.Error())
+ return err
+ }
+ if err := stream.Send(res.Data.(*api.ROA)); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
type GrpcRequest struct {
RequestType int
RemoteAddr string
diff --git a/server/rpki.go b/server/rpki.go
new file mode 100644
index 00000000..6ad6aa0a
--- /dev/null
+++ b/server/rpki.go
@@ -0,0 +1,121 @@
+// 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 (
+ "bufio"
+ "fmt"
+ "github.com/osrg/gobgp/api"
+ "github.com/osrg/gobgp/packet"
+ "net"
+)
+
+type roa struct {
+ AS uint32
+ PrefixLen uint8
+ MaxLen uint8
+ Prefix net.IP
+}
+
+func (r *roa) key() string {
+ return fmt.Sprintf("%s/%d", r.Prefix.String(), r.PrefixLen)
+}
+
+func (r *roa) toApiStruct() *api.ROA {
+ return &api.ROA{
+ As: r.AS,
+ Prefixlen: uint32(r.PrefixLen),
+ Maxlen: uint32(r.MaxLen),
+ Prefix: r.Prefix.String(),
+ }
+}
+
+type roaClient struct {
+ roas map[bgp.RouteFamily]map[string]*roa
+ outgoing chan *roa
+}
+
+func (c *roaClient) recieveROA() chan *roa {
+ return c.outgoing
+}
+
+func (c *roaClient) handleRTRMsg(r *roa) {
+ if r.Prefix.To4() != nil {
+ c.roas[bgp.RF_IPv4_UC][r.key()] = r
+ } else {
+ c.roas[bgp.RF_IPv6_UC][r.key()] = r
+ }
+}
+
+func (c *roaClient) handleGRPC(grpcReq *GrpcRequest) {
+ if roas, ok := c.roas[grpcReq.RouteFamily]; ok {
+ for _, r := range roas {
+ result := &GrpcResponse{}
+ result.Data = r.toApiStruct()
+ grpcReq.ResponseCh <- result
+ }
+ }
+ close(grpcReq.ResponseCh)
+}
+
+func newROAClient(url string) (*roaClient, error) {
+ c := &roaClient{
+ roas: make(map[bgp.RouteFamily]map[string]*roa),
+ }
+ c.roas[bgp.RF_IPv4_UC] = make(map[string]*roa)
+ c.roas[bgp.RF_IPv6_UC] = make(map[string]*roa)
+
+ if url == "" {
+ return c, nil
+ }
+
+ conn, err := net.Dial("tcp", url)
+ if err != nil {
+ return c, err
+ }
+
+ r := bgp.NewRTRResetQuery()
+ data, _ := r.Serialize()
+ conn.Write(data)
+ reader := bufio.NewReader(conn)
+ scanner := bufio.NewScanner(reader)
+ scanner.Split(bgp.SplitRTR)
+
+ ch := make(chan *roa)
+ c.outgoing = ch
+
+ go func(ch chan *roa) {
+ for scanner.Scan() {
+ m, _ := bgp.ParseRTR(scanner.Bytes())
+ if m != nil {
+ switch msg := m.(type) {
+ case *bgp.RTRIPPrefix:
+ p := make([]byte, len(msg.Prefix))
+ copy(p, msg.Prefix)
+ ch <- &roa{
+ AS: msg.AS,
+ PrefixLen: msg.PrefixLen,
+ MaxLen: msg.MaxLen,
+ Prefix: p,
+ }
+ }
+
+ }
+ }
+ }(ch)
+
+ return c, nil
+}
diff --git a/server/server.go b/server/server.go
index ef0b2ce3..dfc7058a 100644
--- a/server/server.go
+++ b/server/server.go
@@ -79,9 +79,10 @@ type BgpServer struct {
neighborMap map[string]*Peer
localRibMap map[string]*LocalRib
zclient *zebra.Client
+ roaClient *roaClient
}
-func NewBgpServer(port int) *BgpServer {
+func NewBgpServer(port int, roaURL string) *BgpServer {
b := BgpServer{}
b.globalTypeCh = make(chan config.Global)
b.addedPeerCh = make(chan config.Neighbor)
@@ -91,6 +92,7 @@ func NewBgpServer(port int) *BgpServer {
b.localRibMap = make(map[string]*LocalRib)
b.neighborMap = make(map[string]*Peer)
b.listenPort = port
+ b.roaClient, _ = newROAClient(roaURL)
return &b
}
@@ -214,6 +216,8 @@ func (server *BgpServer) Serve() {
}
select {
+ case rmsg := <-server.roaClient.recieveROA():
+ server.roaClient.handleRTRMsg(rmsg)
case zmsg := <-zapiMsgCh:
handleZapiMsg(zmsg)
case conn := <-acceptCh:
@@ -1289,6 +1293,8 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
server.broadcastReqs = append(server.broadcastReqs, grpcReq)
case REQ_MRT_GLOBAL_RIB:
server.handleMrt(grpcReq)
+ case REQ_RPKI:
+ server.roaClient.handleGRPC(grpcReq)
default:
errmsg := fmt.Errorf("Unknown request type: %v", grpcReq.RequestType)
result := &GrpcResponse{