diff options
-rw-r--r-- | api/gobgp.pb.go | 148 | ||||
-rw-r--r-- | api/gobgp.proto | 25 | ||||
-rw-r--r-- | gobgp/cmd/common.go | 16 | ||||
-rw-r--r-- | gobgp/cmd/neighbor.go | 8 | ||||
-rw-r--r-- | gobgp/cmd/policy.go | 790 | ||||
-rw-r--r-- | server/grpc_server.go | 50 | ||||
-rw-r--r-- | server/server.go | 215 | ||||
-rw-r--r-- | table/policy.go | 166 |
8 files changed, 584 insertions, 834 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go index d4ec9c0a..577c29ed 100644 --- a/api/gobgp.pb.go +++ b/api/gobgp.pb.go @@ -21,9 +21,10 @@ It has these top-level messages: PeerInfo Peer Prefix + DefinedSet PrefixSet - AsPathLength MatchSet + AsPathLength Conditions CommunityAction MedAction @@ -396,42 +397,51 @@ func (m *Prefix) Reset() { *m = Prefix{} } func (m *Prefix) String() string { return proto.CompactTextString(m) } func (*Prefix) ProtoMessage() {} -type PrefixSet struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - List []*Prefix `protobuf:"bytes,2,rep,name=list" json:"list,omitempty"` - Option int32 `protobuf:"varint,3,opt,name=option" json:"option,omitempty"` +type DefinedSet struct { + Type int32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + List []string `protobuf:"bytes,3,rep,name=list" json:"list,omitempty"` + Prefixes []*Prefix `protobuf:"bytes,4,rep,name=prefixes" json:"prefixes,omitempty"` } -func (m *PrefixSet) Reset() { *m = PrefixSet{} } -func (m *PrefixSet) String() string { return proto.CompactTextString(m) } -func (*PrefixSet) ProtoMessage() {} +func (m *DefinedSet) Reset() { *m = DefinedSet{} } +func (m *DefinedSet) String() string { return proto.CompactTextString(m) } +func (*DefinedSet) ProtoMessage() {} -func (m *PrefixSet) GetList() []*Prefix { +func (m *DefinedSet) GetPrefixes() []*Prefix { if m != nil { - return m.List + return m.Prefixes } return nil } -type AsPathLength struct { - Length uint32 `protobuf:"varint,1,opt,name=length" json:"length,omitempty"` - Type int32 `protobuf:"varint,2,opt,name=type" json:"type,omitempty"` +type PrefixSet struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Option int32 `protobuf:"varint,2,opt,name=option" json:"option,omitempty"` } -func (m *AsPathLength) Reset() { *m = AsPathLength{} } -func (m *AsPathLength) String() string { return proto.CompactTextString(m) } -func (*AsPathLength) ProtoMessage() {} +func (m *PrefixSet) Reset() { *m = PrefixSet{} } +func (m *PrefixSet) String() string { return proto.CompactTextString(m) } +func (*PrefixSet) ProtoMessage() {} type MatchSet struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - List []string `protobuf:"bytes,2,rep,name=list" json:"list,omitempty"` - Option int32 `protobuf:"varint,3,opt,name=option" json:"option,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Option int32 `protobuf:"varint,2,opt,name=option" json:"option,omitempty"` } func (m *MatchSet) Reset() { *m = MatchSet{} } func (m *MatchSet) String() string { return proto.CompactTextString(m) } func (*MatchSet) ProtoMessage() {} +type AsPathLength struct { + Length uint32 `protobuf:"varint,1,opt,name=length" json:"length,omitempty"` + Type int32 `protobuf:"varint,2,opt,name=type" json:"type,omitempty"` +} + +func (m *AsPathLength) Reset() { *m = AsPathLength{} } +func (m *AsPathLength) String() string { return proto.CompactTextString(m) } +func (*AsPathLength) ProtoMessage() {} + type Conditions struct { PrefixSet *PrefixSet `protobuf:"bytes,1,opt,name=prefix_set" json:"prefix_set,omitempty"` NeighborSet *MatchSet `protobuf:"bytes,2,opt,name=neighbor_set" json:"neighbor_set,omitempty"` @@ -597,22 +607,15 @@ func (m *PolicyDefinition) GetStatements() []*Statement { } type ApplyPolicy struct { - Type PolicyType `protobuf:"varint,1,opt,name=type,enum=gobgpapi.PolicyType" json:"type,omitempty"` - Policies []*PolicyDefinition `protobuf:"bytes,2,rep,name=policies" json:"policies,omitempty"` - Default RouteAction `protobuf:"varint,3,opt,name=default,enum=gobgpapi.RouteAction" json:"default,omitempty"` + Type PolicyType `protobuf:"varint,1,opt,name=type,enum=gobgpapi.PolicyType" json:"type,omitempty"` + Policies []string `protobuf:"bytes,2,rep,name=policies" json:"policies,omitempty"` + Default RouteAction `protobuf:"varint,3,opt,name=default,enum=gobgpapi.RouteAction" json:"default,omitempty"` } func (m *ApplyPolicy) Reset() { *m = ApplyPolicy{} } func (m *ApplyPolicy) String() string { return proto.CompactTextString(m) } func (*ApplyPolicy) ProtoMessage() {} -func (m *ApplyPolicy) GetPolicies() []*PolicyDefinition { - if m != nil { - return m.Policies - } - return nil -} - type MrtMessage struct { Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` } @@ -723,6 +726,8 @@ type GobgpApiClient interface { GetROA(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetROAClient, error) GetVrfs(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetVrfsClient, error) ModVrf(ctx context.Context, in *ModVrfArguments, opts ...grpc.CallOption) (*Error, error) + GetDefinedSet(ctx context.Context, in *DefinedSet, opts ...grpc.CallOption) (*DefinedSet, error) + GetDefinedSets(ctx context.Context, in *DefinedSet, opts ...grpc.CallOption) (GobgpApi_GetDefinedSetsClient, error) } type gobgpApiClient struct { @@ -1216,6 +1221,47 @@ func (c *gobgpApiClient) ModVrf(ctx context.Context, in *ModVrfArguments, opts . return out, nil } +func (c *gobgpApiClient) GetDefinedSet(ctx context.Context, in *DefinedSet, opts ...grpc.CallOption) (*DefinedSet, error) { + out := new(DefinedSet) + err := grpc.Invoke(ctx, "/gobgpapi.GobgpApi/GetDefinedSet", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gobgpApiClient) GetDefinedSets(ctx context.Context, in *DefinedSet, opts ...grpc.CallOption) (GobgpApi_GetDefinedSetsClient, error) { + stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[12], c.cc, "/gobgpapi.GobgpApi/GetDefinedSets", opts...) + if err != nil { + return nil, err + } + x := &gobgpApiGetDefinedSetsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type GobgpApi_GetDefinedSetsClient interface { + Recv() (*DefinedSet, error) + grpc.ClientStream +} + +type gobgpApiGetDefinedSetsClient struct { + grpc.ClientStream +} + +func (x *gobgpApiGetDefinedSetsClient) Recv() (*DefinedSet, error) { + m := new(DefinedSet) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // Server API for GobgpApi service type GobgpApiServer interface { @@ -1242,6 +1288,8 @@ type GobgpApiServer interface { GetROA(*Arguments, GobgpApi_GetROAServer) error GetVrfs(*Arguments, GobgpApi_GetVrfsServer) error ModVrf(context.Context, *ModVrfArguments) (*Error, error) + GetDefinedSet(context.Context, *DefinedSet) (*DefinedSet, error) + GetDefinedSets(*DefinedSet, GobgpApi_GetDefinedSetsServer) error } func RegisterGobgpApiServer(s *grpc.Server, srv GobgpApiServer) { @@ -1647,6 +1695,39 @@ func _GobgpApi_ModVrf_Handler(srv interface{}, ctx context.Context, dec func(int return out, nil } +func _GobgpApi_GetDefinedSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(DefinedSet) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(GobgpApiServer).GetDefinedSet(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _GobgpApi_GetDefinedSets_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(DefinedSet) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(GobgpApiServer).GetDefinedSets(m, &gobgpApiGetDefinedSetsServer{stream}) +} + +type GobgpApi_GetDefinedSetsServer interface { + Send(*DefinedSet) error + grpc.ServerStream +} + +type gobgpApiGetDefinedSetsServer struct { + grpc.ServerStream +} + +func (x *gobgpApiGetDefinedSetsServer) Send(m *DefinedSet) error { + return x.ServerStream.SendMsg(m) +} + var _GobgpApi_serviceDesc = grpc.ServiceDesc{ ServiceName: "gobgpapi.GobgpApi", HandlerType: (*GobgpApiServer)(nil), @@ -1695,6 +1776,10 @@ var _GobgpApi_serviceDesc = grpc.ServiceDesc{ MethodName: "ModVrf", Handler: _GobgpApi_ModVrf_Handler, }, + { + MethodName: "GetDefinedSet", + Handler: _GobgpApi_GetDefinedSet_Handler, + }, }, Streams: []grpc.StreamDesc{ { @@ -1759,5 +1844,10 @@ var _GobgpApi_serviceDesc = grpc.ServiceDesc{ Handler: _GobgpApi_GetVrfs_Handler, ServerStreams: true, }, + { + StreamName: "GetDefinedSets", + Handler: _GobgpApi_GetDefinedSets_Handler, + ServerStreams: true, + }, }, } diff --git a/api/gobgp.proto b/api/gobgp.proto index b91ef183..7ef404f4 100644 --- a/api/gobgp.proto +++ b/api/gobgp.proto @@ -43,6 +43,8 @@ service GobgpApi { rpc GetROA(Arguments) returns (stream ROA) {} rpc GetVrfs(Arguments) returns (stream Vrf) {} rpc ModVrf(ModVrfArguments) returns (Error) {} + rpc GetDefinedSet(DefinedSet) returns (DefinedSet) {} + rpc GetDefinedSets(DefinedSet) returns (stream DefinedSet) {} } message Error { @@ -177,10 +179,21 @@ message Prefix { uint32 mask_length_max = 3; } +message DefinedSet { + int32 type = 1; + string name = 2; + repeated string list = 3; + repeated Prefix prefixes = 4; +} + message PrefixSet { string name = 1; - repeated Prefix list = 2; - int32 option = 3; + int32 option = 2; +} + +message MatchSet { + string name = 1; + int32 option = 2; } message AsPathLength { @@ -188,12 +201,6 @@ message AsPathLength { int32 type = 2; } -message MatchSet { - string name = 1; - repeated string list = 2; - int32 option = 3; -} - message Conditions { PrefixSet prefix_set = 1; MatchSet neighbor_set = 2; @@ -253,7 +260,7 @@ enum PolicyType { message ApplyPolicy { PolicyType type = 1; - repeated PolicyDefinition policies = 2; + repeated string policies = 2; RouteAction default = 3; } diff --git a/gobgp/cmd/common.go b/gobgp/cmd/common.go index 197b58cf..12f54008 100644 --- a/gobgp/cmd/common.go +++ b/gobgp/cmd/common.go @@ -310,21 +310,7 @@ func (c capabilities) Less(i, j int) bool { return c[i].Code() < c[j].Code() } -type prefixes []*gobgpapi.PrefixSet - -func (p prefixes) Len() int { - return len(p) -} - -func (p prefixes) Swap(i, j int) { - p[i], p[j] = p[j], p[i] -} - -func (p prefixes) Less(i, j int) bool { - return p[i].Name < p[j].Name -} - -type sets []*gobgpapi.MatchSet +type sets []*gobgpapi.DefinedSet func (n sets) Len() int { return len(n) diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go index 0efa6840..12dbabf0 100644 --- a/gobgp/cmd/neighbor.go +++ b/gobgp/cmd/neighbor.go @@ -642,8 +642,7 @@ func showNeighborPolicy(remoteIP net.IP, policyType string) error { fmt.Printf("Default: %s\n", ap.Default) for _, p := range ap.Policies { - fmt.Printf(" PolicyName %s:\n", p.Name) - showPolicyStatement(2, p) + fmt.Printf(" PolicyName %s:\n", p) } return nil } @@ -677,14 +676,13 @@ func modNeighborPolicy(remoteIP net.IP, policyType, cmdType string, eArg []strin switch cmdType { case CMD_ADD: if len(eArg) < 3 { - return fmt.Errorf("Usage: gobgp neighbor <ipaddr> policy %s %s <policies> {%s|%s}", policyType, cmdType, "accept", "reject") + return fmt.Errorf("Usage: gobgp neighbor <ipaddr> policy %s %s [<policy name>...] [default {%s|%s}]", policyType, cmdType, "accept", "reject") } - policies := parsePolicy(eArg[0]) defaultPolicy, err := parseRouteAction(eArg[1]) if err != nil { return err } - p.Policies = policies + p.Policies = []string{eArg[0]} p.Default = defaultPolicy operation = api.Operation_ADD case CMD_DEL: diff --git a/gobgp/cmd/policy.go b/gobgp/cmd/policy.go index ab2e08b3..6443ba28 100644 --- a/gobgp/cmd/policy.go +++ b/gobgp/cmd/policy.go @@ -32,7 +32,7 @@ import ( "strings" ) -func formatPolicyPrefix(head bool, indent int, psl []*api.PrefixSet) string { +func formatPolicyPrefix(head bool, indent int, psl []*api.DefinedSet) string { buff := bytes.NewBuffer(make([]byte, 0, 64)) sIndent := strings.Repeat(" ", indent) maxNameLen := 0 @@ -41,7 +41,7 @@ func formatPolicyPrefix(head bool, indent int, psl []*api.PrefixSet) string { if len(ps.Name) > maxNameLen { maxNameLen = len(ps.Name) } - for _, p := range ps.List { + for _, p := range ps.Prefixes { if len(p.IpPrefix) > maxPrefixLen { maxPrefixLen = len(p.IpPrefix) } @@ -63,7 +63,7 @@ func formatPolicyPrefix(head bool, indent int, psl []*api.PrefixSet) string { buff.WriteString("MaskLengthRange\n") } for _, ps := range psl { - for i, p := range ps.List { + for i, p := range ps.Prefixes { if i == 0 { buff.WriteString(fmt.Sprintf(format, ps.Name, p.IpPrefix)) buff.WriteString(fmt.Sprintf("%d..%d\n", p.MaskLengthMin, p.MaskLengthMax)) @@ -77,15 +77,198 @@ func formatPolicyPrefix(head bool, indent int, psl []*api.PrefixSet) string { return buff.String() } -func showPolicyPrefixes() error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_PREFIX, +func formatPolicyNeighbor(head bool, indent int, nsl []*api.DefinedSet) string { + buff := bytes.NewBuffer(make([]byte, 0, 64)) + sIndent := strings.Repeat(" ", indent) + maxNameLen := 0 + maxAddressLen := 0 + for _, ns := range nsl { + if len(ns.Name) > maxNameLen { + maxNameLen = len(ns.Name) + } + for _, n := range ns.List { + if len(n) > maxAddressLen { + maxAddressLen = len(n) + } + } } - stream, e := client.GetPolicyRoutePolicies(context.Background(), arg) + + if head { + if len("Name") > maxNameLen { + maxNameLen = len("Name") + } + if len("Address") > maxAddressLen { + maxAddressLen = len("Address") + } + } + + format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxAddressLen) + "s\n" + if head { + buff.WriteString(fmt.Sprintf(format, "Name", "Address")) + } + for _, ns := range nsl { + for i, n := range ns.List { + if i == 0 { + buff.WriteString(fmt.Sprintf(format, ns.Name, n)) + } else { + buff.WriteString(fmt.Sprintf(sIndent)) + buff.WriteString(fmt.Sprintf(format, "", n)) + } + } + } + return buff.String() +} + +func formatPolicyAsPath(haed bool, indent int, apsl []*api.DefinedSet) string { + buff := bytes.NewBuffer(make([]byte, 0, 64)) + sIndent := strings.Repeat(" ", indent) + maxNameLen := 0 + maxPathLen := 0 + for _, aps := range apsl { + if len(aps.Name) > maxNameLen { + maxNameLen = len(aps.Name) + } + for _, m := range aps.List { + if len(m) > maxPathLen { + maxPathLen = len(m) + } + } + } + + if haed { + if len("Name") > maxNameLen { + maxNameLen = len("Name") + } + if len("AsPath") > maxPathLen { + maxPathLen = len("AsPath") + } + } + + format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxPathLen) + "s\n" + if haed { + buff.WriteString(fmt.Sprintf(format, "Name", "AsPath")) + } + for _, aps := range apsl { + for i, a := range aps.List { + if i == 0 { + buff.WriteString(fmt.Sprintf(format, aps.Name, a)) + } else { + buff.WriteString(fmt.Sprintf(sIndent)) + buff.WriteString(fmt.Sprintf(format, "", a)) + } + } + } + return buff.String() +} + +func formatPolicyCommunity(head bool, indent int, csl []*api.DefinedSet) string { + buff := bytes.NewBuffer(make([]byte, 0, 64)) + sIndent := strings.Repeat(" ", indent) + maxNameLen := 0 + maxCommunityLen := 0 + for _, cs := range csl { + if len(cs.Name) > maxNameLen { + maxNameLen = len(cs.Name) + } + for _, m := range cs.List { + if len(m) > maxCommunityLen { + maxCommunityLen = len(m) + } + } + } + + if head { + if len("Name") > maxNameLen { + maxNameLen = len("Name") + } + if len("Community") > maxCommunityLen { + maxCommunityLen = len("Community") + } + } + + format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxCommunityLen) + "s\n" + if head { + buff.WriteString(fmt.Sprintf(format, "Name", "Community")) + } + for _, cs := range csl { + for i, c := range cs.List { + if i == 0 { + buff.WriteString(fmt.Sprintf(format, cs.Name, c)) + } else { + buff.WriteString(fmt.Sprintf(sIndent)) + buff.WriteString(fmt.Sprintf(format, "", c)) + } + } + } + return buff.String() +} + +func formatPolicyExtCommunity(head bool, indent int, ecsl []*api.DefinedSet) string { + buff := bytes.NewBuffer(make([]byte, 0, 64)) + sIndent := strings.Repeat(" ", indent) + maxNameLen := 0 + maxCommunityLen := 0 + for _, es := range ecsl { + if len(es.Name) > maxNameLen { + maxNameLen = len(es.Name) + } + for _, m := range es.List { + if len(m) > maxCommunityLen { + maxCommunityLen = len(m) + } + } + } + + if head { + if len("Name") > maxNameLen { + maxNameLen = len("Name") + } + if len("ExtCommunity") > maxCommunityLen { + maxCommunityLen = len("ExtCommunity") + } + } + + format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxCommunityLen) + "s\n" + if head { + buff.WriteString(fmt.Sprintf(format, "Name", "ExtCommunity")) + } + for _, ecs := range ecsl { + for i, ec := range ecs.List { + if i == 0 { + buff.WriteString(fmt.Sprintf(format, ecs.Name, ec)) + } else { + buff.WriteString(fmt.Sprintf(sIndent)) + buff.WriteString(fmt.Sprintf(format, "", ec)) + } + } + } + return buff.String() +} + +func showAll(v string) error { + var typ table.DefinedType + switch v { + case CMD_PREFIX: + typ = table.DEFINED_TYPE_PREFIX + case CMD_NEIGHBOR: + typ = table.DEFINED_TYPE_NEIGHBOR + case CMD_ASPATH: + typ = table.DEFINED_TYPE_AS_PATH + case CMD_COMMUNITY: + typ = table.DEFINED_TYPE_COMMUNITY + case CMD_EXTCOMMUNITY: + typ = table.DEFINED_TYPE_EXT_COMMUNITY + default: + return fmt.Errorf("unknown defined type: %s", v) + } + arg := &api.DefinedSet{ + Type: int32(typ), + } + stream, e := client.GetDefinedSets(context.Background(), arg) if e != nil { return e } - m := prefixes{} + m := sets{} for { p, e := stream.Recv() if e == io.EOF { @@ -93,15 +276,13 @@ func showPolicyPrefixes() error { } else if e != nil { return e } - m = append(m, p.Statements[0].Conditions.PrefixSet) + m = append(m, p) } - if globalOpts.Json { j, _ := json.Marshal(m) fmt.Println(string(j)) return nil } - if globalOpts.Quiet { for _, p := range m { fmt.Println(p.Name) @@ -110,22 +291,47 @@ func showPolicyPrefixes() error { } sort.Sort(m) - output := formatPolicyPrefix(true, 0, m) + var output string + switch v { + case CMD_PREFIX: + output = formatPolicyPrefix(true, 0, m) + case CMD_NEIGHBOR: + output = formatPolicyNeighbor(true, 0, m) + case CMD_ASPATH: + output = formatPolicyAsPath(true, 0, m) + case CMD_COMMUNITY: + output = formatPolicyCommunity(true, 0, m) + case CMD_EXTCOMMUNITY: + output = formatPolicyExtCommunity(true, 0, m) + } fmt.Print(output) - return nil } -func showPolicyPrefix(args []string) error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_PREFIX, - Name: args[0], +func showOne(v string, args []string) error { + var typ table.DefinedType + switch v { + case CMD_PREFIX: + typ = table.DEFINED_TYPE_PREFIX + case CMD_NEIGHBOR: + typ = table.DEFINED_TYPE_NEIGHBOR + case CMD_ASPATH: + typ = table.DEFINED_TYPE_AS_PATH + case CMD_COMMUNITY: + typ = table.DEFINED_TYPE_COMMUNITY + case CMD_EXTCOMMUNITY: + typ = table.DEFINED_TYPE_EXT_COMMUNITY + default: + return fmt.Errorf("unknown defined type: %s", v) } - pd, e := client.GetPolicyRoutePolicy(context.Background(), arg) + arg := &api.DefinedSet{ + Type: int32(typ), + Name: args[0], + } + ps, e := client.GetDefinedSet(context.Background(), arg) if e != nil { return e } - ps := pd.Statements[0].Conditions.PrefixSet if globalOpts.Json { j, _ := json.Marshal(ps) fmt.Println(string(j)) @@ -133,16 +339,32 @@ func showPolicyPrefix(args []string) error { } if globalOpts.Quiet { for _, p := range ps.List { + fmt.Println(p) + } + for _, p := range ps.Prefixes { fmt.Printf("%s %d..%d\n", p.IpPrefix, p.MaskLengthMin, p.MaskLengthMax) } return nil } - output := formatPolicyPrefix(true, 0, []*api.PrefixSet{ps}) + var output string + m := []*api.DefinedSet{ps} + switch v { + case CMD_PREFIX: + output = formatPolicyPrefix(true, 0, m) + case CMD_NEIGHBOR: + output = formatPolicyNeighbor(true, 0, m) + case CMD_ASPATH: + output = formatPolicyAsPath(true, 0, m) + case CMD_COMMUNITY: + output = formatPolicyCommunity(true, 0, m) + case CMD_EXTCOMMUNITY: + output = formatPolicyExtCommunity(true, 0, m) + } fmt.Print(output) return nil } -func parsePrefixSet(eArgs []string) (*api.PrefixSet, error) { +func parsePrefixSet(eArgs []string) (*api.DefinedSet, error) { _, ipNet, e := net.ParseCIDR(eArgs[1]) if e != nil { return nil, fmt.Errorf("invalid prefix: %s\nplease enter ipv4 or ipv6 format", eArgs[1]) @@ -185,11 +407,11 @@ func parsePrefixSet(eArgs []string) (*api.PrefixSet, error) { prefix.MaskLengthMax = uint32(max) } prefixList := []*api.Prefix{prefix} - prefixSet := &api.PrefixSet{ - Name: eArgs[0], - List: prefixList, - } - return prefixSet, nil + return &api.DefinedSet{ + Type: int32(table.DEFINED_TYPE_PREFIX), + Name: eArgs[0], + Prefixes: prefixList, + }, nil } func modPolicy(resource api.Resource, op api.Operation, data interface{}) error { pd := &api.PolicyDefinition{} @@ -237,7 +459,7 @@ func modPolicy(resource api.Resource, op api.Operation, data interface{}) error } func modPolicyPrefix(modtype string, eArgs []string) error { - prefixSet := &api.PrefixSet{} + prefixSet := &api.DefinedSet{} var e error var operation api.Operation @@ -254,7 +476,7 @@ func modPolicyPrefix(modtype string, eArgs []string) error { if len(eArgs) == 0 { return fmt.Errorf("usage: policy prefix del <prefix set name> [<prefix> [<mask length renge>]]") } else if len(eArgs) == 1 { - prefixSet = &api.PrefixSet{ + prefixSet = &api.DefinedSet{ Name: eArgs[0], } } else { @@ -277,96 +499,15 @@ func modPolicyPrefix(modtype string, eArgs []string) error { return nil } -func formatPolicyNeighbor(head bool, indent int, nsl []*api.MatchSet) string { - buff := bytes.NewBuffer(make([]byte, 0, 64)) - sIndent := strings.Repeat(" ", indent) - maxNameLen := 0 - maxAddressLen := 0 - for _, ns := range nsl { - if len(ns.Name) > maxNameLen { - maxNameLen = len(ns.Name) - } - for _, n := range ns.List { - if len(n) > maxAddressLen { - maxAddressLen = len(n) - } - } - } - - if head { - if len("Name") > maxNameLen { - maxNameLen = len("Name") - } - if len("Address") > maxAddressLen { - maxAddressLen = len("Address") - } - } - - format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxAddressLen) + "s\n" - if head { - buff.WriteString(fmt.Sprintf(format, "Name", "Address")) - } - for _, ns := range nsl { - for i, n := range ns.List { - if i == 0 { - buff.WriteString(fmt.Sprintf(format, ns.Name, n)) - } else { - buff.WriteString(fmt.Sprintf(sIndent)) - buff.WriteString(fmt.Sprintf(format, "", n)) - } - } - } - return buff.String() -} - -func showPolicyNeighbors() error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_NEIGHBOR, - } - stream, e := client.GetPolicyRoutePolicies(context.Background(), arg) - if e != nil { - return e - } - m := sets{} - for { - p, e := stream.Recv() - if e == io.EOF { - break - } else if e != nil { - return e - } - m = append(m, p.Statements[0].Conditions.NeighborSet) - } - - if globalOpts.Json { - j, _ := json.Marshal(m) - fmt.Println(string(j)) - return nil - } - - if globalOpts.Quiet { - for _, n := range m { - fmt.Println(n.Name) - } - return nil - } - sort.Sort(m) - - output := formatPolicyNeighbor(true, 0, m) - fmt.Print(output) - return nil -} - func showPolicyNeighbor(args []string) error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_NEIGHBOR, - Name: args[0], + arg := &api.DefinedSet{ + Type: int32(table.DEFINED_TYPE_NEIGHBOR), + Name: args[0], } - pd, e := client.GetPolicyRoutePolicy(context.Background(), arg) + ns, e := client.GetDefinedSet(context.Background(), arg) if e != nil { return e } - ns := pd.Statements[0].Conditions.NeighborSet if globalOpts.Json { j, _ := json.Marshal(ns) fmt.Println(string(j)) @@ -378,12 +519,12 @@ func showPolicyNeighbor(args []string) error { } return nil } - output := formatPolicyNeighbor(true, 0, []*api.MatchSet{ns}) + output := formatPolicyNeighbor(true, 0, []*api.DefinedSet{ns}) fmt.Print(output) return nil } -func parseNeighborSet(eArgs []string) (*api.MatchSet, error) { +func parseNeighborSet(eArgs []string) (*api.DefinedSet, error) { address := net.ParseIP(eArgs[1]) if address.To4() == nil { if address.To16() == nil { @@ -391,15 +532,15 @@ func parseNeighborSet(eArgs []string) (*api.MatchSet, error) { } } - neighborSet := &api.MatchSet{ + return &api.DefinedSet{ + Type: int32(table.DEFINED_TYPE_NEIGHBOR), Name: eArgs[0], List: []string{address.String()}, - } - return neighborSet, nil + }, nil } func modPolicyNeighbor(modtype string, eArgs []string) error { - neighborSet := &api.MatchSet{} + neighborSet := &api.DefinedSet{} var e error var operation api.Operation @@ -416,7 +557,7 @@ func modPolicyNeighbor(modtype string, eArgs []string) error { if len(eArgs) == 0 { return fmt.Errorf("usage: policy neighbor del <neighbor set name> [<address>]") } else if len(eArgs) == 1 { - neighborSet = &api.MatchSet{ + neighborSet = &api.DefinedSet{ Name: eArgs[0], } } else { @@ -439,111 +580,7 @@ func modPolicyNeighbor(modtype string, eArgs []string) error { return nil } -func formatPolicyAsPath(haed bool, indent int, apsl []*api.MatchSet) string { - buff := bytes.NewBuffer(make([]byte, 0, 64)) - sIndent := strings.Repeat(" ", indent) - maxNameLen := 0 - maxPathLen := 0 - for _, aps := range apsl { - if len(aps.Name) > maxNameLen { - maxNameLen = len(aps.Name) - } - for _, m := range aps.List { - if len(m) > maxPathLen { - maxPathLen = len(m) - } - } - } - - if haed { - if len("Name") > maxNameLen { - maxNameLen = len("Name") - } - if len("AsPath") > maxPathLen { - maxPathLen = len("AsPath") - } - } - - format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxPathLen) + "s\n" - if haed { - buff.WriteString(fmt.Sprintf(format, "Name", "AsPath")) - } - for _, aps := range apsl { - for i, a := range aps.List { - if i == 0 { - buff.WriteString(fmt.Sprintf(format, aps.Name, a)) - } else { - buff.WriteString(fmt.Sprintf(sIndent)) - buff.WriteString(fmt.Sprintf(format, "", a)) - } - } - } - return buff.String() -} - -func showPolicyAsPaths() error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_ASPATH, - } - stream, e := client.GetPolicyRoutePolicies(context.Background(), arg) - if e != nil { - return e - } - m := sets{} - for { - a, e := stream.Recv() - if e == io.EOF { - break - } else if e != nil { - return e - } - m = append(m, a.Statements[0].Conditions.AsPathSet) - } - if globalOpts.Json { - j, _ := json.Marshal(m) - fmt.Println(string(j)) - return nil - } - if globalOpts.Quiet { - for _, a := range m { - fmt.Println(a.Name) - } - return nil - } - sort.Sort(m) - - output := formatPolicyAsPath(true, 0, m) - fmt.Print(output) - return nil -} - -func showPolicyAsPath(args []string) error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_ASPATH, - Name: args[0], - } - pd, e := client.GetPolicyRoutePolicy(context.Background(), arg) - if e != nil { - return e - } - as := pd.Statements[0].Conditions.AsPathSet - if globalOpts.Json { - j, _ := json.Marshal(as) - fmt.Println(string(j)) - return nil - } - if globalOpts.Quiet { - for _, a := range as.List { - fmt.Println(a) - } - return nil - } - output := formatPolicyAsPath(true, 0, []*api.MatchSet{as}) - fmt.Print(output) - return nil -} - -func parseAsPathSet(eArgs []string) (*api.MatchSet, error) { +func parseAsPathSet(eArgs []string) (*api.DefinedSet, error) { as := eArgs[1] isTop := as[:1] == "^" if isTop { @@ -564,15 +601,14 @@ func parseAsPathSet(eArgs []string) (*api.MatchSet, error) { "can not comple aspath values to regular expressions.", eArgs[1]) } } - asPathSet := &api.MatchSet{ + return &api.DefinedSet{ Name: eArgs[0], List: []string{eArgs[1]}, - } - return asPathSet, nil + }, nil } func modPolicyAsPath(modtype string, eArgs []string) error { - asPathSet := &api.MatchSet{} + asPathSet := &api.DefinedSet{} var e error var operation api.Operation @@ -589,7 +625,7 @@ func modPolicyAsPath(modtype string, eArgs []string) error { if len(eArgs) == 0 { return fmt.Errorf("usage: policy aspath del <aspath set name> [<aspath>]") } else if len(eArgs) == 1 { - asPathSet = &api.MatchSet{ + asPathSet = &api.DefinedSet{ Name: eArgs[0], } } else { @@ -612,110 +648,6 @@ func modPolicyAsPath(modtype string, eArgs []string) error { return nil } -func formatPolicyCommunity(head bool, indent int, csl []*api.MatchSet) string { - buff := bytes.NewBuffer(make([]byte, 0, 64)) - sIndent := strings.Repeat(" ", indent) - maxNameLen := 0 - maxCommunityLen := 0 - for _, cs := range csl { - if len(cs.Name) > maxNameLen { - maxNameLen = len(cs.Name) - } - for _, m := range cs.List { - if len(m) > maxCommunityLen { - maxCommunityLen = len(m) - } - } - } - - if head { - if len("Name") > maxNameLen { - maxNameLen = len("Name") - } - if len("Community") > maxCommunityLen { - maxCommunityLen = len("Community") - } - } - - format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxCommunityLen) + "s\n" - if head { - buff.WriteString(fmt.Sprintf(format, "Name", "Community")) - } - for _, cs := range csl { - for i, c := range cs.List { - if i == 0 { - buff.WriteString(fmt.Sprintf(format, cs.Name, c)) - } else { - buff.WriteString(fmt.Sprintf(sIndent)) - buff.WriteString(fmt.Sprintf(format, "", c)) - } - } - } - return buff.String() -} - -func showPolicyCommunities() error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_COMMUNITY, - } - stream, e := client.GetPolicyRoutePolicies(context.Background(), arg) - if e != nil { - return e - } - m := sets{} - for { - a, e := stream.Recv() - if e == io.EOF { - break - } else if e != nil { - return e - } - m = append(m, a.Statements[0].Conditions.CommunitySet) - } - if globalOpts.Json { - j, _ := json.Marshal(m) - fmt.Println(string(j)) - return nil - } - if globalOpts.Quiet { - for _, c := range m { - fmt.Println(c.Name) - } - return nil - } - sort.Sort(m) - - output := formatPolicyCommunity(true, 0, m) - fmt.Print(output) - return nil -} - -func showPolicyCommunity(args []string) error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_COMMUNITY, - Name: args[0], - } - pd, e := client.GetPolicyRoutePolicy(context.Background(), arg) - if e != nil { - return e - } - cs := pd.Statements[0].Conditions.GetCommunitySet() - if globalOpts.Json { - j, _ := json.Marshal(cs) - fmt.Println(string(j)) - return nil - } - if globalOpts.Quiet { - for _, c := range cs.List { - fmt.Println(c) - } - return nil - } - output := formatPolicyCommunity(true, 0, []*api.MatchSet{cs}) - fmt.Print(output) - return nil -} - func checkCommunityFormat(comStr string) bool { _, e := table.ParseCommunity(comStr) if e == nil { @@ -724,13 +656,13 @@ func checkCommunityFormat(comStr string) bool { return false } -func parseCommunitySet(eArgs []string) (*api.MatchSet, error) { +func parseCommunitySet(eArgs []string) (*api.DefinedSet, error) { if !checkCommunityFormat(eArgs[1]) { if _, err := regexp.Compile(eArgs[1]); err != nil { return nil, fmt.Errorf("invalid community: %s\nplease enter community format", eArgs[1]) } } - communitySet := &api.MatchSet{ + communitySet := &api.DefinedSet{ Name: eArgs[0], List: []string{eArgs[1]}, } @@ -738,7 +670,7 @@ func parseCommunitySet(eArgs []string) (*api.MatchSet, error) { } func modPolicyCommunity(modtype string, eArgs []string) error { - communitySet := &api.MatchSet{} + communitySet := &api.DefinedSet{} var e error var operation api.Operation @@ -755,7 +687,7 @@ func modPolicyCommunity(modtype string, eArgs []string) error { if len(eArgs) == 0 { return fmt.Errorf("usage: policy community add <community set name> [<community>]") } else if len(eArgs) == 1 { - communitySet = &api.MatchSet{ + communitySet = &api.DefinedSet{ Name: eArgs[0], } } else { @@ -778,110 +710,6 @@ func modPolicyCommunity(modtype string, eArgs []string) error { return nil } -func formatPolicyExtCommunity(head bool, indent int, ecsl []*api.MatchSet) string { - buff := bytes.NewBuffer(make([]byte, 0, 64)) - sIndent := strings.Repeat(" ", indent) - maxNameLen := 0 - maxCommunityLen := 0 - for _, es := range ecsl { - if len(es.Name) > maxNameLen { - maxNameLen = len(es.Name) - } - for _, m := range es.List { - if len(m) > maxCommunityLen { - maxCommunityLen = len(m) - } - } - } - - if head { - if len("Name") > maxNameLen { - maxNameLen = len("Name") - } - if len("ExtCommunity") > maxCommunityLen { - maxCommunityLen = len("ExtCommunity") - } - } - - format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxCommunityLen) + "s\n" - if head { - buff.WriteString(fmt.Sprintf(format, "Name", "ExtCommunity")) - } - for _, ecs := range ecsl { - for i, ec := range ecs.List { - if i == 0 { - buff.WriteString(fmt.Sprintf(format, ecs.Name, ec)) - } else { - buff.WriteString(fmt.Sprintf(sIndent)) - buff.WriteString(fmt.Sprintf(format, "", ec)) - } - } - } - return buff.String() -} - -func showPolicyExtCommunities() error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_EXTCOMMUNITY, - } - stream, e := client.GetPolicyRoutePolicies(context.Background(), arg) - if e != nil { - return e - } - m := sets{} - for { - a, e := stream.Recv() - if e == io.EOF { - break - } else if e != nil { - return e - } - m = append(m, a.Statements[0].Conditions.ExtCommunitySet) - } - if globalOpts.Json { - j, _ := json.Marshal(m) - fmt.Println(string(j)) - return nil - } - if globalOpts.Quiet { - for _, e := range m { - fmt.Println(e.Name) - } - return nil - } - sort.Sort(m) - - output := formatPolicyExtCommunity(true, 0, m) - fmt.Print(output) - return nil -} - -func showPolicyExtCommunity(args []string) error { - arg := &api.PolicyArguments{ - Resource: api.Resource_POLICY_EXTCOMMUNITY, - Name: args[0], - } - pd, e := client.GetPolicyRoutePolicy(context.Background(), arg) - if e != nil { - return e - } - ecs := pd.Statements[0].Conditions.GetExtCommunitySet() - if globalOpts.Json { - j, _ := json.Marshal(ecs) - fmt.Println(string(j)) - return nil - } - if globalOpts.Quiet { - for _, ec := range ecs.List { - fmt.Println(ec) - } - return nil - } - output := formatPolicyExtCommunity(true, 0, []*api.MatchSet{ecs}) - fmt.Print(output) - return nil -} - func checkExtCommunityFormat(eComStr string) bool { // extended community regexp checkSubType := func(eComStr string) (bool, string) { @@ -927,18 +755,18 @@ func checkExtCommunityFormat(eComStr string) bool { return false } -func parseExtCommunitySet(eArgs []string) (*api.MatchSet, error) { +func parseExtCommunitySet(eArgs []string) (*api.DefinedSet, error) { if !checkExtCommunityFormat(eArgs[1]) { return nil, fmt.Errorf("invalid extended community: %s\nplease enter extended community format", eArgs[1]) } - return &api.MatchSet{ + return &api.DefinedSet{ Name: eArgs[0], List: []string{eArgs[1]}, }, nil } func modPolicyExtCommunity(modtype string, eArgs []string) error { - extCommunitySet := &api.MatchSet{} + extCommunitySet := &api.DefinedSet{} var e error var operation api.Operation @@ -955,7 +783,7 @@ func modPolicyExtCommunity(modtype string, eArgs []string) error { if len(eArgs) == 0 { return fmt.Errorf("usage: policy extcommunity add <community set name> [<community>]") } else if len(eArgs) == 1 { - extCommunitySet = &api.MatchSet{ + extCommunitySet = &api.DefinedSet{ Name: eArgs[0], } } else { @@ -982,64 +810,38 @@ func showPolicyStatement(indent int, pd *api.PolicyDefinition) { sIndent := func(indent int) string { return strings.Repeat(" ", indent) } - baseIndent := 28 for _, st := range pd.Statements { fmt.Printf("%sStatementName %s:\n", sIndent(indent), st.Name) fmt.Printf("%sConditions:\n", sIndent(indent+2)) ps := st.Conditions.PrefixSet if ps != nil { - fmt.Printf("%sPrefixSet: %-6s ", sIndent(indent+4), table.MatchOption(ps.Option)) - if out := formatPolicyPrefix(false, baseIndent+indent, []*api.PrefixSet{ps}); out != "" { - fmt.Print(out) - } else { - fmt.Printf("\n") - } + fmt.Printf("%sPrefixSet: %s %s\n", sIndent(indent+4), table.MatchOption(ps.Option), ps.Name) } ns := st.Conditions.NeighborSet if ns != nil { - fmt.Printf("%sNeighborSet: %-6s ", sIndent(indent+4), table.MatchOption(ns.Option)) - if out := formatPolicyNeighbor(false, baseIndent+indent, []*api.MatchSet{ns}); out != "" { - fmt.Print(out) - } else { - fmt.Printf("\n") - } + fmt.Printf("%sNeighborSet: %s %s\n", sIndent(indent+4), table.MatchOption(ns.Option), ns.Name) } aps := st.Conditions.AsPathSet if aps != nil { - fmt.Printf("%sAsPathSet: %-6s ", sIndent(indent+4), aps.Option) - if out := formatPolicyAsPath(false, baseIndent+indent, []*api.MatchSet{aps}); out != "" { - fmt.Print(out) - } else { - fmt.Printf("\n") - } + fmt.Printf("%sAsPathSet: %s %s\n", sIndent(indent+4), table.MatchOption(aps.Option), aps.Name) } cs := st.Conditions.CommunitySet if cs != nil { - fmt.Printf("%sCommunitySet: %-6s ", sIndent(indent+4), cs.Option) - if out := formatPolicyCommunity(false, baseIndent+indent, []*api.MatchSet{cs}); out != "" { - fmt.Print(out) - } else { - fmt.Printf("\n") - } + fmt.Printf("%sCommunitySet: %s %s\n", sIndent(indent+4), table.MatchOption(cs.Option), cs.Name) } ecs := st.Conditions.ExtCommunitySet if ecs != nil { - fmt.Printf("%sExtCommunitySet: %-6s ", sIndent(indent+4), ecs.Option) - if out := formatPolicyExtCommunity(false, baseIndent+indent, []*api.MatchSet{ecs}); out != "" { - fmt.Print(out) - } else { - fmt.Printf("\n") - } + fmt.Printf("%sExtCommunitySet: %s %s\n", sIndent(indent+4), table.MatchOption(ecs.Option), ecs.Name) } asPathLentgh := st.Conditions.AsPathLength if asPathLentgh != nil { - fmt.Printf("%sAsPathLength: %-6s %s\n", sIndent(indent+4), asPathLentgh.Type, asPathLentgh.Length) + fmt.Printf("%sAsPathLength: %s %s\n", sIndent(indent+4), asPathLentgh.Type, asPathLentgh.Length) } fmt.Printf("%sActions:\n", sIndent(indent+2)) @@ -1485,36 +1287,33 @@ func NewPolicyDelCmd(mod func(string, []string) error) *cobra.Command { func NewPolicyCmd() *cobra.Command { policyCmd := &cobra.Command{ Use: CMD_POLICY, + Run: func(cmd *cobra.Command, args []string) { + var err error + if len(args) == 0 { + err = showPolicyRoutePolicies() + } else { + err = showPolicyRoutePolicy(args) + } + if err != nil { + fmt.Println(err) + } + }, } for _, v := range []string{CMD_PREFIX, CMD_NEIGHBOR, CMD_ASPATH, CMD_COMMUNITY, CMD_EXTCOMMUNITY, CMD_ROUTEPOLICY} { - var showAll func() error - var showOne func([]string) error var mod func(string, []string) error switch v { case CMD_PREFIX: - showAll = showPolicyPrefixes - showOne = showPolicyPrefix mod = modPolicyPrefix case CMD_NEIGHBOR: - showAll = showPolicyNeighbors - showOne = showPolicyNeighbor mod = modPolicyNeighbor case CMD_ASPATH: - showAll = showPolicyAsPaths - showOne = showPolicyAsPath mod = modPolicyAsPath case CMD_COMMUNITY: - showAll = showPolicyCommunities - showOne = showPolicyCommunity mod = modPolicyCommunity case CMD_EXTCOMMUNITY: - showAll = showPolicyExtCommunities - showOne = showPolicyExtCommunity mod = modPolicyExtCommunity case CMD_ROUTEPOLICY: - showAll = showPolicyRoutePolicies - showOne = showPolicyRoutePolicy mod = modPolicyRoutePolicy } cmd := &cobra.Command{ @@ -1522,9 +1321,9 @@ func NewPolicyCmd() *cobra.Command { Run: func(cmd *cobra.Command, args []string) { var err error if len(args) == 0 { - err = showAll() + err = showAll(cmd.Use) } else { - err = showOne(args) + err = showOne(cmd.Use, args) } if err != nil { @@ -1532,14 +1331,11 @@ func NewPolicyCmd() *cobra.Command { } }, } - policyAddCmd := NewPolicyAddCmd(v, mod) cmd.AddCommand(policyAddCmd) policyDelCmd := NewPolicyDelCmd(mod) cmd.AddCommand(policyDelCmd) - policyCmd.AddCommand(cmd) } - return policyCmd } diff --git a/server/grpc_server.go b/server/grpc_server.go index 16b501ec..c3f004df 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -43,18 +43,12 @@ const ( REQ_NEIGHBOR_POLICY REQ_MOD_NEIGHBOR_POLICY REQ_GLOBAL_RIB - REQ_POLICY_PREFIX - REQ_POLICY_PREFIXES REQ_POLICY_PREFIX_ADD REQ_POLICY_PREFIX_DELETE REQ_POLICY_PREFIXES_DELETE - REQ_POLICY_NEIGHBOR - REQ_POLICY_NEIGHBORS REQ_POLICY_NEIGHBOR_ADD REQ_POLICY_NEIGHBOR_DELETE REQ_POLICY_NEIGHBORS_DELETE - REQ_POLICY_ASPATH - REQ_POLICY_ASPATHS REQ_POLICY_ASPATH_ADD REQ_POLICY_ASPATH_DELETE REQ_POLICY_ASPATHS_DELETE @@ -63,13 +57,9 @@ const ( REQ_POLICY_ROUTEPOLICY_ADD REQ_POLICY_ROUTEPOLICY_DELETE REQ_POLICY_ROUTEPOLICIES_DELETE - REQ_POLICY_COMMUNITY - REQ_POLICY_COMMUNITIES REQ_POLICY_COMMUNITY_ADD REQ_POLICY_COMMUNITY_DELETE REQ_POLICY_COMMUNITIES_DELETE - REQ_POLICY_EXTCOMMUNITY - REQ_POLICY_EXTCOMMUNITIES REQ_POLICY_EXTCOMMUNITY_ADD REQ_POLICY_EXTCOMMUNITY_DELETE REQ_POLICY_EXTCOMMUNITIES_DELETE @@ -84,6 +74,7 @@ const ( REQ_VRF_MOD REQ_MOD_PATH REQ_GLOBAL_POLICY + REQ_DEFINED_SET ) const GRPC_PORT = 8080 @@ -406,16 +397,6 @@ func (s *Server) GetPolicyRoutePolicies(arg *api.PolicyArguments, stream api.Gob var rf bgp.RouteFamily var reqType int switch arg.Resource { - case api.Resource_POLICY_PREFIX: - reqType = REQ_POLICY_PREFIXES - case api.Resource_POLICY_NEIGHBOR: - reqType = REQ_POLICY_NEIGHBORS - case api.Resource_POLICY_ASPATH: - reqType = REQ_POLICY_ASPATHS - case api.Resource_POLICY_COMMUNITY: - reqType = REQ_POLICY_COMMUNITIES - case api.Resource_POLICY_EXTCOMMUNITY: - reqType = REQ_POLICY_EXTCOMMUNITIES case api.Resource_POLICY_ROUTEPOLICY: reqType = REQ_POLICY_ROUTEPOLICIES default: @@ -432,16 +413,6 @@ func (s *Server) GetPolicyRoutePolicy(ctx context.Context, arg *api.PolicyArgume var rf bgp.RouteFamily var reqType int switch arg.Resource { - case api.Resource_POLICY_PREFIX: - reqType = REQ_POLICY_PREFIX - case api.Resource_POLICY_NEIGHBOR: - reqType = REQ_POLICY_NEIGHBOR - case api.Resource_POLICY_ASPATH: - reqType = REQ_POLICY_ASPATH - case api.Resource_POLICY_COMMUNITY: - reqType = REQ_POLICY_COMMUNITY - case api.Resource_POLICY_EXTCOMMUNITY: - reqType = REQ_POLICY_EXTCOMMUNITY case api.Resource_POLICY_ROUTEPOLICY: reqType = REQ_POLICY_ROUTEPOLICY default: @@ -529,6 +500,25 @@ func (s *Server) ModVrf(ctx context.Context, arg *api.ModVrfArguments) (*api.Err return none, nil } +func (s *Server) GetDefinedSet(ctx context.Context, arg *api.DefinedSet) (*api.DefinedSet, error) { + req := NewGrpcRequest(REQ_DEFINED_SET, "", bgp.RouteFamily(0), arg) + s.bgpServerCh <- req + res := <-req.ResponseCh + if err := res.Err(); err != nil { + return nil, err + } + return res.Data.(*api.DefinedSet), nil +} + +func (s *Server) GetDefinedSets(arg *api.DefinedSet, stream api.GobgpApi_GetDefinedSetsServer) error { + req := NewGrpcRequest(REQ_DEFINED_SET, "", bgp.RouteFamily(0), arg) + s.bgpServerCh <- req + + return handleMultipleResponses(req, func(res *GrpcResponse) error { + return stream.Send(res.Data.(*api.DefinedSet)) + }) +} + type GrpcRequest struct { RequestType int Name string diff --git a/server/server.go b/server/server.go index 9f9b70d8..f60d4d6e 100644 --- a/server/server.go +++ b/server/server.go @@ -1580,28 +1580,14 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { def = api.RouteAction_ACCEPT } } - policies := make([]*api.PolicyDefinition, 0, len(names)) - for _, name := range names { - p, ok := server.policy.PolicyMap[name] - if !ok { - log.WithFields(log.Fields{ - "Topic": "Peer", - "Name": name, - }).Error("can't find policy which is applied") - continue - } - policies = append(policies, p.ToApiStruct()) - } - result := &GrpcResponse{ Data: &api.ApplyPolicy{ - Policies: policies, + Policies: names, Default: def, }, } grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) - case REQ_MOD_NEIGHBOR_POLICY: peer, err := server.checkNeighborRequest(grpcReq) if err != nil { @@ -1619,37 +1605,62 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { switch arg.ApplyPolicy.Type { case api.PolicyType_IMPORT: applyPolicy.DefaultImportPolicy = def - applyPolicy.ImportPolicy = table.PoliciesToString(arg.ApplyPolicy.Policies) + applyPolicy.ImportPolicy = arg.ApplyPolicy.Policies case api.PolicyType_EXPORT: applyPolicy.DefaultExportPolicy = def - applyPolicy.ExportPolicy = table.PoliciesToString(arg.ApplyPolicy.Policies) + applyPolicy.ExportPolicy = arg.ApplyPolicy.Policies case api.PolicyType_IN: applyPolicy.DefaultInPolicy = def - applyPolicy.InPolicy = table.PoliciesToString(arg.ApplyPolicy.Policies) + applyPolicy.InPolicy = arg.ApplyPolicy.Policies } case api.Operation_DEL: switch arg.ApplyPolicy.Type { case api.PolicyType_IMPORT: applyPolicy.DefaultImportPolicy = def - applyPolicy.ImportPolicy = []string{} + applyPolicy.ImportPolicy = nil case api.PolicyType_EXPORT: applyPolicy.DefaultExportPolicy = def - applyPolicy.ExportPolicy = []string{} + applyPolicy.ExportPolicy = nil case api.PolicyType_IN: applyPolicy.DefaultInPolicy = def - applyPolicy.InPolicy = []string{} + applyPolicy.InPolicy = nil } } peer.setPolicy(server.policy.PolicyMap) grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) - - case REQ_POLICY_PREFIXES, REQ_POLICY_NEIGHBORS, REQ_POLICY_ASPATHS, - REQ_POLICY_COMMUNITIES, REQ_POLICY_EXTCOMMUNITIES, REQ_POLICY_ROUTEPOLICIES, - REQ_POLICY_PREFIX, REQ_POLICY_NEIGHBOR, REQ_POLICY_ASPATH, - REQ_POLICY_COMMUNITY, REQ_POLICY_EXTCOMMUNITY, REQ_POLICY_ROUTEPOLICY: - server.handleGrpcShowPolicy(grpcReq) + case REQ_DEFINED_SET: + if err := server.handleGrpcGetDefinedSet(grpcReq); err != nil { + grpcReq.ResponseCh <- &GrpcResponse{ + ResponseErr: err, + } + } + close(grpcReq.ResponseCh) + case REQ_POLICY_ROUTEPOLICY, REQ_POLICY_ROUTEPOLICIES: + info := server.policy.PolicyMap + typ := grpcReq.RequestType + arg := grpcReq.Data.(*api.PolicyArguments) + result := &GrpcResponse{} + if len(info) > 0 { + for _, i := range info { + if typ == REQ_POLICY_ROUTEPOLICY && i.Name() != arg.Name { + continue + } + d := i.ToApiStruct() + result = &GrpcResponse{ + Data: d, + } + grpcReq.ResponseCh <- result + if typ == REQ_POLICY_ROUTEPOLICY { + break + } + } + } else { + result.ResponseErr = fmt.Errorf("Route Policy doesn't exist.") + grpcReq.ResponseCh <- result + } + 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: @@ -1672,144 +1683,26 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { return msgs } -func (server *BgpServer) handleGrpcShowPolicy(grpcReq *GrpcRequest) { - result := &GrpcResponse{} - typ := grpcReq.RequestType - arg := grpcReq.Data.(*api.PolicyArguments) - switch typ { - case REQ_POLICY_PREFIX, REQ_POLICY_PREFIXES: - info := server.policy.DefinedSetMap[table.DEFINED_TYPE_PREFIX] - if len(info) > 0 { - for _, ps := range info { - if typ == REQ_POLICY_PREFIX && ps.Name() != arg.Name { - continue - } - resPrefixSet := ps.(*table.PrefixSet).ToApiStruct() - pd := &api.PolicyDefinition{} - pd.Statements = []*api.Statement{{Conditions: &api.Conditions{PrefixSet: resPrefixSet}}} - result = &GrpcResponse{ - Data: pd, - } - grpcReq.ResponseCh <- result - if typ == REQ_POLICY_PREFIX { - break - } - } - } else { - result.ResponseErr = fmt.Errorf("Policy prefix doesn't exist.") - grpcReq.ResponseCh <- result - } - case REQ_POLICY_NEIGHBOR, REQ_POLICY_NEIGHBORS: - info := server.policy.DefinedSetMap[table.DEFINED_TYPE_NEIGHBOR] - if len(info) > 0 { - for _, ns := range info { - if typ == REQ_POLICY_NEIGHBOR && ns.Name() != arg.Name { - continue - } - resNeighborSet := ns.(*table.NeighborSet).ToApiStruct() - pd := &api.PolicyDefinition{} - pd.Statements = []*api.Statement{{Conditions: &api.Conditions{NeighborSet: resNeighborSet}}} - result = &GrpcResponse{ - Data: pd, - } - grpcReq.ResponseCh <- result - if typ == REQ_POLICY_NEIGHBOR { - break - } - } - } else { - result.ResponseErr = fmt.Errorf("Policy neighbor doesn't exist.") - grpcReq.ResponseCh <- result - } - case REQ_POLICY_ASPATH, REQ_POLICY_ASPATHS: - info := server.policy.DefinedSetMap[table.DEFINED_TYPE_AS_PATH] - if len(info) > 0 { - for _, as := range info { - if typ == REQ_POLICY_ASPATH && as.Name() != arg.Name { - continue - } - resAsPathSet := as.(*table.AsPathSet).ToApiStruct() - pd := &api.PolicyDefinition{} - pd.Statements = []*api.Statement{{Conditions: &api.Conditions{AsPathSet: resAsPathSet}}} - result = &GrpcResponse{ - Data: pd, - } - grpcReq.ResponseCh <- result - if typ == REQ_POLICY_ASPATH { - break - } - } - } else { - result.ResponseErr = fmt.Errorf("Policy aspath doesn't exist.") - grpcReq.ResponseCh <- result - } - case REQ_POLICY_COMMUNITY, REQ_POLICY_COMMUNITIES: - info := server.policy.DefinedSetMap[table.DEFINED_TYPE_COMMUNITY] - if len(info) > 0 { - for _, cs := range info { - if typ == REQ_POLICY_COMMUNITY && cs.Name() != arg.Name { - continue - } - resCommunitySet := cs.(*table.CommunitySet).ToApiStruct() - pd := &api.PolicyDefinition{} - pd.Statements = []*api.Statement{{Conditions: &api.Conditions{CommunitySet: resCommunitySet}}} - result = &GrpcResponse{ - Data: pd, - } - grpcReq.ResponseCh <- result - if typ == REQ_POLICY_COMMUNITY { - break - } - } - } else { - result.ResponseErr = fmt.Errorf("Policy community doesn't exist.") - grpcReq.ResponseCh <- result +func (server *BgpServer) handleGrpcGetDefinedSet(grpcReq *GrpcRequest) error { + arg := grpcReq.Data.(*api.DefinedSet) + typ := table.DefinedType(arg.Type) + name := arg.Name + set, ok := server.policy.DefinedSetMap[typ] + if !ok { + return fmt.Errorf("invalid defined-set type: %d", typ) + } + for _, s := range set { + if name != "" && name != s.Name() { + continue } - case REQ_POLICY_EXTCOMMUNITY, REQ_POLICY_EXTCOMMUNITIES: - info := server.policy.DefinedSetMap[table.DEFINED_TYPE_EXT_COMMUNITY] - if len(info) > 0 { - for _, es := range info { - if typ == REQ_POLICY_EXTCOMMUNITY && es.Name() != arg.Name { - continue - } - resExtcommunitySet := es.(*table.ExtCommunitySet).ToApiStruct() - pd := &api.PolicyDefinition{} - pd.Statements = []*api.Statement{{Conditions: &api.Conditions{ExtCommunitySet: resExtcommunitySet}}} - result = &GrpcResponse{ - Data: pd, - } - grpcReq.ResponseCh <- result - if typ == REQ_POLICY_EXTCOMMUNITY { - break - } - } - } else { - result.ResponseErr = fmt.Errorf("Policy extended community doesn't exist.") - grpcReq.ResponseCh <- result + grpcReq.ResponseCh <- &GrpcResponse{ + Data: s.ToApiStruct(), } - case REQ_POLICY_ROUTEPOLICY, REQ_POLICY_ROUTEPOLICIES: - info := server.policy.PolicyMap - result := &GrpcResponse{} - if len(info) > 0 { - for _, pd := range info { - if typ == REQ_POLICY_ROUTEPOLICY && pd.Name() != arg.Name { - continue - } - resPolicyDefinition := pd.ToApiStruct() - result = &GrpcResponse{ - Data: resPolicyDefinition, - } - grpcReq.ResponseCh <- result - if typ == REQ_POLICY_ROUTEPOLICY { - break - } - } - } else { - result.ResponseErr = fmt.Errorf("Route Policy doesn't exist.") - grpcReq.ResponseCh <- result + if name != "" { + break } } - close(grpcReq.ResponseCh) + return nil } func (server *BgpServer) handleMrt(grpcReq *GrpcRequest) { diff --git a/table/policy.go b/table/policy.go index 51d5a0c7..843eb7d2 100644 --- a/table/policy.go +++ b/table/policy.go @@ -136,6 +136,7 @@ const ( type DefinedSet interface { Type() DefinedType Name() string + ToApiStruct() *api.DefinedSet } type DefinedSetMap map[DefinedType]map[string]DefinedSet @@ -247,23 +248,24 @@ func (s *PrefixSet) Type() DefinedType { return DEFINED_TYPE_PREFIX } -func (s *PrefixSet) ToApiStruct() *api.PrefixSet { +func (s *PrefixSet) ToApiStruct() *api.DefinedSet { list := make([]*api.Prefix, 0, len(s.list)) for _, p := range s.list { list = append(list, p.ToApiStruct()) } - return &api.PrefixSet{ - Name: s.name, - List: list, + return &api.DefinedSet{ + Type: int32(s.Type()), + Name: s.name, + Prefixes: list, } } -func NewPrefixSetFromApiStruct(a *api.PrefixSet) (*PrefixSet, error) { +func NewPrefixSetFromApiStruct(a *api.DefinedSet) (*PrefixSet, error) { if a.Name == "" { return nil, fmt.Errorf("empty prefix set name") } - list := make([]*Prefix, 0, len(a.List)) - for _, x := range a.List { + list := make([]*Prefix, 0, len(a.Prefixes)) + for _, x := range a.Prefixes { y, err := NewPrefixFromApiStruct(x) if err != nil { return nil, err @@ -311,18 +313,19 @@ func (s *NeighborSet) Type() DefinedType { return DEFINED_TYPE_NEIGHBOR } -func (s *NeighborSet) ToApiStruct() *api.MatchSet { +func (s *NeighborSet) ToApiStruct() *api.DefinedSet { list := make([]string, 0, len(s.list)) for _, n := range s.list { list = append(list, n.String()) } - return &api.MatchSet{ + return &api.DefinedSet{ + Type: int32(s.Type()), Name: s.name, List: list, } } -func NewNeighborSetFromApiStruct(a *api.MatchSet) (*NeighborSet, error) { +func NewNeighborSetFromApiStruct(a *api.DefinedSet) (*NeighborSet, error) { if a.Name == "" { return nil, fmt.Errorf("empty neighbor set name") } @@ -359,6 +362,7 @@ func NewNeighborSet(c config.NeighborSet) (*NeighborSet, error) { } type regExpSet struct { + typ DefinedType name string list []*regexp.Regexp } @@ -367,12 +371,17 @@ func (s *regExpSet) Name() string { return s.name } -func (s *regExpSet) ToApiStruct() *api.MatchSet { +func (s *regExpSet) Type() DefinedType { + return s.typ +} + +func (s *regExpSet) ToApiStruct() *api.DefinedSet { list := make([]string, 0, len(s.list)) for _, exp := range s.list { list = append(list, exp.String()) } - return &api.MatchSet{ + return &api.DefinedSet{ + Type: int32(s.typ), Name: s.name, List: list, } @@ -382,11 +391,7 @@ type AsPathSet struct { regExpSet } -func (s *AsPathSet) Type() DefinedType { - return DEFINED_TYPE_AS_PATH -} - -func NewAsPathSetFromApiStruct(a *api.MatchSet) (*AsPathSet, error) { +func NewAsPathSetFromApiStruct(a *api.DefinedSet) (*AsPathSet, error) { c := config.AsPathSet{ AsPathSetName: a.Name, AsPathList: make([]config.AsPath, 0, len(a.List)), @@ -415,6 +420,7 @@ func NewAsPathSet(c config.AsPathSet) (*AsPathSet, error) { } return &AsPathSet{ regExpSet: regExpSet{ + typ: DEFINED_TYPE_AS_PATH, name: name, list: list, }, @@ -425,10 +431,6 @@ type CommunitySet struct { regExpSet } -func (s *CommunitySet) Type() DefinedType { - return DEFINED_TYPE_COMMUNITY -} - func ParseCommunity(arg string) (uint32, error) { i, err := strconv.Atoi(arg) if err == nil { @@ -504,7 +506,7 @@ func parseExtCommunityRegexp(arg string) (bgp.ExtendedCommunityAttrSubType, *reg return subtype, exp, err } -func NewCommunitySetFromApiStruct(a *api.MatchSet) (*CommunitySet, error) { +func NewCommunitySetFromApiStruct(a *api.DefinedSet) (*CommunitySet, error) { c := config.CommunitySet{ CommunitySetName: a.Name, CommunityList: make([]config.Community, 0, len(a.List)), @@ -533,6 +535,7 @@ func NewCommunitySet(c config.CommunitySet) (*CommunitySet, error) { } return &CommunitySet{ regExpSet: regExpSet{ + typ: DEFINED_TYPE_COMMUNITY, name: name, list: list, }, @@ -544,11 +547,7 @@ type ExtCommunitySet struct { subtypeList []bgp.ExtendedCommunityAttrSubType } -func (s *ExtCommunitySet) Type() DefinedType { - return DEFINED_TYPE_EXT_COMMUNITY -} - -func NewExtCommunitySetFromApiStruct(a *api.MatchSet) (*ExtCommunitySet, error) { +func NewExtCommunitySetFromApiStruct(a *api.DefinedSet) (*ExtCommunitySet, error) { c := config.ExtCommunitySet{ ExtCommunitySetName: a.Name, ExtCommunityList: make([]config.ExtCommunity, 0, len(a.List)), @@ -579,6 +578,7 @@ func NewExtCommunitySet(c config.ExtCommunitySet) (*ExtCommunitySet, error) { } return &ExtCommunitySet{ regExpSet: regExpSet{ + typ: DEFINED_TYPE_EXT_COMMUNITY, name: name, list: list, }, @@ -635,20 +635,18 @@ func (c *PrefixCondition) Evaluate(path *Path) bool { } func (c *PrefixCondition) ToApiStruct() *api.PrefixSet { - s := c.set.ToApiStruct() - s.Option = int32(c.option) - return s + return &api.PrefixSet{ + Name: c.set.Name(), + Option: int32(c.option), + } } -func NewPrefixConditionFromApiStruct(a *api.PrefixSet) (*PrefixCondition, error) { - s, err := NewPrefixSetFromApiStruct(a) - if err != nil { - return nil, err +func NewPrefixConditionFromApiStruct(a *api.PrefixSet, m map[string]DefinedSet) (*PrefixCondition, error) { + c := config.MatchPrefixSet{ + PrefixSet: a.Name, + MatchSetOptions: config.MatchSetOptionsRestrictedType(a.Option), } - return &PrefixCondition{ - set: s, - option: MatchOption(a.Option), - }, nil + return NewPrefixCondition(c, m) } func NewPrefixCondition(c config.MatchPrefixSet, m map[string]DefinedSet) (*PrefixCondition, error) { @@ -722,20 +720,18 @@ func (c *NeighborCondition) Evaluate(path *Path) bool { } func (c *NeighborCondition) ToApiStruct() *api.MatchSet { - s := c.set.ToApiStruct() - s.Option = int32(c.option) - return s + return &api.MatchSet{ + Name: c.set.Name(), + Option: int32(c.option), + } } -func NewNeighborConditionFromApiStruct(a *api.MatchSet) (*NeighborCondition, error) { - s, err := NewNeighborSetFromApiStruct(a) - if err != nil { - return nil, err +func NewNeighborConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*NeighborCondition, error) { + c := config.MatchNeighborSet{ + NeighborSet: a.Name, + MatchSetOptions: config.MatchSetOptionsRestrictedType(a.Option), } - return &NeighborCondition{ - set: s, - option: MatchOption(a.Option), - }, nil + return NewNeighborCondition(c, m) } func NewNeighborCondition(c config.MatchNeighborSet, m map[string]DefinedSet) (*NeighborCondition, error) { @@ -774,9 +770,10 @@ func (c *AsPathCondition) Option() MatchOption { } func (c *AsPathCondition) ToApiStruct() *api.MatchSet { - s := c.set.ToApiStruct() - s.Option = int32(c.option) - return s + return &api.MatchSet{ + Name: c.set.Name(), + Option: int32(c.option), + } } func (c *AsPathCondition) Evaluate(path *Path) bool { @@ -806,15 +803,12 @@ func (c *AsPathCondition) Evaluate(path *Path) bool { return result } -func NewAsPathConditionFromApiStruct(a *api.MatchSet) (*AsPathCondition, error) { - s, err := NewAsPathSetFromApiStruct(a) - if err != nil { - return nil, err +func NewAsPathConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*AsPathCondition, error) { + c := config.MatchAsPathSet{ + AsPathSet: a.Name, + MatchSetOptions: config.MatchSetOptionsType(a.Option), } - return &AsPathCondition{ - set: s, - option: MatchOption(a.Option), - }, nil + return NewAsPathCondition(c, m) } func NewAsPathCondition(c config.MatchAsPathSet, m map[string]DefinedSet) (*AsPathCondition, error) { @@ -853,9 +847,10 @@ func (c *CommunityCondition) Option() MatchOption { } func (c *CommunityCondition) ToApiStruct() *api.MatchSet { - s := c.set.ToApiStruct() - s.Option = int32(c.option) - return s + return &api.MatchSet{ + Name: c.set.Name(), + Option: int32(c.option), + } } func (c *CommunityCondition) Evaluate(path *Path) bool { @@ -888,15 +883,12 @@ func (c *CommunityCondition) Evaluate(path *Path) bool { return result } -func NewCommunityConditionFromApiStruct(a *api.MatchSet) (*CommunityCondition, error) { - s, err := NewCommunitySetFromApiStruct(a) - if err != nil { - return nil, err +func NewCommunityConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*CommunityCondition, error) { + c := config.MatchCommunitySet{ + CommunitySet: a.Name, + MatchSetOptions: config.MatchSetOptionsType(a.Option), } - return &CommunityCondition{ - set: s, - option: MatchOption(a.Option), - }, nil + return NewCommunityCondition(c, m) } func NewCommunityCondition(c config.MatchCommunitySet, m map[string]DefinedSet) (*CommunityCondition, error) { @@ -935,9 +927,10 @@ func (c *ExtCommunityCondition) Option() MatchOption { } func (c *ExtCommunityCondition) ToApiStruct() *api.MatchSet { - s := c.set.ToApiStruct() - s.Option = int32(c.option) - return s + return &api.MatchSet{ + Name: c.set.Name(), + Option: int32(c.option), + } } func (c *ExtCommunityCondition) Evaluate(path *Path) bool { @@ -976,15 +969,12 @@ func (c *ExtCommunityCondition) Evaluate(path *Path) bool { return result } -func NewExtCommunityConditionFromApiStruct(a *api.MatchSet) (*ExtCommunityCondition, error) { - s, err := NewExtCommunitySetFromApiStruct(a) - if err != nil { - return nil, err +func NewExtCommunityConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*ExtCommunityCondition, error) { + c := config.MatchExtCommunitySet{ + ExtCommunitySet: a.Name, + MatchSetOptions: config.MatchSetOptionsType(a.Option), } - return &ExtCommunityCondition{ - set: s, - option: MatchOption(a.Option), - }, nil + return NewExtCommunityCondition(c, m) } func NewExtCommunityCondition(c config.MatchExtCommunitySet, m map[string]DefinedSet) (*ExtCommunityCondition, error) { @@ -1646,7 +1636,7 @@ func (s *Statement) ToApiStruct() *api.Statement { } } -func NewStatementFromApiStruct(a api.Statement) (*Statement, error) { +func NewStatementFromApiStruct(a api.Statement, dmap DefinedSetMap) (*Statement, error) { if a.Name == "" { return nil, fmt.Errorf("empty statement name") } @@ -1657,10 +1647,10 @@ func NewStatementFromApiStruct(a api.Statement) (*Statement, error) { if a.Conditions != nil { cfs := []func() (Condition, error){ func() (Condition, error) { - return NewPrefixConditionFromApiStruct(a.Conditions.PrefixSet) + return NewPrefixConditionFromApiStruct(a.Conditions.PrefixSet, dmap[DEFINED_TYPE_PREFIX]) }, func() (Condition, error) { - return NewNeighborConditionFromApiStruct(a.Conditions.NeighborSet) + return NewNeighborConditionFromApiStruct(a.Conditions.NeighborSet, dmap[DEFINED_TYPE_NEIGHBOR]) }, func() (Condition, error) { return NewAsPathLengthConditionFromApiStruct(a.Conditions.AsPathLength) @@ -1669,13 +1659,13 @@ func NewStatementFromApiStruct(a api.Statement) (*Statement, error) { return NewRpkiValidationConditionFromApiStruct(a.Conditions.RpkiResult) }, func() (Condition, error) { - return NewAsPathConditionFromApiStruct(a.Conditions.AsPathSet) + return NewAsPathConditionFromApiStruct(a.Conditions.AsPathSet, dmap[DEFINED_TYPE_AS_PATH]) }, func() (Condition, error) { - return NewCommunityConditionFromApiStruct(a.Conditions.CommunitySet) + return NewCommunityConditionFromApiStruct(a.Conditions.CommunitySet, dmap[DEFINED_TYPE_COMMUNITY]) }, func() (Condition, error) { - return NewExtCommunityConditionFromApiStruct(a.Conditions.ExtCommunitySet) + return NewExtCommunityConditionFromApiStruct(a.Conditions.ExtCommunitySet, dmap[DEFINED_TYPE_EXT_COMMUNITY]) }, } cs = make([]Condition, 0, len(cfs)) |