func NewRootCmd() *cobra.Command { cobra.EnablePrefixMatching = true rootCmd := &cobra.Command{ Use: "gobgp", PersistentPreRun: func(cmd *cobra.Command, args []string) { if !globalOpts.GenCmpl { conn := connGrpc() client = api.NewGrpcClient(conn) } }, Run: func(cmd *cobra.Command, args []string) { cmd.GenBashCompletionFile(globalOpts.BashCmplFile) }, } rootCmd.PersistentFlags().StringVarP(&globalOpts.Host, "host", "u", "127.0.0.1", "host") rootCmd.PersistentFlags().IntVarP(&globalOpts.Port, "port", "p", 8080, "port") rootCmd.PersistentFlags().BoolVarP(&globalOpts.Json, "json", "j", false, "use json format to output format") rootCmd.PersistentFlags().BoolVarP(&globalOpts.Debug, "debug", "d", false, "use debug") rootCmd.PersistentFlags().BoolVarP(&globalOpts.Quiet, "quiet", "q", false, "use quiet") rootCmd.PersistentFlags().BoolVarP(&globalOpts.GenCmpl, "gen-cmpl", "c", false, "generate completion file") rootCmd.PersistentFlags().StringVarP(&globalOpts.BashCmplFile, "bash-cmpl-file", "", "gobgp_completion.bash", "bash cmpl filename") globalCmd := NewGlobalCmd() neighborCmd := NewNeighborCmd() vrfCmd := NewVrfCmd() policyCmd := NewPolicyCmd() monitorCmd := NewMonitorCmd() mrtCmd := NewMrtCmd() rpkiCmd := NewRPKICmd() rootCmd.AddCommand(globalCmd, neighborCmd, vrfCmd, policyCmd, monitorCmd, mrtCmd, rpkiCmd) return rootCmd }
func main() { rootCmd := &cobra.Command{ Use: "gomrt", PersistentPreRun: func(cmd *cobra.Command, args []string) { conn := connGrpc() client = api.NewGrpcClient(conn) }, Run: func(cmd *cobra.Command, args []string) { file, err := os.Open(globalOpts.Input) if err != nil { fmt.Println("failed to open file") os.Exit(1) } idx := 0 ch := make(chan *api.Path, 1024) go func() { for { buf := make([]byte, bgp.MRT_COMMON_HEADER_LEN) _, err := file.Read(buf) if err == io.EOF { break } else if err != nil { fmt.Println("failed to read:", err) os.Exit(1) } h := &bgp.MRTHeader{} err = h.DecodeFromBytes(buf) if err != nil { fmt.Println("failed to parse") os.Exit(1) } buf = make([]byte, h.Len) _, err = file.Read(buf) if err != nil { fmt.Println("failed to read") os.Exit(1) } msg, err := bgp.ParseMRTBody(h, buf) if err != nil { fmt.Println("failed to parse:", err) os.Exit(1) } if msg.Header.Type == bgp.TABLE_DUMPv2 { subType := bgp.MRTSubTypeTableDumpv2(msg.Header.SubType) var af *api.AddressFamily switch subType { case bgp.PEER_INDEX_TABLE: continue case bgp.RIB_IPV4_UNICAST: af = api.AF_IPV4_UC case bgp.RIB_IPV6_UNICAST: af = api.AF_IPV6_UC default: fmt.Println("unsupported subType:", subType) os.Exit(1) } rib := msg.Body.(*bgp.Rib) prefix := rib.Prefix.String() path := &api.Path{} path.Nlri = &api.Nlri{ Af: af, Prefix: prefix, } ch <- path } idx += 1 if idx == globalOpts.Count { break } } close(ch) }() stream, err := client.ModPath(context.Background()) if err != nil { fmt.Println("failed to modpath:", err) os.Exit(1) } for path := range ch { arg := &api.ModPathArguments{ Resource: api.Resource_GLOBAL, Path: path, } err = stream.Send(arg) if err != nil { fmt.Println("failed to send:", err) os.Exit(1) } } res, err := stream.CloseAndRecv() if err != nil { fmt.Println("failed to send:", err) os.Exit(1) } if res.Code != api.Error_SUCCESS { fmt.Errorf("error: code: %d, msg: %s", res.Code, res.Msg) os.Exit(1) } }, } rootCmd.PersistentFlags().StringVarP(&globalOpts.Host, "host", "u", "127.0.0.1", "host") rootCmd.PersistentFlags().IntVarP(&globalOpts.Port, "port", "p", 8080, "port") rootCmd.Flags().StringVarP(&globalOpts.Input, "input", "i", "", "input mrt file") rootCmd.Flags().IntVarP(&globalOpts.Count, "count", "c", -1, "how many mrt record you read") rootCmd.Execute() }