BPI-R2 Kernel 4.14 HNAT


i’m trying to port HNAT to 4.14…hangung currently on calls “nf_register_hooks” and “nf_unregister_hooks”, which are removed from netfilter.h

does anybody know, how the new way is?

int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);

is replaced by

int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg,
			  unsigned int n);
void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
			     unsigned int n);

with Kernel 4.12.x (old functions still there in 4.11)

to change it i need a net-variable, but i’ve not found out how to get it…

drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c:279:int hnat_register_nf_hooks(void)
drivers/net/ethernet/mediatek/mtk_hnat/hnat.c:275:	err = hnat_register_nf_hooks();

it seems it must be implemented like this (patch modified to get real function):


int nf_register_hook(struct nf_hook_ops *reg)
  struct net *net, *last;
  int ret;
  for_each_net(net) { //seems to get the net-var which is only declared above
    ret = nf_register_net_hook(net, reg);
    if (ret && ret != -ENOENT)
       goto rollback;
    list_add_tail(&reg->list, &nf_hook_list);

happy holidays

regards Frank

1 Like


It’s much easier if you add network name space support, It’s future proof.

For example , look here : https://github.com/torvalds/linux/commit/e661a58279132da0127c67705e59d12f6027858d#diff-790c7c240656e2362777d59ab5721a3a

In this patch they introduced “pernet_operations” support .

hi, looked through the patch and added the pernet-functions, the main-problem is how to get the net-param…this i did not found in the patch itself…it seems they use a struct for the callbacks, in hnat-source there is a direct call

too few arguments to function ‘hnat_unregister_nf_hooks’

can i use the register_pernet_subsys without collision? it should not be a function of a specific framework

the problem is how to remove static calls and use the callbacks from the struct…how the right function is called where the static calls are to be removed (how to replace them)

it seems that i got it with my way above (no compile-error…don’t know it’s the right way…)

currently biting on that error:

drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c: In function ‘skb_to_hnat_info’:
drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c:31:9: error: missing braces around initializer [-Werror=missing-braces]
  struct foe_entry entry = { 0 };
drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c:31:9: error: (near initialization for ‘entry.<anonymous>’) [-Werror=missing-braces]
cc1: all warnings being treated as errors

according to this https://stackoverflow.com/questions/13746033/how-to-repair-warning-missing-braces-around-initializer

foe_entry is defined like this:

struct foe_entry {
    union {
        struct hnat_unbind_info_blk udib1;
        struct hnat_bind_info_blk bfib1;
        struct hnat_ipv4_hnapt ipv4_hnapt;

after reading that ( http://en.cppreference.com/w/c/language/struct_initialization ) i tried to change it to

struct foe_entry entry = {.udib1={ 0 },.bfib1={0},.ipv4_hnapt={0}};

but same error :frowning:

last error is a bug of gcc 4.8, disabled that waring in my github…hnat compiles fine, can be tested (hnat branch)

Had forgotten the last patch…included now on github and precompiled Kernel on gdrive

Please test and give me feedback if it works correctly

@garywang @sinovoip

did HNAT affect QoS, Port-forwarding or PPPoE-usage?

which kind of HNAT is realized in mt7623? (acceleration/Cut-Through Forwarding/CTF+Flow Accelerator)

reference: https://routerguide.net/nat-acceleration-on-or-off/

Hi Frank

I don’t think the Qos, Port-Forwarding, and PPPoE will be impacted, below is the block diagram of ethernet system, the forwarding entry of HNAT is in the PSE, let me know if you have any question.


Thanks Gary

1 Like

thank you Gary, in the block-diagram the PSE is always between system-bus (i assume to CPU) and the GMACs how do you conclude, that hnat does not affect QOS and port-forwarding?

in https://github.com/frank-w/BPI-R2-4.14/blob/hnat/0026-net-mediatek-backport-v4.10-driver.patch i’ve read, that the driver is backported from 4.10, but i had not found that original patch yet…maybe there it is adapted to the per-net-functions, so i can look if i have done make it right :slight_smile:

have you a block-diagram of WAN/LAN to GMAC1/2? for LAN/WAN-Separation…

Dear Gary,

We are not allowed to open MT7623N datasheet’s content which shows “Foxconn confidential” that will against Foxconn NDA with MTK.

Pls only provide open source MT7623N datasheet which shows “Banana Pi”, Tks for your kind cooperation!

Nora Lee Banana Pi PM

Thanks for your reminder, Nora.

BR Gary

How can we test if its working? is it enough loading the module and set up a nat via ip-tables or there are additional steps needed? How to define type of hnat if possible?

Hi Frank

We just need to load the hnat driver, other things will be done by driver, we can check the interrupt count of ethernet to see if ethernet packet is passed to CPU.

How to check cpu-pass of packets?

cat /proc/interrupt If you see the interrupt count of ethernet increases quickly when testing the throughput, that means the hardware NAT doesn’t work.

user pkalemba tries to test it, but it seems not working in 4.14. are there any requirements (maybe 2nd gmac)?

the following steps must be imho done (first without hnat then enable hnat):

  1. make sure all interfaces used have ip-adresses (lan/wan different subnets)

  2. setting up NAT: ${ipt} -t nat -A POSTROUTING -o ${if_wan} -j MASQUERADE

  3. set up port-forwarding to your client-machine: ${ipt} -t nat -A PREROUTING -p udp --dport $inport -j DNAT --to-destination $dip:$dport

  4. enable routing: echo 1 > /proc/sys/net/ipv4/ip_forward

  5. test connection between lan-wan

  6. loading hnat-kernelmodule via “modprobe mtkhnat”

  7. “watch cat /proc/interrupts” and generating traffic like with iperf

is that right?

i currently on the way setup NAT (without HNAT) on wan-interface…added rules on my other router and the pi, my raspberry is accessable from a client (which goes first over my other router). i now try to find a way how to test if NAT really works (i’t not a simple forwarding).

iptables itself says it’s right:

root@bpi-r2:~# iptables -L -v -t nat
Chain POSTROUTING (policy ACCEPT 233 packets, 14339 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   20  1368 MASQUERADE  all  --  any    wan     anywhere             anywhere

but tcpdump looks like normal routing:

root@bpi-r2:~# tcpdump -i wan

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wan, link-type EN10MB (Ethernet), capture size 262144 bytes
14:04:26.285393 IP > ICMP echo request, id 2160, seq 1, length 64
14:04:26.286030 IP > ICMP echo reply, id 2160, seq 1, length 64
14:04:27.287170 IP > ICMP echo request, id 2160, seq 2, length 64
14:04:27.287793 IP > ICMP echo reply, id 2160, seq 2, length 64
14:04:28.288186 IP > ICMP echo request, id 2160, seq 3, length 64
14:04:28.288817 IP > ICMP echo reply, id 2160, seq 3, length 64
14:04:31.327195 ARP, Request who-has tell, length 46
14:04:31.327220 ARP, Reply is-at 72:56:c3:44:17:77 (oui Unknown), length 28
14:04:31.343694 ARP, Request who-has tell, length 28
14:04:31.344246 ARP, Reply is-at b8:27:eb:5f:b8:a2 (oui Unknown), length 46

wan on r2 has the, my raspberrypi directly connected to wan has .2, NAT is activated like above:

/sbin/iptables -t nat -A POSTROUTING -o wan -j MASQUERADE

Where can i find the module hnat-kernel module in the kernel config? I am trying with 4.14.14.

it’s currently only in the hnat-branch (not main) till it is tested and working…

i see that a build warning came up and compiled again with CONFIG_DEBUG_SECTION_MISMATCH=y

WARNING: drivers/net/ethernet/mediatek/mtk_hnat/mtkhnat.o(.text+0x658): Section mismatch in reference from the function hnat_probe() to the function .init.text:hnat_init_debugfs()
The function hnat_probe() references
the function __init hnat_init_debugfs().
This is often because hnat_probe lacks a __init 
annotation or the annotation of hnat_init_debugfs is wrong.

currently i can’t see no error (except hnat_probe has no header-entry and no __init…but should it have it??):

drivers/net/ethernet/mediatek/mtk_hnat/hnat.c:236:static int hnat_probe(struct platform_device *pdev)

drivers/net/ethernet/mediatek/mtk_hnat/hnat.h:422:extern int __init hnat_init_debugfs(struct hnat_priv *h); drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c:426:int __init hnat_init_debugfs(struct hnat_priv *h)

anyone is testing it?

with kernel from main-branch i can setup NAT this way:

[rpi] eth0: (vlan60
[bpi-r2]: (vlan60
iptables -t nat -A POSTROUTING -o $wan -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
ip route add default via
you router must be configured to route packets to 50.2 to 0.10 (lan-IP of BPI-R2 in your net), currently seems not working
route add -net netmask gw
route add -net netmask gw

now if you ping, you should get a response, if you look at the rpi (or client holding the IP behind the NAT) with TCP-Dump you should only see the IP 50.1 not that one from the client (0.x)

that works from my client only if i set the route there to subnet 50.x, not over the existing router

i cannot get working hnat,even i cannot get connection to my router on wan interface. Looks like wan is not responding with packets…

Have you configured it with main-kernel first (working?) then with hnat-kernel without hnat-module loaded (still working)?

I need to know when the problem comes up…maybe it’s a problem, where lede (from which the patch comes from) uses 2nd gmac for wan…

maybe this is related: https://github.com/frank-w/BPI-R2-4.14/blob/24452db480fa6683472d44bdc83ccb28def772da/drivers/net/ethernet/mediatek/mtk_eth_soc.c#L702

it’s not clear what is done here, because fport is overridden after the if…but also on original-patch: https://github.com/frank-w/BPI-R2-4.14/blob/4.9/patches_from_lede/0056-net-mediatek-add-hw-nat-support.patch

@pkalemba please try using the mtk_eth.c from main-branch and compile with this…hnat will not be work, but wan should work and we know thats a problem with this file