summaryrefslogtreecommitdiffhomepage
path: root/server/rpki.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/rpki.go')
-rw-r--r--server/rpki.go121
1 files changed, 121 insertions, 0 deletions
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
+}