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
random Number Percentage to match randomly, 0 (never matches) to 100 (always matches)
recv_peer String/Regexp Match peer node we received the request from
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: AVP path
  • 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
any Array ORed array of objects containing matching criteria. Evaluation stops when a criteria set matches. Objects may contain any matching criteria including any
Objects with no matching fields will be ignored

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, peer_list, node, node_override
peer NODE Next peer node to forward the request (peer of current node or node indicated in local_node)
peer_list Object Next peer nodes to forward the request (peers of current node or node indicated in local_node).
This parameter is ignored if peer is set.
Parameters:
  • peers: Array of NODE
  • algorithm: String: Optional algorithm to use:
    • rotate: Rotate the list of peers each time a request is forwarded. This is the default value
    • fixed or -: Always forward to the same peers list
    • avp-hash: Rotate the list starting from a fixed point given by AVP value hash
    • random: Rotate the list starting from a random point in it
  • path: AVP path. This parameter is required for algorithm=avp-hash, ignored otherwise. If AVP value is missing (AVP is missing or it's a grouped one) the initial list is used

NOTE: This option needs Yate 6.0.1

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.
This parameter is ignored if peer or peer_list is set
The following parameters are ignored if this parameter is set: proxy, msgparams, alternate_node
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

Other parameters

Parameters used to alter the message when forwarding a request:

Field Format Description
msgparams Object Yate message parameters to set (without routing prefix)
alternate_node Array List of objects with 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 or String (with host only): 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

Miscellaneous parameters:

Field Format Description
trace String String to be put on output when route matches. Matching parameters are replaced in it (e.g. trace:"Matched ${recv_peer}/${appid}")

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
  • AVP path format: String with AVP tree separated by '/'. Empty elements in path (including first element) are not allowed
    Valid values: TerminalInfo/IMEI or Username
    Invalid values: TerminalInfo/IMEI/ or /Username

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 match in realm entry
  • 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,
        },
      },
    ]
  }
]

Other examples

Load balancing

This example shows how to distribute 3GPP S6a/d requests with no Destination-Host AVP to HSS

{
  cmdappid: "16777251",
  cmdshortname: "^(AIR\|ULR\|PUR\|NOR)$"
  host: "^$",
  peer_list: {
    peers: ["example.com/hss1.example.com", "example.com/hss2.example.com"]
  }
}

any matching usage

In this example the request will be forwarded to destination host if it starts with 'hss' AND:

  • Peer sending the request has 'example.com' as realm AND command application ID is 16777251 OR
  • Command application ID is 16777216
{
  host: "^hss",
  any: [
    {
      recv_peer: "^example\\.com/",
      cmdappid: "16777251"
    },
    { cmdappid: "16777216" }
  ],
  forward: true
}

Probabilistic distribution

In this example the request will be sent to 'hss1.example.com' with a probability of 60% or load balanced between HSS1 and HSS2

{
  host: "^$",
  cmdappid: "16777251",
  random: 60,
  peer: "example.com/hss1.example.com"
}
{
  host: "^$",
  cmdappid: "16777251",
  peer_list: {
    peers: ["example.com/hss1.example.com", "example.com/hss2.example.com"]
  }
}