diff options
-rw-r--r-- | api/grpc_server.go | 2 | ||||
-rw-r--r-- | gobgp/cmd/bmp.go | 17 | ||||
-rw-r--r-- | gobgp/cmd/common.go | 137 | ||||
-rw-r--r-- | gobgp/cmd/global.go | 89 | ||||
-rw-r--r-- | gobgp/cmd/global_test.go | 5 | ||||
-rw-r--r-- | gobgp/cmd/monitor.go | 53 | ||||
-rw-r--r-- | gobgp/cmd/mrt.go | 113 | ||||
-rw-r--r-- | gobgp/cmd/neighbor.go | 358 | ||||
-rw-r--r-- | gobgp/cmd/policy.go | 649 | ||||
-rw-r--r-- | gobgp/cmd/root.go | 12 | ||||
-rw-r--r-- | gobgp/cmd/rpki.go | 89 | ||||
-rw-r--r-- | gobgp/cmd/vrf.go | 59 | ||||
-rw-r--r-- | gobgp/lib/path.go | 4 | ||||
-rw-r--r-- | server/rpki.go | 4 | ||||
-rw-r--r-- | test/lib/gobgp.py | 2 | ||||
-rw-r--r-- | test/scenario_test/route_server_softreset_test.py | 10 | ||||
-rw-r--r-- | test/scenario_test/route_server_test2.py | 2 |
17 files changed, 559 insertions, 1046 deletions
diff --git a/api/grpc_server.go b/api/grpc_server.go index 4d3da7ec..a21a3d85 100644 --- a/api/grpc_server.go +++ b/api/grpc_server.go @@ -505,7 +505,7 @@ func (s *Server) api2PathList(resource Resource, ApiPathList []*Path) ([]*table. } } - if nlri == nil || nexthop == "" { + if nlri == nil || (!path.IsWithdraw && nexthop == "") { return nil, fmt.Errorf("not found nlri or nexthop") } diff --git a/gobgp/cmd/bmp.go b/gobgp/cmd/bmp.go index 20364592..dfc0cd62 100644 --- a/gobgp/cmd/bmp.go +++ b/gobgp/cmd/bmp.go @@ -17,10 +17,9 @@ package cmd import ( "fmt" - api "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bmp" "github.com/spf13/cobra" - "golang.org/x/net/context" "net" "strconv" ) @@ -47,26 +46,24 @@ func modBmpServer(cmdType string, args []string) error { var err error switch cmdType { case CMD_ADD: - policyType := api.AddBmpRequest_PRE + policyType := config.BMP_ROUTE_MONITORING_POLICY_TYPE_PRE_POLICY if len(args) > 1 { switch args[1] { - case "pre": - policyType = api.AddBmpRequest_PRE case "post": - policyType = api.AddBmpRequest_POST + policyType = config.BMP_ROUTE_MONITORING_POLICY_TYPE_POST_POLICY case "both": - policyType = api.AddBmpRequest_BOTH + policyType = config.BMP_ROUTE_MONITORING_POLICY_TYPE_BOTH default: return fmt.Errorf("invalid bmp policy type. valid type is {pre|post|both}") } } - _, err = client.AddBmp(context.Background(), &api.AddBmpRequest{ + err = client.AddBMP(&config.BmpServerConfig{ Address: address, Port: port, - Type: policyType, + RouteMonitoringPolicy: policyType, }) case CMD_DEL: - _, err = client.DeleteBmp(context.Background(), &api.DeleteBmpRequest{ + err = client.DeleteBMP(&config.BmpServerConfig{ Address: address, Port: port, }) diff --git a/gobgp/cmd/common.go b/gobgp/cmd/common.go index d284701c..7d2f77aa 100644 --- a/gobgp/cmd/common.go +++ b/gobgp/cmd/common.go @@ -19,15 +19,16 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/osrg/gobgp/api" - "github.com/osrg/gobgp/packet/bgp" - "google.golang.org/grpc" "net" "os" "sort" "strconv" "strings" - "time" + + cli "github.com/osrg/gobgp/client" + "github.com/osrg/gobgp/config" + "github.com/osrg/gobgp/packet/bgp" + "github.com/osrg/gobgp/table" ) const ( @@ -162,78 +163,19 @@ func extractReserved(args, keys []string) map[string][]string { return m } -type PeerConf struct { - RemoteIp string `json:"remote_ip,omitempty"` - Id net.IP `json:"id,omitempty"` - RemoteAs uint32 `json:"remote_as,omitempty"` - LocalAs uint32 `json:"local-as,omitempty"` - RemoteCap []bgp.ParameterCapabilityInterface `json:"remote_cap,omitempty"` - LocalCap []bgp.ParameterCapabilityInterface `json:"local_cap,omitempty"` - Holdtime uint32 `json:"holdtime,omitempty"` - KeepaliveInterval uint32 `json:"keepalive_interval,omitempty"` - PrefixLimits []*gobgpapi.PrefixLimit `json:"prefix_limits,omitempty"` - LocalIp string `json:"local_ip,omitempty"` - Interface string `json:"interface,omitempty"` - Description string `json:"description,omitempty"` - VRF string `json:"vrf,omitempty"` -} - -type Peer struct { - Conf PeerConf `json:"conf,omitempty"` - Info *gobgpapi.PeerState `json:"info,omitempty"` - Timers *gobgpapi.Timers `json:"timers,omitempty"` - RouteReflector *gobgpapi.RouteReflector `json:"route_reflector,omitempty"` - RouteServer *gobgpapi.RouteServer `json:"route_server,omitempty"` -} - -func ApiStruct2Peer(p *gobgpapi.Peer) *Peer { - localCaps := capabilities{} - remoteCaps := capabilities{} - for _, buf := range p.Conf.LocalCap { - c, _ := bgp.DecodeCapability(buf) - localCaps = append(localCaps, c) - } - for _, buf := range p.Conf.RemoteCap { - c, _ := bgp.DecodeCapability(buf) - remoteCaps = append(remoteCaps, c) - } - remoteIp, _ := net.ResolveIPAddr("ip", p.Conf.NeighborAddress) - localIp, _ := net.ResolveIPAddr("ip", p.Conf.LocalAddress) - conf := PeerConf{ - RemoteIp: remoteIp.String(), - Id: net.ParseIP(p.Conf.Id), - RemoteAs: p.Conf.PeerAs, - LocalAs: p.Conf.LocalAs, - RemoteCap: remoteCaps, - LocalCap: localCaps, - PrefixLimits: p.Conf.PrefixLimits, - LocalIp: localIp.String(), - Interface: p.Conf.NeighborInterface, - Description: p.Conf.Description, - VRF: p.Conf.Vrf, - } - return &Peer{ - Conf: conf, - Info: p.Info, - Timers: p.Timers, - RouteReflector: p.RouteReflector, - RouteServer: p.RouteServer, - } -} - -type peers []*Peer +type neighbors []*config.Neighbor -func (p peers) Len() int { - return len(p) +func (n neighbors) Len() int { + return len(n) } -func (p peers) Swap(i, j int) { - p[i], p[j] = p[j], p[i] +func (n neighbors) Swap(i, j int) { + n[i], n[j] = n[j], n[i] } -func (p peers) Less(i, j int) bool { - p1 := p[i].Conf.RemoteIp - p2 := p[j].Conf.RemoteIp +func (n neighbors) Less(i, j int) bool { + p1 := n[i].Config.NeighborAddress + p2 := n[j].Config.NeighborAddress p1Isv4 := !strings.Contains(p1, ":") p2Isv4 := !strings.Contains(p2, ":") if p1Isv4 != p2Isv4 { @@ -265,51 +207,7 @@ func (c capabilities) Less(i, j int) bool { return c[i].Code() < c[j].Code() } -type sets []*gobgpapi.DefinedSet - -func (n sets) Len() int { - return len(n) -} - -func (n sets) Swap(i, j int) { - n[i], n[j] = n[j], n[i] -} - -func (n sets) Less(i, j int) bool { - return n[i].Name < n[j].Name -} - -type policies []*gobgpapi.Policy - -func (p policies) Len() int { - return len(p) -} - -func (p policies) Swap(i, j int) { - p[i], p[j] = p[j], p[i] -} - -func (p policies) Less(i, j int) bool { - return p[i].Name < p[j].Name -} - -type roas []*gobgpapi.Roa - -func (r roas) Len() int { - return len(r) -} - -func (r roas) Swap(i, j int) { - r[i], r[j] = r[j], r[i] -} - -func (r roas) Less(i, j int) bool { - strings := sort.StringSlice{cidr2prefix(fmt.Sprintf("%s/%d", r[i].Prefix, r[i].Prefixlen)), - cidr2prefix(fmt.Sprintf("%s/%d", r[j].Prefix, r[j].Prefixlen))} - return strings.Less(0, 1) -} - -type vrfs []*gobgpapi.Vrf +type vrfs []*table.Vrf func (v vrfs) Len() int { return len(v) @@ -323,14 +221,13 @@ func (v vrfs) Less(i, j int) bool { return v[i].Name < v[j].Name } -func connGrpc() *grpc.ClientConn { - timeout := grpc.WithTimeout(time.Second) +func newClient() *cli.GoBGPClient { target := net.JoinHostPort(globalOpts.Host, strconv.Itoa(globalOpts.Port)) - conn, err := grpc.Dial(target, timeout, grpc.WithBlock(), grpc.WithInsecure()) + client, err := cli.NewGoBGPClient(target) if err != nil { exitWithError(err) } - return conn + return client } func addr2AddressFamily(a net.IP) bgp.RouteFamily { diff --git a/gobgp/cmd/global.go b/gobgp/cmd/global.go index bd7b1a88..651d6866 100644 --- a/gobgp/cmd/global.go +++ b/gobgp/cmd/global.go @@ -18,16 +18,17 @@ package cmd import ( "encoding/json" "fmt" - api "github.com/osrg/gobgp/api" - "github.com/osrg/gobgp/packet/bgp" - "github.com/osrg/gobgp/table" - "github.com/spf13/cobra" - "golang.org/x/net/context" "net" "regexp" "sort" "strconv" "strings" + "time" + + "github.com/osrg/gobgp/config" + "github.com/osrg/gobgp/packet/bgp" + "github.com/osrg/gobgp/table" + "github.com/spf13/cobra" ) type ExtCommType int @@ -655,17 +656,13 @@ func extractRouteDistinguisher(args []string) ([]string, bgp.RouteDistinguisherI return args, nil, nil } -func ParsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) { +func ParsePath(rf bgp.RouteFamily, args []string) (*table.Path, error) { var nlri bgp.AddrPrefixInterface var rd bgp.RouteDistinguisherInterface var extcomms []string var err error attrs := table.PathAttrs(make([]bgp.PathAttributeInterface, 0, 1)) - path := &api.Path{ - Pattrs: make([][]byte, 0), - } - fns := []func([]string) ([]string, bgp.PathAttributeInterface, error){ extractOrigin, extractMed, @@ -801,7 +798,6 @@ func ParsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) { } if rf == bgp.RF_IPv4_UC { - path.Nlri, _ = nlri.Serialize() attrs = append(attrs, bgp.NewPathAttributeNextHop(nexthop)) } else { mpreach := bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri}) @@ -819,21 +815,14 @@ func ParsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) { sort.Sort(attrs) - for _, attr := range attrs { - buf, err := attr.Serialize() - if err != nil { - return nil, err - } - path.Pattrs = append(path.Pattrs, buf) - } - return path, nil + return table.NewPath(nil, nlri, false, attrs, time.Now(), false), nil } func showGlobalRib(args []string) error { return showNeighborRib(CMD_GLOBAL, "", args) } -func modPath(resource api.Resource, name, modtype string, args []string) error { +func modPath(resource string, name, modtype string, args []string) error { rf, err := checkAddressFamily(bgp.RF_IPv4_UC) if err != nil { return err @@ -842,7 +831,7 @@ func modPath(resource api.Resource, name, modtype string, args []string) error { path, err := ParsePath(rf, args) if err != nil { cmdstr := "global" - if resource == api.Resource_VRF { + if resource == CMD_VRF { cmdstr = fmt.Sprintf("vrf %s", name) } @@ -929,40 +918,37 @@ usage: %s rib %s%%smatch <MATCH_EXPR> then <THEN_EXPR> -a %%s } if modtype == CMD_ADD { - arg := &api.AddPathRequest{ - Resource: resource, - VrfId: name, - Path: path, + if resource == CMD_VRF { + _, err = client.AddVRFPath(name, []*table.Path{path}) + } else { + _, err = client.AddPath([]*table.Path{path}) } - _, err = client.AddPath(context.Background(), arg) } else { - arg := &api.DeletePathRequest{ - Resource: resource, - VrfId: name, - Path: path, + if resource == CMD_VRF { + err = client.DeleteVRFPath(name, []*table.Path{path}) + } else { + err = client.DeletePath([]*table.Path{path}) } - _, err = client.DeletePath(context.Background(), arg) } return err } func showGlobalConfig(args []string) error { - rsp, err := client.GetServer(context.Background(), &api.GetServerRequest{}) + g, err := client.GetServer() if err != nil { return err } - g := rsp.Global if globalOpts.Json { j, _ := json.Marshal(g) fmt.Println(string(j)) return nil } - fmt.Println("AS: ", g.As) - fmt.Println("Router-ID:", g.RouterId) - if len(g.ListenAddresses) > 0 { - fmt.Printf("Listening Port: %d, Addresses: %s\n", g.ListenPort, strings.Join(g.ListenAddresses, ", ")) + fmt.Println("AS: ", g.Config.As) + fmt.Println("Router-ID:", g.Config.RouterId) + if len(g.Config.LocalAddressList) > 0 { + fmt.Printf("Listening Port: %d, Addresses: %s\n", g.Config.Port, strings.Join(g.Config.LocalAddressList, ", ")) } - if g.UseMultiplePaths { + if g.UseMultiplePaths.Config.Enabled { fmt.Printf("Multipath: enabled") } return nil @@ -994,16 +980,19 @@ func modGlobalConfig(args []string) error { if _, ok := m["use-multipath"]; ok { useMultipath = true } - _, err = client.StartServer(context.Background(), &api.StartServerRequest{ - Global: &api.Global{ + return client.StartServer(&config.Global{ + Config: config.GlobalConfig{ As: uint32(asn), RouterId: id.String(), - ListenPort: int32(port), - ListenAddresses: m["listen-addresses"], - UseMultiplePaths: useMultipath, + Port: int32(port), + LocalAddressList: m["listen-addresses"], + }, + UseMultiplePaths: config.UseMultiplePaths{ + Config: config.UseMultiplePathsConfig{ + Enabled: useMultipath, + }, }, }) - return err } func NewGlobalCmd() *cobra.Command { @@ -1037,7 +1026,7 @@ func NewGlobalCmd() *cobra.Command { cmd := &cobra.Command{ Use: v, Run: func(cmd *cobra.Command, args []string) { - err := modPath(api.Resource_GLOBAL, "", cmd.Use, args) + err := modPath(CMD_GLOBAL, "", cmd.Use, args) if err != nil { exitWithError(err) } @@ -1053,12 +1042,7 @@ func NewGlobalCmd() *cobra.Command { if err != nil { exitWithError(err) } - arg := &api.DeletePathRequest{ - Resource: api.Resource_GLOBAL, - Family: uint32(family), - } - _, err = client.DeletePath(context.Background(), arg) - if err != nil { + if err = client.DeletePathByFamily(family); err != nil { exitWithError(err) } }, @@ -1124,8 +1108,7 @@ func NewGlobalCmd() *cobra.Command { allCmd := &cobra.Command{ Use: CMD_ALL, Run: func(cmd *cobra.Command, args []string) { - _, err := client.StopServer(context.Background(), &api.StopServerRequest{}) - if err != nil { + if err := client.StopServer(); err != nil { exitWithError(err) } }, diff --git a/gobgp/cmd/global_test.go b/gobgp/cmd/global_test.go index c41f4c56..c4115587 100644 --- a/gobgp/cmd/global_test.go +++ b/gobgp/cmd/global_test.go @@ -30,11 +30,8 @@ func Test_ParsePath(t *testing.T) { path, err := ParsePath(bgp.RF_IPv4_UC, strings.Split(buf, " ")) assert.Nil(err) fmt.Println(path) - path.Family = uint32(bgp.RF_IPv4_UC) - p, err := path.ToNativePath() - assert.Nil(err) i := 0 - for _, a := range p.GetPathAttrs() { + for _, a := range path.GetPathAttrs() { assert.True(i < int(a.GetType())) i = int(a.GetType()) } diff --git a/gobgp/cmd/monitor.go b/gobgp/cmd/monitor.go index dd45901e..bc73f129 100644 --- a/gobgp/cmd/monitor.go +++ b/gobgp/cmd/monitor.go @@ -18,33 +18,26 @@ package cmd import ( "encoding/json" "fmt" - "github.com/osrg/gobgp/api" - "github.com/osrg/gobgp/packet/bgp" - "github.com/spf13/cobra" - "golang.org/x/net/context" "io" "net" + + "github.com/osrg/gobgp/packet/bgp" + "github.com/osrg/gobgp/table" + "github.com/spf13/cobra" ) func NewMonitorCmd() *cobra.Command { - monitor := func(arg *gobgpapi.Table) { - stream, err := client.MonitorRib(context.Background(), arg) - if err != nil { - exitWithError(err) - } + monitor := func(recver interface { + Recv() (*table.Destination, error) + }) { for { - d, err := stream.Recv() + dst, err := recver.Recv() if err == io.EOF { break } else if err != nil { exitWithError(err) } - dst, err := d.ToNativeDestination() - if err != nil { - exitWithError(err) - } - if globalOpts.Json { j, _ := json.Marshal(dst.GetAllKnownPathList()) fmt.Println(string(j)) @@ -61,11 +54,11 @@ func NewMonitorCmd() *cobra.Command { if err != nil { exitWithError(err) } - arg := &gobgpapi.Table{ - Type: gobgpapi.Resource_GLOBAL, - Family: uint32(family), + recver, err := client.MonitorRIB(family) + if err != nil { + exitWithError(err) } - monitor(arg) + monitor(recver) }, } ribCmd.PersistentFlags().StringVarP(&subOpts.AddressFamily, "address-family", "a", "", "address family") @@ -78,16 +71,11 @@ func NewMonitorCmd() *cobra.Command { neighborCmd := &cobra.Command{ Use: CMD_NEIGHBOR, Run: func(cmd *cobra.Command, args []string) { - var arg *gobgpapi.Arguments + var names []string if len(args) > 0 { - arg = &gobgpapi.Arguments{ - Name: args[0], - } - } else { - arg = &gobgpapi.Arguments{} + names = []string{args[0]} } - - stream, err := client.MonitorPeerState(context.Background(), arg) + stream, err := client.MonitorNeighborState(names...) if err != nil { exitWithError(err) } @@ -102,7 +90,7 @@ func NewMonitorCmd() *cobra.Command { j, _ := json.Marshal(s) fmt.Println(string(j)) } else { - fmt.Printf("[NEIGH] %s fsm: %s admin: %s\n", s.Conf.NeighborAddress, s.Info.BgpState, s.Info.AdminState) + fmt.Printf("[NEIGH] %s fsm: %s admin: %s\n", s.Config.NeighborAddress, s.State.SessionState, s.State.AdminState) } } }, @@ -123,12 +111,11 @@ func NewMonitorCmd() *cobra.Command { if err != nil { exitWithError(err) } - arg := &gobgpapi.Table{ - Type: gobgpapi.Resource_ADJ_IN, - Family: uint32(family), - Name: name, + recver, err := client.MonitorAdjRIBIn(name, family) + if err != nil { + exitWithError(err) } - monitor(arg) + monitor(recver) }, } adjInCmd.PersistentFlags().StringVarP(&subOpts.AddressFamily, "address-family", "a", "", "address family") diff --git a/gobgp/cmd/mrt.go b/gobgp/cmd/mrt.go index f92db025..c548a677 100644 --- a/gobgp/cmd/mrt.go +++ b/gobgp/cmd/mrt.go @@ -17,27 +17,17 @@ package cmd import ( "fmt" - api "github.com/osrg/gobgp/api" - "github.com/osrg/gobgp/packet/bgp" - "github.com/osrg/gobgp/packet/mrt" - "github.com/osrg/gobgp/table" - "github.com/spf13/cobra" - "golang.org/x/net/context" "io" "os" "strconv" "time" + + "github.com/osrg/gobgp/packet/mrt" + "github.com/osrg/gobgp/table" + "github.com/spf13/cobra" ) -func injectMrt(r string, filename string, count int, skip int, onlyBest bool) error { - - var resource api.Resource - switch r { - case CMD_GLOBAL: - resource = api.Resource_GLOBAL - default: - return fmt.Errorf("unknown resource type: %s", r) - } +func injectMrt(filename string, count int, skip int, onlyBest bool) error { file, err := os.Open(filename) if err != nil { @@ -46,7 +36,7 @@ func injectMrt(r string, filename string, count int, skip int, onlyBest bool) er idx := 0 - ch := make(chan *api.InjectMrtRequest, 1<<20) + ch := make(chan []*table.Path, 1<<20) go func() { @@ -85,15 +75,10 @@ func injectMrt(r string, filename string, count int, skip int, onlyBest bool) er if msg.Header.Type == mrt.TABLE_DUMPv2 { subType := mrt.MRTSubTypeTableDumpv2(msg.Header.SubType) - var rf bgp.RouteFamily switch subType { case mrt.PEER_INDEX_TABLE: peers = msg.Body.(*mrt.PeerIndexTable).Peers continue - case mrt.RIB_IPV4_UNICAST: - rf = bgp.RF_IPv4_UC - case mrt.RIB_IPV6_UNICAST: - rf = bgp.RF_IPv6_UC default: exitWithError(fmt.Errorf("unsupported subType: %s", subType)) } @@ -105,77 +90,34 @@ func injectMrt(r string, filename string, count int, skip int, onlyBest bool) er rib := msg.Body.(*mrt.Rib) nlri := rib.Prefix - paths := make([]*api.Path, 0, len(rib.Entries)) + paths := make([]*table.Path, 0, len(rib.Entries)) for _, e := range rib.Entries { if len(peers) < int(e.PeerIndex) { exitWithError(fmt.Errorf("invalid peer index: %d (PEER_INDEX_TABLE has only %d peers)\n", e.PeerIndex, len(peers))) } - - if !onlyBest { - path := &api.Path{ - Pattrs: make([][]byte, 0), - NoImplicitWithdraw: true, - SourceAsn: peers[e.PeerIndex].AS, - SourceId: peers[e.PeerIndex].BgpId.String(), - } - - if rf == bgp.RF_IPv4_UC { - path.Nlri, _ = nlri.Serialize() - } - - for _, p := range e.PathAttributes { - b, err := p.Serialize() - if err != nil { - continue - } - path.Pattrs = append(path.Pattrs, b) - } - - paths = append(paths, path) + source := &table.PeerInfo{ + AS: peers[e.PeerIndex].AS, + ID: peers[e.PeerIndex].BgpId, } + t := time.Unix(int64(e.OriginatedTime), 0) + paths = append(paths, table.NewPath(source, nlri, false, e.PathAttributes, t, false)) } + if onlyBest { - paths = func() []*api.Path { - dst := table.NewDestination(nlri) - pathList := make([]*table.Path, 0, len(rib.Entries)) - for _, e := range rib.Entries { - p := table.NewPath(&table.PeerInfo{AS: peers[e.PeerIndex].AS, ID: peers[e.PeerIndex].BgpId}, nlri, false, e.PathAttributes, time.Unix(int64(e.OriginatedTime), 0), false) - dst.AddNewPath(p) - pathList = append(pathList, p) - } - best, _, _ := dst.Calculate([]string{table.GLOBAL_RIB_NAME}) - for _, p := range pathList { - if p == best[table.GLOBAL_RIB_NAME] { - nb, _ := nlri.Serialize() - return []*api.Path{&api.Path{ - Nlri: nb, - NoImplicitWithdraw: true, - SourceAsn: p.GetSource().AS, - SourceId: p.GetSource().ID.String(), - Pattrs: func() [][]byte { - attrs := make([][]byte, 0) - for _, a := range p.GetPathAttrs() { - if b, e := a.Serialize(); e == nil { - - attrs = append(attrs, b) - } - } - return attrs - }(), - }} - } - } + dst := table.NewDestination(nlri) + for _, p := range paths { + dst.AddNewPath(p) + } + best, _, _ := dst.Calculate([]string{table.GLOBAL_RIB_NAME}) + if best[table.GLOBAL_RIB_NAME] == nil { exitWithError(fmt.Errorf("Can't find the best %v", nlri)) - return []*api.Path{} - }() + } + paths = []*table.Path{best[table.GLOBAL_RIB_NAME]} } if idx >= skip { - ch <- &api.InjectMrtRequest{ - Resource: resource, - Paths: paths, - } + ch <- paths } idx += 1 @@ -188,20 +130,19 @@ func injectMrt(r string, filename string, count int, skip int, onlyBest bool) er close(ch) }() - stream, err := client.InjectMrt(context.Background()) + stream, err := client.AddPathByStream() if err != nil { return fmt.Errorf("failed to modpath: %s", err) } - for arg := range ch { - err = stream.Send(arg) + for paths := range ch { + err = stream.Send(paths...) if err != nil { return fmt.Errorf("failed to send: %s", err) } } - _, err = stream.CloseAndRecv() - if err != nil { + if err := stream.Close(); err != nil { return fmt.Errorf("failed to send: %s", err) } return nil @@ -230,7 +171,7 @@ func NewMrtCmd() *cobra.Command { } } } - err := injectMrt(CMD_GLOBAL, filename, count, skip, mrtOpts.Best) + err := injectMrt(filename, count, skip, mrtOpts.Best) if err != nil { exitWithError(err) } diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go index fa6591f2..14f10245 100644 --- a/gobgp/cmd/neighbor.go +++ b/gobgp/cmd/neighbor.go @@ -18,12 +18,10 @@ package cmd import ( "encoding/json" "fmt" - api "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bgp" "github.com/osrg/gobgp/table" "github.com/spf13/cobra" - "golang.org/x/net/context" "net" "sort" "strconv" @@ -31,16 +29,16 @@ import ( "time" ) -func getNeighbors(vrf string) (peers, error) { - r, e := client.GetNeighbor(context.Background(), &api.GetNeighborRequest{}) +func getNeighbors(vrf string) (neighbors, error) { + ns, e := client.GetNeighbor() if e != nil { fmt.Println(e) return nil, e } - m := peers{} - for _, p := range r.Peers { + var m neighbors + for _, n := range ns { if neighborsOpts.Transport != "" { - addr, _ := net.ResolveIPAddr("ip", p.Conf.NeighborAddress) + addr, _ := net.ResolveIPAddr("ip", n.Config.NeighborAddress) if addr.IP.To4() != nil { if neighborsOpts.Transport != "ipv4" { continue @@ -51,21 +49,21 @@ func getNeighbors(vrf string) (peers, error) { } } } - if vrf != "" && p.Conf.Vrf != vrf { + if vrf != "" && n.Config.Vrf != vrf { continue } - m = append(m, ApiStruct2Peer(p)) + m = append(m, n) } return m, nil } -func getNeighbor(name string) (*Peer, error) { +func getNeighbor(name string) (*config.Neighbor, error) { l, e := getNeighbors("") if e != nil { return nil, e } for _, p := range l { - if p.Conf.RemoteIp == name || p.Conf.Interface == name { + if p.Config.NeighborAddress == name || p.Config.NeighborAddress == name { return p, nil } } @@ -85,7 +83,7 @@ func showNeighbors(vrf string) error { if globalOpts.Quiet { for _, p := range m { - fmt.Println(p.Conf.RemoteIp) + fmt.Println(p.Config.NeighborAddress) } return nil } @@ -97,20 +95,20 @@ func showNeighbors(vrf string) error { sort.Sort(m) now := time.Now() - for _, p := range m { - if i := len(p.Conf.Interface); i > maxaddrlen { + for _, n := range m { + if i := len(n.Config.NeighborInterface); i > maxaddrlen { maxaddrlen = i - } else if j := len(p.Conf.RemoteIp); j > maxaddrlen { + } else if j := len(n.Config.NeighborAddress); j > maxaddrlen { maxaddrlen = j } - if len(fmt.Sprint(p.Conf.RemoteAs)) > maxaslen { - maxaslen = len(fmt.Sprint(p.Conf.RemoteAs)) + if len(fmt.Sprint(n.Config.PeerAs)) > maxaslen { + maxaslen = len(fmt.Sprint(n.Config.PeerAs)) } timeStr := "never" - if p.Timers.State.Uptime != 0 { - t := int64(p.Timers.State.Downtime) - if p.Info.BgpState == string(config.SESSION_STATE_ESTABLISHED) { - t = int64(p.Timers.State.Uptime) + if n.Timers.State.Uptime != 0 { + t := int64(n.Timers.State.Downtime) + if n.State.SessionState == config.SESSION_STATE_ESTABLISHED { + t = int64(n.Timers.State.Uptime) } timeStr = formatTimedelta(int64(now.Sub(time.Unix(int64(t), 0)).Seconds())) } @@ -123,7 +121,7 @@ func showNeighbors(vrf string) error { format = "%-" + fmt.Sprint(maxaddrlen) + "s" + " %" + fmt.Sprint(maxaslen) + "s" + " %" + fmt.Sprint(maxtimelen) + "s" format += " %-11s |%11s %8s %8s\n" fmt.Printf(format, "Peer", "AS", "Up/Down", "State", "#Advertised", "Received", "Accepted") - format_fsm := func(admin, fsm string) string { + format_fsm := func(admin string, fsm config.SessionState) string { switch admin { case "ADMIN_STATE_DOWN": return "Idle(Admin)" @@ -131,7 +129,7 @@ func showNeighbors(vrf string) error { return "Idle(PfxCt)" } - switch config.SessionState(fsm) { + switch fsm { case config.SESSION_STATE_IDLE: return "Idle" case config.SESSION_STATE_CONNECT: @@ -145,16 +143,16 @@ func showNeighbors(vrf string) error { case config.SESSION_STATE_ESTABLISHED: return "Establ" default: - return fsm + return string(fsm) } } - for i, p := range m { - neigh := p.Conf.RemoteIp - if p.Conf.Interface != "" { - neigh = p.Conf.Interface + for i, n := range m { + neigh := n.Config.NeighborAddress + if n.Config.NeighborInterface != "" { + neigh = n.Config.NeighborInterface } - fmt.Printf(format, neigh, fmt.Sprint(p.Conf.RemoteAs), timedelta[i], format_fsm(p.Info.AdminState, p.Info.BgpState), fmt.Sprint(p.Info.Advertised), fmt.Sprint(p.Info.Received), fmt.Sprint(p.Info.Accepted)) + fmt.Printf(format, neigh, fmt.Sprint(n.Config.PeerAs), timedelta[i], format_fsm(n.State.AdminState, n.State.SessionState), fmt.Sprint(n.State.AdjTable.Advertised), fmt.Sprint(n.State.AdjTable.Received), fmt.Sprint(n.State.AdjTable.Accepted)) } return nil @@ -171,23 +169,23 @@ func showNeighbor(args []string) error { return nil } - fmt.Printf("BGP neighbor is %s, remote AS %d", p.Conf.RemoteIp, p.Conf.RemoteAs) + fmt.Printf("BGP neighbor is %s, remote AS %d", p.Config.NeighborAddress, p.Config.PeerAs) - if p.RouteReflector != nil && p.RouteReflector.RouteReflectorClient { + if p.RouteReflector.Config.RouteReflectorClient { fmt.Printf(", route-reflector-client\n") - } else if p.RouteServer != nil && p.RouteServer.RouteServerClient { + } else if p.RouteServer.Config.RouteServerClient { fmt.Printf(", route-server-client\n") } else { fmt.Printf("\n") } id := "unknown" - if p.Conf.Id != nil { - id = p.Conf.Id.String() + if p.State.RemoteRouterId != "" { + id = p.State.RemoteRouterId } fmt.Printf(" BGP version 4, remote router ID %s\n", id) - fmt.Printf(" BGP state = %s, up for %s\n", p.Info.BgpState, formatTimedelta(int64(p.Timers.State.Uptime)-time.Now().Unix())) - fmt.Printf(" BGP OutQ = %d, Flops = %d\n", p.Info.OutQ, p.Info.Flops) + fmt.Printf(" BGP state = %s, up for %s\n", p.State.SessionState, formatTimedelta(int64(p.Timers.State.Uptime)-time.Now().Unix())) + fmt.Printf(" BGP OutQ = %d, Flops = %d\n", p.State.Queues.Output, p.State.Flops) fmt.Printf(" Hold time is %d, keepalive interval is %d seconds\n", p.Timers.State.NegotiatedHoldTime, p.Timers.State.KeepaliveInterval) fmt.Printf(" Configured hold time is %d, keepalive interval is %d seconds\n", p.Timers.Config.HoldTime, p.Timers.Config.KeepaliveInterval) @@ -209,10 +207,10 @@ func showNeighbor(args []string) error { } return nil } - for _, c := range p.Conf.LocalCap { + for _, c := range p.State.LocalCapabilityList { caps = append(caps, c) } - for _, c := range p.Conf.RemoteCap { + for _, c := range p.State.RemoteCapabilityList { if lookup(c, caps) == nil { caps = append(caps, c) } @@ -224,10 +222,10 @@ func showNeighbor(args []string) error { for _, c := range caps { support := "" - if m := lookup(c, p.Conf.LocalCap); m != nil { + if m := lookup(c, p.State.LocalCapabilityList); m != nil { support += "advertised" } - if lookup(c, p.Conf.RemoteCap) != nil { + if lookup(c, p.State.RemoteCapabilityList) != nil { if len(support) != 0 { support += " and " } @@ -274,13 +272,13 @@ func showNeighbor(args []string) error { } return str } - if m := lookup(c, p.Conf.LocalCap); m != nil { + if m := lookup(c, p.State.LocalCapabilityList); m != nil { g := m.(*bgp.CapGracefulRestart) if s := grStr(g); len(s) > 0 { fmt.Printf(" Local: %s", s) } } - if m := lookup(c, p.Conf.RemoteCap); m != nil { + if m := lookup(c, p.State.LocalCapabilityList); m != nil { g := m.(*bgp.CapGracefulRestart) if s := grStr(g); len(s) > 0 { fmt.Printf(" Remote: %s", s) @@ -299,13 +297,13 @@ func showNeighbor(args []string) error { } return str } - if m := lookup(c, p.Conf.LocalCap); m != nil { + if m := lookup(c, p.State.LocalCapabilityList); m != nil { g := m.(*bgp.CapLongLivedGracefulRestart) if s := grStr(g); len(s) > 0 { fmt.Printf(" Local:\n%s", s) } } - if m := lookup(c, p.Conf.RemoteCap); m != nil { + if m := lookup(c, p.State.LocalCapabilityList); m != nil { g := m.(*bgp.CapLongLivedGracefulRestart) if s := grStr(g); len(s) > 0 { fmt.Printf(" Remote:\n%s", s) @@ -318,29 +316,32 @@ func showNeighbor(args []string) error { } fmt.Print(" Message statistics:\n") fmt.Print(" Sent Rcvd\n") - fmt.Printf(" Opens: %10d %10d\n", p.Info.Messages.Sent.OPEN, p.Info.Messages.Received.OPEN) - fmt.Printf(" Notifications: %10d %10d\n", p.Info.Messages.Sent.NOTIFICATION, p.Info.Messages.Received.NOTIFICATION) - fmt.Printf(" Updates: %10d %10d\n", p.Info.Messages.Sent.UPDATE, p.Info.Messages.Received.UPDATE) - fmt.Printf(" Keepalives: %10d %10d\n", p.Info.Messages.Sent.KEEPALIVE, p.Info.Messages.Received.KEEPALIVE) - fmt.Printf(" Route Refesh: %10d %10d\n", p.Info.Messages.Sent.REFRESH, p.Info.Messages.Received.REFRESH) - fmt.Printf(" Discarded: %10d %10d\n", p.Info.Messages.Sent.DISCARDED, p.Info.Messages.Received.DISCARDED) - fmt.Printf(" Total: %10d %10d\n", p.Info.Messages.Sent.TOTAL, p.Info.Messages.Received.TOTAL) + fmt.Printf(" Opens: %10d %10d\n", p.State.Messages.Sent.Open, p.State.Messages.Received.Open) + fmt.Printf(" Notifications: %10d %10d\n", p.State.Messages.Sent.Notification, p.State.Messages.Received.Notification) + fmt.Printf(" Updates: %10d %10d\n", p.State.Messages.Sent.Update, p.State.Messages.Received.Update) + fmt.Printf(" Keepalives: %10d %10d\n", p.State.Messages.Sent.Keepalive, p.State.Messages.Received.Keepalive) + fmt.Printf(" Route Refesh: %10d %10d\n", p.State.Messages.Sent.Refresh, p.State.Messages.Received.Refresh) + fmt.Printf(" Discarded: %10d %10d\n", p.State.Messages.Sent.Discarded, p.State.Messages.Received.Discarded) + fmt.Printf(" Total: %10d %10d\n", p.State.Messages.Sent.Total, p.State.Messages.Received.Total) fmt.Print(" Route statistics:\n") - fmt.Printf(" Advertised: %10d\n", p.Info.Advertised) - fmt.Printf(" Received: %10d\n", p.Info.Received) - fmt.Printf(" Accepted: %10d\n", p.Info.Accepted) - if len(p.Conf.PrefixLimits) > 0 { - fmt.Println(" Prefix Limits:") - for _, c := range p.Conf.PrefixLimits { - fmt.Printf(" %s:\tMaximum prefixes allowed %d", bgp.RouteFamily(c.Family), c.MaxPrefixes) - if c.ShutdownThresholdPct > 0 { - fmt.Printf(", Threshold for warning message %d%%\n", c.ShutdownThresholdPct) + fmt.Printf(" Advertised: %10d\n", p.State.AdjTable.Advertised) + fmt.Printf(" Received: %10d\n", p.State.AdjTable.Received) + fmt.Printf(" Accepted: %10d\n", p.State.AdjTable.Accepted) + first := true + for _, afisafi := range p.AfiSafis { + if afisafi.PrefixLimit.Config.MaxPrefixes > 0 { + if first { + fmt.Println(" Prefix Limits:") + first = false + } + fmt.Printf(" %s:\tMaximum prefixes allowed %d", afisafi.Config.AfiSafiName, afisafi.PrefixLimit.Config.MaxPrefixes) + if afisafi.PrefixLimit.Config.ShutdownThresholdPct > 0 { + fmt.Printf(", Threshold for warning message %d%%\n", afisafi.PrefixLimit.Config.ShutdownThresholdPct) } else { fmt.Printf("\n") } } } - return nil } @@ -478,38 +479,33 @@ func ShowRoute(pathList []*table.Path, showAge, showBest, showLabel, isMonitor, } func showRibInfo(r, name string) error { - var resource api.Resource def := addr2AddressFamily(net.ParseIP(name)) + if r == CMD_GLOBAL { + def = bgp.RF_IPv4_UC + } + family, err := checkAddressFamily(def) + if err != nil { + return err + } + + var info *table.TableInfo switch r { case CMD_GLOBAL: - def = bgp.RF_IPv4_UC - resource = api.Resource_GLOBAL + info, err = client.GetRIBInfo(family) case CMD_LOCAL: - resource = api.Resource_LOCAL + info, err = client.GetLocalRIBInfo(name, family) case CMD_ADJ_IN: - resource = api.Resource_ADJ_IN + info, err = client.GetAdjRIBInInfo(name, family) case CMD_ADJ_OUT: - resource = api.Resource_ADJ_OUT + info, err = client.GetAdjRIBOutInfo(name, family) default: return fmt.Errorf("invalid resource to show RIB info: %s", r) } - family, err := checkAddressFamily(def) if err != nil { return err } - res, err := client.GetRibInfo(context.Background(), &api.GetRibInfoRequest{ - Info: &api.TableInfo{ - Type: resource, - Name: name, - Family: uint32(family), - }, - }) - if err != nil { - return err - } - info := res.Info if globalOpts.Json { j, _ := json.Marshal(info) fmt.Println(string(j)) @@ -522,7 +518,6 @@ func showRibInfo(r, name string) error { } func showNeighborRib(r string, name string, args []string) error { - var resource api.Resource showBest := false showAge := true showLabel := false @@ -531,79 +526,72 @@ func showNeighborRib(r string, name string, args []string) error { case CMD_GLOBAL: def = bgp.RF_IPv4_UC showBest = true - resource = api.Resource_GLOBAL case CMD_LOCAL: showBest = true - resource = api.Resource_LOCAL - case CMD_ADJ_IN, CMD_ACCEPTED, CMD_REJECTED: - resource = api.Resource_ADJ_IN case CMD_ADJ_OUT: showAge = false - resource = api.Resource_ADJ_OUT case CMD_VRF: def = bgp.RF_IPv4_UC - resource = api.Resource_VRF } - rf, err := checkAddressFamily(def) + family, err := checkAddressFamily(def) if err != nil { return err } - switch rf { + switch family { case bgp.RF_IPv4_MPLS, bgp.RF_IPv6_MPLS, bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN: showLabel = true } - arg := &api.Table{ - Type: resource, - Family: uint32(rf), - Name: name, - } - + var filter []*table.LookupPrefix if len(args) > 0 { - longerPrefixes := false - shorterPrefixes := false + var option table.LookupOption if len(args) > 1 { if args[1] == "longer-prefixes" { - longerPrefixes = true + option = table.LOOKUP_LONGER } else if args[1] == "shorter-prefixes" { - shorterPrefixes = true + option = table.LOOKUP_SHORTER } else { return fmt.Errorf("invalid format for route filtering") } } - arg.Destinations = []*api.Destination{ - &api.Destination{ - Prefix: args[0], - LongerPrefixes: longerPrefixes, - ShorterPrefixes: shorterPrefixes, - }, + filter = []*table.LookupPrefix{&table.LookupPrefix{ + Prefix: args[0], + LookupOption: option, + }, } } - rsp, err := client.GetRib(context.Background(), &api.GetRibRequest{ - Table: arg, - }) + var rib *table.Table + switch r { + case CMD_GLOBAL: + rib, err = client.GetRIB(family, filter) + case CMD_LOCAL: + rib, err = client.GetLocalRIB(name, family, filter) + case CMD_ADJ_IN, CMD_ACCEPTED, CMD_REJECTED: + rib, err = client.GetAdjRIBIn(name, family, filter) + case CMD_ADJ_OUT: + rib, err = client.GetAdjRIBOut(name, family, filter) + case CMD_VRF: + rib, err = client.GetVRFRIB(name, family, filter) + } + if err != nil { return err } + switch r { case CMD_LOCAL, CMD_ADJ_IN, CMD_ACCEPTED, CMD_REJECTED, CMD_ADJ_OUT: - if len(rsp.Table.Destinations) == 0 { + if rib.Info("").NumDestination == 0 { peer, err := getNeighbor(name) if err != nil { return err } - if peer.Info.BgpState != string(config.SESSION_STATE_ESTABLISHED) { + if peer.State.SessionState != config.SESSION_STATE_ESTABLISHED { return fmt.Errorf("Neighbor %v's BGP session is not established", name) } } } - rib, err := rsp.Table.ToNativeTable() - if err != nil { - return err - } - if globalOpts.Json { j, _ := json.Marshal(rib.GetDestinations()) fmt.Println(string(j)) @@ -645,126 +633,105 @@ func showNeighborRib(r string, name string, args []string) error { } func resetNeighbor(cmd string, remoteIP string, args []string) error { + family := bgp.RouteFamily(0) switch cmd { case CMD_RESET: - client.ResetNeighbor(context.Background(), &api.ResetNeighborRequest{Address: remoteIP}) + return client.ResetNeighbor(remoteIP) case CMD_SOFT_RESET: - client.SoftResetNeighbor(context.Background(), &api.SoftResetNeighborRequest{ - Address: remoteIP, - Direction: api.SoftResetNeighborRequest_BOTH, - }) + return client.SoftReset(remoteIP, family) case CMD_SOFT_RESET_IN: - client.SoftResetNeighbor(context.Background(), &api.SoftResetNeighborRequest{ - Address: remoteIP, - Direction: api.SoftResetNeighborRequest_IN, - }) + return client.SoftResetIn(remoteIP, family) case CMD_SOFT_RESET_OUT: - client.SoftResetNeighbor(context.Background(), &api.SoftResetNeighborRequest{ - Address: remoteIP, - Direction: api.SoftResetNeighborRequest_OUT, - }) + return client.SoftResetOut(remoteIP, family) } return nil } func stateChangeNeighbor(cmd string, remoteIP string, args []string) error { - var err error switch cmd { case CMD_SHUTDOWN: fmt.Printf("WARNING: command `%s` is deprecated. use `%s` instead", CMD_SHUTDOWN, CMD_DISABLE) - _, err = client.ShutdownNeighbor(context.Background(), &api.ShutdownNeighborRequest{Address: remoteIP}) + return client.ShutdownNeighbor(remoteIP) case CMD_ENABLE: - _, err = client.EnableNeighbor(context.Background(), &api.EnableNeighborRequest{Address: remoteIP}) + return client.EnableNeighbor(remoteIP) case CMD_DISABLE: - _, err = client.DisableNeighbor(context.Background(), &api.DisableNeighborRequest{Address: remoteIP}) + return client.DisableNeighbor(remoteIP) } - return err + return nil } func showNeighborPolicy(remoteIP, policyType string, indent int) error { - var typ api.PolicyType + var assignment *table.PolicyAssignment + var err error + switch strings.ToLower(policyType) { case "in": - typ = api.PolicyType_IN + assignment, err = client.GetRouteServerInPolicy(remoteIP) case "import": - typ = api.PolicyType_IMPORT + assignment, err = client.GetRouteServerImportPolicy(remoteIP) case "export": - typ = api.PolicyType_EXPORT - } - r := api.Resource_LOCAL - if remoteIP == "" { - r = api.Resource_GLOBAL - } - arg := &api.GetPolicyAssignmentRequest{ - Assignment: &api.PolicyAssignment{ - Name: remoteIP, - Resource: r, - Type: typ, - }, + assignment, err = client.GetRouteServerExportPolicy(remoteIP) + default: + fmt.Errorf("invalid policy type: choose from (in|import|export)") } - ap, e := client.GetPolicyAssignment(context.Background(), arg) - if e != nil { - return e + + if err != nil { + return err } if globalOpts.Json { - j, _ := json.Marshal(ap) + j, _ := json.Marshal(assignment) fmt.Println(string(j)) return nil } fmt.Printf("%s policy:\n", strings.Title(policyType)) - fmt.Printf("%sDefault: %s\n", strings.Repeat(" ", indent), ap.Assignment.Default) - for _, p := range ap.Assignment.Policies { + fmt.Printf("%sDefault: %s\n", strings.Repeat(" ", indent), assignment.Default) + for _, p := range assignment.Policies { fmt.Printf("%sName %s:\n", strings.Repeat(" ", indent), p.Name) printPolicy(indent+4, p) } return nil } -func extractDefaultAction(args []string) ([]string, api.RouteAction, error) { +func extractDefaultAction(args []string) ([]string, table.RouteType, error) { for idx, arg := range args { if arg == "default" { if len(args) < (idx + 2) { - return nil, api.RouteAction_NONE, fmt.Errorf("specify default action [accept|reject]") + return nil, table.ROUTE_TYPE_NONE, fmt.Errorf("specify default action [accept|reject]") } typ := args[idx+1] switch strings.ToLower(typ) { case "accept": - return append(args[:idx], args[idx+2:]...), api.RouteAction_ACCEPT, nil + return append(args[:idx], args[idx+2:]...), table.ROUTE_TYPE_ACCEPT, nil case "reject": - return append(args[:idx], args[idx+2:]...), api.RouteAction_REJECT, nil + return append(args[:idx], args[idx+2:]...), table.ROUTE_TYPE_REJECT, nil default: - return nil, api.RouteAction_NONE, fmt.Errorf("invalid default action") + return nil, table.ROUTE_TYPE_NONE, fmt.Errorf("invalid default action") } } } - return args, api.RouteAction_NONE, nil + return args, table.ROUTE_TYPE_NONE, nil } func modNeighborPolicy(remoteIP, policyType, cmdType string, args []string) error { - var typ api.PolicyType + assign := &table.PolicyAssignment{ + Name: remoteIP, + } switch strings.ToLower(policyType) { case "in": - typ = api.PolicyType_IN + assign.Type = table.POLICY_DIRECTION_IN case "import": - typ = api.PolicyType_IMPORT + assign.Type = table.POLICY_DIRECTION_IMPORT case "export": - typ = api.PolicyType_EXPORT + assign.Type = table.POLICY_DIRECTION_EXPORT } - r := api.Resource_LOCAL + usage := fmt.Sprintf("usage: gobgp neighbor %s policy %s %s", remoteIP, policyType, cmdType) if remoteIP == "" { - r = api.Resource_GLOBAL usage = fmt.Sprintf("usage: gobgp global policy %s %s", policyType, cmdType) } - assign := &api.PolicyAssignment{ - Type: typ, - Resource: r, - Name: remoteIP, - } - var err error switch cmdType { case CMD_ADD, CMD_SET: @@ -772,36 +739,29 @@ func modNeighborPolicy(remoteIP, policyType, cmdType string, args []string) erro return fmt.Errorf("%s <policy name>... [default {%s|%s}]", usage, "accept", "reject") } var err error - var def api.RouteAction + var def table.RouteType args, def, err = extractDefaultAction(args) if err != nil { return fmt.Errorf("%s\n%s <policy name>... [default {%s|%s}]", err, usage, "accept", "reject") } assign.Default = def } - ps := make([]*api.Policy, 0, len(args)) + ps := make([]*table.Policy, 0, len(args)) for _, name := range args { - ps = append(ps, &api.Policy{Name: name}) + ps = append(ps, &table.Policy{Name: name}) } assign.Policies = ps switch cmdType { case CMD_ADD: - _, err = client.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{ - Assignment: assign, - }) + err = client.AddPolicyAssignment(assign) case CMD_SET: - _, err = client.ReplacePolicyAssignment(context.Background(), &api.ReplacePolicyAssignmentRequest{ - Assignment: assign, - }) + err = client.ReplacePolicyAssignment(assign) case CMD_DEL: all := false if len(args) == 0 { all = true } - _, err = client.DeletePolicyAssignment(context.Background(), &api.DeletePolicyAssignmentRequest{ - Assignment: assign, - All: all, - }) + err = client.DeletePolicyAssignment(assign, all) } return err } @@ -823,30 +783,30 @@ func modNeighbor(cmdType string, args []string) error { } } - getConf := func(asn int) *api.Peer { - peer := &api.Peer{ - Conf: &api.PeerConf{ + getConf := func(asn int) *config.Neighbor { + peer := &config.Neighbor{ + Config: config.NeighborConfig{ PeerAs: uint32(asn), }, } if unnumbered { - peer.Conf.NeighborInterface = m["interface"][0] + peer.Config.NeighborInterface = m["interface"][0] } else { - peer.Conf.NeighborAddress = m[""][0] + peer.Config.NeighborAddress = m[""][0] } if len(m["vrf"]) == 1 { - peer.Conf.Vrf = m["vrf"][0] + peer.Config.Vrf = m["vrf"][0] } if rr, ok := m["route-reflector-client"]; ok { - peer.RouteReflector = &api.RouteReflector{ + peer.RouteReflector.Config = config.RouteReflectorConfig{ RouteReflectorClient: true, } if len(rr) == 1 { - peer.RouteReflector.RouteReflectorClusterId = rr[0] + peer.RouteReflector.Config.RouteReflectorClusterId = config.RrClusterIdType(rr[0]) } } if _, ok := m["route-server-client"]; ok { - peer.RouteServer = &api.RouteServer{ + peer.RouteServer.Config = config.RouteServerConfig{ RouteServerClient: true, } } @@ -863,9 +823,9 @@ func modNeighbor(cmdType string, args []string) error { if err != nil { return err } - _, err = client.AddNeighbor(context.Background(), &api.AddNeighborRequest{Peer: getConf(as)}) + err = client.AddNeighbor(getConf(as)) case CMD_DEL: - _, err = client.DeleteNeighbor(context.Background(), &api.DeleteNeighborRequest{Peer: getConf(0)}) + err = client.DeleteNeighbor(getConf(0)) } return err } @@ -902,7 +862,7 @@ func NewNeighborCmd() *cobra.Command { if err != nil { exitWithError(err) } - addr = peer.Conf.RemoteIp + addr = peer.Config.NeighborAddress } err := f(cmd.Use, addr, args[:len(args)-1]) if err != nil { @@ -933,7 +893,7 @@ func NewNeighborCmd() *cobra.Command { if err != nil { exitWithError(err) } - remoteIP := peer.Conf.RemoteIp + remoteIP := peer.Config.NeighborAddress for _, v := range []string{CMD_IN, CMD_IMPORT, CMD_EXPORT} { if err := showNeighborPolicy(remoteIP, v, 4); err != nil { exitWithError(err) @@ -950,7 +910,7 @@ func NewNeighborCmd() *cobra.Command { if err != nil { exitWithError(err) } - remoteIP := peer.Conf.RemoteIp + remoteIP := peer.Config.NeighborAddress err = showNeighborPolicy(remoteIP, cmd.Use, 0) if err != nil { exitWithError(err) @@ -966,7 +926,7 @@ func NewNeighborCmd() *cobra.Command { if err != nil { exitWithError(err) } - remoteIP := peer.Conf.RemoteIp + remoteIP := peer.Config.NeighborAddress args = args[:len(args)-1] if err = modNeighborPolicy(remoteIP, cmd.Use, subcmd.Use, args); err != nil { exitWithError(err) diff --git a/gobgp/cmd/policy.go b/gobgp/cmd/policy.go index d6bc0439..583cbc89 100644 --- a/gobgp/cmd/policy.go +++ b/gobgp/cmd/policy.go @@ -19,111 +19,50 @@ import ( "bytes" "encoding/json" "fmt" - api "github.com/osrg/gobgp/api" - "github.com/osrg/gobgp/config" - "github.com/osrg/gobgp/table" - "github.com/spf13/cobra" - "golang.org/x/net/context" "net" "regexp" "sort" "strconv" "strings" -) - -func formatPolicyPrefix(head bool, indent int, psl []*api.DefinedSet) string { - if len(psl) == 0 { - return "Nothing defined yet\n" - } - buff := bytes.NewBuffer(make([]byte, 0, 64)) - sIndent := strings.Repeat(" ", indent) - maxNameLen := 0 - maxPrefixLen := 0 - for _, ps := range psl { - if len(ps.Name) > maxNameLen { - maxNameLen = len(ps.Name) - } - for _, p := range ps.Prefixes { - if len(p.IpPrefix) > maxPrefixLen { - maxPrefixLen = len(p.IpPrefix) - } - } - } - if head { - if len("NAME") > maxNameLen { - maxNameLen = len("NAME") - } - if len("PREFIX") > maxPrefixLen { - maxPrefixLen = len("PREFIX") - } - } - - format := fmt.Sprintf("%%-%ds %%-%ds ", maxNameLen, maxPrefixLen) - if head { - buff.WriteString(fmt.Sprintf(format, "NAME", "PREFIX")) - buff.WriteString("MaskLengthRange\n") - } - for _, ps := range psl { - if len(ps.Prefixes) == 0 { - buff.WriteString(fmt.Sprintf(format, ps.Name, "")) - buff.WriteString("\n") - } - 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)) - } else { - buff.WriteString(fmt.Sprintf(sIndent)) - buff.WriteString(fmt.Sprintf(format, "", p.IpPrefix)) - buff.WriteString(fmt.Sprintf("%d..%d\n", p.MaskLengthMin, p.MaskLengthMax)) - } - } - } - return buff.String() -} + "github.com/osrg/gobgp/config" + "github.com/osrg/gobgp/table" + "github.com/spf13/cobra" +) -func formatDefinedSet(head bool, typ string, indent int, list []*api.DefinedSet) string { +func formatDefinedSet(head bool, typ string, indent int, list []table.DefinedSet) string { if len(list) == 0 { return "Nothing defined yet\n" } buff := bytes.NewBuffer(make([]byte, 0, 64)) sIndent := strings.Repeat(" ", indent) maxNameLen := 0 - maxValueLen := 0 for _, s := range list { - if len(s.Name) > maxNameLen { - maxNameLen = len(s.Name) - } - for _, x := range s.List { - if len(x) > maxValueLen { - maxValueLen = len(x) - } + if len(s.Name()) > maxNameLen { + maxNameLen = len(s.Name()) } } if head { if len("NAME") > maxNameLen { maxNameLen = len("NAME") } - if len(typ) > maxValueLen { - maxValueLen = len(typ) - } } - format := fmt.Sprintf("%%-%ds %%-%ds\n", maxNameLen, maxValueLen) + format := fmt.Sprintf("%%-%ds %%s\n", maxNameLen) if head { buff.WriteString(fmt.Sprintf(format, "NAME", typ)) } for _, s := range list { - if len(s.List) == 0 { - buff.WriteString(fmt.Sprintf(format, s.Name, "")) + l := s.List() + if len(l) == 0 { + buff.WriteString(fmt.Sprintf(format, s.Name(), "")) } - for i, x := range s.List { + for i, x := range l { if typ == "COMMUNITY" || typ == "EXT-COMMUNITY" || typ == "LARGE-COMMUNITY" { exp := regexp.MustCompile("\\^(\\S+)\\$") x = exp.ReplaceAllString(x, "$1") } if i == 0 { - buff.WriteString(fmt.Sprintf(format, s.Name, x)) + buff.WriteString(fmt.Sprintf(format, s.Name(), x)) } else { buff.WriteString(fmt.Sprintf(sIndent)) buff.WriteString(fmt.Sprintf(format, "", x)) @@ -134,31 +73,31 @@ func formatDefinedSet(head bool, typ string, indent int, list []*api.DefinedSet) } func showDefinedSet(v string, args []string) error { - var typ api.DefinedType + var typ table.DefinedType switch v { case CMD_PREFIX: - typ = api.DefinedType_PREFIX + typ = table.DEFINED_TYPE_PREFIX case CMD_NEIGHBOR: - typ = api.DefinedType_NEIGHBOR + typ = table.DEFINED_TYPE_NEIGHBOR case CMD_ASPATH: - typ = api.DefinedType_AS_PATH + typ = table.DEFINED_TYPE_AS_PATH case CMD_COMMUNITY: - typ = api.DefinedType_COMMUNITY + typ = table.DEFINED_TYPE_COMMUNITY case CMD_EXTCOMMUNITY: - typ = api.DefinedType_EXT_COMMUNITY + typ = table.DEFINED_TYPE_EXT_COMMUNITY case CMD_LARGECOMMUNITY: - typ = api.DefinedType_LARGE_COMMUNITY + typ = table.DEFINED_TYPE_LARGE_COMMUNITY default: return fmt.Errorf("unknown defined type: %s", v) } - rsp, err := client.GetDefinedSet(context.Background(), &api.GetDefinedSetRequest{Type: typ}) + ds, err := client.GetDefinedSet(typ) if err != nil { return err } - m := sets{} + var m table.DefinedSetList if len(args) > 0 { - for _, set := range rsp.Sets { - if args[0] == set.Name { + for _, set := range ds { + if args[0] == set.Name() { m = append(m, set) } } @@ -166,7 +105,7 @@ func showDefinedSet(v string, args []string) error { return fmt.Errorf("not found %s", args[0]) } } else { - m = rsp.Sets + m = ds } if globalOpts.Json { j, _ := json.Marshal(m) @@ -175,15 +114,10 @@ func showDefinedSet(v string, args []string) error { } if globalOpts.Quiet { if len(args) > 0 { - for _, p := range m[0].List { - fmt.Println(p) - } - for _, p := range m[0].Prefixes { - fmt.Printf("%s %d..%d\n", p.IpPrefix, p.MaskLengthMin, p.MaskLengthMax) - } + fmt.Println(m) } else { for _, p := range m { - fmt.Println(p.Name) + fmt.Println(p.Name()) } } return nil @@ -192,7 +126,7 @@ func showDefinedSet(v string, args []string) error { var output string switch v { case CMD_PREFIX: - output = formatPolicyPrefix(true, 0, m) + output = formatDefinedSet(true, "PREFIX", 0, m) case CMD_NEIGHBOR: output = formatDefinedSet(true, "ADDRESS", 0, m) case CMD_ASPATH: @@ -208,65 +142,35 @@ func showDefinedSet(v string, args []string) error { return nil } -func parsePrefixSet(args []string) (*api.DefinedSet, error) { +func parsePrefixSet(args []string) (table.DefinedSet, error) { if len(args) < 1 { return nil, fmt.Errorf("empty neighbor set name") } name := args[0] args = args[1:] - var list []*api.Prefix + var list []config.Prefix if len(args) > 0 { - _, ipNet, err := net.ParseCIDR(args[0]) + mask := "" + if len(args) > 1 { + mask = args[1] + } + min, max, err := config.ParseMaskLength(args[0], mask) if err != nil { - return nil, fmt.Errorf("invalid prefix: %s\nplease enter ipv4 or ipv6 format", args[1]) + return nil, err } - l, _ := ipNet.Mask.Size() - prefix := &api.Prefix{ - IpPrefix: args[0], - MaskLengthMin: uint32(l), - MaskLengthMax: uint32(l), + prefix := config.Prefix{ + IpPrefix: args[0], + MasklengthRange: fmt.Sprintf("%d..%d", min, max), } - if len(args) > 1 { - maskRange := args[1] - exp := regexp.MustCompile("(\\d+)\\.\\.(\\d+)") - elems := exp.FindStringSubmatch(maskRange) - if len(elems) != 3 { - return nil, fmt.Errorf("invalid mask length range: %s", maskRange) - } - // we've already checked the range is sane by regexp - min, _ := strconv.Atoi(elems[1]) - max, _ := strconv.Atoi(elems[2]) - if min > max { - return nil, fmt.Errorf("invalid mask length range: %s", maskRange) - } - if ipv4 := ipNet.IP.To4(); ipv4 != nil { - f := func(i int) bool { - return i >= 0 && i <= 32 - } - if !f(min) || !f(max) { - return nil, fmt.Errorf("ipv4 mask length range outside scope :%s", maskRange) - } - } else { - f := func(i int) bool { - return i >= 0 && i <= 128 - } - if !f(min) || !f(max) { - return nil, fmt.Errorf("ipv6 mask length range outside scope :%s", maskRange) - } - } - prefix.MaskLengthMin = uint32(min) - prefix.MaskLengthMax = uint32(max) - } - list = []*api.Prefix{prefix} + list = []config.Prefix{prefix} } - return &api.DefinedSet{ - Type: api.DefinedType_PREFIX, - Name: name, - Prefixes: list, - }, nil + return table.NewPrefixSet(config.PrefixSet{ + PrefixSetName: name, + PrefixList: list, + }) } -func parseNeighborSet(args []string) (*api.DefinedSet, error) { +func parseNeighborSet(args []string) (table.DefinedSet, error) { if len(args) < 1 { return nil, fmt.Errorf("empty neighbor set name") } @@ -278,14 +182,13 @@ func parseNeighborSet(args []string) (*api.DefinedSet, error) { return nil, fmt.Errorf("invalid address: %s\nplease enter ipv4 or ipv6 format", arg) } } - return &api.DefinedSet{ - Type: api.DefinedType_NEIGHBOR, - Name: name, - List: args, - }, nil + return table.NewNeighborSet(config.NeighborSet{ + NeighborSetName: name, + NeighborInfoList: args, + }) } -func parseAsPathSet(args []string) (*api.DefinedSet, error) { +func parseAsPathSet(args []string) (table.DefinedSet, error) { if len(args) < 1 { return nil, fmt.Errorf("empty as-path set name") } @@ -297,14 +200,13 @@ func parseAsPathSet(args []string) (*api.DefinedSet, error) { return nil, err } } - return &api.DefinedSet{ - Type: api.DefinedType_AS_PATH, - Name: name, - List: args, - }, nil + return table.NewAsPathSet(config.AsPathSet{ + AsPathSetName: name, + AsPathList: args, + }) } -func parseCommunitySet(args []string) (*api.DefinedSet, error) { +func parseCommunitySet(args []string) (table.DefinedSet, error) { if len(args) < 1 { return nil, fmt.Errorf("empty community set name") } @@ -315,14 +217,13 @@ func parseCommunitySet(args []string) (*api.DefinedSet, error) { return nil, err } } - return &api.DefinedSet{ - Type: api.DefinedType_COMMUNITY, - Name: name, - List: args, - }, nil + return table.NewCommunitySet(config.CommunitySet{ + CommunitySetName: name, + CommunityList: args, + }) } -func parseExtCommunitySet(args []string) (*api.DefinedSet, error) { +func parseExtCommunitySet(args []string) (table.DefinedSet, error) { if len(args) < 1 { return nil, fmt.Errorf("empty ext-community set name") } @@ -333,14 +234,13 @@ func parseExtCommunitySet(args []string) (*api.DefinedSet, error) { return nil, err } } - return &api.DefinedSet{ - Type: api.DefinedType_EXT_COMMUNITY, - Name: name, - List: args, - }, nil + return table.NewExtCommunitySet(config.ExtCommunitySet{ + ExtCommunitySetName: name, + ExtCommunityList: args, + }) } -func parseLargeCommunitySet(args []string) (*api.DefinedSet, error) { +func parseLargeCommunitySet(args []string) (table.DefinedSet, error) { if len(args) < 1 { return nil, fmt.Errorf("empty large-community set name") } @@ -351,14 +251,13 @@ func parseLargeCommunitySet(args []string) (*api.DefinedSet, error) { return nil, err } } - return &api.DefinedSet{ - Type: api.DefinedType_LARGE_COMMUNITY, - Name: name, - List: args, - }, nil + return table.NewLargeCommunitySet(config.LargeCommunitySet{ + LargeCommunitySetName: name, + LargeCommunityList: args, + }) } -func parseDefinedSet(settype string, args []string) (*api.DefinedSet, error) { +func parseDefinedSet(settype string, args []string) (table.DefinedSet, error) { switch settype { case CMD_PREFIX: return parsePrefixSet(args) @@ -387,7 +286,7 @@ var modPolicyUsageFormat = map[string]string{ } func modDefinedSet(settype string, modtype string, args []string) error { - var d *api.DefinedSet + var d table.DefinedSet var err error if len(args) < 1 { return fmt.Errorf(modPolicyUsageFormat[settype], modtype) @@ -397,137 +296,98 @@ func modDefinedSet(settype string, modtype string, args []string) error { } switch modtype { case CMD_ADD: - _, err = client.AddDefinedSet(context.Background(), &api.AddDefinedSetRequest{ - Set: d, - }) + err = client.AddDefinedSet(d) case CMD_DEL: all := false if len(args) < 2 { all = true } - _, err = client.DeleteDefinedSet(context.Background(), &api.DeleteDefinedSetRequest{ - Set: d, - All: all, - }) + err = client.DeleteDefinedSet(d, all) case CMD_SET: - _, err = client.ReplaceDefinedSet(context.Background(), &api.ReplaceDefinedSetRequest{ - Set: d, - }) + err = client.ReplaceDefinedSet(d) } return err } -func printStatement(indent int, s *api.Statement) { +func printStatement(indent int, s *table.Statement) { sIndent := func(indent int) string { return strings.Repeat(" ", indent) } fmt.Printf("%sStatementName %s:\n", sIndent(indent), s.Name) fmt.Printf("%sConditions:\n", sIndent(indent+2)) - ps := s.Conditions.PrefixSet - if ps != nil { - fmt.Printf("%sPrefixSet: %s %s\n", sIndent(indent+4), ps.Type, ps.Name) - } - - ns := s.Conditions.NeighborSet - if ns != nil { - fmt.Printf("%sNeighborSet: %s %s\n", sIndent(indent+4), ns.Type, ns.Name) - } - - aps := s.Conditions.AsPathSet - if aps != nil { - fmt.Printf("%sAsPathSet: %s %s\n", sIndent(indent+4), aps.Type, aps.Name) - } - - cs := s.Conditions.CommunitySet - if cs != nil { - fmt.Printf("%sCommunitySet: %s %s\n", sIndent(indent+4), cs.Type, cs.Name) - } - - ecs := s.Conditions.ExtCommunitySet - if ecs != nil { - fmt.Printf("%sExtCommunitySet: %s %s\n", sIndent(indent+4), ecs.Type, ecs.Name) - } - - lcs := s.Conditions.LargeCommunitySet - if lcs != nil { - fmt.Printf("%sLargeCommunitySet: %s %s\n", sIndent(indent+4), ecs.Type, ecs.Name) - } - - asPathLentgh := s.Conditions.AsPathLength - if asPathLentgh != nil { - fmt.Printf("%sAsPathLength: %s %d\n", sIndent(indent+4), asPathLentgh.Type, asPathLentgh.Length) - } - - rpki := s.Conditions.RpkiResult - if rpki > 0 { - fmt.Printf("%sRPKI result: %s\n", sIndent(indent+4), config.IntToRpkiValidationResultTypeMap[int(rpki)]) - } - - if routeType := s.Conditions.RouteType; routeType > 0 { - fmt.Printf("%sRoute Type: %s\n", sIndent(indent+4), config.IntToRouteTypeMap[int(routeType)]) + ind := sIndent(indent + 4) + + for _, c := range s.Conditions { + switch t := c.(type) { + case *table.PrefixCondition: + fmt.Printf("%sPrefixSet: %s %s\n", ind, t.Option(), t.Name()) + case *table.NeighborCondition: + fmt.Printf("%sNeighborSet: %s %s\n", ind, t.Option(), t.Name()) + case *table.AsPathCondition: + fmt.Printf("%sAsPathSet: %s %s\n", ind, t.Option(), t.Name()) + case *table.CommunityCondition: + fmt.Printf("%sCommunitySet: %s %s\n", ind, t.Option(), t.Name()) + case *table.ExtCommunityCondition: + fmt.Printf("%sExtCommunitySet: %s %s\n", ind, t.Option(), t.Name()) + case *table.LargeCommunityCondition: + fmt.Printf("%sLargeCommunitySet: %s %s\n", ind, t.Option(), t.Name()) + case *table.AsPathLengthCondition: + fmt.Printf("%sAsPathLength: %s %d\n", ind, t.String()) + case *table.RpkiValidationCondition: + fmt.Printf("%sRPKI result: %s\n", ind, t.String()) + case *table.RouteTypeCondition: + fmt.Printf("%sRoute Type: %s\n", ind, t.String()) + } } fmt.Printf("%sActions:\n", sIndent(indent+2)) - - formatComAction := func(c *api.CommunityAction) string { - option := c.Type.String() - if len(c.Communities) != 0 { - exp := regexp.MustCompile("[\\^\\$]") - communities := exp.ReplaceAllString(strings.Join(c.Communities, ","), "") - option = fmt.Sprintf("%s[%s]", c.Type, communities) + for _, a := range s.ModActions { + switch t := a.(type) { + case *table.RoutingAction: + action := "accept" + if !t.AcceptRoute { + action = "reject" + } + fmt.Println(ind, action) + case *table.CommunityAction: + fmt.Println(ind, "Community: ", t.String()) + case *table.ExtCommunityAction: + fmt.Println(ind, "ExtCommunity: ", t.String()) + case *table.LargeCommunityAction: + fmt.Println(ind, "LargeCommunity: ", t.String()) + case *table.MedAction: + fmt.Println(ind, "MED: ", t.String()) + case *table.LocalPrefAction: + fmt.Println(ind, "LocalPref: ", t.String()) + case *table.AsPathPrependAction: + fmt.Println(ind, "ASPathPrepend: ", t.String()) + case *table.NexthopAction: + fmt.Println(ind, "Nexthop: ", t.String()) } - return option - } - if s.Actions.Community != nil { - fmt.Printf("%sCommunity: %s\n", sIndent(indent+4), formatComAction(s.Actions.Community)) } - if s.Actions.ExtCommunity != nil { - fmt.Printf("%sExtCommunity: %s\n", sIndent(indent+4), formatComAction(s.Actions.ExtCommunity)) - } - if s.Actions.LargeCommunity != nil { - fmt.Printf("%sLargeCommunity: %s\n", sIndent(indent+4), formatComAction(s.Actions.LargeCommunity)) - } - if s.Actions.Med != nil { - fmt.Printf("%sMed: %d\n", sIndent(indent+4), s.Actions.Med.Value) - } - if s.Actions.LocalPref != nil { - fmt.Printf("%sLocalPref: %d\n", sIndent(indent+4), s.Actions.LocalPref.Value) - } - if s.Actions.AsPrepend != nil { - var asn string - if s.Actions.AsPrepend.UseLeftMost { - asn = "left-most" - } else { - asn = fmt.Sprintf("%d", s.Actions.AsPrepend.Asn) - } - fmt.Printf("%sAsPrepend: %s %d\n", sIndent(indent+4), asn, s.Actions.AsPrepend.Repeat) - } - if s.Actions.Nexthop != nil { - addr := s.Actions.Nexthop.Address - if s.Actions.Nexthop.Self { - addr = "SELF" - } - fmt.Printf("%sNexthop: %s\n", sIndent(indent+4), addr) + if s.RouteAction != nil && s.RouteAction.(*table.RoutingAction) != nil { + t := s.RouteAction.(*table.RoutingAction) + fmt.Println(ind, t.String()) } - fmt.Printf("%s%s\n", sIndent(indent+4), s.Actions.RouteAction) + } -func printPolicy(indent int, pd *api.Policy) { +func printPolicy(indent int, pd *table.Policy) { for _, s := range pd.Statements { printStatement(indent, s) } } func showPolicy(args []string) error { - rsp, err := client.GetPolicy(context.Background(), &api.GetPolicyRequest{}) + policies, err := client.GetPolicy() if err != nil { return err } - m := policies{} + var m table.Policies if len(args) > 0 { - for _, p := range rsp.Policies { + for _, p := range policies { if args[0] == p.Name { m = append(m, p) break @@ -537,7 +397,7 @@ func showPolicy(args []string) error { return fmt.Errorf("not found %s", args[0]) } } else { - m = rsp.Policies + m = policies } if globalOpts.Json { j, _ := json.Marshal(m) @@ -559,13 +419,13 @@ func showPolicy(args []string) error { } func showStatement(args []string) error { - rsp, err := client.GetStatement(context.Background(), &api.GetStatementRequest{}) + stmts, err := client.GetStatement() if err != nil { return err } - m := []*api.Statement{} + var m []*table.Statement if len(args) > 0 { - for _, s := range rsp.Statements { + for _, s := range stmts { if args[0] == s.Name { m = append(m, s) break @@ -575,7 +435,7 @@ func showStatement(args []string) error { return fmt.Errorf("not found %s", args[0]) } } else { - m = rsp.Statements + m = stmts } if globalOpts.Json { j, _ := json.Marshal(m) @@ -598,19 +458,15 @@ func modStatement(op string, args []string) error { if len(args) < 1 { return fmt.Errorf("usage: gobgp policy statement %s <name>", op) } - stmt := &api.Statement{ + stmt := &table.Statement{ Name: args[0], } var err error switch op { case CMD_ADD: - _, err = client.AddStatement(context.Background(), &api.AddStatementRequest{ - Statement: stmt, - }) + err = client.AddStatement(stmt) case CMD_DEL: - _, err = client.DeleteStatement(context.Background(), &api.DeleteStatementRequest{ - Statement: stmt, - }) + err = client.DeleteStatement(stmt, false) default: return fmt.Errorf("invalid operation: %s", op) } @@ -618,9 +474,8 @@ func modStatement(op string, args []string) error { } func modCondition(name, op string, args []string) error { - stmt := &api.Statement{ - Name: name, - Conditions: &api.Conditions{}, + stmt := config.Statement{ + Name: name, } usage := fmt.Sprintf("usage: gobgp policy statement %s %s condition", name, op) if len(args) < 1 { @@ -633,17 +488,15 @@ func modCondition(name, op string, args []string) error { if len(args) < 1 { return fmt.Errorf("%s prefix <set-name> [{ any | invert }]", usage) } - stmt.Conditions.PrefixSet = &api.MatchSet{ - Name: args[0], - } + stmt.Conditions.MatchPrefixSet.PrefixSet = args[0] if len(args) == 1 { break } switch strings.ToLower(args[1]) { case "any": - stmt.Conditions.PrefixSet.Type = api.MatchType_ANY + stmt.Conditions.MatchPrefixSet.MatchSetOptions = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY case "invert": - stmt.Conditions.PrefixSet.Type = api.MatchType_INVERT + stmt.Conditions.MatchPrefixSet.MatchSetOptions = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT default: return fmt.Errorf("%s prefix <set-name> [{ any | invert }]", usage) } @@ -651,17 +504,15 @@ func modCondition(name, op string, args []string) error { if len(args) < 1 { return fmt.Errorf("%s neighbor <set-name> [{ any | invert }]", usage) } - stmt.Conditions.NeighborSet = &api.MatchSet{ - Name: args[0], - } + stmt.Conditions.MatchNeighborSet.NeighborSet = args[0] if len(args) == 1 { break } switch strings.ToLower(args[1]) { case "any": - stmt.Conditions.NeighborSet.Type = api.MatchType_ANY + stmt.Conditions.MatchNeighborSet.MatchSetOptions = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY case "invert": - stmt.Conditions.NeighborSet.Type = api.MatchType_ANY + stmt.Conditions.MatchNeighborSet.MatchSetOptions = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT default: return fmt.Errorf("%s neighbor <set-name> [{ any | invert }]", usage) } @@ -669,19 +520,17 @@ func modCondition(name, op string, args []string) error { if len(args) < 1 { return fmt.Errorf("%s as-path <set-name> [{ any | all | invert }]", usage) } - stmt.Conditions.AsPathSet = &api.MatchSet{ - Name: args[0], - } + stmt.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = args[0] if len(args) == 1 { break } switch strings.ToLower(args[1]) { case "any": - stmt.Conditions.AsPathSet.Type = api.MatchType_ANY + stmt.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ANY case "all": - stmt.Conditions.AsPathSet.Type = api.MatchType_ALL + stmt.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ALL case "invert": - stmt.Conditions.AsPathSet.Type = api.MatchType_INVERT + stmt.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_INVERT default: return fmt.Errorf("%s as-path <set-name> [{ any | all | invert }]", usage) } @@ -689,19 +538,17 @@ func modCondition(name, op string, args []string) error { if len(args) < 1 { return fmt.Errorf("%s community <set-name> [{ any | all | invert }]", usage) } - stmt.Conditions.CommunitySet = &api.MatchSet{ - Name: args[0], - } + stmt.Conditions.BgpConditions.MatchCommunitySet.CommunitySet = args[0] if len(args) == 1 { break } switch strings.ToLower(args[1]) { case "any": - stmt.Conditions.CommunitySet.Type = api.MatchType_ANY + stmt.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ANY case "all": - stmt.Conditions.CommunitySet.Type = api.MatchType_ALL + stmt.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ALL case "invert": - stmt.Conditions.CommunitySet.Type = api.MatchType_INVERT + stmt.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_INVERT default: return fmt.Errorf("%s community <set-name> [{ any | all | invert }]", usage) } @@ -709,19 +556,17 @@ func modCondition(name, op string, args []string) error { if len(args) < 1 { return fmt.Errorf("%s ext-community <set-name> [{ any | all | invert }]", usage) } - stmt.Conditions.ExtCommunitySet = &api.MatchSet{ - Name: args[0], - } + stmt.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet = args[0] if len(args) == 1 { break } switch strings.ToLower(args[1]) { case "any": - stmt.Conditions.ExtCommunitySet.Type = api.MatchType_ANY + stmt.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ANY case "all": - stmt.Conditions.ExtCommunitySet.Type = api.MatchType_ALL + stmt.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ALL case "invert": - stmt.Conditions.ExtCommunitySet.Type = api.MatchType_INVERT + stmt.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_INVERT default: return fmt.Errorf("%s ext-community <set-name> [{ any | all | invert }]", usage) } @@ -729,19 +574,17 @@ func modCondition(name, op string, args []string) error { if len(args) < 1 { return fmt.Errorf("%s large-community <set-name> [{ any | all | invert }]", usage) } - stmt.Conditions.LargeCommunitySet = &api.MatchSet{ - Name: args[0], - } + stmt.Conditions.BgpConditions.MatchLargeCommunitySet.LargeCommunitySet = args[0] if len(args) == 1 { break } switch strings.ToLower(args[1]) { case "any": - stmt.Conditions.LargeCommunitySet.Type = api.MatchType_ANY + stmt.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ANY case "all": - stmt.Conditions.LargeCommunitySet.Type = api.MatchType_ALL + stmt.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_ALL case "invert": - stmt.Conditions.LargeCommunitySet.Type = api.MatchType_INVERT + stmt.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions = config.MATCH_SET_OPTIONS_TYPE_INVERT default: return fmt.Errorf("%s large-community <set-name> [{ any | all | invert }]", usage) } @@ -753,16 +596,14 @@ func modCondition(name, op string, args []string) error { if err != nil { return err } - stmt.Conditions.AsPathLength = &api.AsPathLength{ - Length: uint32(length), - } + stmt.Conditions.BgpConditions.AsPathLength.Value = uint32(length) switch strings.ToLower(args[1]) { case "eq": - stmt.Conditions.AsPathLength.Type = api.AsPathLengthType_EQ + stmt.Conditions.BgpConditions.AsPathLength.Operator = config.ATTRIBUTE_COMPARISON_EQ case "ge": - stmt.Conditions.AsPathLength.Type = api.AsPathLengthType_GE + stmt.Conditions.BgpConditions.AsPathLength.Operator = config.ATTRIBUTE_COMPARISON_GE case "le": - stmt.Conditions.AsPathLength.Type = api.AsPathLengthType_LE + stmt.Conditions.BgpConditions.AsPathLength.Operator = config.ATTRIBUTE_COMPARISON_LE default: return fmt.Errorf("%s as-path-length <length> { eq | ge | le }", usage) } @@ -772,11 +613,11 @@ func modCondition(name, op string, args []string) error { } switch strings.ToLower(args[0]) { case "valid": - stmt.Conditions.RpkiResult = int32(config.RPKI_VALIDATION_RESULT_TYPE_VALID.ToInt()) + stmt.Conditions.BgpConditions.RpkiValidationResult = config.RPKI_VALIDATION_RESULT_TYPE_VALID case "invalid": - stmt.Conditions.RpkiResult = int32(config.RPKI_VALIDATION_RESULT_TYPE_INVALID.ToInt()) + stmt.Conditions.BgpConditions.RpkiValidationResult = config.RPKI_VALIDATION_RESULT_TYPE_INVALID case "not-found": - stmt.Conditions.RpkiResult = int32(config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND.ToInt()) + stmt.Conditions.BgpConditions.RpkiValidationResult = config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND default: return fmt.Errorf("%s rpki { valid | invalid | not-found }", usage) } @@ -787,31 +628,29 @@ func modCondition(name, op string, args []string) error { } switch strings.ToLower(args[0]) { case "internal": - stmt.Conditions.RouteType = api.Conditions_ROUTE_TYPE_INTERNAL + stmt.Conditions.BgpConditions.RouteType = config.ROUTE_TYPE_INTERNAL case "external": - stmt.Conditions.RouteType = api.Conditions_ROUTE_TYPE_EXTERNAL + stmt.Conditions.BgpConditions.RouteType = config.ROUTE_TYPE_EXTERNAL case "local": - stmt.Conditions.RouteType = api.Conditions_ROUTE_TYPE_LOCAL + stmt.Conditions.BgpConditions.RouteType = config.ROUTE_TYPE_LOCAL default: return err } default: return fmt.Errorf("%s { prefix | neighbor | as-path | community | ext-community | large-community | as-path-length | rpki | route-type }", usage) } - var err error + + t, err := table.NewStatement(stmt) + if err != nil { + return err + } switch op { case CMD_ADD: - _, err = client.AddStatement(context.Background(), &api.AddStatementRequest{ - Statement: stmt, - }) + err = client.AddStatement(t) case CMD_DEL: - _, err = client.DeleteStatement(context.Background(), &api.DeleteStatementRequest{ - Statement: stmt, - }) + err = client.DeleteStatement(t, false) case CMD_SET: - _, err = client.ReplaceStatement(context.Background(), &api.ReplaceStatementRequest{ - Statement: stmt, - }) + err = client.ReplaceStatement(t) default: return fmt.Errorf("invalid operation: %s", op) } @@ -819,9 +658,8 @@ func modCondition(name, op string, args []string) error { } func modAction(name, op string, args []string) error { - stmt := &api.Statement{ - Name: name, - Actions: &api.Actions{}, + stmt := config.Statement{ + Name: name, } usage := fmt.Sprintf("usage: gobgp policy statement %s %s action", name, op) if len(args) < 1 { @@ -831,23 +669,21 @@ func modAction(name, op string, args []string) error { args = args[1:] switch typ { case "reject": - stmt.Actions.RouteAction = api.RouteAction_REJECT + stmt.Actions.RouteDisposition = config.RouteDisposition{RejectRoute: true} case "accept": - stmt.Actions.RouteAction = api.RouteAction_ACCEPT + stmt.Actions.RouteDisposition = config.RouteDisposition{AcceptRoute: true} case "community": if len(args) < 1 { return fmt.Errorf("%s community { add | remove | replace } <value>...", usage) } - stmt.Actions.Community = &api.CommunityAction{ - Communities: args[1:], - } + stmt.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList = args[1:] switch strings.ToLower(args[0]) { case "add": - stmt.Actions.Community.Type = api.CommunityActionType_COMMUNITY_ADD + stmt.Actions.BgpActions.SetCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD) case "remove": - stmt.Actions.Community.Type = api.CommunityActionType_COMMUNITY_REMOVE + stmt.Actions.BgpActions.SetCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE) case "replace": - stmt.Actions.Community.Type = api.CommunityActionType_COMMUNITY_REPLACE + stmt.Actions.BgpActions.SetCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE) default: return fmt.Errorf("%s community { add | remove | replace } <value>...", usage) } @@ -855,16 +691,14 @@ func modAction(name, op string, args []string) error { if len(args) < 1 { return fmt.Errorf("%s ext-community { add | remove | replace } <value>...", usage) } - stmt.Actions.ExtCommunity = &api.CommunityAction{ - Communities: args[1:], - } + stmt.Actions.BgpActions.SetExtCommunity.SetExtCommunityMethod.CommunitiesList = args[1:] switch strings.ToLower(args[0]) { case "add": - stmt.Actions.ExtCommunity.Type = api.CommunityActionType_COMMUNITY_ADD + stmt.Actions.BgpActions.SetExtCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD) case "remove": - stmt.Actions.ExtCommunity.Type = api.CommunityActionType_COMMUNITY_REMOVE + stmt.Actions.BgpActions.SetExtCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE) case "replace": - stmt.Actions.ExtCommunity.Type = api.CommunityActionType_COMMUNITY_REPLACE + stmt.Actions.BgpActions.SetExtCommunity.Options = string(config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE) default: return fmt.Errorf("%s ext-community { add | remove | replace } <value>...", usage) } @@ -872,16 +706,14 @@ func modAction(name, op string, args []string) error { if len(args) < 1 { return fmt.Errorf("%s large-community { add | remove | replace } <value>...", usage) } - stmt.Actions.LargeCommunity = &api.CommunityAction{ - Communities: args[1:], - } + stmt.Actions.BgpActions.SetLargeCommunity.SetLargeCommunityMethod.CommunitiesList = args[1:] switch strings.ToLower(args[0]) { case "add": - stmt.Actions.LargeCommunity.Type = api.CommunityActionType_COMMUNITY_ADD + stmt.Actions.BgpActions.SetLargeCommunity.Options = config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD case "remove": - stmt.Actions.LargeCommunity.Type = api.CommunityActionType_COMMUNITY_REMOVE + stmt.Actions.BgpActions.SetLargeCommunity.Options = config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE case "replace": - stmt.Actions.LargeCommunity.Type = api.CommunityActionType_COMMUNITY_REPLACE + stmt.Actions.BgpActions.SetLargeCommunity.Options = config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE default: return fmt.Errorf("%s large-community { add | remove | replace } <value>...", usage) } @@ -893,17 +725,13 @@ func modAction(name, op string, args []string) error { if err != nil { return err } - stmt.Actions.Med = &api.MedAction{ - Value: int64(med), - } switch strings.ToLower(args[0]) { case "add": - stmt.Actions.Med.Type = api.MedActionType_MED_MOD + stmt.Actions.BgpActions.SetMed = config.BgpSetMedType(fmt.Sprintf("+%d", med)) case "sub": - stmt.Actions.Med.Type = api.MedActionType_MED_MOD - stmt.Actions.Med.Value *= -1 + stmt.Actions.BgpActions.SetMed = config.BgpSetMedType(fmt.Sprintf("-%d", med)) case "set": - stmt.Actions.Med.Type = api.MedActionType_MED_REPLACE + stmt.Actions.BgpActions.SetMed = config.BgpSetMedType(fmt.Sprintf("%d", med)) default: return fmt.Errorf("%s med { add | sub | set } <value>") } @@ -915,60 +743,31 @@ func modAction(name, op string, args []string) error { if err != nil { return err } - stmt.Actions.LocalPref = &api.LocalPrefAction{ - Value: uint32(value), - } + stmt.Actions.BgpActions.SetLocalPref = uint32(value) case "as-prepend": if len(args) < 2 { return fmt.Errorf("%s as-prepend { <asn> | last-as } <repeat-value>", usage) } - asn, err := strconv.Atoi(args[0]) - last := false - if args[0] == "last-as" { - last = true - } else if err != nil { - return err - } + stmt.Actions.BgpActions.SetAsPathPrepend.As = args[0] repeat, err := strconv.Atoi(args[1]) if err != nil { return err } - stmt.Actions.AsPrepend = &api.AsPrependAction{ - Asn: uint32(asn), - Repeat: uint32(repeat), - UseLeftMost: last, - } + stmt.Actions.BgpActions.SetAsPathPrepend.RepeatN = uint8(repeat) case "next-hop": if len(args) != 1 { return fmt.Errorf("%s next-hop { <value> | self }", usage) } - if strings.ToLower(args[0]) == "self" { - stmt.Actions.Nexthop = &api.NexthopAction{ - Self: true, - } - } else { - if net.ParseIP(args[0]) == nil { - return fmt.Errorf("invalid next-hop format: %s", args[0]) - } - stmt.Actions.Nexthop = &api.NexthopAction{ - Address: args[0], - } - } + stmt.Actions.BgpActions.SetNextHop = config.BgpNextHopType(args[0]) } - var err error + t, err := table.NewStatement(stmt) switch op { case CMD_ADD: - _, err = client.AddStatement(context.Background(), &api.AddStatementRequest{ - Statement: stmt, - }) + err = client.AddStatement(t) case CMD_DEL: - _, err = client.DeleteStatement(context.Background(), &api.DeleteStatementRequest{ - Statement: stmt, - }) + err = client.DeleteStatement(t, false) case CMD_SET: - _, err = client.ReplaceStatement(context.Background(), &api.ReplaceStatementRequest{ - Statement: stmt, - }) + err = client.ReplaceStatement(t) default: return fmt.Errorf("invalid operation: %s", op) } @@ -981,42 +780,28 @@ func modPolicy(modtype string, args []string) error { } name := args[0] args = args[1:] - stmts := make([]*api.Statement, 0, len(args)) + stmts := make([]config.Statement, 0, len(args)) for _, n := range args { - stmts = append(stmts, &api.Statement{Name: n}) + stmts = append(stmts, config.Statement{Name: n}) + } + policy, err := table.NewPolicy(config.PolicyDefinition{ + Name: name, + Statements: stmts, + }) + if err != nil { + return err } - var err error switch modtype { case CMD_ADD: - _, err = client.AddPolicy(context.Background(), &api.AddPolicyRequest{ - Policy: &api.Policy{ - Name: name, - Statements: stmts, - }, - ReferExistingStatements: true, - }) + err = client.AddPolicy(policy, true) case CMD_DEL: all := false if len(args) < 1 { all = true } - _, err = client.DeletePolicy(context.Background(), &api.DeletePolicyRequest{ - Policy: &api.Policy{ - Name: name, - Statements: stmts, - }, - All: all, - PreserveStatements: true, - }) + err = client.DeletePolicy(policy, all, true) case CMD_SET: - _, err = client.ReplacePolicy(context.Background(), &api.ReplacePolicyRequest{ - Policy: &api.Policy{ - Name: name, - Statements: stmts, - }, - ReferExistingStatements: true, - PreserveStatements: true, - }) + err = client.ReplacePolicy(policy, true, true) } return err } diff --git a/gobgp/cmd/root.go b/gobgp/cmd/root.go index 8e0bed40..f676af44 100644 --- a/gobgp/cmd/root.go +++ b/gobgp/cmd/root.go @@ -17,7 +17,7 @@ package cmd import ( "fmt" - api "github.com/osrg/gobgp/api" + cli "github.com/osrg/gobgp/client" "github.com/spf13/cobra" "net/http" _ "net/http/pprof" @@ -35,7 +35,7 @@ var globalOpts struct { } var cmds []string -var client api.GobgpApiClient +var client *cli.GoBGPClient func NewRootCmd() *cobra.Command { cobra.EnablePrefixMatching = true @@ -51,8 +51,7 @@ func NewRootCmd() *cobra.Command { } if !globalOpts.GenCmpl { - conn := connGrpc() - client = api.NewGobgpApiClient(conn) + client = newClient() } }, Run: func(cmd *cobra.Command, args []string) { @@ -62,6 +61,11 @@ func NewRootCmd() *cobra.Command { cmd.HelpFunc()(cmd, args) } }, + PersistentPostRun: func(cmd *cobra.Command, args []string) { + if client != nil { + client.Close() + } + }, } rootCmd.PersistentFlags().StringVarP(&globalOpts.Host, "host", "u", "127.0.0.1", "host") diff --git a/gobgp/cmd/rpki.go b/gobgp/cmd/rpki.go index 11c75b6a..567c4b1b 100644 --- a/gobgp/cmd/rpki.go +++ b/gobgp/cmd/rpki.go @@ -17,16 +17,15 @@ package cmd import ( "fmt" - api "github.com/osrg/gobgp/api" - "github.com/osrg/gobgp/packet/bgp" - "github.com/spf13/cobra" - "golang.org/x/net/context" "net" "time" + + "github.com/osrg/gobgp/packet/bgp" + "github.com/spf13/cobra" ) func showRPKIServer(args []string) error { - rsp, err := client.GetRpki(context.Background(), &api.GetRpkiRequest{}) + servers, err := client.GetRPKI() if err != nil { fmt.Println(err) return err @@ -34,7 +33,7 @@ func showRPKIServer(args []string) error { if len(args) == 0 { format := "%-23s %-6s %-10s %s\n" fmt.Printf(format, "Session", "State", "Uptime", "#IPv4/IPv6 records") - for _, r := range rsp.Servers { + for _, r := range servers { s := "Down" uptime := "never" if r.State.Up == true { @@ -42,30 +41,30 @@ func showRPKIServer(args []string) error { uptime = fmt.Sprint(formatTimedelta(int64(time.Now().Sub(time.Unix(r.State.Uptime, 0)).Seconds()))) } - fmt.Printf(format, net.JoinHostPort(r.Conf.Address, r.Conf.RemotePort), s, uptime, fmt.Sprintf("%d/%d", r.State.RecordIpv4, r.State.RecordIpv6)) + fmt.Printf(format, net.JoinHostPort(r.Config.Address, fmt.Sprintf("%d", r.Config.Port)), s, uptime, fmt.Sprintf("%d/%d", r.State.RecordsV4, r.State.RecordsV6)) } } else { - for _, r := range rsp.Servers { - if r.Conf.Address == args[0] { + for _, r := range servers { + if r.Config.Address == args[0] { up := "Down" if r.State.Up == true { up = "Up" } - fmt.Printf("Session: %s, State: %s\n", r.Conf.Address, up) - fmt.Println(" Port:", r.Conf.RemotePort) - fmt.Println(" Serial:", r.State.Serial) - fmt.Printf(" Prefix: %d/%d\n", r.State.PrefixIpv4, r.State.PrefixIpv6) - fmt.Printf(" Record: %d/%d\n", r.State.RecordIpv4, r.State.RecordIpv6) + fmt.Printf("Session: %s, State: %s\n", r.Config.Address, up) + fmt.Println(" Port:", r.Config.Port) + fmt.Println(" Serial:", r.State.SerialNumber) + fmt.Printf(" Prefix: %d/%d\n", r.State.PrefixesV4, r.State.PrefixesV6) + fmt.Printf(" Record: %d/%d\n", r.State.RecordsV4, r.State.RecordsV6) fmt.Println(" Message statistics:") - fmt.Printf(" Receivedv4: %10d\n", r.State.ReceivedIpv4) - fmt.Printf(" Receivedv6: %10d\n", r.State.ReceivedIpv6) - fmt.Printf(" SerialNotify: %10d\n", r.State.SerialNotify) - fmt.Printf(" CacheReset: %10d\n", r.State.CacheReset) - fmt.Printf(" CacheResponse: %10d\n", r.State.CacheResponse) - fmt.Printf(" EndOfData: %10d\n", r.State.EndOfData) - fmt.Printf(" Error: %10d\n", r.State.Error) - fmt.Printf(" SerialQuery: %10d\n", r.State.SerialQuery) - fmt.Printf(" ResetQuery: %10d\n", r.State.ResetQuery) + fmt.Printf(" Receivedv4: %10d\n", r.State.RpkiMessages.RpkiReceived.Ipv4Prefix) + fmt.Printf(" Receivedv6: %10d\n", r.State.RpkiMessages.RpkiReceived.Ipv4Prefix) + fmt.Printf(" SerialNotify: %10d\n", r.State.RpkiMessages.RpkiReceived.SerialNotify) + fmt.Printf(" CacheReset: %10d\n", r.State.RpkiMessages.RpkiReceived.CacheReset) + fmt.Printf(" CacheResponse: %10d\n", r.State.RpkiMessages.RpkiReceived.CacheResponse) + fmt.Printf(" EndOfData: %10d\n", r.State.RpkiMessages.RpkiReceived.EndOfData) + fmt.Printf(" Error: %10d\n", r.State.RpkiMessages.RpkiReceived.Error) + fmt.Printf(" SerialQuery: %10d\n", r.State.RpkiMessages.RpkiSent.SerialQuery) + fmt.Printf(" ResetQuery: %10d\n", r.State.RpkiMessages.RpkiSent.ResetQuery) } } } @@ -77,13 +76,9 @@ func showRPKITable(args []string) error { if err != nil { exitWithError(err) } - arg := &api.GetRoaRequest{ - Family: uint32(family), - } - rsp, err := client.GetRoa(context.Background(), arg) + roas, err := client.GetROA(family) if err != nil { - fmt.Println(err) - return err + exitWithError(err) } var format string @@ -94,13 +89,12 @@ func showRPKITable(args []string) error { format = "%-42s %-6s %-10s %s\n" } fmt.Printf(format, "Network", "Maxlen", "AS", "Server") - for _, r := range rsp.Roas { - if len(args) > 0 && args[0] != r.Conf.Address { + for _, r := range roas { + host, _, _ := net.SplitHostPort(r.Src) + if len(args) > 0 && args[0] != host { continue } - - server := net.JoinHostPort(r.Conf.Address, r.Conf.RemotePort) - fmt.Printf(format, fmt.Sprintf("%s/%d", r.Prefix, r.Prefixlen), fmt.Sprint(r.Maxlen), fmt.Sprint(r.As), server) + fmt.Printf(format, r.Prefix.String(), fmt.Sprint(r.MaxLen), fmt.Sprint(r.AS), r.Src) } return nil } @@ -126,26 +120,15 @@ func NewRPKICmd() *cobra.Command { var err error switch args[1] { case "add": - _, err = client.AddRpki(context.Background(), &api.AddRpkiRequest{ - Address: addr.String(), - Port: 323, - }) + err = client.AddRPKIServer(addr.String(), 323, 0) case "reset": - _, err = client.ResetRpki(context.Background(), &api.ResetRpkiRequest{ - Address: addr.String(), - }) + err = client.ResetRPKIServer(addr.String()) case "softreset": - _, err = client.SoftResetRpki(context.Background(), &api.SoftResetRpkiRequest{ - Address: addr.String(), - }) + err = client.SoftResetRPKIServer(addr.String()) case "enable": - _, err = client.EnableRpki(context.Background(), &api.EnableRpkiRequest{ - Address: addr.String(), - }) + err = client.EnableRPKIServer(addr.String()) case "disable": - _, err = client.DisableRpki(context.Background(), &api.DisableRpkiRequest{ - Address: addr.String(), - }) + err = client.DisableRPKIServer(addr.String()) default: exitWithError(fmt.Errorf("unknown operation: %s", args[1])) } @@ -167,11 +150,9 @@ func NewRPKICmd() *cobra.Command { validateCmd := &cobra.Command{ Use: "validate", Run: func(cmd *cobra.Command, args []string) { - arg := &api.ValidateRibRequest{} - if len(args) == 1 { - arg.Prefix = args[0] + if err := client.ValidateRIBWithRPKI(args...); err != nil { + exitWithError(err) } - client.ValidateRib(context.Background(), arg) }, } rpkiCmd.AddCommand(validateCmd) diff --git a/gobgp/cmd/vrf.go b/gobgp/cmd/vrf.go index 26683d16..52a05f0c 100644 --- a/gobgp/cmd/vrf.go +++ b/gobgp/cmd/vrf.go @@ -18,22 +18,20 @@ package cmd import ( "encoding/json" "fmt" - api "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/packet/bgp" "github.com/spf13/cobra" - "golang.org/x/net/context" "sort" "strconv" "strings" ) func getVrfs() (vrfs, error) { - rsp, err := client.GetVrf(context.Background(), &api.GetVrfRequest{}) + ret, err := client.GetVRF() if err != nil { return nil, err } - sort.Sort(vrfs(rsp.Vrfs)) - return rsp.Vrfs, nil + sort.Sort(vrfs(ret)) + return ret, nil } func showVrfs() error { @@ -56,16 +54,12 @@ func showVrfs() error { lines := make([][]string, 0, len(vrfs)) for _, v := range vrfs { name := v.Name - rd := bgp.GetRouteDistinguisher(v.Rd).String() + rd := v.Rd.String() - f := func(bufs [][]byte) (string, error) { - ret := make([]string, 0, len(bufs)) - for _, rt := range bufs { - r, err := bgp.ParseExtended(rt) - if err != nil { - return "", err - } - ret = append(ret, r.String()) + f := func(rts []bgp.ExtendedCommunityInterface) (string, error) { + ret := make([]string, 0, len(rts)) + for _, rt := range rts { + ret = append(ret, rt.String()) } return strings.Join(ret, ", "), nil } @@ -107,8 +101,8 @@ func modVrf(typ string, args []string) error { return err } cur := "" - importRt := make([][]byte, 0) - exportRt := make([][]byte, 0) + importRt := make([]bgp.ExtendedCommunityInterface, 0) + exportRt := make([]bgp.ExtendedCommunityInterface, 0) for _, elem := range a["rt"] { if elem == "import" || elem == "export" || elem == "both" { cur = elem @@ -118,18 +112,14 @@ func modVrf(typ string, args []string) error { if err != nil { return err } - buf, err := rt.Serialize() - if err != nil { - return err - } switch cur { case "import": - importRt = append(importRt, buf) + importRt = append(importRt, rt) case "export": - exportRt = append(exportRt, buf) + exportRt = append(exportRt, rt) case "both": - importRt = append(importRt, buf) - exportRt = append(exportRt, buf) + importRt = append(importRt, rt) + exportRt = append(exportRt, rt) default: return fmt.Errorf("Usage: gobgp vrf add <vrf name> rd <rd> rt { import | export | both } <rt>...") } @@ -141,27 +131,12 @@ func modVrf(typ string, args []string) error { return err } } - buf, _ := rd.Serialize() - arg := &api.AddVrfRequest{ - Vrf: &api.Vrf{ - Name: name, - Rd: buf, - Id: uint32(vrfId), - ImportRt: importRt, - ExportRt: exportRt, - }, - } - _, err = client.AddVrf(context.Background(), arg) + err = client.AddVRF(name, vrfId, rd, importRt, exportRt) case CMD_DEL: if len(args) != 1 { return fmt.Errorf("Usage: gobgp vrf del <vrf name>") } - arg := &api.DeleteVrfRequest{ - Vrf: &api.Vrf{ - Name: args[0], - }, - } - _, err = client.DeleteVrf(context.Background(), arg) + err = client.DeleteVRF(args[0]) } return err } @@ -187,7 +162,7 @@ func NewVrfCmd() *cobra.Command { cmd := &cobra.Command{ Use: v, Run: func(cmd *cobra.Command, args []string) { - err := modPath(api.Resource_VRF, args[len(args)-1], cmd.Use, args[:len(args)-1]) + err := modPath(CMD_VRF, args[len(args)-1], cmd.Use, args[:len(args)-1]) if err != nil { exitWithError(err) } diff --git a/gobgp/lib/path.go b/gobgp/lib/path.go index 3fef6e42..67cf8b06 100644 --- a/gobgp/lib/path.go +++ b/gobgp/lib/path.go @@ -36,6 +36,7 @@ import ( "encoding/json" "strings" + api "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/gobgp/cmd" "github.com/osrg/gobgp/packet/bgp" ) @@ -52,11 +53,12 @@ func get_route_family(input *C.char) C.int { //export serialize_path func serialize_path(rf C.int, input *C.char) *C.path { args := strings.Split(C.GoString(input), " ") - p, err := cmd.ParsePath(bgp.RouteFamily(rf), args) + pp, err := cmd.ParsePath(bgp.RouteFamily(rf), args) if err != nil { return nil } path := C.new_path() + p := api.ToPathApi(pp) if len(p.Nlri) > 0 { path.nlri.len = C.int(len(p.Nlri)) path.nlri.value = C.CString(string(p.Nlri)) diff --git a/server/rpki.go b/server/rpki.go index df105a65..cbef5dee 100644 --- a/server/rpki.go +++ b/server/rpki.go @@ -42,6 +42,10 @@ type ipPrefix struct { Length uint8 } +func (p *ipPrefix) String() string { + return fmt.Sprintf("%s/%d", p.Prefix, p.Length) +} + type roaBucket struct { Prefix *ipPrefix entries []*ROA diff --git a/test/lib/gobgp.py b/test/lib/gobgp.py index 9d2b4237..8c0d9cdd 100644 --- a/test/lib/gobgp.py +++ b/test/lib/gobgp.py @@ -211,7 +211,7 @@ class GoBGPContainer(BGPContainer): return json.loads(self.local(cmd, capture=True)) def get_neighbor_state(self, peer): - return self.get_neighbor(peer)['info']['bgp_state'] + return self.get_neighbor(peer)['state']['session-state'] def clear_policy(self): self.policies = {} diff --git a/test/scenario_test/route_server_softreset_test.py b/test/scenario_test/route_server_softreset_test.py index 6bd91c03..05e39ba2 100644 --- a/test/scenario_test/route_server_softreset_test.py +++ b/test/scenario_test/route_server_softreset_test.py @@ -91,7 +91,7 @@ class GoBGPTestBase(unittest.TestCase): time.sleep(1) - num = g2.get_neighbor(g1)['info']['messages']['received']['UPDATE'] + num = g2.get_neighbor(g1)['state']['messages']['received']['update'] ps0 = {'prefix-set-name': 'ps0', 'prefix-list': [p1]} g1.set_prefix_set(ps0) @@ -101,14 +101,14 @@ class GoBGPTestBase(unittest.TestCase): time.sleep(1) - num2 = g2.get_neighbor(g1)['info']['messages']['received']['UPDATE'] + num2 = g2.get_neighbor(g1)['state']['messages']['received']['update'] self.assertTrue(num+1 == num2) g3.softreset(g1, type='out') time.sleep(1) - num3 = g2.get_neighbor(g1)['info']['messages']['received']['UPDATE'] + num3 = g2.get_neighbor(g1)['state']['messages']['received']['update'] self.assertTrue(num2 == num3) def test_03_softresetin_test2(self): @@ -118,13 +118,13 @@ class GoBGPTestBase(unittest.TestCase): g2.add_route('10.0.10.0/24') time.sleep(1) - num = g2.get_neighbor(g1)['info']['messages']['received']['UPDATE'] + num = g2.get_neighbor(g1)['state']['messages']['received']['update'] time.sleep(3) g1.local('gobgp n all softresetin') time.sleep(3) - num1 = g2.get_neighbor(g1)['info']['messages']['received']['UPDATE'] + num1 = g2.get_neighbor(g1)['state']['messages']['received']['update'] self.assertTrue(num == num1) diff --git a/test/scenario_test/route_server_test2.py b/test/scenario_test/route_server_test2.py index 477d81ea..124d8916 100644 --- a/test/scenario_test/route_server_test2.py +++ b/test/scenario_test/route_server_test2.py @@ -85,7 +85,7 @@ class GoBGPTestBase(unittest.TestCase): def test_04_withdraw_path(self): self.clients['g2'].local('gobgp global rib del 10.0.0.0/24') time.sleep(1) - info = self.gobgp.get_neighbor(self.clients['g2'])['info'] + info = self.gobgp.get_neighbor(self.clients['g2'])['state']['adj-table'] self.assertTrue(info['advertised'] == 1) self.assertTrue('accepted' not in info) # means info['accepted'] == 0 self.assertTrue('received' not in info) # means info['received'] == 0 |