YateDRA Routing

From YateBTS
Jump to: navigation, search

Routing table description

Each configured node have its own routing table.
Each entry contains:

Field Format Description
realm String/Regexp Realm to match (from DestinationRealm)
routes Array List of routes for the realm

A route entry will be used to route a list of destination hosts and/or applications to a peer with whom DRA has a direct connection.
Route entry contents:

Matching parameters

Parameters used to match a request against current routing table entry.

Field Format Description
host String/Regexp Host (Destination-Host AVP) to match
appid String/Regexp Application ID to match (this is the Auth-/Acct-/Vendor-Specific Application-ID AVP). Vendor specific application ID should expect a vendor. E.g. S6a/d should match 16777251/10415
cmdappid String/Regexp Command application ID from Diameter message header to match
cmdcode
cmdshortname
cmdname
String/Regexp Command identifier. These parameters are mutually exclusive. When one of them is set to non empty value the subsequent parameters will be ignored.

cmdcode: Command code (e.g. 316)
cmdshortname:Command short name (e.g. ULR)
cmdname: Command full name (e.g. UpdateLocationRequest)

avp Array AVP(s) to match. Each entry is an object with the following fields:
  • path: String: AVP path, separated by '/'. Empty elements in path (including first element) are not allowed
    Valid values: TerminalInfo/IMEI or Username
    Invalid values: TerminalInfo/IMEI/ or /Username
  • value: String/Regexp: Value to match if the AVP is present. Empty or missing value matches AVP presence
  • optional: Boolean: Set it to true to indicate the AVP may not be present. This is the matching rule if the AVP is not found

Forwarding parameters

Parameters used to forward a request matching current routing table entry.

Field Format Description
forward Boolean True to forward the request to indicated Destination-Host AVP. Request will fail if Destination-Host is empty

The following parameters are ignored if this parameter is enabled: peer, node, node_override

