diff options
author | Yuji Oshima <yuji.oshima0x3fd@gmail.com> | 2015-10-29 17:26:01 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-10-29 17:26:01 +0900 |
commit | b780fed28a735fa97cfbb220769f6f2082543674 (patch) | |
tree | b45b5ed4b2c56f93a70c44b7c4404df6e9d22582 | |
parent | 645ce47b986cf7296d217bc98af7b4a8446833a9 (diff) |
api: confirm api.Peer to openconfig and add ModPeer api
Signed-off-by: YujiOshima <yuji.oshima0x3fd@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | api/gobgp.pb.go | 744 | ||||
-rw-r--r-- | api/gobgp.proto | 266 | ||||
-rw-r--r-- | gobgp/cmd/common.go | 22 | ||||
-rw-r--r-- | gobgp/cmd/monitor.go | 2 | ||||
-rw-r--r-- | gobgp/cmd/neighbor.go | 28 | ||||
-rw-r--r-- | server/grpc_server.go | 5 | ||||
-rw-r--r-- | server/peer.go | 114 | ||||
-rw-r--r-- | server/server.go | 172 |
8 files changed, 1179 insertions, 174 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go index 6f0648e7..d856e19d 100644 --- a/api/gobgp.pb.go +++ b/api/gobgp.pb.go @@ -12,6 +12,7 @@ It has these top-level messages: Error Arguments ModPathArguments + ModNeighborArguments MrtArguments ModVrfArguments ModDefinedSetArguments @@ -20,9 +21,35 @@ It has these top-level messages: ModPolicyAssignmentArguments Path Destination - PeerConf - PeerInfo Peer + AddPaths + AfiSafis + AfiSafi + ApplyPolicy + AfiSafiGracefulRestart + LabelledUnicast + PrefixLimit + Unicast + Vpn + Prefixes + UseMultiplePaths + Ebgp + AsPathOptions + PeerConf + EbgpMultihop + ErrorHandling + PeerGracefulRestart + LoggingOptions + RouteReflector + PeerState + Messages + Message + Queues + Timers + TimersConfig + TimersState + Transport + RouteServer Prefix DefinedSet MatchSet @@ -336,6 +363,22 @@ func (m *ModPathArguments) GetPaths() []*Path { return nil } +type ModNeighborArguments struct { + Operation Operation `protobuf:"varint,1,opt,name=operation,enum=gobgpapi.Operation" json:"operation,omitempty"` + Peer *Peer `protobuf:"bytes,2,opt,name=peer" json:"peer,omitempty"` +} + +func (m *ModNeighborArguments) Reset() { *m = ModNeighborArguments{} } +func (m *ModNeighborArguments) String() string { return proto.CompactTextString(m) } +func (*ModNeighborArguments) ProtoMessage() {} + +func (m *ModNeighborArguments) GetPeer() *Peer { + if m != nil { + return m.Peer + } + return nil +} + type MrtArguments struct { Resource Resource `protobuf:"varint,1,opt,name=resource,enum=gobgpapi.Resource" json:"resource,omitempty"` Rf uint32 `protobuf:"varint,2,opt,name=rf" json:"rf,omitempty"` @@ -469,77 +512,647 @@ func (m *Destination) GetPaths() []*Path { return nil } +type Peer struct { + Addpaths *AddPaths `protobuf:"bytes,1,opt,name=addpaths" json:"addpaths,omitempty"` + Afisafis *AfiSafis `protobuf:"bytes,2,opt,name=afisafis" json:"afisafis,omitempty"` + ApplyPolicy *ApplyPolicy `protobuf:"bytes,3,opt,name=apply_policy" json:"apply_policy,omitempty"` + AsPathOptions *AsPathOptions `protobuf:"bytes,4,opt,name=as_path_options" json:"as_path_options,omitempty"` + Conf *PeerConf `protobuf:"bytes,5,opt,name=conf" json:"conf,omitempty"` + EbgpMultihop *EbgpMultihop `protobuf:"bytes,6,opt,name=ebgp_multihop" json:"ebgp_multihop,omitempty"` + ErrorHandling *ErrorHandling `protobuf:"bytes,7,opt,name=error_handling" json:"error_handling,omitempty"` + GracefulRestart *PeerGracefulRestart `protobuf:"bytes,8,opt,name=graceful_restart" json:"graceful_restart,omitempty"` + LoggingOptions *LoggingOptions `protobuf:"bytes,9,opt,name=logging_options" json:"logging_options,omitempty"` + NighborAddress string `protobuf:"bytes,10,opt,name=nighbor_address" json:"nighbor_address,omitempty"` + RouteReflector *RouteReflector `protobuf:"bytes,11,opt,name=route_reflector" json:"route_reflector,omitempty"` + Info *PeerState `protobuf:"bytes,12,opt,name=info" json:"info,omitempty"` + Timers *Timers `protobuf:"bytes,13,opt,name=timers" json:"timers,omitempty"` + Transport *Transport `protobuf:"bytes,14,opt,name=transport" json:"transport,omitempty"` + UseMultiplePaths *UseMultiplePaths `protobuf:"bytes,15,opt,name=use_multiple_paths" json:"use_multiple_paths,omitempty"` + RouteServer *RouteServer `protobuf:"bytes,16,opt,name=route_server" json:"route_server,omitempty"` +} + +func (m *Peer) Reset() { *m = Peer{} } +func (m *Peer) String() string { return proto.CompactTextString(m) } +func (*Peer) ProtoMessage() {} + +func (m *Peer) GetAddpaths() *AddPaths { + if m != nil { + return m.Addpaths + } + return nil +} + +func (m *Peer) GetAfisafis() *AfiSafis { + if m != nil { + return m.Afisafis + } + return nil +} + +func (m *Peer) GetApplyPolicy() *ApplyPolicy { + if m != nil { + return m.ApplyPolicy + } + return nil +} + +func (m *Peer) GetAsPathOptions() *AsPathOptions { + if m != nil { + return m.AsPathOptions + } + return nil +} + +func (m *Peer) GetConf() *PeerConf { + if m != nil { + return m.Conf + } + return nil +} + +func (m *Peer) GetEbgpMultihop() *EbgpMultihop { + if m != nil { + return m.EbgpMultihop + } + return nil +} + +func (m *Peer) GetErrorHandling() *ErrorHandling { + if m != nil { + return m.ErrorHandling + } + return nil +} + +func (m *Peer) GetGracefulRestart() *PeerGracefulRestart { + if m != nil { + return m.GracefulRestart + } + return nil +} + +func (m *Peer) GetLoggingOptions() *LoggingOptions { + if m != nil { + return m.LoggingOptions + } + return nil +} + +func (m *Peer) GetRouteReflector() *RouteReflector { + if m != nil { + return m.RouteReflector + } + return nil +} + +func (m *Peer) GetInfo() *PeerState { + if m != nil { + return m.Info + } + return nil +} + +func (m *Peer) GetTimers() *Timers { + if m != nil { + return m.Timers + } + return nil +} + +func (m *Peer) GetTransport() *Transport { + if m != nil { + return m.Transport + } + return nil +} + +func (m *Peer) GetUseMultiplePaths() *UseMultiplePaths { + if m != nil { + return m.UseMultiplePaths + } + return nil +} + +func (m *Peer) GetRouteServer() *RouteServer { + if m != nil { + return m.RouteServer + } + return nil +} + +type AddPaths struct { + Receive bool `protobuf:"varint,1,opt,name=receive" json:"receive,omitempty"` + SendMax uint32 `protobuf:"varint,2,opt,name=send_max" json:"send_max,omitempty"` +} + +func (m *AddPaths) Reset() { *m = AddPaths{} } +func (m *AddPaths) String() string { return proto.CompactTextString(m) } +func (*AddPaths) ProtoMessage() {} + +type AfiSafis struct { + Afisafi []*AfiSafi `protobuf:"bytes,1,rep,name=afisafi" json:"afisafi,omitempty"` +} + +func (m *AfiSafis) Reset() { *m = AfiSafis{} } +func (m *AfiSafis) String() string { return proto.CompactTextString(m) } +func (*AfiSafis) ProtoMessage() {} + +func (m *AfiSafis) GetAfisafi() []*AfiSafi { + if m != nil { + return m.Afisafi + } + return nil +} + +type AfiSafi struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + ApplyPolicy *ApplyPolicy `protobuf:"bytes,2,opt,name=apply_policy" json:"apply_policy,omitempty"` + Enabled bool `protobuf:"varint,3,opt,name=enabled" json:"enabled,omitempty"` + GracefulRestart *AfiSafiGracefulRestart `protobuf:"bytes,4,opt,name=graceful_restart" json:"graceful_restart,omitempty"` + Ipv4LabelledUnicast *LabelledUnicast `protobuf:"bytes,5,opt,name=ipv4_labelled_unicast" json:"ipv4_labelled_unicast,omitempty"` + Ipv4Unicast *Unicast `protobuf:"bytes,6,opt,name=ipv4_unicast" json:"ipv4_unicast,omitempty"` + Ipv6LabelledUnicast *LabelledUnicast `protobuf:"bytes,7,opt,name=ipv6_labelled_unicast" json:"ipv6_labelled_unicast,omitempty"` + Ipv6Unicast *Unicast `protobuf:"bytes,8,opt,name=ipv6_unicast" json:"ipv6_unicast,omitempty"` + L2VpnEvpn *Vpn `protobuf:"bytes,9,opt,name=l2_vpn_evpn" json:"l2_vpn_evpn,omitempty"` + L2VpnVpls *Vpn `protobuf:"bytes,10,opt,name=l2_vpn_vpls" json:"l2_vpn_vpls,omitempty"` + L3VpnIpv4Multicast *Vpn `protobuf:"bytes,11,opt,name=l3_vpn_ipv4_multicast" json:"l3_vpn_ipv4_multicast,omitempty"` + L3VpnIpv4Unicast *Vpn `protobuf:"bytes,12,opt,name=l3_vpn_ipv4_unicast" json:"l3_vpn_ipv4_unicast,omitempty"` + L3VpnIpv6Multicast *Vpn `protobuf:"bytes,13,opt,name=l3_vpn_ipv6_multicast" json:"l3_vpn_ipv6_multicast,omitempty"` + L3VpnIpv6Unicast *Vpn `protobuf:"bytes,14,opt,name=l3_vpn_ipv6_unicast" json:"l3_vpn_ipv6_unicast,omitempty"` + UseMultiplePaths *UseMultiplePaths `protobuf:"bytes,15,opt,name=use_multiple_paths" json:"use_multiple_paths,omitempty"` + Active bool `protobuf:"varint,16,opt,name=active" json:"active,omitempty"` + Prefixes *Prefixes `protobuf:"bytes,17,opt,name=prefixes" json:"prefixes,omitempty"` +} + +func (m *AfiSafi) Reset() { *m = AfiSafi{} } +func (m *AfiSafi) String() string { return proto.CompactTextString(m) } +func (*AfiSafi) ProtoMessage() {} + +func (m *AfiSafi) GetApplyPolicy() *ApplyPolicy { + if m != nil { + return m.ApplyPolicy + } + return nil +} + +func (m *AfiSafi) GetGracefulRestart() *AfiSafiGracefulRestart { + if m != nil { + return m.GracefulRestart + } + return nil +} + +func (m *AfiSafi) GetIpv4LabelledUnicast() *LabelledUnicast { + if m != nil { + return m.Ipv4LabelledUnicast + } + return nil +} + +func (m *AfiSafi) GetIpv4Unicast() *Unicast { + if m != nil { + return m.Ipv4Unicast + } + return nil +} + +func (m *AfiSafi) GetIpv6LabelledUnicast() *LabelledUnicast { + if m != nil { + return m.Ipv6LabelledUnicast + } + return nil +} + +func (m *AfiSafi) GetIpv6Unicast() *Unicast { + if m != nil { + return m.Ipv6Unicast + } + return nil +} + +func (m *AfiSafi) GetL2VpnEvpn() *Vpn { + if m != nil { + return m.L2VpnEvpn + } + return nil +} + +func (m *AfiSafi) GetL2VpnVpls() *Vpn { + if m != nil { + return m.L2VpnVpls + } + return nil +} + +func (m *AfiSafi) GetL3VpnIpv4Multicast() *Vpn { + if m != nil { + return m.L3VpnIpv4Multicast + } + return nil +} + +func (m *AfiSafi) GetL3VpnIpv4Unicast() *Vpn { + if m != nil { + return m.L3VpnIpv4Unicast + } + return nil +} + +func (m *AfiSafi) GetL3VpnIpv6Multicast() *Vpn { + if m != nil { + return m.L3VpnIpv6Multicast + } + return nil +} + +func (m *AfiSafi) GetL3VpnIpv6Unicast() *Vpn { + if m != nil { + return m.L3VpnIpv6Unicast + } + return nil +} + +func (m *AfiSafi) GetUseMultiplePaths() *UseMultiplePaths { + if m != nil { + return m.UseMultiplePaths + } + return nil +} + +func (m *AfiSafi) GetPrefixes() *Prefixes { + if m != nil { + return m.Prefixes + } + return nil +} + +type ApplyPolicy struct { + InPolicy *PolicyAssignment `protobuf:"bytes,1,opt,name=in_policy" json:"in_policy,omitempty"` + ExportPolicy *PolicyAssignment `protobuf:"bytes,2,opt,name=export_policy" json:"export_policy,omitempty"` + ImportPolicy *PolicyAssignment `protobuf:"bytes,3,opt,name=import_policy" json:"import_policy,omitempty"` +} + +func (m *ApplyPolicy) Reset() { *m = ApplyPolicy{} } +func (m *ApplyPolicy) String() string { return proto.CompactTextString(m) } +func (*ApplyPolicy) ProtoMessage() {} + +func (m *ApplyPolicy) GetInPolicy() *PolicyAssignment { + if m != nil { + return m.InPolicy + } + return nil +} + +func (m *ApplyPolicy) GetExportPolicy() *PolicyAssignment { + if m != nil { + return m.ExportPolicy + } + return nil +} + +func (m *ApplyPolicy) GetImportPolicy() *PolicyAssignment { + if m != nil { + return m.ImportPolicy + } + return nil +} + +type AfiSafiGracefulRestart struct { + Advertised bool `protobuf:"varint,1,opt,name=advertised" json:"advertised,omitempty"` + Enabled bool `protobuf:"varint,2,opt,name=enabled" json:"enabled,omitempty"` + Received bool `protobuf:"varint,3,opt,name=received" json:"received,omitempty"` +} + +func (m *AfiSafiGracefulRestart) Reset() { *m = AfiSafiGracefulRestart{} } +func (m *AfiSafiGracefulRestart) String() string { return proto.CompactTextString(m) } +func (*AfiSafiGracefulRestart) ProtoMessage() {} + +type LabelledUnicast struct { + PrefixLimit *PrefixLimit `protobuf:"bytes,1,opt,name=prefix_limit" json:"prefix_limit,omitempty"` +} + +func (m *LabelledUnicast) Reset() { *m = LabelledUnicast{} } +func (m *LabelledUnicast) String() string { return proto.CompactTextString(m) } +func (*LabelledUnicast) ProtoMessage() {} + +func (m *LabelledUnicast) GetPrefixLimit() *PrefixLimit { + if m != nil { + return m.PrefixLimit + } + return nil +} + +type PrefixLimit struct { + MaxPrefixes uint32 `protobuf:"varint,1,opt,name=max_prefixes" json:"max_prefixes,omitempty"` + RestartTimer uint64 `protobuf:"varint,2,opt,name=restart_timer" json:"restart_timer,omitempty"` + ShutdownThresholdPct uint32 `protobuf:"varint,3,opt,name=shutdown_threshold_pct" json:"shutdown_threshold_pct,omitempty"` +} + +func (m *PrefixLimit) Reset() { *m = PrefixLimit{} } +func (m *PrefixLimit) String() string { return proto.CompactTextString(m) } +func (*PrefixLimit) ProtoMessage() {} + +type Unicast struct { + SendDefaultRoute bool `protobuf:"varint,1,opt,name=send_default_route" json:"send_default_route,omitempty"` + PrefixLimit *PrefixLimit `protobuf:"bytes,2,opt,name=prefix_limit" json:"prefix_limit,omitempty"` +} + +func (m *Unicast) Reset() { *m = Unicast{} } +func (m *Unicast) String() string { return proto.CompactTextString(m) } +func (*Unicast) ProtoMessage() {} + +func (m *Unicast) GetPrefixLimit() *PrefixLimit { + if m != nil { + return m.PrefixLimit + } + return nil +} + +type Vpn struct { + PrefixLimit *PrefixLimit `protobuf:"bytes,1,opt,name=prefix_limit" json:"prefix_limit,omitempty"` +} + +func (m *Vpn) Reset() { *m = Vpn{} } +func (m *Vpn) String() string { return proto.CompactTextString(m) } +func (*Vpn) ProtoMessage() {} + +func (m *Vpn) GetPrefixLimit() *PrefixLimit { + if m != nil { + return m.PrefixLimit + } + return nil +} + +type Prefixes struct { + Installed uint32 `protobuf:"varint,1,opt,name=installed" json:"installed,omitempty"` + Received uint32 `protobuf:"varint,2,opt,name=received" json:"received,omitempty"` + Sent uint32 `protobuf:"varint,3,opt,name=sent" json:"sent,omitempty"` +} + +func (m *Prefixes) Reset() { *m = Prefixes{} } +func (m *Prefixes) String() string { return proto.CompactTextString(m) } +func (*Prefixes) ProtoMessage() {} + +type UseMultiplePaths struct { + Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"` + Ebgp *Ebgp `protobuf:"bytes,2,opt,name=ebgp" json:"ebgp,omitempty"` +} + +func (m *UseMultiplePaths) Reset() { *m = UseMultiplePaths{} } +func (m *UseMultiplePaths) String() string { return proto.CompactTextString(m) } +func (*UseMultiplePaths) ProtoMessage() {} + +func (m *UseMultiplePaths) GetEbgp() *Ebgp { + if m != nil { + return m.Ebgp + } + return nil +} + +type Ebgp struct { + AllowMultipleAs bool `protobuf:"varint,1,opt,name=allow_multiple_as" json:"allow_multiple_as,omitempty"` +} + +func (m *Ebgp) Reset() { *m = Ebgp{} } +func (m *Ebgp) String() string { return proto.CompactTextString(m) } +func (*Ebgp) ProtoMessage() {} + +type AsPathOptions struct { + AllowOwnAs uint32 `protobuf:"varint,1,opt,name=allow_own_as" json:"allow_own_as,omitempty"` + ReplacePeerAs bool `protobuf:"varint,2,opt,name=replace_peer_as" json:"replace_peer_as,omitempty"` +} + +func (m *AsPathOptions) Reset() { *m = AsPathOptions{} } +func (m *AsPathOptions) String() string { return proto.CompactTextString(m) } +func (*AsPathOptions) ProtoMessage() {} + type PeerConf struct { - RemoteIp string `protobuf:"bytes,1,opt,name=remote_ip" json:"remote_ip,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` - RemoteAs uint32 `protobuf:"varint,3,opt,name=remote_as" json:"remote_as,omitempty"` - RemoteCap [][]byte `protobuf:"bytes,6,rep,name=remote_cap,proto3" json:"remote_cap,omitempty"` - LocalCap [][]byte `protobuf:"bytes,7,rep,name=local_cap,proto3" json:"local_cap,omitempty"` - Holdtime uint32 `protobuf:"varint,8,opt,name=holdtime" json:"holdtime,omitempty"` - KeepaliveInterval uint32 `protobuf:"varint,9,opt,name=keepalive_interval" json:"keepalive_interval,omitempty"` + AuthPassword string `protobuf:"bytes,1,opt,name=auth_password" json:"auth_password,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"` + LocalAs uint32 `protobuf:"varint,3,opt,name=local_as" json:"local_as,omitempty"` + NeighborAddress string `protobuf:"bytes,4,opt,name=neighbor_address" json:"neighbor_address,omitempty"` + PeerAs uint32 `protobuf:"varint,5,opt,name=peer_as" json:"peer_as,omitempty"` + PeerGroup string `protobuf:"bytes,6,opt,name=peer_group" json:"peer_group,omitempty"` + PeerType uint32 `protobuf:"varint,7,opt,name=peer_type" json:"peer_type,omitempty"` + RemovePrivateAs uint32 `protobuf:"varint,8,opt,name=remove_private_as" json:"remove_private_as,omitempty"` + RouteFlapDamping bool `protobuf:"varint,9,opt,name=route_flap_damping" json:"route_flap_damping,omitempty"` + SendCommunity uint32 `protobuf:"varint,10,opt,name=send_community" json:"send_community,omitempty"` + RemoteCap [][]byte `protobuf:"bytes,11,rep,name=remote_cap,proto3" json:"remote_cap,omitempty"` + LocalCap [][]byte `protobuf:"bytes,12,rep,name=local_cap,proto3" json:"local_cap,omitempty"` } func (m *PeerConf) Reset() { *m = PeerConf{} } func (m *PeerConf) String() string { return proto.CompactTextString(m) } func (*PeerConf) ProtoMessage() {} -type PeerInfo struct { - BgpState string `protobuf:"bytes,1,opt,name=bgp_state" json:"bgp_state,omitempty"` - AdminState string `protobuf:"bytes,2,opt,name=admin_state" json:"admin_state,omitempty"` - FsmEstablishedTransitions uint32 `protobuf:"varint,3,opt,name=fsm_established_transitions" json:"fsm_established_transitions,omitempty"` - TotalMessageOut uint64 `protobuf:"varint,4,opt,name=total_message_out" json:"total_message_out,omitempty"` - TotalMessageIn uint64 `protobuf:"varint,5,opt,name=total_message_in" json:"total_message_in,omitempty"` - UpdateMessageOut uint64 `protobuf:"varint,6,opt,name=update_message_out" json:"update_message_out,omitempty"` - UpdateMessageIn uint64 `protobuf:"varint,7,opt,name=update_message_in" json:"update_message_in,omitempty"` - KeepAliveMessageOut uint64 `protobuf:"varint,8,opt,name=keep_alive_message_out" json:"keep_alive_message_out,omitempty"` - KeepAliveMessageIn uint64 `protobuf:"varint,9,opt,name=keep_alive_message_in" json:"keep_alive_message_in,omitempty"` - OpenMessageOut uint64 `protobuf:"varint,10,opt,name=open_message_out" json:"open_message_out,omitempty"` - OpenMessageIn uint64 `protobuf:"varint,11,opt,name=open_message_in" json:"open_message_in,omitempty"` - NotificationOut uint64 `protobuf:"varint,12,opt,name=notification_out" json:"notification_out,omitempty"` - NotificationIn uint64 `protobuf:"varint,13,opt,name=notification_in" json:"notification_in,omitempty"` - RefreshMessageOut uint64 `protobuf:"varint,14,opt,name=refresh_message_out" json:"refresh_message_out,omitempty"` - RefreshMessageIn uint64 `protobuf:"varint,15,opt,name=refresh_message_in" json:"refresh_message_in,omitempty"` - DiscardedOut uint64 `protobuf:"varint,16,opt,name=discarded_out" json:"discarded_out,omitempty"` - DiscardedIn uint64 `protobuf:"varint,17,opt,name=discarded_in" json:"discarded_in,omitempty"` - Uptime int64 `protobuf:"varint,18,opt,name=uptime" json:"uptime,omitempty"` - Downtime int64 `protobuf:"varint,19,opt,name=downtime" json:"downtime,omitempty"` - LastError string `protobuf:"bytes,20,opt,name=last_error" json:"last_error,omitempty"` - Received uint32 `protobuf:"varint,21,opt,name=received" json:"received,omitempty"` - Accepted uint32 `protobuf:"varint,22,opt,name=accepted" json:"accepted,omitempty"` - Advertized uint32 `protobuf:"varint,23,opt,name=advertized" json:"advertized,omitempty"` - OutQ uint32 `protobuf:"varint,24,opt,name=out_q" json:"out_q,omitempty"` - Flops uint32 `protobuf:"varint,25,opt,name=flops" json:"flops,omitempty"` - NegotiatedHoldtime uint32 `protobuf:"varint,26,opt,name=negotiated_holdtime" json:"negotiated_holdtime,omitempty"` - KeepaliveInterval uint32 `protobuf:"varint,27,opt,name=keepalive_interval" json:"keepalive_interval,omitempty"` -} - -func (m *PeerInfo) Reset() { *m = PeerInfo{} } -func (m *PeerInfo) String() string { return proto.CompactTextString(m) } -func (*PeerInfo) ProtoMessage() {} +type EbgpMultihop struct { + Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"` + MultihopTtl uint32 `protobuf:"varint,2,opt,name=multihop_ttl" json:"multihop_ttl,omitempty"` +} + +func (m *EbgpMultihop) Reset() { *m = EbgpMultihop{} } +func (m *EbgpMultihop) String() string { return proto.CompactTextString(m) } +func (*EbgpMultihop) ProtoMessage() {} + +type ErrorHandling struct { + ErroneousUpdateMessages uint32 `protobuf:"varint,1,opt,name=erroneous_update_messages" json:"erroneous_update_messages,omitempty"` + TreatAsWithdraw bool `protobuf:"varint,2,opt,name=treat_as_withdraw" json:"treat_as_withdraw,omitempty"` +} + +func (m *ErrorHandling) Reset() { *m = ErrorHandling{} } +func (m *ErrorHandling) String() string { return proto.CompactTextString(m) } +func (*ErrorHandling) ProtoMessage() {} + +type PeerGracefulRestart struct { + Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"` + HelperOnly bool `protobuf:"varint,2,opt,name=helper_only" json:"helper_only,omitempty"` + LocalRestarting bool `protobuf:"varint,3,opt,name=local_restarting" json:"local_restarting,omitempty"` + Mode uint32 `protobuf:"varint,4,opt,name=mode" json:"mode,omitempty"` + PeerRestartTime uint32 `protobuf:"varint,5,opt,name=peer_restart_time" json:"peer_restart_time,omitempty"` + PeerRestarting bool `protobuf:"varint,6,opt,name=peer_restarting" json:"peer_restarting,omitempty"` + RestartTime uint32 `protobuf:"varint,7,opt,name=restart_time" json:"restart_time,omitempty"` + StaleRoutesTime uint64 `protobuf:"varint,8,opt,name=stale_routes_time" json:"stale_routes_time,omitempty"` +} + +func (m *PeerGracefulRestart) Reset() { *m = PeerGracefulRestart{} } +func (m *PeerGracefulRestart) String() string { return proto.CompactTextString(m) } +func (*PeerGracefulRestart) ProtoMessage() {} + +type LoggingOptions struct { + LogNeighborStateChanges bool `protobuf:"varint,1,opt,name=logNeighbor_state_changes" json:"logNeighbor_state_changes,omitempty"` +} + +func (m *LoggingOptions) Reset() { *m = LoggingOptions{} } +func (m *LoggingOptions) String() string { return proto.CompactTextString(m) } +func (*LoggingOptions) ProtoMessage() {} + +type RouteReflector struct { + RouteReflectorClient bool `protobuf:"varint,1,opt,name=route_reflector_client" json:"route_reflector_client,omitempty"` + RouteReflectorClusterId uint32 `protobuf:"varint,2,opt,name=route_reflector_cluster_id" json:"route_reflector_cluster_id,omitempty"` +} + +func (m *RouteReflector) Reset() { *m = RouteReflector{} } +func (m *RouteReflector) String() string { return proto.CompactTextString(m) } +func (*RouteReflector) ProtoMessage() {} + +type PeerState struct { + AuthPassword string `protobuf:"bytes,1,opt,name=auth_password" json:"auth_password,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"` + LocalAs uint32 `protobuf:"varint,3,opt,name=local_as" json:"local_as,omitempty"` + Messages *Messages `protobuf:"bytes,4,opt,name=messages" json:"messages,omitempty"` + NeighborAddress string `protobuf:"bytes,5,opt,name=neighbor_address" json:"neighbor_address,omitempty"` + PeerAs uint32 `protobuf:"varint,6,opt,name=peer_as" json:"peer_as,omitempty"` + PeerGroup string `protobuf:"bytes,7,opt,name=peer_group" json:"peer_group,omitempty"` + PeerType uint32 `protobuf:"varint,8,opt,name=peer_type" json:"peer_type,omitempty"` + Queues *Queues `protobuf:"bytes,9,opt,name=queues" json:"queues,omitempty"` + RemovePrivateAs uint32 `protobuf:"varint,10,opt,name=remove_private_as" json:"remove_private_as,omitempty"` + RouteFlapDamping bool `protobuf:"varint,11,opt,name=route_flap_damping" json:"route_flap_damping,omitempty"` + SendCommunity uint32 `protobuf:"varint,12,opt,name=send_community" json:"send_community,omitempty"` + SessionState uint32 `protobuf:"varint,13,opt,name=session_state" json:"session_state,omitempty"` + SupportedCapabilities []string `protobuf:"bytes,14,rep,name=supported_capabilities" json:"supported_capabilities,omitempty"` + BgpState string `protobuf:"bytes,15,opt,name=bgp_state" json:"bgp_state,omitempty"` + AdminState string `protobuf:"bytes,16,opt,name=admin_state" json:"admin_state,omitempty"` + Received uint32 `protobuf:"varint,17,opt,name=received" json:"received,omitempty"` + Accepted uint32 `protobuf:"varint,18,opt,name=accepted" json:"accepted,omitempty"` + Advertized uint32 `protobuf:"varint,19,opt,name=advertized" json:"advertized,omitempty"` + OutQ uint32 `protobuf:"varint,20,opt,name=out_q" json:"out_q,omitempty"` + Flops uint32 `protobuf:"varint,21,opt,name=flops" json:"flops,omitempty"` +} + +func (m *PeerState) Reset() { *m = PeerState{} } +func (m *PeerState) String() string { return proto.CompactTextString(m) } +func (*PeerState) ProtoMessage() {} + +func (m *PeerState) GetMessages() *Messages { + if m != nil { + return m.Messages + } + return nil +} -type Peer struct { - Conf *PeerConf `protobuf:"bytes,1,opt,name=conf" json:"conf,omitempty"` - Info *PeerInfo `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"` +func (m *PeerState) GetQueues() *Queues { + if m != nil { + return m.Queues + } + return nil } -func (m *Peer) Reset() { *m = Peer{} } -func (m *Peer) String() string { return proto.CompactTextString(m) } -func (*Peer) ProtoMessage() {} +type Messages struct { + Received *Message `protobuf:"bytes,1,opt,name=received" json:"received,omitempty"` + Sent *Message `protobuf:"bytes,2,opt,name=sent" json:"sent,omitempty"` +} -func (m *Peer) GetConf() *PeerConf { +func (m *Messages) Reset() { *m = Messages{} } +func (m *Messages) String() string { return proto.CompactTextString(m) } +func (*Messages) ProtoMessage() {} + +func (m *Messages) GetReceived() *Message { if m != nil { - return m.Conf + return m.Received } return nil } -func (m *Peer) GetInfo() *PeerInfo { +func (m *Messages) GetSent() *Message { if m != nil { - return m.Info + return m.Sent } return nil } +type Message struct { + NOTIFICATION uint64 `protobuf:"varint,1,opt,name=NOTIFICATION" json:"NOTIFICATION,omitempty"` + UPDATE uint64 `protobuf:"varint,2,opt,name=UPDATE" json:"UPDATE,omitempty"` + OPEN uint64 `protobuf:"varint,3,opt,name=OPEN" json:"OPEN,omitempty"` + KEEPALIVE uint64 `protobuf:"varint,4,opt,name=KEEPALIVE" json:"KEEPALIVE,omitempty"` + REFRESH uint64 `protobuf:"varint,5,opt,name=REFRESH" json:"REFRESH,omitempty"` + DISCARDED uint64 `protobuf:"varint,6,opt,name=DISCARDED" json:"DISCARDED,omitempty"` + TOTAL uint64 `protobuf:"varint,7,opt,name=TOTAL" json:"TOTAL,omitempty"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} + +type Queues struct { + Input uint32 `protobuf:"varint,1,opt,name=input" json:"input,omitempty"` + Output uint32 `protobuf:"varint,2,opt,name=output" json:"output,omitempty"` +} + +func (m *Queues) Reset() { *m = Queues{} } +func (m *Queues) String() string { return proto.CompactTextString(m) } +func (*Queues) ProtoMessage() {} + +type Timers struct { + Config *TimersConfig `protobuf:"bytes,1,opt,name=config" json:"config,omitempty"` + State *TimersState `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` +} + +func (m *Timers) Reset() { *m = Timers{} } +func (m *Timers) String() string { return proto.CompactTextString(m) } +func (*Timers) ProtoMessage() {} + +func (m *Timers) GetConfig() *TimersConfig { + if m != nil { + return m.Config + } + return nil +} + +func (m *Timers) GetState() *TimersState { + if m != nil { + return m.State + } + return nil +} + +type TimersConfig struct { + ConnectRetry uint64 `protobuf:"varint,1,opt,name=connect_retry" json:"connect_retry,omitempty"` + HoldTime uint64 `protobuf:"varint,2,opt,name=hold_time" json:"hold_time,omitempty"` + KeepaliveInterval uint64 `protobuf:"varint,3,opt,name=keepalive_interval" json:"keepalive_interval,omitempty"` + MinimumAdvertisementInterval uint64 `protobuf:"varint,4,opt,name=minimum_advertisement_interval" json:"minimum_advertisement_interval,omitempty"` +} + +func (m *TimersConfig) Reset() { *m = TimersConfig{} } +func (m *TimersConfig) String() string { return proto.CompactTextString(m) } +func (*TimersConfig) ProtoMessage() {} + +type TimersState struct { + ConnectRetry uint64 `protobuf:"varint,1,opt,name=connect_retry" json:"connect_retry,omitempty"` + HoldTime uint64 `protobuf:"varint,2,opt,name=hold_time" json:"hold_time,omitempty"` + KeepaliveInterval uint64 `protobuf:"varint,3,opt,name=keepalive_interval" json:"keepalive_interval,omitempty"` + MinimumAdvertisementInterval uint64 `protobuf:"varint,4,opt,name=minimum_advertisement_interval" json:"minimum_advertisement_interval,omitempty"` + NegotiatedHoldTime uint64 `protobuf:"varint,5,opt,name=negotiated_hold_time" json:"negotiated_hold_time,omitempty"` + Uptime uint64 `protobuf:"varint,6,opt,name=uptime" json:"uptime,omitempty"` + Downtime uint64 `protobuf:"varint,7,opt,name=downtime" json:"downtime,omitempty"` +} + +func (m *TimersState) Reset() { *m = TimersState{} } +func (m *TimersState) String() string { return proto.CompactTextString(m) } +func (*TimersState) ProtoMessage() {} + +type Transport struct { + LocalAddress string `protobuf:"bytes,1,opt,name=local_address" json:"local_address,omitempty"` + LocalPort uint32 `protobuf:"varint,2,opt,name=local_port" json:"local_port,omitempty"` + MtuDiscovery bool `protobuf:"varint,3,opt,name=mtu_discovery" json:"mtu_discovery,omitempty"` + PassiveMode bool `protobuf:"varint,4,opt,name=passive_mode" json:"passive_mode,omitempty"` + RemoteAddress string `protobuf:"bytes,5,opt,name=remote_address" json:"remote_address,omitempty"` + RemotePort uint32 `protobuf:"varint,6,opt,name=remote_port" json:"remote_port,omitempty"` + TcpMss uint32 `protobuf:"varint,7,opt,name=tcp_mss" json:"tcp_mss,omitempty"` +} + +func (m *Transport) Reset() { *m = Transport{} } +func (m *Transport) String() string { return proto.CompactTextString(m) } +func (*Transport) ProtoMessage() {} + +type RouteServer struct { + RouteServerClient bool `protobuf:"varint,1,opt,name=route_server_client" json:"route_server_client,omitempty"` +} + +func (m *RouteServer) Reset() { *m = RouteServer{} } +func (m *RouteServer) String() string { return proto.CompactTextString(m) } +func (*RouteServer) ProtoMessage() {} + type Prefix struct { IpPrefix string `protobuf:"bytes,1,opt,name=ip_prefix" json:"ip_prefix,omitempty"` MaskLengthMin uint32 `protobuf:"varint,2,opt,name=mask_length_min" json:"mask_length_min,omitempty"` @@ -863,6 +1476,7 @@ var _ grpc.ClientConn type GobgpApiClient interface { GetNeighbors(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetNeighborsClient, error) GetNeighbor(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Peer, error) + ModNeighbor(ctx context.Context, in *ModNeighborArguments, opts ...grpc.CallOption) (*Error, error) GetRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetRibClient, error) Reset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) SoftReset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) @@ -941,6 +1555,15 @@ func (c *gobgpApiClient) GetNeighbor(ctx context.Context, in *Arguments, opts .. return out, nil } +func (c *gobgpApiClient) ModNeighbor(ctx context.Context, in *ModNeighborArguments, opts ...grpc.CallOption) (*Error, error) { + out := new(Error) + err := grpc.Invoke(ctx, "/gobgpapi.GobgpApi/ModNeighbor", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *gobgpApiClient) GetRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetRibClient, error) { stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[1], c.cc, "/gobgpapi.GobgpApi/GetRib", opts...) if err != nil { @@ -1444,6 +2067,7 @@ func (c *gobgpApiClient) ModPolicyAssignment(ctx context.Context, in *ModPolicyA type GobgpApiServer interface { GetNeighbors(*Arguments, GobgpApi_GetNeighborsServer) error GetNeighbor(context.Context, *Arguments) (*Peer, error) + ModNeighbor(context.Context, *ModNeighborArguments) (*Error, error) GetRib(*Arguments, GobgpApi_GetRibServer) error Reset(context.Context, *Arguments) (*Error, error) SoftReset(context.Context, *Arguments) (*Error, error) @@ -1510,6 +2134,18 @@ func _GobgpApi_GetNeighbor_Handler(srv interface{}, ctx context.Context, dec fun return out, nil } +func _GobgpApi_ModNeighbor_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(ModNeighborArguments) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(GobgpApiServer).ModNeighbor(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + func _GobgpApi_GetRib_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(Arguments) if err := stream.RecvMsg(m); err != nil { @@ -1947,6 +2583,10 @@ var _GobgpApi_serviceDesc = grpc.ServiceDesc{ Handler: _GobgpApi_GetNeighbor_Handler, }, { + MethodName: "ModNeighbor", + Handler: _GobgpApi_ModNeighbor_Handler, + }, + { MethodName: "Reset", Handler: _GobgpApi_Reset_Handler, }, diff --git a/api/gobgp.proto b/api/gobgp.proto index 1a17a2cd..98085a10 100644 --- a/api/gobgp.proto +++ b/api/gobgp.proto @@ -22,6 +22,7 @@ package gobgpapi; service GobgpApi { rpc GetNeighbors(Arguments) returns (stream Peer) {} rpc GetNeighbor(Arguments) returns (Peer) {} + rpc ModNeighbor(ModNeighborArguments) returns(Error) {} rpc GetRib(Arguments) returns (stream Destination) {} rpc Reset(Arguments) returns (Error) {} rpc SoftReset(Arguments) returns (Error) {} @@ -72,6 +73,10 @@ message ModPathArguments { repeated Path paths = 3; } +message ModNeighborArguments { + Operation operation = 1; + Peer peer = 2; +} message MrtArguments { Resource resource = 1; uint32 rf = 2; @@ -146,49 +151,228 @@ message Destination { repeated Path paths = 2; } -message PeerConf { - string remote_ip = 1; - string id = 2; - uint32 remote_as = 3; - repeated bytes remote_cap = 6; - repeated bytes local_cap = 7; - uint32 holdtime = 8; - uint32 keepalive_interval = 9; -} - -message PeerInfo { - string bgp_state = 1; - string admin_state = 2; - uint32 fsm_established_transitions = 3; - uint64 total_message_out = 4; - uint64 total_message_in = 5; - uint64 update_message_out = 6; - uint64 update_message_in = 7; - uint64 keep_alive_message_out = 8; - uint64 keep_alive_message_in = 9; - uint64 open_message_out = 10; - uint64 open_message_in = 11; - uint64 notification_out = 12; - uint64 notification_in = 13; - uint64 refresh_message_out = 14; - uint64 refresh_message_in = 15; - uint64 discarded_out = 16; - uint64 discarded_in = 17; - int64 uptime = 18; - int64 downtime = 19; - string last_error = 20; - uint32 received = 21; - uint32 accepted = 22; - uint32 advertized = 23; - uint32 out_q = 24; - uint32 flops = 25; - uint32 negotiated_holdtime = 26; - uint32 keepalive_interval = 27; +message Peer { + AddPaths addpaths = 1; + AfiSafis afisafis = 2; + ApplyPolicy apply_policy = 3; + AsPathOptions as_path_options = 4; + PeerConf conf = 5; + EbgpMultihop ebgp_multihop = 6; + ErrorHandling error_handling = 7; + PeerGracefulRestart graceful_restart = 8; + LoggingOptions logging_options = 9; + string nighbor_address = 10; + RouteReflector route_reflector = 11; + PeerState info = 12; + Timers timers = 13; + Transport transport = 14; + UseMultiplePaths use_multiple_paths = 15; + RouteServer route_server = 16; } -message Peer { - PeerConf conf = 1; - PeerInfo info = 2; +message AddPaths { + bool receive = 1; + uint32 send_max = 2; +} + +message AfiSafis { + repeated AfiSafi afisafi = 1; +} + +message AfiSafi { + string name = 1; + ApplyPolicy apply_policy = 2; + bool enabled = 3; + AfiSafiGracefulRestart graceful_restart = 4; + LabelledUnicast ipv4_labelled_unicast = 5; + Unicast ipv4_unicast = 6; + LabelledUnicast ipv6_labelled_unicast = 7; + Unicast ipv6_unicast = 8; + Vpn l2_vpn_evpn = 9; + Vpn l2_vpn_vpls = 10; + Vpn l3_vpn_ipv4_multicast = 11; + Vpn l3_vpn_ipv4_unicast = 12; + Vpn l3_vpn_ipv6_multicast = 13; + Vpn l3_vpn_ipv6_unicast = 14; + UseMultiplePaths use_multiple_paths = 15; + bool active = 16; + Prefixes prefixes = 17; + } + +message ApplyPolicy { + PolicyAssignment in_policy = 1; + PolicyAssignment export_policy = 2; + PolicyAssignment import_policy = 3; +} + +message AfiSafiGracefulRestart { + bool advertised = 1; + bool enabled = 2; + bool received = 3; +} + +message LabelledUnicast { + PrefixLimit prefix_limit = 1; +} + +message PrefixLimit { + uint32 max_prefixes = 1; + uint64 restart_timer = 2; + uint32 shutdown_threshold_pct = 3; +} + +message Unicast { + bool send_default_route = 1; + PrefixLimit prefix_limit = 2; +} + +message Vpn { + PrefixLimit prefix_limit = 1; +} + +message Prefixes { + uint32 installed = 1; + uint32 received = 2; + uint32 sent = 3; +} + +message UseMultiplePaths { + bool enabled = 1; + Ebgp ebgp = 2; +} + +message Ebgp { + bool allow_multiple_as = 1; +} + +message AsPathOptions { + uint32 allow_own_as = 1; + bool replace_peer_as = 2; +} + +message PeerConf { + string auth_password = 1; + string description = 2; + uint32 local_as = 3; + string neighbor_address = 4; + uint32 peer_as = 5; + string peer_group = 6; + uint32 peer_type = 7; + uint32 remove_private_as = 8; + bool route_flap_damping = 9; + uint32 send_community = 10; + repeated bytes remote_cap = 11; + repeated bytes local_cap = 12; +} + +message EbgpMultihop { + bool enabled = 1; + uint32 multihop_ttl = 2; +} + +message ErrorHandling { + uint32 erroneous_update_messages = 1; + bool treat_as_withdraw = 2; +} + +message PeerGracefulRestart { + bool enabled = 1; + bool helper_only = 2; + bool local_restarting = 3; + uint32 mode = 4; + uint32 peer_restart_time = 5; + bool peer_restarting = 6; + uint32 restart_time = 7; + uint64 stale_routes_time = 8; +} + +message LoggingOptions { + bool logNeighbor_state_changes = 1; +} + +message RouteReflector { + bool route_reflector_client = 1; + uint32 route_reflector_cluster_id = 2; + } + +message PeerState { + string auth_password = 1; + string description = 2; + uint32 local_as = 3; + Messages messages = 4; + string neighbor_address = 5; + uint32 peer_as = 6; + string peer_group = 7; + uint32 peer_type = 8; + Queues queues = 9; + uint32 remove_private_as = 10; + bool route_flap_damping = 11; + uint32 send_community = 12; + uint32 session_state = 13; + repeated string supported_capabilities = 14; + string bgp_state = 15; + string admin_state = 16; + uint32 received = 17; + uint32 accepted = 18; + uint32 advertized = 19; + uint32 out_q = 20; + uint32 flops = 21; +} + +message Messages { + Message received = 1; + Message sent = 2; +} + +message Message { + uint64 NOTIFICATION = 1; + uint64 UPDATE = 2; + uint64 OPEN = 3; + uint64 KEEPALIVE = 4; + uint64 REFRESH = 5; + uint64 DISCARDED = 6; + uint64 TOTAL = 7; +} + +message Queues { + uint32 input = 1; + uint32 output = 2; +} + +message Timers { + TimersConfig config =1; + TimersState state = 2; +} + +message TimersConfig{ + uint64 connect_retry = 1; + uint64 hold_time = 2; + uint64 keepalive_interval = 3; + uint64 minimum_advertisement_interval = 4; +} + +message TimersState{ + uint64 connect_retry = 1; + uint64 hold_time = 2; + uint64 keepalive_interval = 3; + uint64 minimum_advertisement_interval = 4; + uint64 negotiated_hold_time = 5; + uint64 uptime = 6; + uint64 downtime = 7; +} + +message Transport { + string local_address = 1; + uint32 local_port = 2; + bool mtu_discovery = 3; + bool passive_mode = 4; + string remote_address = 5; + uint32 remote_port = 6; + uint32 tcp_mss = 7; + } + +message RouteServer { + bool route_server_client = 1; } message Prefix { diff --git a/gobgp/cmd/common.go b/gobgp/cmd/common.go index 9e1c3315..32cff9b5 100644 --- a/gobgp/cmd/common.go +++ b/gobgp/cmd/common.go @@ -237,8 +237,9 @@ type PeerConf struct { } type Peer struct { - Conf PeerConf `json:"conf,omitempty"` - Info *gobgpapi.PeerInfo `json:"info,omitempty"` + Conf PeerConf `json:"conf,omitempty"` + Info *gobgpapi.PeerState `json:"info,omitempty"` + Timers *gobgpapi.Timers `json:"timers,,omitempty"` } func ApiStruct2Peer(p *gobgpapi.Peer) *Peer { @@ -253,17 +254,16 @@ func ApiStruct2Peer(p *gobgpapi.Peer) *Peer { remoteCaps = append(remoteCaps, c) } conf := PeerConf{ - RemoteIp: net.ParseIP(p.Conf.RemoteIp), - Id: net.ParseIP(p.Conf.Id), - RemoteAs: p.Conf.RemoteAs, - RemoteCap: remoteCaps, - LocalCap: localCaps, - Holdtime: p.Conf.Holdtime, - KeepaliveInterval: p.Conf.KeepaliveInterval, + RemoteIp: net.ParseIP(p.Conf.NeighborAddress), + Id: net.ParseIP(p.Conf.NeighborAddress), + RemoteAs: p.Conf.PeerAs, + RemoteCap: remoteCaps, + LocalCap: localCaps, } return &Peer{ - Conf: conf, - Info: p.Info, + Conf: conf, + Info: p.Info, + Timers: p.Timers, } } diff --git a/gobgp/cmd/monitor.go b/gobgp/cmd/monitor.go index 5d0d201e..3c1e0bc0 100644 --- a/gobgp/cmd/monitor.go +++ b/gobgp/cmd/monitor.go @@ -105,7 +105,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.RemoteIp, s.Info.BgpState, s.Info.AdminState) + fmt.Printf("[NEIGH] %s fsm: %s admin: %s\n", s.Conf.NeighborAddress, s.Info.BgpState, s.Info.AdminState) } } }, diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go index bbb524bc..170e6726 100644 --- a/gobgp/cmd/neighbor.go +++ b/gobgp/cmd/neighbor.go @@ -47,7 +47,7 @@ func getNeighbors() (peers, error) { return nil, e } if neighborsOpts.Transport != "" { - addr := net.ParseIP(p.Conf.RemoteIp) + addr := net.ParseIP(p.Conf.NeighborAddress) if addr.To4() != nil { if neighborsOpts.Transport != "ipv4" { continue @@ -96,12 +96,12 @@ func showNeighbors() error { maxaslen = len(fmt.Sprint(p.Conf.RemoteAs)) } var t string - if p.Info.Uptime == 0 { + if p.Timers.State.Uptime == 0 { t = "never" } else if p.Info.BgpState == "BGP_FSM_ESTABLISHED" { - t = formatTimedelta(p.Info.Uptime) + t = formatTimedelta(int64(p.Timers.State.Uptime)) } else { - t = formatTimedelta(p.Info.Downtime) + t = formatTimedelta(int64(p.Timers.State.Downtime)) } if len(t) > maxtimelen { maxtimelen = len(t) @@ -157,10 +157,10 @@ func showNeighbor(args []string) error { fmt.Printf("BGP neighbor is %s, remote AS %d\n", p.Conf.RemoteIp, p.Conf.RemoteAs) fmt.Printf(" BGP version 4, remote router ID %s\n", p.Conf.Id) - fmt.Printf(" BGP state = %s, up for %s\n", p.Info.BgpState, formatTimedelta(p.Info.Uptime)) + fmt.Printf(" BGP state = %s, up for %s\n", p.Info.BgpState, formatTimedelta(int64(p.Timers.State.Uptime))) fmt.Printf(" BGP OutQ = %d, Flops = %d\n", p.Info.OutQ, p.Info.Flops) - fmt.Printf(" Hold time is %d, keepalive interval is %d seconds\n", p.Info.NegotiatedHoldtime, p.Info.KeepaliveInterval) - fmt.Printf(" Configured hold time is %d, keepalive interval is %d seconds\n", p.Conf.Holdtime, p.Conf.KeepaliveInterval) + fmt.Printf(" Hold time is %d, keepalive interval is %d seconds\n", p.Timers.State.NegotiatedHoldTime, p.Timers.Config.KeepaliveInterval) + fmt.Printf(" Configured hold time is %d, keepalive interval is %d seconds\n", p.Timers.Config.HoldTime, p.Timers.Config.KeepaliveInterval) fmt.Printf(" Neighbor capabilities:\n") caps := capabilities{} @@ -218,13 +218,13 @@ func showNeighbor(args []string) error { } fmt.Print(" Message statistics:\n") fmt.Print(" Sent Rcvd\n") - fmt.Printf(" Opens: %10d %10d\n", p.Info.OpenMessageOut, p.Info.OpenMessageIn) - fmt.Printf(" Notifications: %10d %10d\n", p.Info.NotificationOut, p.Info.NotificationIn) - fmt.Printf(" Updates: %10d %10d\n", p.Info.UpdateMessageOut, p.Info.UpdateMessageIn) - fmt.Printf(" Keepalives: %10d %10d\n", p.Info.KeepAliveMessageOut, p.Info.KeepAliveMessageIn) - fmt.Printf(" Route Refesh: %10d %10d\n", p.Info.RefreshMessageOut, p.Info.RefreshMessageIn) - fmt.Printf(" Discarded: %10d %10d\n", p.Info.DiscardedOut, p.Info.DiscardedIn) - fmt.Printf(" Total: %10d %10d\n", p.Info.TotalMessageOut, p.Info.TotalMessageIn) + 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.Print(" Route statistics:\n") fmt.Printf(" Advertised: %10d\n", p.Info.Advertized) fmt.Printf(" Received: %10d\n", p.Info.Received) diff --git a/server/grpc_server.go b/server/grpc_server.go index f6f233a0..348d11c7 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -40,6 +40,7 @@ const ( REQ_NEIGHBOR_SOFT_RESET_OUT REQ_NEIGHBOR_ENABLE REQ_NEIGHBOR_DISABLE + REQ_MOD_NEIGHBOR REQ_GLOBAL_RIB REQ_MONITOR_GLOBAL_BEST_CHANGED REQ_MONITOR_NEIGHBOR_PEER_STATE @@ -308,6 +309,10 @@ func (s *Server) ModVrf(ctx context.Context, arg *api.ModVrfArguments) (*api.Err return s.mod(REQ_VRF_MOD, arg) } +func (s *Server) ModNeighbor(ctx context.Context, arg *api.ModNeighborArguments) (*api.Error, error) { + return s.mod(REQ_MOD_NEIGHBOR, arg) +} + func (s *Server) GetDefinedSet(ctx context.Context, arg *api.DefinedSet) (*api.DefinedSet, error) { d, err := s.get(REQ_DEFINED_SET, arg) if err != nil { diff --git a/server/peer.go b/server/peer.go index f21ed0bd..26158a1e 100644 --- a/server/peer.go +++ b/server/peer.go @@ -298,26 +298,20 @@ func (peer *Peer) ToApiStruct() *api.Peer { } conf := &api.PeerConf{ - RemoteIp: c.NeighborConfig.NeighborAddress.String(), - Id: peer.peerInfo.ID.To4().String(), - RemoteAs: c.NeighborConfig.PeerAs, - RemoteCap: remoteCap, - LocalCap: localCap, - KeepaliveInterval: uint32(peer.conf.Timers.TimersConfig.KeepaliveInterval), - Holdtime: uint32(peer.conf.Timers.TimersConfig.HoldTime), + NeighborAddress: c.NeighborConfig.NeighborAddress.String(), + PeerAs: c.NeighborConfig.PeerAs, + LocalAs: c.NeighborConfig.LocalAs, + PeerType: uint32(c.NeighborConfig.PeerType), + AuthPassword: c.NeighborConfig.AuthPassword, + RemovePrivateAs: uint32(c.NeighborConfig.RemovePrivateAs), + RouteFlapDamping: c.NeighborConfig.RouteFlapDamping, + SendCommunity: uint32(c.NeighborConfig.SendCommunity), + Description: c.NeighborConfig.Description, + PeerGroup: c.NeighborConfig.PeerGroup, } - s := &c.NeighborState timer := &c.Timers - - uptime := int64(0) - if timer.TimersState.Uptime != 0 { - uptime = int64(time.Now().Sub(time.Unix(timer.TimersState.Uptime, 0)).Seconds()) - } - downtime := int64(0) - if timer.TimersState.Downtime != 0 { - downtime = int64(time.Now().Sub(time.Unix(timer.TimersState.Downtime, 0)).Seconds()) - } + s := &c.NeighborState advertized := uint32(0) received := uint32(0) @@ -334,6 +328,15 @@ func (peer *Peer) ToApiStruct() *api.Peer { } } + uptime := int64(0) + if timer.TimersState.Uptime != 0 { + uptime = int64(time.Now().Sub(time.Unix(timer.TimersState.Uptime, 0)).Seconds()) + } + downtime := int64(0) + if timer.TimersState.Downtime != 0 { + downtime = int64(time.Now().Sub(time.Unix(timer.TimersState.Downtime, 0)).Seconds()) + } + keepalive := uint32(0) if f.negotiatedHoldTime != 0 { if f.negotiatedHoldTime < timer.TimersConfig.HoldTime { @@ -343,38 +346,57 @@ func (peer *Peer) ToApiStruct() *api.Peer { } } - info := &api.PeerInfo{ - BgpState: f.state.String(), - AdminState: f.adminState.String(), - FsmEstablishedTransitions: s.EstablishedCount, - TotalMessageOut: s.Messages.Sent.Total, - TotalMessageIn: s.Messages.Received.Total, - UpdateMessageOut: s.Messages.Sent.Update, - UpdateMessageIn: s.Messages.Received.Update, - KeepAliveMessageOut: s.Messages.Sent.Keepalive, - KeepAliveMessageIn: s.Messages.Received.Keepalive, - OpenMessageOut: s.Messages.Sent.Open, - OpenMessageIn: s.Messages.Received.Open, - NotificationOut: s.Messages.Sent.Notification, - NotificationIn: s.Messages.Received.Notification, - RefreshMessageOut: s.Messages.Sent.Refresh, - RefreshMessageIn: s.Messages.Received.Refresh, - DiscardedOut: s.Messages.Sent.Discarded, - DiscardedIn: s.Messages.Received.Discarded, - Uptime: uptime, - Downtime: downtime, - Received: received, - Accepted: accepted, - Advertized: advertized, - OutQ: uint32(len(peer.outgoing)), - Flops: s.Flops, - NegotiatedHoldtime: uint32(f.negotiatedHoldTime), - KeepaliveInterval: keepalive, + timerconf := &api.TimersConfig{ + ConnectRetry: uint64(timer.TimersConfig.ConnectRetry), + HoldTime: uint64(timer.TimersConfig.HoldTime), + KeepaliveInterval: uint64(keepalive), + MinimumAdvertisementInterval: uint64(timer.TimersConfig.MinimumAdvertisementInterval), + } + + timerstate := &api.TimersState{ + Uptime: uint64(uptime), + Downtime: uint64(downtime), + } + + apitimer := &api.Timers{ + Config: timerconf, + State: timerstate, + } + msgrcv := &api.Message{ + NOTIFICATION: s.Messages.Received.Notification, + UPDATE: s.Messages.Received.Update, + OPEN: s.Messages.Received.Open, + KEEPALIVE: s.Messages.Received.Keepalive, + REFRESH: s.Messages.Received.Refresh, + DISCARDED: s.Messages.Received.Discarded, + TOTAL: s.Messages.Received.Total, + } + msgsnt := &api.Message{ + NOTIFICATION: s.Messages.Sent.Notification, + UPDATE: s.Messages.Sent.Update, + OPEN: s.Messages.Sent.Open, + KEEPALIVE: s.Messages.Sent.Keepalive, + REFRESH: s.Messages.Sent.Refresh, + DISCARDED: s.Messages.Sent.Discarded, + TOTAL: s.Messages.Sent.Total, + } + msg := &api.Messages{ + Received: msgrcv, + Sent: msgsnt, + } + info := &api.PeerState{ + BgpState: f.state.String(), + AdminState: f.adminState.String(), + Messages: msg, + Received: received, + Accepted: accepted, + Advertized: advertized, } return &api.Peer{ - Conf: conf, - Info: info, + Conf: conf, + Info: info, + Timers: apitimer, } } diff --git a/server/server.go b/server/server.go index a14f8395..49b584ca 100644 --- a/server/server.go +++ b/server/server.go @@ -80,6 +80,7 @@ type BgpServer struct { addedPeerCh chan config.Neighbor deletedPeerCh chan config.Neighbor updatedPeerCh chan config.Neighbor + fsmincomingCh chan *fsmMsg rpkiConfigCh chan config.RpkiServers bmpConfigCh chan config.BmpServers dumper *dumper @@ -90,6 +91,7 @@ type BgpServer struct { policy *table.RoutingPolicy broadcastReqs []*GrpcRequest broadcastMsgs []broadcastMsg + listenerMap map[string]*net.TCPListener neighborMap map[string]*Peer globalRib *table.TableManager zclient *zebra.Client @@ -210,12 +212,12 @@ func (server *BgpServer) Serve() { return rfList } server.globalRib = table.NewTableManager(GLOBAL_RIB_NAME, toRFlist(g.AfiSafis.AfiSafiList), g.MplsLabelRange.MinLabel, g.MplsLabelRange.MaxLabel) - listenerMap := make(map[string]*net.TCPListener) + server.listenerMap = make(map[string]*net.TCPListener) acceptCh := make(chan *net.TCPConn) l4, err1 := listenAndAccept("tcp4", server.listenPort, acceptCh) - listenerMap["tcp4"] = l4 + server.listenerMap["tcp4"] = l4 l6, err2 := listenAndAccept("tcp6", server.listenPort, acceptCh) - listenerMap["tcp6"] = l6 + server.listenerMap["tcp6"] = l6 if err1 != nil && err2 != nil { log.Fatal("can't listen either v4 and v6") os.Exit(1) @@ -224,14 +226,14 @@ func (server *BgpServer) Serve() { listener := func(addr net.IP) *net.TCPListener { var l *net.TCPListener if addr.To4() != nil { - l = listenerMap["tcp4"] + l = server.listenerMap["tcp4"] } else { - l = listenerMap["tcp6"] + l = server.listenerMap["tcp6"] } return l } - incoming := make(chan *fsmMsg, 4096) + server.fsmincomingCh = make(chan *fsmMsg, 4096) var senderMsgs []*SenderMsg var zapiMsgCh chan *zebra.Message @@ -367,7 +369,7 @@ func (server *BgpServer) Serve() { } } server.neighborMap[addr] = peer - peer.startFSMHandler(incoming) + peer.startFSMHandler(server.fsmincomingCh) server.broadcastPeerState(peer) case config := <-server.deletedPeerCh: addr := config.NeighborConfig.NeighborAddress.String() @@ -399,13 +401,13 @@ func (server *BgpServer) Serve() { peer := server.neighborMap[addr] peer.conf = config server.setPolicyByConfig(peer, config.ApplyPolicy) - case e := <-incoming: + case e := <-server.fsmincomingCh: peer, found := server.neighborMap[e.MsgSrc] if !found { log.Warn("Can't find the neighbor ", e.MsgSrc) break } - m := server.handleFSMMessage(peer, e, incoming) + m := server.handleFSMMessage(peer, e, server.fsmincomingCh) if len(m) > 0 { senderMsgs = append(senderMsgs, m...) } @@ -1544,6 +1546,15 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { result.Data = err grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) + case REQ_MOD_NEIGHBOR: + m, err := server.handleGrpcModNeighbor(grpcReq) + grpcReq.ResponseCh <- &GrpcResponse{ + ResponseErr: err, + } + if len(m) > 0 { + msgs = append(msgs, m...) + } + close(grpcReq.ResponseCh) case REQ_DEFINED_SET: if err := server.handleGrpcGetDefinedSet(grpcReq); err != nil { grpcReq.ResponseCh <- &GrpcResponse{ @@ -1644,6 +1655,149 @@ func (server *BgpServer) handleGrpcGetDefinedSet(grpcReq *GrpcRequest) error { } return nil } +func (server *BgpServer) handleGrpcModNeighbor(grpcReq *GrpcRequest) (sMsgs []*SenderMsg, err error) { + arg := grpcReq.Data.(*api.ModNeighborArguments) + addr := arg.Peer.Conf.NeighborAddress + n, ok := server.neighborMap[addr] + if arg.Operation != api.Operation_ADD && !ok { + return nil, fmt.Errorf("not found neighbor %s", addr) + } + listener := func(addr net.IP) *net.TCPListener { + var l *net.TCPListener + if addr.To4() != nil { + l = server.listenerMap["tcp4"] + } else { + l = server.listenerMap["tcp6"] + } + return l + } + + switch arg.Operation { + case api.Operation_ADD: + if ok { + return nil, fmt.Errorf("Can't overwrite the exising peer %s", addr) + } else { + log.Infof("Peer %s is added", addr) + } + SetTcpMD5SigSockopts(listener(net.ParseIP(addr)), addr, arg.Peer.Conf.AuthPassword) + var loc *table.TableManager + if arg.Peer.RouteServer != nil { + if arg.Peer.RouteServer.RouteServerClient { + apitoRFlist := func(l []*api.AfiSafi) []bgp.RouteFamily { + rfList := []bgp.RouteFamily{} + for _, rf := range l { + k, _ := bgp.GetRouteFamily(rf.Name) + rfList = append(rfList, k) + } + return rfList + } + loc = table.NewTableManager(addr, apitoRFlist(arg.Peer.Afisafis.Afisafi), server.bgpConfig.Global.MplsLabelRange.MinLabel, server.bgpConfig.Global.MplsLabelRange.MaxLabel) + } else { + loc = server.globalRib + } + } else { + loc = server.globalRib + } + apitoConfig := func(a *api.Peer) config.Neighbor { + var pconf config.Neighbor + if a.Conf != nil { + pconf.NeighborAddress = net.ParseIP(a.Conf.NeighborAddress) + pconf.NeighborConfig.PeerAs = a.Conf.PeerAs + pconf.NeighborConfig.LocalAs = a.Conf.LocalAs + if pconf.NeighborConfig.PeerAs != server.bgpConfig.Global.GlobalConfig.As { + pconf.NeighborConfig.PeerType = config.PEER_TYPE_EXTERNAL + } else { + pconf.NeighborConfig.PeerType = config.PEER_TYPE_INTERNAL + } + pconf.NeighborConfig.AuthPassword = a.Conf.AuthPassword + pconf.NeighborConfig.RemovePrivateAs = config.RemovePrivateAsOption(a.Conf.RemovePrivateAs) + pconf.NeighborConfig.RouteFlapDamping = a.Conf.RouteFlapDamping + pconf.NeighborConfig.SendCommunity = config.CommunityType(a.Conf.SendCommunity) + pconf.NeighborConfig.Description = a.Conf.Description + pconf.NeighborConfig.PeerGroup = a.Conf.PeerGroup + pconf.NeighborConfig.NeighborAddress = net.ParseIP(a.Conf.NeighborAddress) + } + if a.Timers != nil { + if a.Timers.Config != nil { + pconf.Timers.TimersConfig.ConnectRetry = float64(a.Timers.Config.ConnectRetry) + pconf.Timers.TimersConfig.HoldTime = float64(a.Timers.Config.HoldTime) + pconf.Timers.TimersConfig.KeepaliveInterval = float64(a.Timers.Config.KeepaliveInterval) + pconf.Timers.TimersConfig.MinimumAdvertisementInterval = float64(a.Timers.Config.MinimumAdvertisementInterval) + } + } else { + pconf.Timers.TimersConfig.ConnectRetry = float64(config.DEFAULT_CONNECT_RETRY) + pconf.Timers.TimersConfig.HoldTime = float64(config.DEFAULT_HOLDTIME) + pconf.Timers.TimersConfig.KeepaliveInterval = float64(config.DEFAULT_HOLDTIME / 3) + } + if a.RouteReflector != nil { + pconf.RouteReflector.RouteReflectorConfig.RouteReflectorClusterId = config.RrClusterIdType(a.RouteReflector.RouteReflectorClusterId) + pconf.RouteReflector.RouteReflectorConfig.RouteReflectorClient = a.RouteReflector.RouteReflectorClient + } + if a.RouteServer != nil { + pconf.RouteServer.RouteServerConfig.RouteServerClient = a.RouteServer.RouteServerClient + } + if a.ApplyPolicy != nil { + if a.ApplyPolicy.ImportPolicy != nil { + pconf.ApplyPolicy.ApplyPolicyConfig.DefaultImportPolicy = config.DefaultPolicyType(a.ApplyPolicy.ImportPolicy.Default) + for _, p := range a.ApplyPolicy.ImportPolicy.Policies { + pconf.ApplyPolicy.ApplyPolicyConfig.ImportPolicy = append(pconf.ApplyPolicy.ApplyPolicyConfig.ImportPolicy, p.Name) + } + } + if a.ApplyPolicy.ExportPolicy != nil { + pconf.ApplyPolicy.ApplyPolicyConfig.DefaultExportPolicy = config.DefaultPolicyType(a.ApplyPolicy.ExportPolicy.Default) + for _, p := range a.ApplyPolicy.ExportPolicy.Policies { + pconf.ApplyPolicy.ApplyPolicyConfig.ExportPolicy = append(pconf.ApplyPolicy.ApplyPolicyConfig.ExportPolicy, p.Name) + } + } + if a.ApplyPolicy.InPolicy != nil { + pconf.ApplyPolicy.ApplyPolicyConfig.DefaultInPolicy = config.DefaultPolicyType(a.ApplyPolicy.InPolicy.Default) + for _, p := range a.ApplyPolicy.InPolicy.Policies { + pconf.ApplyPolicy.ApplyPolicyConfig.InPolicy = append(pconf.ApplyPolicy.ApplyPolicyConfig.InPolicy, p.Name) + } + } + } + return pconf + } + configneigh := apitoConfig(arg.Peer) + peer := NewPeer(server.bgpConfig.Global, configneigh, loc) + server.setPolicyByConfig(peer, configneigh.ApplyPolicy) + if peer.isRouteServerClient() { + pathList := make([]*table.Path, 0) + rfList := peer.configuredRFlist() + for _, p := range server.neighborMap { + if p.isRouteServerClient() == true { + pathList = append(pathList, p.getAccepted(rfList)...) + } + } + pathList, _ = peer.ApplyPolicy(table.POLICY_DIRECTION_IMPORT, pathList) + if len(pathList) > 0 { + peer.localRib.ProcessPaths(pathList) + } + } + server.neighborMap[addr] = peer + peer.startFSMHandler(server.fsmincomingCh) + server.broadcastPeerState(peer) + case api.Operation_DEL: + SetTcpMD5SigSockopts(listener(net.ParseIP(addr)), addr, "") + log.Info("Delete a peer configuration for ", addr) + go func(addr string) { + t := time.AfterFunc(time.Minute*5, func() { log.Fatal("failed to free the fsm.h.t for ", addr) }) + n.fsm.h.t.Kill(nil) + n.fsm.h.t.Wait() + t.Stop() + t = time.AfterFunc(time.Minute*5, func() { log.Fatal("failed to free the fsm.h for ", addr) }) + n.fsm.t.Kill(nil) + n.fsm.t.Wait() + t.Stop() + }(addr) + m := server.dropPeerAllRoutes(n) + if len(m) > 0 { + sMsgs = append(sMsgs, m...) + } + delete(server.neighborMap, addr) + } + return sMsgs, err +} func (server *BgpServer) handleGrpcModDefinedSet(grpcReq *GrpcRequest) error { arg := grpcReq.Data.(*api.ModDefinedSetArguments) |