syntax = "proto3";

package api;

import "api/common.proto";
import "api/extcom.proto";

option go_package = "github.com/osrg/gobgp/v4/api;api";

// Main NLRI type

message NLRI {
  oneof nlri {
    IPAddressPrefix prefix = 1;
    LabeledIPAddressPrefix labeled_prefix = 2;
    EncapsulationNLRI encapsulation = 3;
    VPLSNLRI vpls = 4;
    EVPNEthernetAutoDiscoveryRoute evpn_ethernet_ad = 5;
    EVPNMACIPAdvertisementRoute evpn_macadv = 6;
    EVPNInclusiveMulticastEthernetTagRoute evpn_multicast = 7;
    EVPNEthernetSegmentRoute evpn_ethernet_segment = 8;
    EVPNIPPrefixRoute evpn_ip_prefix = 9;
    EVPNIPMSIRoute evpn_i_pmsi = 10;
    LabeledVPNIPAddressPrefix labeled_vpn_ip_prefix = 11;
    RouteTargetMembershipNLRI route_target_membership = 12;
    FlowSpecNLRI flow_spec = 13;
    VPNFlowSpecNLRI vpn_flow_spec = 14;
    OpaqueNLRI opaque = 15;
    LsAddrPrefix ls_addr_prefix = 16;
    SRPolicyNLRI sr_policy = 17;
    MUPInterworkSegmentDiscoveryRoute mup_interwork_segment_discovery = 18;
    MUPDirectSegmentDiscoveryRoute mup_direct_segment_discovery = 19;
    MUPType1SessionTransformedRoute mup_type_1_session_transformed = 20;
    MUPType2SessionTransformedRoute mup_type_2_session_transformed = 21;
  }
}

// IPAddressPrefix represents the NLRI for:
// - AFI=1, SAFI=1
// - AFI=2, SAFI=1
message IPAddressPrefix {
  uint32 prefix_len = 1;
  string prefix = 2;
}

// LabeledIPAddressPrefix represents the NLRI for:
// - AFI=1, SAFI=4
// - AFI=2, SAFI=4
message LabeledIPAddressPrefix {
  repeated uint32 labels = 1;
  uint32 prefix_len = 2;
  string prefix = 3;
}

// EncapsulationNLRI represents the NLRI for:
// - AFI=1, SAFI=7
// - AFI=2, SAFI=7
message EncapsulationNLRI {
  string address = 1;
}

// VPLSNLRI represents the NLRI for:
// - AFI=25, SAFI=65
message VPLSNLRI {
  RouteDistinguisher rd = 1;
  uint32 ve_id = 2;
  uint32 ve_block_offset = 3;
  uint32 ve_block_size = 4;
  uint32 label_block_base = 5;
}

message EthernetSegmentIdentifier {
  uint32 type = 1;
  bytes value = 2;
}

// EVPNEthernetAutoDiscoveryRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=1
message EVPNEthernetAutoDiscoveryRoute {
  RouteDistinguisher rd = 1;
  EthernetSegmentIdentifier esi = 2;
  uint32 ethernet_tag = 3;
  uint32 label = 4;
}

// EVPNMACIPAdvertisementRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=2
message EVPNMACIPAdvertisementRoute {
  RouteDistinguisher rd = 1;
  EthernetSegmentIdentifier esi = 2;
  uint32 ethernet_tag = 3;
  string mac_address = 4;
  string ip_address = 5;
  repeated uint32 labels = 6;
}

// EVPNInclusiveMulticastEthernetTagRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=3
message EVPNInclusiveMulticastEthernetTagRoute {
  RouteDistinguisher rd = 1;
  uint32 ethernet_tag = 2;
  string ip_address = 3;
}

// EVPNEthernetSegmentRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=4
message EVPNEthernetSegmentRoute {
  RouteDistinguisher rd = 1;
  EthernetSegmentIdentifier esi = 2;
  string ip_address = 3;
}

// EVPNIPPrefixRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=5
message EVPNIPPrefixRoute {
  RouteDistinguisher rd = 1;
  EthernetSegmentIdentifier esi = 2;
  uint32 ethernet_tag = 3;
  string ip_prefix = 4;
  uint32 ip_prefix_len = 5;
  string gw_address = 6;
  uint32 label = 7;
}

