Hot reloaded — edits apply within about 200 ms with no restart.
A rule is four colon-separated parts
Target is a worker instance (vendor1, smppserver.smpp), a group, or another table to chain
into (MESSAGE).
Rules are evaluated top to bottom within a table, and the first match wins.
A malformed rule fails the whole reload and the previous table is retained. Check the log for
Error parsing new routing table after editing — the gateway keeps working on the old table, so
nothing appears wrong until you wonder why your change did nothing.
The two mistakes the parser will not save you from
== is a numeric operator. Use equals for strings:
matches is anchored, startsWith is literal. ^61.* matches a full number; a bare 61 does
not. And startsWith compares literal text — a regular expression handed to it matches nothing, quietly.
A minimal table
The catch-all goes at the end. Above other rules it makes everything below it unreachable, and
nothing warns you — the rules parse fine, they simply never run.
product comes from the system_type on the client’s SMPP bind, falling back to the credential’s
product. HTTP callers always use the credential value.
Vendor groups
A group is another name a rule can send to. Instead of naming one vendor, the rule names a group and
the group picks a member — skipping any that is suspended or not accepting, which is the failover
a single-target rule cannot do.
Group blocks must come before the first [table] header. Inside a table block a member line
matches nothing and is dropped silently.A weight is read only by weighted. Setting one on the other two changes nothing, and the gateway
says so at WARN rather than letting you believe a split is happening.
Least-cost routing tables
A table marked ->function(LCR) behaves differently: instead of stopping at the first matching rule,
every matching rule is a candidate and the vendor with the cheapest rate in rates.conf wins.
Rule order is therefore irrelevant in an LCR table — the rules are alternatives, not a fallback chain.
- Vendors that are down or not accepting are skipped, so the next cheapest carries the traffic.
- A vendor with no matching rate is used only if nothing else matches, so a missing rate line
degrades rather than blocks.
- Rules pointing at another table are ignored inside an LCR table.
See Least-cost routing.
Filters
A rule may reference a named filter from the filter library instead of spelling its conditions inline.
A missing or disabled filter skips every rule that references it, rather than loading the rule
with fewer conditions. Dropping a condition would make the rule match more traffic, so failing that
way would be silent and would route the wrong things.This is why disabling a filter can make a rule appear to match less, and why the fix is never to
“just remove the condition”.
In database mode this file is not read after startup; the same data lives in app_route_table,
app_route_rule and their condition tables. See Database.