1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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
}
|