// EVPNIPMSIRoute represents the NLRI for:
// - AFI=25, SAFI=70, RouteType=9
message EVPNIPMSIRoute {
  RouteDistinguisher rd = 1;
  uint32 ethernet_tag = 2;
  RouteTarget rt = 3;
}

// SRPolicyNLRI represents the NLRI for:
// - AFI=1, SAFI=73
// - AFI=2, SAFI=73
message SRPolicyNLRI {
  // length field carries the length of NLRI portion expressed in bits
  uint32 length = 1;
  // distinguisher field carries 4-octet value uniquely identifying the policy
  // in the context of <color, endpoint> tuple.
  uint32 distinguisher = 2;
  // color field carries 4-octet value identifying (with the endpoint) the
  // policy.  The color is used to match the color of the destination
  // prefixes to steer traffic into the SR Policy
  uint32 color = 3;
  // endpoint field identifies the endpoint of a policy.  The Endpoint may
  // represent a single node or a set of nodes (e.g., an anycast
  // address).  The Endpoint is an IPv4 (4-octet) address or an IPv6
  // (16-octet) address according to the AFI of the NLRI.
  bytes endpoint = 4;
}

// LabeledVPNIPAddressPrefix represents the NLRI for:
// - AFI=1, SAFI=128
// - AFI=2, SAFI=128
message LabeledVPNIPAddressPrefix {
  repeated uint32 labels = 1;
  RouteDistinguisher rd = 2;
  uint32 prefix_len = 3;
  string prefix = 4;
}

// RouteTargetMembershipNLRI represents the NLRI for:
// - AFI=1, SAFI=132
message RouteTargetMembershipNLRI {
  uint32 asn = 1;
  RouteTarget rt = 2;
}

message FlowSpecIPPrefix {
  uint32 type = 1;
  uint32 prefix_len = 2;
  string prefix = 3;
  // IPv6 only
  uint32 offset = 4;
}

message FlowSpecMAC {
  uint32 type = 1;
  string address = 2;
}

message FlowSpecComponentItem {
  // Operator for Numeric type, Operand for Bitmask type
  uint32 op = 1;
  uint64 value = 2;
}

message FlowSpecComponent {
  uint32 type = 1;
  repeated FlowSpecComponentItem items = 2;
}

message FlowSpecRule {
  oneof rule {
    FlowSpecIPPrefix ip_prefix = 1;
    FlowSpecMAC mac = 2;
    FlowSpecComponent component = 3;
  }
}

// FlowSpecNLRI represents the NLRI for:
// - AFI=1, SAFI=133
// - AFI=2, SAFI=133
message FlowSpecNLRI {
  repeated FlowSpecRule rules = 1;
}

// VPNFlowSpecNLRI represents the NLRI for:
// - AFI=1, SAFI=134
// - AFI=2, SAFI=134
// - AFI=25, SAFI=134
message VPNFlowSpecNLRI {
  RouteDistinguisher rd = 1;
  repeated FlowSpecRule rules = 2;
}

// OpaqueNLRI represents the NLRI for:
// - AFI=16397, SAFI=241
message OpaqueNLRI {
  bytes key = 1;
  bytes value = 2;
}

// Based om RFC 7752, Table 1.
enum LsNLRIType {
  LS_NLRI_TYPE_UNSPECIFIED = 0;
  LS_NLRI_TYPE_NODE = 1;
  LS_NLRI_TYPE_LINK = 2;
  LS_NLRI_TYPE_PREFIX_V4 = 3;
  LS_NLRI_TYPE_PREFIX_V6 = 4;
  LS_NLRI_TYPE_SRV6_SID = 6;
}

enum LsProtocolID {
  LS_PROTOCOL_ID_UNSPECIFIED = 0;
  LS_PROTOCOL_ID_ISIS_L1 = 1;
  LS_PROTOCOL_ID_ISIS_L2 = 2;
  LS_PROTOCOL_ID_OSPF_V2 = 3;
  LS_PROTOCOL_ID_DIRECT = 4;
  LS_PROTOCOL_ID_STATIC = 5;
  LS_PROTOCOL_ID_OSPF_V3 = 6;
}

