I want to simply forward the RTP packet received from one IP:Port pair to another IP:Port pair. I have already done it with iptables. iptables use conntrack module. But there is no need of conntrack in my application. So I want to do it with stateless NAT. I have found that statless NAT rules can be executed with "ip route add nat" command e.g

ip route add nat via

This command tells the kernel to perform network address translation on any packet bound for The parameter via tells the NAT code to rewrite the packet bound for with the new destination address

As I understand, the problem is this will forward all packets bound for to Is there any option to forward RTP packets received on specific port of to another IP:Port?

  • No ip route add nat is not a requirement. Kindly share your answer. It would be good if you also give a web link for a more detailed explanation.
    – UserXYZ
    Mar 11 '18 at 10:18

By mangling packet header fields with nftables it's possible, without even using ip route add nat which, as a simple router functionality, is limited to layer 3 (IP), not layer 4 (TCP, UDP, ...).

WARNING: requires nftables >= 0.6 (>= 0.7 here if using notrack) and kernel >= 4.10. Tested here with nftables 0.8.3 and kernel 4.15.x.

It's quite compact, because nftables can combine multiple targets (3 targets here):

# nft add table raw
# nft 'add chain raw prerouting {type filter hook prerouting priority -300;}'
# nft add rule raw prerouting ip daddr udp dport 5004 notrack ip daddr set udp dport set 5006

Quotes on the 2nd line to avoid shell interpretation. If doing tests, the fastest way to remove all of nft is nft flush ruleset.

So just reading it aloud, the rule tells to select only an IP packet with destination, being UDP with destination port 5004, then tags it as non trackable (by conntrack, if it's loaded), sets its destination IP to and sets its destination port to 5006.

You can mix nftables with iptables rules without much problem as long as you don't use nat tables on both at the same time (fine, you don't want to use that anyway). Being able to state the explicit chain priority even allows to choose if nftables hooks will run before or after corresponding iptables hooks, eg here by choosing -301 or -299 to be certain to run before or after iptables' raw table if there was such need.


It does not appear that Linux provides support for stateless NATing that allows you to restrict the behavior by a specific port or set of ports.

From the iproute2 documentation:

Stateless NAT, occasionally maligned as dumb NAT, is the simplest form of NAT. It involves rewriting addresses passing through a routing device: inbound packets will undergo destination address rewriting and outbound packets will undergo source address rewriting.

Looks like this type of NATting is limited to IP addresses only. Taking a look at the current mainstream kernel implementation here, it appears that the functions responsible for doing the work do not accept port numbers, only ip addresses and netmasks.


You need to edit the packets with tc pedit munge. Match the incoming port, rewrite packet destination as the LAN address, and reverse for the outgoing packet. https://www.man7.org/linux/man-pages/man8/tc-pedit.8.html

The good side about tc is that it's fast, very fast. The bad side is the learning curve.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.