summaryrefslogtreecommitdiffhomepage
path: root/server/server.go
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-10-19 14:39:04 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-10-20 10:33:10 +0900
commitf634b5035729485105d54c25198d36542337aea5 (patch)
tree1c39317df070390f397240868e414b78356c5cd0 /server/server.go
parent204eacc5c0503cecc796a74fd0c1948ad6a28051 (diff)
api: support policy assignment modification via grpc
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'server/server.go')
-rw-r--r--server/server.go243
1 files changed, 153 insertions, 90 deletions
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 := ""