// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package gobgpapi;

// Interface exported by the server.

service GobgpApi {
  rpc GetNeighbors(Arguments) returns (stream Peer) {}
  rpc GetNeighbor(Arguments) returns (Peer) {}
  rpc GetRib(Arguments) returns (stream Destination) {}
  rpc Reset(Arguments) returns (Error) {}
  rpc SoftReset(Arguments) returns (Error) {}
  rpc SoftResetIn(Arguments) returns (Error) {}
  rpc SoftResetOut(Arguments) returns (Error) {}
  rpc Shutdown(Arguments) returns (Error) {}
  rpc Enable(Arguments) returns (Error) {}
  rpc Disable(Arguments) returns (Error) {}
  rpc ModPath(stream ModPathArguments) returns (Error) {}
  rpc MonitorBestChanged(Arguments) returns (stream Destination) {}
  rpc MonitorPeerState(Arguments) returns (stream Peer) {}
  rpc GetMrt(MrtArguments) returns (stream MrtMessage) {}
  rpc GetRPKI(Arguments) returns (stream RPKI) {}
  rpc GetROA(Arguments) returns (stream ROA) {}
  rpc GetVrfs(Arguments) returns (stream Vrf) {}
  rpc ModVrf(ModVrfArguments) returns (Error) {}
  rpc GetDefinedSet(DefinedSet) returns (DefinedSet) {}
  rpc GetDefinedSets(DefinedSet) returns (stream DefinedSet) {}
  rpc ModDefinedSet(ModDefinedSetArguments) returns (Error) {}
  rpc GetStatement(Statement) returns (Statement) {}
  rpc GetStatements(Statement) returns (stream Statement) {}
  rpc ModStatement(ModStatementArguments) returns (Error) {}
  rpc GetPolicy(Policy) returns (Policy) {}
  rpc GetPolicies(Policy) returns (stream Policy) {}
  rpc ModPolicy(ModPolicyArguments) returns (Error) {}
  rpc GetPolicyAssignment(PolicyAssignment) returns (PolicyAssignment) {}
  rpc ModPolicyAssignment(ModPolicyAssignmentArguments) returns (Error) {}
}

message Error {
    enum ErrorCode {
        SUCCESS = 0;
        FAIL = 1;
    }
    ErrorCode code = 1;
    string msg = 2;
}

message Arguments {
    Resource resource = 1;
    uint32 rf = 2;
    string name = 3;
}

message ModPathArguments {
    Resource resource = 1;
    string name = 2;
    repeated Path paths = 3;
}

message MrtArguments {
    Resource resource = 1;
    uint32 rf = 2;
    uint64 interval = 3;
    string neighbor_address = 4;
}

message ModVrfArguments {
    Operation operation = 1;
    Vrf vrf = 2;
}

message ModDefinedSetArguments {
    Operation operation = 1;
    DefinedSet set = 2;
}

message ModStatementArguments {
    Operation operation = 1;
    Statement statement = 2;
}

message ModPolicyArguments {
    Operation operation = 1;
    Policy policy = 2;
    // if this flag is set, gobgpd won't define new statements
    // but refer existing statements using statement's names in this arguments.
    // this flag only works with Operation_ADD
    bool refer_existing_statements = 3;
    // if this flag is set, gobgpd won't delete any statements
    // even if some statements get not used by any policy by this operation.
    // this flag means nothing if it is used with Operation_ADD
    bool preserve_statements = 4;
}

message ModPolicyAssignmentArguments {
    Operation operation = 1;
    PolicyAssignment assignment = 2;
}

enum Resource {
    GLOBAL = 0;
    LOCAL = 1;
    ADJ_IN = 2;
    ADJ_OUT = 3;
    VRF = 4;
}

enum Operation {
    ADD = 0;
    DEL = 1;
    DEL_ALL = 2;
    REPLACE = 3;
}

message Path {
    bytes nlri = 1;
    repeated bytes pattrs = 2;
    int64 age = 3;
    bool best = 4;
    bool is_withdraw = 5;
    int32 validation = 6;
    bool no_implicit_withdraw = 7;
    uint32 rf = 8;
    uint32 source_asn = 9;
    string source_id = 10;
    bool filtered = 11;
}

message Destination {
    string prefix = 1;
    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 {
    PeerConf conf = 1;
    PeerInfo info = 2;
}

message Prefix {
    string ip_prefix  = 1;
    uint32 mask_length_min = 2;
    uint32 mask_length_max = 3;
}

enum DefinedType {
    PREFIX = 0;
    NEIGHBOR = 1;
    TAG = 2;
    AS_PATH = 3;
    COMMUNITY = 4;
    EXT_COMMUNITY = 5;
}

message DefinedSet {
    DefinedType type = 1;
    string name = 2;
    repeated string list = 3;
    repeated Prefix prefixes = 4;
}

enum MatchType {
    ANY = 0;
    ALL = 1;
    INVERT = 2;
}

message MatchSet {
    MatchType type = 1;
    string name = 2;
}

enum AsPathLengthType {
    EQ = 0;
    GE = 1;
    LE = 2;
}

message AsPathLength {
    AsPathLengthType type = 1;
    uint32 length = 2;
}

message Conditions {
    MatchSet prefix_set = 1;
    MatchSet neighbor_set = 2;
    AsPathLength as_path_length = 3;
    MatchSet as_path_set = 4;
    MatchSet community_set = 5;
    MatchSet ext_community_set = 6;
    int32 rpki_result = 7;
}

enum RouteAction {
    NONE = 0;
    ACCEPT = 1;
    REJECT = 2;
}

enum CommunityActionType {
    COMMUNITY_ADD = 0;
    COMMUNITY_REMOVE = 1;
    COMMUNITY_REPLACE = 2;
}

message CommunityAction {
    CommunityActionType type = 1;
    repeated string communities = 2;
}

enum MedActionType {
    MED_MOD = 0;
    MED_REPLACE = 1;
}

message MedAction {
    MedActionType type = 1;
    int64 value = 2;
}

message AsPrependAction {
    uint32 asn = 1;
    uint32 repeat = 2;
    bool use_left_most = 3;
}

message Actions {
    RouteAction route_action = 1;
    CommunityAction community = 2;
    MedAction med = 3;
    AsPrependAction as_prepend = 4;
    CommunityAction ext_community = 5;
}

message Statement {
    string name = 1;
    Conditions conditions = 2;
    Actions actions = 3;
}

message Policy {
    string name = 1;
    repeated Statement statements = 2;
}

enum PolicyType {
    IN = 0;
    IMPORT = 1;
    EXPORT = 2;
}

message PolicyAssignment {
    PolicyType type = 1;
    Resource resource = 2;
    string name = 3;
    repeated Policy policies = 4;
    RouteAction default = 5;
}

message MrtMessage {
    bytes data = 1;
}

message RPKIConf {
    string address = 1;
}

message RPKIState {
    int64 uptime = 1;
    int64 downtime = 2;
    int32 received_ipv4 = 3;
    int32 received_ipv6 = 4;
}

message RPKI {
    RPKIConf conf = 1;
    RPKIState state = 2;
}

message ROA {
    uint32 as = 1;
    uint32 prefixlen = 2;
    uint32 maxlen = 3;
    string prefix = 4;
}

message Vrf {
    string name = 1;
    bytes rd = 2;
    repeated bytes import_rt = 3;
    repeated bytes export_rt = 4;
}