iptablesNAT sets up iptables rules for NAT forwarding. If destIP is specified, the forwarding rule will only apply to traffic to/from that IP (mapvarydest).
( t *testing.T, netNS *os.File, clientIP string, clientPort int, routerIP string, routerPort int, destIP string, )
| 833 | // specified, the forwarding rule will only apply to traffic to/from that IP |
| 834 | // (mapvarydest). |
| 835 | func iptablesNAT( |
| 836 | t *testing.T, netNS *os.File, clientIP string, clientPort int, routerIP string, routerPort int, destIP string, |
| 837 | ) { |
| 838 | t.Helper() |
| 839 | |
| 840 | snatArgs := []string{ |
| 841 | "-t", "nat", |
| 842 | "-A", "POSTROUTING", |
| 843 | "-p", "udp", |
| 844 | "--sport", fmt.Sprint(clientPort), |
| 845 | "-j", "SNAT", |
| 846 | "--to-source", fmt.Sprintf("%s:%d", routerIP, routerPort), |
| 847 | } |
| 848 | if destIP != "" { |
| 849 | // Insert `-d $destIP` after the --sport flag+value. |
| 850 | newSnatArgs := append([]string{}, snatArgs[:8]...) |
| 851 | newSnatArgs = append(newSnatArgs, "-d", destIP) |
| 852 | newSnatArgs = append(newSnatArgs, snatArgs[8:]...) |
| 853 | snatArgs = newSnatArgs |
| 854 | } |
| 855 | _, err := commandInNetNS(netNS, "iptables", snatArgs).Output() |
| 856 | require.NoError(t, wrapExitErr(err), "add iptables SNAT rule") |
| 857 | |
| 858 | // Incoming traffic should be forwarded to the client's IP. |
| 859 | dnatArgs := []string{ |
| 860 | "-t", "nat", |
| 861 | "-A", "PREROUTING", |
| 862 | "-p", "udp", |
| 863 | "--dport", fmt.Sprint(routerPort), |
| 864 | "-j", "DNAT", |
| 865 | "--to-destination", fmt.Sprintf("%s:%d", clientIP, clientPort), |
| 866 | } |
| 867 | if destIP != "" { |
| 868 | // Insert `-s $destIP` before the --dport flag+value. |
| 869 | newDnatArgs := append([]string{}, dnatArgs[:6]...) |
| 870 | newDnatArgs = append(newDnatArgs, "-s", destIP) |
| 871 | newDnatArgs = append(newDnatArgs, dnatArgs[6:]...) |
| 872 | dnatArgs = newDnatArgs |
| 873 | } |
| 874 | _, err = commandInNetNS(netNS, "iptables", dnatArgs).Output() |
| 875 | require.NoError(t, wrapExitErr(err), "add iptables DNAT rule") |
| 876 | } |
| 877 | |
| 878 | func commandInNetNS(netNS *os.File, bin string, args []string) *exec.Cmd { |
| 879 | //nolint:gosec |
no test coverage detected