github.com/osrg/gobgp@v2.0.0+incompatible/cmd/gobgp/rpki.go (about)

     1  // Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package main
    17  
    18  import (
    19  	"fmt"
    20  	"io"
    21  	"net"
    22  	"strconv"
    23  
    24  	"github.com/golang/protobuf/ptypes"
    25  	api "github.com/osrg/gobgp/api"
    26  	"github.com/spf13/cobra"
    27  )
    28  
    29  func showRPKIServer(args []string) error {
    30  	servers := make([]*api.Rpki, 0)
    31  	stream, err := client.ListRpki(ctx, &api.ListRpkiRequest{})
    32  	if err != nil {
    33  		fmt.Println(err)
    34  		return err
    35  	}
    36  	for {
    37  		r, err := stream.Recv()
    38  		if err == io.EOF {
    39  			break
    40  		} else if err != nil {
    41  			return err
    42  		}
    43  		servers = append(servers, r.Server)
    44  	}
    45  	if len(args) == 0 {
    46  		format := "%-23s %-6s %-10s %s\n"
    47  		fmt.Printf(format, "Session", "State", "Uptime", "#IPv4/IPv6 records")
    48  		for _, r := range servers {
    49  			s := "Down"
    50  			uptime := "never"
    51  			if r.State.Up {
    52  				s = "Up"
    53  				t, _ := ptypes.Timestamp(r.State.Uptime)
    54  				uptime = fmt.Sprint(formatTimedelta(t))
    55  			}
    56  
    57  			fmt.Printf(format, net.JoinHostPort(r.Conf.Address, fmt.Sprintf("%d", r.Conf.RemotePort)), s, uptime, fmt.Sprintf("%d/%d", r.State.RecordIpv4, r.State.RecordIpv6))
    58  		}
    59  		return nil
    60  	}
    61  
    62  	for _, r := range servers {
    63  		if r.Conf.Address == args[0] {
    64  			up := "Down"
    65  			if r.State.Up {
    66  				up = "Up"
    67  			}
    68  			fmt.Printf("Session: %s, State: %s\n", r.Conf.Address, up)
    69  			fmt.Println("  Port:", r.Conf.RemotePort)
    70  			fmt.Println("  Serial:", r.State.Serial)
    71  			fmt.Printf("  Prefix: %d/%d\n", r.State.PrefixIpv4, r.State.PrefixIpv6)
    72  			fmt.Printf("  Record: %d/%d\n", r.State.RecordIpv4, r.State.RecordIpv6)
    73  			fmt.Println("  Message statistics:")
    74  			fmt.Printf("    Receivedv4:    %10d\n", r.State.ReceivedIpv4)
    75  			fmt.Printf("    Receivedv6:    %10d\n", r.State.ReceivedIpv6)
    76  			fmt.Printf("    SerialNotify:  %10d\n", r.State.SerialNotify)
    77  			fmt.Printf("    CacheReset:    %10d\n", r.State.CacheReset)
    78  			fmt.Printf("    CacheResponse: %10d\n", r.State.CacheResponse)
    79  			fmt.Printf("    EndOfData:     %10d\n", r.State.EndOfData)
    80  			fmt.Printf("    Error:         %10d\n", r.State.Error)
    81  			fmt.Printf("    SerialQuery:   %10d\n", r.State.SerialQuery)
    82  			fmt.Printf("    ResetQuery:    %10d\n", r.State.ResetQuery)
    83  		}
    84  	}
    85  	return nil
    86  }
    87  
    88  func showRPKITable(args []string) error {
    89  	family, err := checkAddressFamily(ipv4UC)
    90  	if err != nil {
    91  		exitWithError(err)
    92  	}
    93  	stream, err := client.ListRpkiTable(ctx, &api.ListRpkiTableRequest{
    94  		Family: family,
    95  	})
    96  	if err != nil {
    97  		exitWithError(err)
    98  	}
    99  	roas := make([]*api.Roa, 0)
   100  	for {
   101  		r, err := stream.Recv()
   102  		if err == io.EOF {
   103  			break
   104  		} else if err != nil {
   105  			exitWithError(err)
   106  		}
   107  		roas = append(roas, r.Roa)
   108  	}
   109  
   110  	var format string
   111  	if family.Afi == api.Family_AFI_IP {
   112  		format = "%-18s %-6s %-10s %s\n"
   113  	} else {
   114  		format = "%-42s %-6s %-10s %s\n"
   115  	}
   116  	fmt.Printf(format, "Network", "Maxlen", "AS", "Server")
   117  	for _, r := range roas {
   118  		if len(args) > 0 && args[0] != r.Conf.Address {
   119  			continue
   120  		}
   121  		fmt.Printf(format, r.Prefix, fmt.Sprint(r.Maxlen), fmt.Sprint(r.As), net.JoinHostPort(r.Conf.Address, strconv.Itoa(int(r.Conf.RemotePort))))
   122  	}
   123  	return nil
   124  }
   125  
   126  func newRPKICmd() *cobra.Command {
   127  	rpkiCmd := &cobra.Command{
   128  		Use: cmdRPKI,
   129  	}
   130  
   131  	serverCmd := &cobra.Command{
   132  		Use: cmdRPKIServer,
   133  		Run: func(cmd *cobra.Command, args []string) {
   134  			if len(args) == 0 || len(args) == 1 {
   135  				showRPKIServer(args)
   136  				return
   137  			} else if len(args) != 2 {
   138  				exitWithError(fmt.Errorf("usage: gobgp rpki server <ip address> [reset|softreset|enable]"))
   139  			}
   140  			addr := net.ParseIP(args[0])
   141  			if addr == nil {
   142  				exitWithError(fmt.Errorf("invalid ip address: %s", args[0]))
   143  			}
   144  			var err error
   145  			switch args[1] {
   146  			case "add":
   147  				_, err = client.AddRpki(ctx, &api.AddRpkiRequest{
   148  					Address: addr.String(),
   149  					Port:    323,
   150  				})
   151  			case "reset", "softreset":
   152  				_, err = client.ResetRpki(ctx, &api.ResetRpkiRequest{
   153  					Address: addr.String(),
   154  					Soft: func() bool {
   155  						return args[1] != "reset"
   156  					}(),
   157  				})
   158  			case "enable":
   159  				_, err = client.EnableRpki(ctx, &api.EnableRpkiRequest{
   160  					Address: addr.String(),
   161  				})
   162  			case "disable":
   163  				_, err = client.DisableRpki(ctx, &api.DisableRpkiRequest{
   164  					Address: addr.String(),
   165  				})
   166  			default:
   167  				exitWithError(fmt.Errorf("unknown operation: %s", args[1]))
   168  			}
   169  			if err != nil {
   170  				exitWithError(err)
   171  			}
   172  		},
   173  	}
   174  	rpkiCmd.AddCommand(serverCmd)
   175  
   176  	tableCmd := &cobra.Command{
   177  		Use: cmdRPKITable,
   178  		Run: func(cmd *cobra.Command, args []string) {
   179  			showRPKITable(args)
   180  		},
   181  	}
   182  	tableCmd.PersistentFlags().StringVarP(&subOpts.AddressFamily, "address-family", "a", "", "address family")
   183  	rpkiCmd.AddCommand(tableCmd)
   184  	return rpkiCmd
   185  }