peer NODE Next peer node to forward the request (peer of current node or node indicated in local_node)
node NODE Internal node to pass the message to if peer is not set (jump to another node's routing table). The node will apply its own routing rules.

The following parameters are ignored if this parameter is set: proxy, msgparams, alternate_node

Other parameters

Parameters used to alter the message when forwarding a request.

Field Format Description
local_node NODE Local node to use when forwarding the request (current node is used if this parameter is not set).

The following parameters are ignored if this parameter is set: node, node_override

msgparams Object Yate message parameters to set (without routing prefix)
alternate_node Array List of alternate node(s) to use on failure to send using current node (or local_node)

Known item parameters:

  • local_node: NODE: Required local node
  • peer: NODE: Optional peer to use. Leave it empty to use node's default routing priority if set
proxy Object Optional parameters to be set when forwarding a request. These parameters are set in diameter message as they are.
This parameter is ignored if node is set.

Known parameters:

  • hide_network_topology_avps: boolean/string. Boolean: Remove ProxyInfo and RouteRecord AVPs (restore ProxyInfo in answer if true)
  • add_avps: string: XML fragment with AVPs to add to request. XML is not validated
node_override Object Override destination node table parameters when jumping to another node's table:
  • alternate_node: Boolean: Set it to true to ignore alternate node(s) when forwarding the request
  • proxy: Boolean: Set it to true to ignore proxy parameters when forwarding the request
  • msgparams: Boolean: Set it to true to ignore Yate message parameters when forwarding the request
  • route_record: Boolean: Set it to true to ignore (disable) Route-Record AVP addition when forwarding the request

NOTES:

  • NODE format: String (realm/host)
  • Regexp values are detected when a string starts with '^'
  • To reverse regexp match condition add a '^' char at string end

Routing algorithm

Routing table not configured:

  • DestinationHost AVP present: Try to forward the request to peer indicated in DestinationHost
  • DestinationHost AVP is missing: Reject the request (UNABLE_TO_DELIVER)

Routing table configured

  • DestinationRealm AVP is missing: Reject the request (UNABLE_TO_DELIVER)
  • DestinationRealm AVP value not found (matched) in routing table: Reject the request (REALM_NOT_SERVED)
  • Search for a rule in realm entry.
    Match 'EMPTY(host) OR host matches DestinationHost' AND 'EMPTY(appid) OR appid matches application_id' AND 'EMPTY(cmdappid) OR cmdappid matches appid'.
    application_id is the message parameter set by Diameter module from request application id AVP. The parameter may be empty if the AVP is missing or invalid. It may also be: mismatch if it doesn't match the command header.
    cmdappid is the message parameter set by Diameter module from Diameter command header
  • Rule not found: Reject the request (UNABLE_TO_DELIVER)
  • Rule found: handle it

JSON routing table example

This example describes a DRA configuration with the follwing nodes:

  • example.com/dra1.example.com: We are assuming all internal network services (HSS, MME, EIR ...) are connected to this node.
  • example.com/dea1.example.com: We are assuming all interconnect with other domain(s) are connected to this node. This node id our Diameter Edge Agent
  • example.com/fallback.dra1.example.com: We are assuming a second (fallback) DRA connected to this node

example.com/dra1.example.com routing table:

[
  {
    // Match example.com (sub)domain
    realm: "^(.*\\.)?example\\.com$",
    routes: [
      {
        // Everything matching destination host goes there
        // We are assuming we have a direct connection with these hosts
        // Use an alternate route if our connection is down
        host: "^(mme|hss|eir)(.*\\.)?example\\.com",
        forward: true,
        alternate_node: [
          local_node: "example.com/fallback.dra1.example.com",
          peer: "example.com/fallback.dra2.example.com",
        ],
      },
      {
        // Handle 3GPP S6a/d interface with missing VendorSpecificApplicationID
        appid: "^$",
        cmdappid: "16777251",
        peer: "example.com/hss.example.com",
      },
      {
        // Reject failed or missing application id AVP
        appid: "^$",
      },
      {
        // Forward some 3GPP S6a/d IMSIs to a specific HSS
        // Remember: on this interface the IMSI is carried by the 'Username' AVP
        appid: "16777251/10415",
        avp: [
          {
            path: "Username",
            value: "^00101",
          },
        ],
        peer: "example.com/hss00101.example.com",
      },
      {
        // Handle 3GPP S6a/d interface
        appid: "16777251/10415",
        peer: "example.com/hss.example.com",
      },
      {
        // Handle faulty agents sending 3GPP S6a/d interface application
        //  id in other AVP (it should be in VendorSpecificApplicationId)
        cmdappid: "16777251",
        peer: "example.com/hss.example.com",
      },
      {
        // Handle 3GPP S6a/d interface application with non 3GPP vendor
        appid: "^16777251/",
        peer: "example.com/hss.example.com",
      },
      {
        // Handle 3GPP S13 interface application with
        //  non 3GPP vendor or with app id set in wrong AVP
        appid: "^16777252(/.*)?",
        peer: "example.com/eir.example.com"
      },
      {
        // Everything else goes to some unknown service(s) handler
        peer: "example.com/unknown-handler.example.com"
      },
    ],
  },
  {
    // Foreign domain(s)
    // Send the request to interconnect
    // Hide ProxyInfo, RouteRecord. Restore ProxyInfo when handling the answer
    // Add some custom AVP
    // Use an alternate route if our connection is down
    realm: "foreign.com",
    routes: [
      {
        local_node: "example.com/dea1.example.com",
        peer: "foreign.com/dea1.foreign.com",
        proxy: {
          hide_network_topology_avps: true,
          add_avps: "<AVP_2999 vendor='34501' enc='diamident'>dra.example.com</AVP_2999>",
        }
        alternate_node: [
          local_node: "example.com/fallback.dra1.example.com",
          peer: "example.com/fallback.dra2.example.com",
        ],
      },
    ]
  },
  {
    // Reject all domains we are not handling.
    // This is only an example. The module will reject it anyway if no match
    realm: "^",
  },
]

example.com/dea1.example.com routing table:

[
  {
    // Match our realm(s): example.com (sub)domain
    // Jump to DRA routing table
    realm: "^(.*\\.)?example\\.com$",
    routes: [
      {
        node: "example.com/dra1.example.com"
      },
    ]
  }
]

example.com/fallback.dra1.example.com routing table:

[
  {
    // Match our realm(s): example.com (sub)domain
    // Jump to DRA routing table
    // Disable alternate node: avoid returning the request to our peer (second DRA)
    realm: "^(.*\\.)?example\\.com$",
    routes: [
      {
        node: "example.com/dra1.example.com",
        node_override: {
          alternate_node: false,
        },
      },
    ]
  }
  {
    // Match foreign realm(s)
    // Jump to DRA routing table
    // Disable alternate node: avoid returning the request to our peer (second DRA)
    // Disable proxy parameters: we are expecting our second DRA to do it
    // This will add a RouteRecord AVP (with our second DRA's host): when the message is tracked we (and our partner) will
    //  know the second DRA's connection was down
    realm: "foreign.com",
    routes: [
      {
        node: "example.com/dra1.example.com",
        node_override: {
          alternate_node: false,
          proxy: false,
        },
      },
    ]
  }
]