github.com/osrg/gobgp@v2.0.0+incompatible/cmd/gobgp/monitor.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 "encoding/json" 20 "fmt" 21 "io" 22 "net" 23 "time" 24 25 "github.com/spf13/cobra" 26 27 api "github.com/osrg/gobgp/api" 28 "github.com/osrg/gobgp/internal/pkg/apiutil" 29 "github.com/osrg/gobgp/pkg/packet/bgp" 30 ) 31 32 func makeMonitorRouteArgs(p *api.Path, showIdentifier bgp.BGPAddPathMode) []interface{} { 33 pathStr := make([]interface{}, 0) 34 35 // Title 36 title := "ROUTE" 37 if p.IsWithdraw { 38 title = "DELROUTE" 39 } 40 pathStr = append(pathStr, title) 41 42 // NLRI 43 // If Add-Path required, append Path Identifier. 44 nlri, _ := apiutil.GetNativeNlri(p) 45 if showIdentifier != bgp.BGP_ADD_PATH_NONE { 46 pathStr = append(pathStr, p.GetIdentifier()) 47 } 48 pathStr = append(pathStr, nlri) 49 50 attrs, _ := apiutil.GetNativePathAttributes(p) 51 // Next Hop 52 nexthop := "fictitious" 53 if n := getNextHopFromPathAttributes(attrs); n != nil { 54 nexthop = n.String() 55 } 56 pathStr = append(pathStr, nexthop) 57 58 // AS_PATH 59 aspathstr := func() string { 60 for _, attr := range attrs { 61 switch a := attr.(type) { 62 case *bgp.PathAttributeAsPath: 63 return bgp.AsPathString(a) 64 } 65 } 66 return "" 67 }() 68 pathStr = append(pathStr, aspathstr) 69 70 // Path Attributes 71 pathStr = append(pathStr, getPathAttributeString(nlri, attrs)) 72 73 return pathStr 74 } 75 76 func monitorRoute(pathList []*api.Path, showIdentifier bgp.BGPAddPathMode) { 77 var pathStrs [][]interface{} 78 79 for _, p := range pathList { 80 pathStrs = append(pathStrs, makeMonitorRouteArgs(p, showIdentifier)) 81 } 82 83 format := time.Now().UTC().Format(time.RFC3339) 84 if showIdentifier == bgp.BGP_ADD_PATH_NONE { 85 format += " [%s] %s via %s aspath [%s] attrs %s\n" 86 } else { 87 format += " [%s] %d:%s via %s aspath [%s] attrs %s\n" 88 } 89 for _, pathStr := range pathStrs { 90 fmt.Printf(format, pathStr...) 91 } 92 } 93 94 func newMonitorCmd() *cobra.Command { 95 96 var current bool 97 98 monitor := func(recver interface { 99 Recv() (*api.MonitorTableResponse, error) 100 }, showIdentifier bgp.BGPAddPathMode) { 101 for { 102 r, err := recver.Recv() 103 if err == io.EOF { 104 break 105 } else if err != nil { 106 exitWithError(err) 107 } 108 if globalOpts.Json { 109 j, _ := json.Marshal(apiutil.NewDestination(&api.Destination{Paths: []*api.Path{r.Path}})) 110 fmt.Println(string(j)) 111 } else { 112 monitorRoute([]*api.Path{r.Path}, bgp.BGP_ADD_PATH_NONE) 113 } 114 } 115 } 116 117 ribCmd := &cobra.Command{ 118 Use: cmdRib, 119 Run: func(cmd *cobra.Command, args []string) { 120 family, err := checkAddressFamily(ipv4UC) 121 if err != nil { 122 exitWithError(err) 123 } 124 recver, err := client.MonitorTable(ctx, &api.MonitorTableRequest{ 125 TableType: api.TableType_GLOBAL, 126 Family: family, 127 Current: current, 128 }) 129 if err != nil { 130 exitWithError(err) 131 } 132 monitor(recver, bgp.BGP_ADD_PATH_NONE) 133 }, 134 } 135 ribCmd.PersistentFlags().StringVarP(&subOpts.AddressFamily, "address-family", "a", "", "address family") 136 137 globalCmd := &cobra.Command{ 138 Use: cmdGlobal, 139 } 140 globalCmd.AddCommand(ribCmd) 141 142 neighborCmd := &cobra.Command{ 143 Use: fmt.Sprintf("%s [<neighbor address>]", cmdNeighbor), 144 Args: cobra.MaximumNArgs(1), 145 Run: func(cmd *cobra.Command, args []string) { 146 name := "" 147 if len(args) > 0 { 148 name = args[0] 149 } 150 stream, err := client.MonitorPeer(ctx, &api.MonitorPeerRequest{ 151 Address: name, 152 Current: current, 153 }) 154 if err != nil { 155 exitWithError(err) 156 } 157 for { 158 r, err := stream.Recv() 159 if err == io.EOF { 160 break 161 } else if err != nil { 162 exitWithError(err) 163 } 164 s := r.Peer 165 if globalOpts.Json { 166 j, _ := json.Marshal(s) 167 fmt.Println(string(j)) 168 } else { 169 addr := s.Conf.NeighborAddress 170 if s.Conf.NeighborInterface != "" { 171 addr = fmt.Sprintf("%s(%s)", addr, s.Conf.NeighborInterface) 172 } 173 fmt.Printf("%s [NEIGH] %s fsm: %s admin: %s\n", time.Now().UTC().Format(time.RFC3339), addr, s.State.SessionState, s.State.AdminState) 174 } 175 } 176 }, 177 } 178 179 adjInCmd := &cobra.Command{ 180 Use: cmdAdjIn, 181 Run: func(cmd *cobra.Command, args []string) { 182 name := "" 183 if len(args) > 0 { 184 remoteIP := net.ParseIP(args[0]) 185 if remoteIP == nil { 186 exitWithError(fmt.Errorf("invalid ip address: %s", args[0])) 187 } 188 name = args[0] 189 } 190 family, err := checkAddressFamily(ipv4UC) 191 if err != nil { 192 exitWithError(err) 193 } 194 recver, err := client.MonitorTable(ctx, &api.MonitorTableRequest{ 195 TableType: api.TableType_ADJ_IN, 196 Name: name, 197 Family: family, 198 Current: current, 199 }) 200 if err != nil { 201 exitWithError(err) 202 } 203 monitor(recver, bgp.BGP_ADD_PATH_RECEIVE) 204 }, 205 } 206 adjInCmd.PersistentFlags().StringVarP(&subOpts.AddressFamily, "address-family", "a", "", "address family") 207 208 monitorCmd := &cobra.Command{ 209 Use: cmdMonitor, 210 } 211 monitorCmd.AddCommand(globalCmd) 212 monitorCmd.AddCommand(neighborCmd) 213 monitorCmd.AddCommand(adjInCmd) 214 215 monitorCmd.PersistentFlags().BoolVarP(¤t, "current", "", false, "dump current contents") 216 217 return monitorCmd 218 }