message LsNodeDescriptor {
  uint32 asn = 1;
  uint32 bgp_ls_id = 2;
  uint32 ospf_area_id = 3;
  bool pseudonode = 4;
  string igp_router_id = 5;
  string bgp_router_id = 6;
  uint32 bgp_confederation_member = 7;
}

message LsLinkDescriptor {
  uint32 link_local_id = 1;
  uint32 link_remote_id = 2;
  string interface_addr_ipv4 = 3;
  string neighbor_addr_ipv4 = 4;
  string interface_addr_ipv6 = 5;
  string neighbor_addr_ipv6 = 6;
}

enum LsOspfRouteType {
  LS_OSPF_ROUTE_TYPE_UNSPECIFIED = 0;
  LS_OSPF_ROUTE_TYPE_INTRA_AREA = 1;
  LS_OSPF_ROUTE_TYPE_INTER_AREA = 2;
  LS_OSPF_ROUTE_TYPE_EXTERNAL1 = 3;
  LS_OSPF_ROUTE_TYPE_EXTERNAL2 = 4;
  LS_OSPF_ROUTE_TYPE_NSSA1 = 5;
  LS_OSPF_ROUTE_TYPE_NSSA2 = 6;
}

message LsPrefixDescriptor {
  repeated string ip_reachability = 1;
  LsOspfRouteType ospf_route_type = 2;
}

message LsNodeNLRI {
  LsNodeDescriptor local_node = 1;
}

message LsLinkNLRI {
  LsNodeDescriptor local_node = 1;
  LsNodeDescriptor remote_node = 2;
  LsLinkDescriptor link_descriptor = 3;
}

message LsPrefixV4NLRI {
  LsNodeDescriptor local_node = 1;
  LsPrefixDescriptor prefix_descriptor = 2;
}

message LsPrefixV6NLRI {
  LsNodeDescriptor local_node = 1;
  LsPrefixDescriptor prefix_descriptor = 2;
}

// https://tools.ietf.org/html/rfc9552
message LsSrv6SIDInformation {
  repeated string sids = 1;
}

message LsMultiTopologyIdentifier {
  repeated uint32 multi_topo_ids = 1;
}

// TODO: LsSrPolicyiCandidatePathNLRI
message LsSrv6SIDNLRI {
  LsNodeDescriptor local_node = 1;
  LsSrv6SIDInformation srv6_sid_information = 2;
  LsMultiTopologyIdentifier multi_topo_id = 3;
}

// LsAddrPrefix represents the NLRI for:
// - AFI=16388, SAFI=71
message LsAddrPrefix {
  LsNLRIType type = 1;
  message LsNLRI {
    oneof nlri {
      LsNodeNLRI node = 1;
      LsLinkNLRI link = 2;
      LsPrefixV4NLRI prefix_v4 = 3;
      LsPrefixV6NLRI prefix_v6 = 4;
      LsSrv6SIDNLRI srv6_sid = 5;
    }
  }
  LsNLRI nlri = 2;
  uint32 length = 3;
  LsProtocolID protocol_id = 4;
  uint64 identifier = 5;
}

message MUPInterworkSegmentDiscoveryRoute {
  RouteDistinguisher rd = 1;
  string prefix = 2;
}

message MUPDirectSegmentDiscoveryRoute {
  RouteDistinguisher rd = 1;
  string address = 2;
}

message MUPType1SessionTransformedRoute {
  RouteDistinguisher rd = 1;
  uint32 prefix_length = 2 [deprecated = true];
  string prefix = 3;
  uint32 teid = 4;
  uint32 qfi = 5;
  uint32 endpoint_address_length = 6;
  string endpoint_address = 7;
  uint32 source_address_length = 8;
  string source_address = 9;
}

message MUPType2SessionTransformedRoute {
  RouteDistinguisher rd = 1;
  uint32 endpoint_address_length = 2;
  string endpoint_address = 3;
  uint32 teid = 4;
}
