summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/grpc_server.go64
-rw-r--r--server/peer.go57
-rw-r--r--server/server.go243
3 files changed, 197 insertions, 167 deletions
diff --git a/server/grpc_server.go b/server/grpc_server.go
index 0ff61b47..f6f233a0 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -40,8 +40,6 @@ const (
REQ_NEIGHBOR_SOFT_RESET_OUT
REQ_NEIGHBOR_ENABLE
REQ_NEIGHBOR_DISABLE
- REQ_NEIGHBOR_POLICY
- REQ_MOD_NEIGHBOR_POLICY
REQ_GLOBAL_RIB
REQ_MONITOR_GLOBAL_BEST_CHANGED
REQ_MONITOR_NEIGHBOR_PEER_STATE
@@ -53,13 +51,14 @@ const (
REQ_VRFS
REQ_VRF_MOD
REQ_MOD_PATH
- REQ_GLOBAL_POLICY
REQ_DEFINED_SET
REQ_MOD_DEFINED_SET
REQ_STATEMENT
REQ_MOD_STATEMENT
REQ_POLICY
REQ_MOD_POLICY
+ REQ_POLICY_ASSIGNMENT
+ REQ_MOD_POLICY_ASSIGNMENT
)
const GRPC_PORT = 8080
@@ -240,53 +239,6 @@ func (s *Server) ModPath(stream api.GobgpApi_ModPathServer) error {
return err
}
-func (s *Server) GetNeighborPolicy(ctx context.Context, arg *api.PolicyArguments) (*api.ApplyPolicy, error) {
- r := 0
- switch arg.Resource {
- case api.Resource_GLOBAL:
- r = REQ_GLOBAL_POLICY
- case api.Resource_LOCAL:
- r = REQ_NEIGHBOR_POLICY
- default:
- return nil, fmt.Errorf("unsupported resource: %s", arg.Resource)
- }
-
- req := NewGrpcRequest(r, arg.NeighborAddress, bgp.RouteFamily(0), arg)
- s.bgpServerCh <- req
-
- res := <-req.ResponseCh
- if err := res.Err(); err != nil {
- log.Debug(err.Error())
- return nil, err
- }
- return res.Data.(*api.ApplyPolicy), nil
-}
-
-func (s *Server) ModNeighborPolicy(stream api.GobgpApi_ModNeighborPolicyServer) error {
- for {
- arg, err := stream.Recv()
- if err == io.EOF {
- return nil
- } else if err != nil {
- return err
- }
-
- req := NewGrpcRequest(REQ_MOD_NEIGHBOR_POLICY, arg.NeighborAddress, bgp.RouteFamily(0), arg)
- s.bgpServerCh <- req
- res := <-req.ResponseCh
- if err := res.Err(); err != nil {
- log.Debug(err.Error())
- return err
- }
- err = stream.Send(&api.Error{
- Code: api.Error_SUCCESS,
- })
- if err != nil {
- return err
- }
- }
-}
-
func (s *Server) GetMrt(arg *api.MrtArguments, stream api.GobgpApi_GetMrtServer) error {
var reqType int
switch arg.Resource {
@@ -416,6 +368,18 @@ func (s *Server) ModPolicy(ctx context.Context, arg *api.ModPolicyArguments) (*a
return s.mod(REQ_MOD_POLICY, arg)
}
+func (s *Server) GetPolicyAssignment(ctx context.Context, arg *api.PolicyAssignment) (*api.PolicyAssignment, error) {
+ d, err := s.get(REQ_POLICY_ASSIGNMENT, arg)
+ if err != nil {
+ return nil, err
+ }
+ return d.(*api.PolicyAssignment), nil
+}
+
+func (s *Server) ModPolicyAssignment(ctx context.Context, arg *api.ModPolicyAssignmentArguments) (*api.Error, error) {
+ return s.mod(REQ_MOD_POLICY_ASSIGNMENT, arg)
+}
+
type GrpcRequest struct {
RequestType int
Name string
diff --git a/server/peer.go b/server/peer.go
index 71d07c25..cbc3005a 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -41,7 +41,7 @@ type Peer struct {
peerInfo *table.PeerInfo
outgoing chan *bgp.BGPMessage
inPolicies []*table.Policy
- defaultInPolicy config.DefaultPolicyType
+ defaultInPolicy table.RouteType
accepted uint32
staleAccepted bool
isConfederationMember bool
@@ -381,49 +381,52 @@ func (peer *Peer) ToApiStruct() *api.Peer {
}
}
-func (peer *Peer) setPolicy(policy map[string]*table.Policy) {
- policyConf := peer.conf.ApplyPolicy
- inPolicies := make([]*table.Policy, 0)
- for _, policyName := range policyConf.ApplyPolicyConfig.InPolicy {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": peer.conf.NeighborConfig.NeighborAddress,
- "PolicyName": policyName,
- }).Info("in-policy installed")
- if pol, ok := policy[policyName]; ok {
- log.Debug("in policy : ", pol)
- inPolicies = append(inPolicies, pol)
+func (peer *Peer) GetPolicy(d table.PolicyDirection) []*table.Policy {
+ switch d {
+ case table.POLICY_DIRECTION_IN:
+ return peer.inPolicies
+ default:
+ if peer.localRib != nil {
+ return peer.localRib.GetPolicy(d)
}
}
- peer.inPolicies = inPolicies
- peer.defaultInPolicy = policyConf.ApplyPolicyConfig.DefaultInPolicy
- if peer.localRib != nil {
- peer.localRib.SetPolicy(policyConf, policy)
- }
+ return nil
}
-func (peer *Peer) GetPolicy(d table.PolicyDirection) []*table.Policy {
+func (peer *Peer) SetPolicy(d table.PolicyDirection, policies []*table.Policy) error {
switch d {
case table.POLICY_DIRECTION_IN:
- return peer.inPolicies
+ peer.inPolicies = policies
default:
- return peer.localRib.GetPolicy(d)
+ if peer.localRib != nil {
+ return peer.localRib.SetPolicy(d, policies)
+ }
}
+ return nil
}
func (peer *Peer) GetDefaultPolicy(d table.PolicyDirection) table.RouteType {
- var def config.DefaultPolicyType
switch d {
case table.POLICY_DIRECTION_IN:
- def = peer.defaultInPolicy
+ return peer.defaultInPolicy
default:
- return peer.localRib.GetDefaultPolicy(d)
+ if peer.localRib != nil {
+ return peer.localRib.GetDefaultPolicy(d)
+ }
}
+ return table.ROUTE_TYPE_NONE
+}
- if def == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
- return table.ROUTE_TYPE_ACCEPT
+func (peer *Peer) SetDefaultPolicy(d table.PolicyDirection, typ table.RouteType) error {
+ switch d {
+ case table.POLICY_DIRECTION_IN:
+ peer.defaultInPolicy = typ
+ default:
+ if peer.localRib != nil {
+ return peer.localRib.SetDefaultPolicy(d, typ)
+ }
}
- return table.ROUTE_TYPE_REJECT
+ return nil
}
func (peer *Peer) ApplyPolicy(d table.PolicyDirection, paths []*table.Path) ([]*table.Path, []*table.Path) {
diff --git a/server/server.go b/server/server.go
index 171bee55..b92aec16 100644
--- a/server/server.go
+++ b/server/server.go
@@ -211,7 +211,9 @@ func (server *BgpServer) Serve() {
}(g.AfiSafis.AfiSafiList)
server.globalRib = table.NewTableManager(GLOBAL_RIB_NAME, rfList, g.MplsLabelRange.MinLabel, g.MplsLabelRange.MaxLabel)
-
+ if server.policy != nil {
+ server.setPolicyByConfig(server.globalRib, g.ApplyPolicy)
+ }
listenerMap := make(map[string]*net.TCPListener)
acceptCh := make(chan *net.TCPConn)
l4, err1 := listenAndAccept("tcp4", server.listenPort, acceptCh)
@@ -352,6 +354,7 @@ func (server *BgpServer) Serve() {
SetTcpMD5SigSockopts(listener(config.NeighborConfig.NeighborAddress), addr, config.NeighborConfig.AuthPassword)
peer := NewPeer(g, config)
+ server.setPolicyByConfig(peer, config.ApplyPolicy)
if peer.isRouteServerClient() {
pathList := make([]*table.Path, 0)
rfList := peer.configuredRFlist()
@@ -396,10 +399,8 @@ func (server *BgpServer) Serve() {
case config := <-server.updatedPeerCh:
addr := config.NeighborConfig.NeighborAddress.String()
peer := server.neighborMap[addr]
- if peer.isRouteServerClient() {
- peer.conf.ApplyPolicy = config.ApplyPolicy
- peer.setPolicy(server.policy.PolicyMap)
- }
+ peer.conf = config
+ server.setPolicyByConfig(peer, config.ApplyPolicy)
case e := <-incoming:
peer, found := server.neighborMap[e.MsgSrc]
if !found {
@@ -863,6 +864,21 @@ func (server *BgpServer) UpdatePolicy(policy config.RoutingPolicy) {
server.policyUpdateCh <- policy
}
+func (server *BgpServer) setPolicyByConfig(p policyPoint, c config.ApplyPolicy) {
+ for _, dir := range []table.PolicyDirection{table.POLICY_DIRECTION_IN, table.POLICY_DIRECTION_IMPORT, table.POLICY_DIRECTION_EXPORT} {
+ ps, def, err := server.policy.GetAssignmentFromConfig(dir, c)
+ if err != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "Dir": dir,
+ }).Errorf("failed to get policy info: %s", err)
+ continue
+ }
+ p.SetDefaultPolicy(dir, def)
+ p.SetPolicy(dir, ps)
+ }
+}
+
func (server *BgpServer) SetPolicy(pl config.RoutingPolicy) error {
p, err := table.NewRoutingPolicy(pl)
if err != nil {
@@ -873,7 +889,7 @@ func (server *BgpServer) SetPolicy(pl config.RoutingPolicy) error {
}
server.policy = p
if server.globalRib != nil {
- server.globalRib.SetPolicy(server.bgpConfig.Global.ApplyPolicy, server.policy.PolicyMap)
+ server.setPolicyByConfig(server.globalRib, server.bgpConfig.Global.ApplyPolicy)
}
return nil
}
@@ -885,7 +901,7 @@ func (server *BgpServer) handlePolicy(pl config.RoutingPolicy) {
"Topic": "Peer",
"Key": peer.conf.NeighborConfig.NeighborAddress,
}).Info("call set policy")
- peer.setPolicy(server.policy.PolicyMap)
+ server.setPolicyByConfig(peer, peer.conf.ApplyPolicy)
}
}
@@ -1547,89 +1563,6 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
result.Data = err
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
-
- case REQ_NEIGHBOR_POLICY, REQ_GLOBAL_POLICY:
- arg := grpcReq.Data.(*api.PolicyArguments)
- var names []string
- def := api.RouteAction_REJECT
- var applyPolicy config.ApplyPolicy
- switch grpcReq.RequestType {
- case REQ_NEIGHBOR_POLICY:
- peer, err := server.checkNeighborRequest(grpcReq)
- if err != nil {
- return msgs
- }
- applyPolicy = peer.conf.ApplyPolicy
- case REQ_GLOBAL_RIB:
- applyPolicy = server.bgpConfig.Global.ApplyPolicy
- }
- switch arg.ApplyPolicy.Type {
- case api.PolicyType_IMPORT:
- names = applyPolicy.ApplyPolicyConfig.ImportPolicy
- if applyPolicy.ApplyPolicyConfig.DefaultImportPolicy == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
- def = api.RouteAction_ACCEPT
- }
- case api.PolicyType_EXPORT:
- names = applyPolicy.ApplyPolicyConfig.ExportPolicy
- if applyPolicy.ApplyPolicyConfig.DefaultExportPolicy == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
- def = api.RouteAction_ACCEPT
- }
- case api.PolicyType_IN:
- names = applyPolicy.ApplyPolicyConfig.InPolicy
- if applyPolicy.ApplyPolicyConfig.DefaultInPolicy == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
- def = api.RouteAction_ACCEPT
- }
- }
- result := &GrpcResponse{
- Data: &api.ApplyPolicy{
- Policies: names,
- Default: def,
- },
- }
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- case REQ_MOD_NEIGHBOR_POLICY:
- peer, err := server.checkNeighborRequest(grpcReq)
- if err != nil {
- break
- }
- result := &GrpcResponse{}
- arg := grpcReq.Data.(*api.PolicyArguments)
- applyPolicy := peer.conf.ApplyPolicy.ApplyPolicyConfig
- def := config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE
- switch arg.Operation {
- case api.Operation_ADD:
- if arg.ApplyPolicy.Default != api.RouteAction_REJECT {
- def = config.DEFAULT_POLICY_TYPE_REJECT_ROUTE
- }
- switch arg.ApplyPolicy.Type {
- case api.PolicyType_IMPORT:
- applyPolicy.DefaultImportPolicy = def
- applyPolicy.ImportPolicy = arg.ApplyPolicy.Policies
- case api.PolicyType_EXPORT:
- applyPolicy.DefaultExportPolicy = def
- applyPolicy.ExportPolicy = arg.ApplyPolicy.Policies
- case api.PolicyType_IN:
- applyPolicy.DefaultInPolicy = def
- applyPolicy.InPolicy = arg.ApplyPolicy.Policies
- }
- case api.Operation_DEL:
- switch arg.ApplyPolicy.Type {
- case api.PolicyType_IMPORT:
- applyPolicy.DefaultImportPolicy = def
- applyPolicy.ImportPolicy = nil
- case api.PolicyType_EXPORT:
- applyPolicy.DefaultExportPolicy = def
- applyPolicy.ExportPolicy = nil
- case api.PolicyType_IN:
- applyPolicy.DefaultInPolicy = def
- applyPolicy.InPolicy = nil
- }
- }
- peer.setPolicy(server.policy.PolicyMap)
-
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
case REQ_DEFINED_SET:
if err := server.handleGrpcGetDefinedSet(grpcReq); err != nil {
grpcReq.ResponseCh <- &GrpcResponse{
@@ -1669,6 +1602,19 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
ResponseErr: err,
}
close(grpcReq.ResponseCh)
+ case REQ_POLICY_ASSIGNMENT:
+ if err := server.handleGrpcGetPolicyAssignment(grpcReq); err != nil {
+ grpcReq.ResponseCh <- &GrpcResponse{
+ ResponseErr: err,
+ }
+ }
+ close(grpcReq.ResponseCh)
+ case REQ_MOD_POLICY_ASSIGNMENT:
+ err := server.handleGrpcModPolicyAssignment(grpcReq)
+ grpcReq.ResponseCh <- &GrpcResponse{
+ ResponseErr: err,
+ }
+ close(grpcReq.ResponseCh)
case REQ_MONITOR_GLOBAL_BEST_CHANGED, REQ_MONITOR_NEIGHBOR_PEER_STATE:
server.broadcastReqs = append(server.broadcastReqs, grpcReq)
case REQ_MRT_GLOBAL_RIB, REQ_MRT_LOCAL_RIB:
@@ -1914,6 +1860,123 @@ func (server *BgpServer) handleGrpcModPolicy(grpcReq *GrpcRequest) error {
return err
}
+type policyPoint interface {
+ GetDefaultPolicy(table.PolicyDirection) table.RouteType
+ GetPolicy(table.PolicyDirection) []*table.Policy
+ SetDefaultPolicy(table.PolicyDirection, table.RouteType) error
+ SetPolicy(table.PolicyDirection, []*table.Policy) error
+}
+
+func (server *BgpServer) getPolicyInfo(a *api.PolicyAssignment) (policyPoint, table.PolicyDirection, error) {
+ switch a.Resource {
+ case api.Resource_GLOBAL:
+ switch a.Type {
+ case api.PolicyType_IMPORT:
+ return server.globalRib, table.POLICY_DIRECTION_IMPORT, nil
+ case api.PolicyType_EXPORT:
+ return server.globalRib, table.POLICY_DIRECTION_EXPORT, nil
+ default:
+ return nil, table.POLICY_DIRECTION_NONE, fmt.Errorf("invalid policy type")
+ }
+ case api.Resource_LOCAL:
+ peer, ok := server.neighborMap[a.Name]
+ if !ok {
+ return nil, table.POLICY_DIRECTION_NONE, fmt.Errorf("not found peer %s", a.Name)
+ }
+ switch a.Type {
+ case api.PolicyType_IN:
+ return peer, table.POLICY_DIRECTION_IN, nil
+ case api.PolicyType_IMPORT:
+ return peer, table.POLICY_DIRECTION_IMPORT, nil
+ case api.PolicyType_EXPORT:
+ return peer, table.POLICY_DIRECTION_EXPORT, nil
+ default:
+ return nil, table.POLICY_DIRECTION_NONE, fmt.Errorf("invalid policy type")
+ }
+ default:
+ return nil, table.POLICY_DIRECTION_NONE, fmt.Errorf("invalid resource type")
+ }
+
+}
+
+func (server *BgpServer) handleGrpcGetPolicyAssignment(grpcReq *GrpcRequest) error {
+ arg := grpcReq.Data.(*api.PolicyAssignment)
+ i, dir, err := server.getPolicyInfo(arg)
+ if err != nil {
+ return err
+ }
+ arg.Default = i.GetDefaultPolicy(dir).ToApiStruct()
+ ps := i.GetPolicy(dir)
+ arg.Policies = make([]*api.Policy, 0, len(ps))
+ for _, x := range ps {
+ arg.Policies = append(arg.Policies, x.ToApiStruct())
+ }
+ grpcReq.ResponseCh <- &GrpcResponse{
+ Data: arg,
+ }
+ return nil
+}
+
+func (server *BgpServer) handleGrpcModPolicyAssignment(grpcReq *GrpcRequest) error {
+ var err error
+ var dir table.PolicyDirection
+ var i policyPoint
+ arg := grpcReq.Data.(*api.ModPolicyAssignmentArguments)
+ assignment := arg.Assignment
+ i, dir, err = server.getPolicyInfo(assignment)
+ if err != nil {
+ return err
+ }
+ ps := make([]*table.Policy, 0, len(assignment.Policies))
+ for _, x := range assignment.Policies {
+ p, ok := server.policy.PolicyMap[x.Name]
+ if !ok {
+ return fmt.Errorf("not found policy %s", x.Name)
+ }
+ ps = append(ps, p)
+ }
+ cur := i.GetPolicy(dir)
+ switch arg.Operation {
+ case api.Operation_ADD, api.Operation_REPLACE:
+ if arg.Operation == api.Operation_REPLACE || cur == nil {
+ err = i.SetPolicy(dir, ps)
+ } else {
+ err = i.SetPolicy(dir, append(cur, ps...))
+ }
+ if err != nil {
+ return err
+ }
+ switch assignment.Default {
+ case api.RouteAction_ACCEPT:
+ err = i.SetDefaultPolicy(dir, table.ROUTE_TYPE_ACCEPT)
+ case api.RouteAction_REJECT:
+ err = i.SetDefaultPolicy(dir, table.ROUTE_TYPE_REJECT)
+ }
+ case api.Operation_DEL:
+ n := make([]*table.Policy, 0, len(cur)-len(ps))
+ for _, x := range ps {
+ found := false
+ for _, y := range cur {
+ if x.Name() == y.Name() {
+ found = true
+ break
+ }
+ }
+ if !found {
+ n = append(n, x)
+ }
+ }
+ err = i.SetPolicy(dir, n)
+ case api.Operation_DEL_ALL:
+ err = i.SetPolicy(dir, nil)
+ if err != nil {
+ return err
+ }
+ err = i.SetDefaultPolicy(dir, table.ROUTE_TYPE_NONE)
+ }
+ return err
+}
+
func (server *BgpServer) handleMrt(grpcReq *GrpcRequest) {
now := uint32(time.Now().Unix())
view := ""