[][Add hnat count to nf_conntrack]
[Description]
Add hnat count to nf_conntrack through keepalive.
Notice that we need to enable it by command:
echo "7 1" > /sys/kernel/debug/hnat/hnat_setting
Test Result:
root@OpenWrt:/# conntrack -L
tcp 6 7439 ESTABLISHED ... packets=126876 bytes=192176221 ... packets=27121 bytes=1629422
After keepalive interval, "conntrack -L" again, we could see hnat counter is updated to conntrack.
root@OpenWrt:/# conntrack -L
tcp 6 7439 ESTABLISHED ... packets=596148 bytes=902807461 ... packets=116947 bytes=7025906
[Release-log]
N/A
Change-Id: I189a8f8a5a332b67f00b8fc922a1d5c5343acde8
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5211150
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index d5b4c8d..52c8419 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -663,6 +663,7 @@
struct timer_list hnat_sma_build_entry_timer;
struct timer_list hnat_reset_timestamp_timer;
struct timer_list hnat_mcast_check_timer;
+ bool nf_stat_en;
};
struct extdev_entry {
@@ -940,6 +941,8 @@
int entry_detail(int ppe_id, int index);
int entry_delete_by_mac(u8 *mac);
int entry_delete(int ppe_id, int index);
+struct hnat_accounting *hnat_get_count(struct mtk_hnat *h, int ppe_id,
+ u32 index, struct hnat_accounting *diff);
static inline u16 foe_timestamp(struct mtk_hnat *h)
{
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
index 3ade0b0..335bd66 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c
@@ -563,6 +563,7 @@
pr_info(" 4 0~65535 Set UDP bind lifetime\n");
pr_info(" 5 0~255 Set TCP keep alive interval\n");
pr_info(" 6 0~255 Set UDP keep alive interval\n");
+ pr_info(" 7 0~1 Set hnat counter update to nf_conntrack\n");
return 0;
}
@@ -659,6 +660,21 @@
return 0;
}
+int set_nf_update_toggle(int toggle)
+{
+ struct mtk_hnat *h = hnat_priv;
+
+ if (toggle == 1)
+ pr_info("Enable hnat counter update to nf_conntrack\n");
+ else if (toggle == 0)
+ pr_info("Disable hnat counter update to nf_conntrack\n");
+ else
+ pr_info("input error\n");
+ h->nf_stat_en = toggle;
+
+ return 0;
+}
+
static const debugfs_write_func hnat_set_func[] = {
[0] = hnat_set_usage,
[1] = hnat_cpu_reason,
@@ -677,47 +693,66 @@
[0] = cr_set_usage, [1] = binding_threshold,
[2] = tcp_bind_lifetime, [3] = fin_bind_lifetime,
[4] = udp_bind_lifetime, [5] = tcp_keep_alive,
- [6] = udp_keep_alive,
+ [6] = udp_keep_alive, [7] = set_nf_update_toggle,
};
-static struct hnat_accounting *hnat_get_count(struct mtk_hnat *h,
- int ppe_id, u32 index)
+int read_mib(struct mtk_hnat *h, int ppe_id,
+ u32 index, u64 *bytes, u64 *packets)
{
- struct hnat_accounting *acount;
+ int ret;
u32 val, cnt_r0, cnt_r1, cnt_r2;
- int ret = -1;
-
- if (!hnat_priv->data->per_flow_accounting)
- return NULL;
-
writel(index | (1 << 16), h->ppe_base[ppe_id] + PPE_MIB_SER_CR);
- ret = readx_poll_timeout_atomic(readl, h->ppe_base[ppe_id] + PPE_MIB_SER_CR,
- val, !(val & BIT_MIB_BUSY), 20, 10000);
+ ret = readx_poll_timeout_atomic(readl, h->ppe_base[ppe_id] + PPE_MIB_SER_CR, val,
+ !(val & BIT_MIB_BUSY), 20, 10000);
+
if (ret < 0) {
- pr_notice("mib busy,please check later\n");
- return NULL;
+ pr_notice("mib busy, please check later\n");
+ return ret;
}
cnt_r0 = readl(h->ppe_base[ppe_id] + PPE_MIB_SER_R0);
cnt_r1 = readl(h->ppe_base[ppe_id] + PPE_MIB_SER_R1);
cnt_r2 = readl(h->ppe_base[ppe_id] + PPE_MIB_SER_R2);
- acount = &h->acct[ppe_id][index];
- acount->bytes += cnt_r0 + ((u64)(cnt_r1 & 0xffff) << 32);
- acount->packets +=
- ((cnt_r1 & 0xffff0000) >> 16) + ((cnt_r2 & 0xffffff) << 16);
+ *bytes = cnt_r0 + ((u64)(cnt_r1 & 0xffff) << 32);
+ *packets = ((cnt_r1 & 0xffff0000) >> 16) + ((cnt_r2 & 0xffffff) << 16);
- return acount;
+ return 0;
+
+}
+
+struct hnat_accounting *hnat_get_count(struct mtk_hnat *h, int ppe_id,
+ u32 index, struct hnat_accounting *diff)
+
+{
+ u64 bytes, packets;
+
+ if (!hnat_priv->data->per_flow_accounting)
+ return NULL;
+
+ if (read_mib(h, ppe_id, index, &bytes, &packets))
+ return NULL;
+
+ h->acct[ppe_id][index].bytes += bytes;
+ h->acct[ppe_id][index].packets += packets;
+
+ if (diff) {
+ diff->bytes = bytes;
+ diff->packets = packets;
+ }
+
+ return &h->acct[ppe_id][index];
}
+EXPORT_SYMBOL(hnat_get_count);
-#define PRINT_COUNT(m, acount) {if (acount) \
+#define PRINT_COUNT(m, acct) {if (acct) \
seq_printf(m, "bytes=%llu|packets=%llu|", \
- acount->bytes, acount->packets); }
+ acct->bytes, acct->packets); }
static int __hnat_debug_show(struct seq_file *m, void *private, int ppe_id)
{
struct mtk_hnat *h = hnat_priv;
struct foe_entry *entry, *end;
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
- struct hnat_accounting *acount;
+ struct hnat_accounting *acct;
u32 entry_index = 0;
entry = h->foe_table_cpu[ppe_id];
@@ -728,7 +763,7 @@
entry_index++;
continue;
}
- acount = hnat_get_count(h, ppe_id, entry_index);
+ acct = hnat_get_count(h, ppe_id, entry_index, NULL);
if (IS_IPV4_HNAPT(entry)) {
__be32 saddr = htonl(entry->ipv4_hnapt.sip);
__be32 daddr = htonl(entry->ipv4_hnapt.dip);
@@ -741,7 +776,7 @@
*((u32 *)h_dest) = swab32(entry->ipv4_hnapt.dmac_hi);
*((u16 *)&h_dest[4]) =
swab16(entry->ipv4_hnapt.dmac_lo);
- PRINT_COUNT(m, acount);
+ PRINT_COUNT(m, acct);
seq_printf(m,
"addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|%pI4:%d->%pI4:%d=>%pI4:%d->%pI4:%d|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
entry, ppe_id, ei(entry, end),
@@ -767,7 +802,7 @@
*((u32 *)h_dest) = swab32(entry->ipv4_hnapt.dmac_hi);
*((u16 *)&h_dest[4]) =
swab16(entry->ipv4_hnapt.dmac_lo);
- PRINT_COUNT(m, acount);
+ PRINT_COUNT(m, acct);
seq_printf(m,
"addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|%pI4->%pI4=>%pI4->%pI4|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n",
entry, ppe_id, ei(entry, end),
@@ -795,7 +830,7 @@
*((u32 *)h_dest) = swab32(entry->ipv6_5t_route.dmac_hi);
*((u16 *)&h_dest[4]) =
swab16(entry->ipv6_5t_route.dmac_lo);
- PRINT_COUNT(m, acount);
+ PRINT_COUNT(m, acct);
seq_printf(m,
"addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x(sp=%d)->DIP=%08x:%08x:%08x:%08x(dp=%d)|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
entry, ppe_id, ei(entry, end), es(entry), pt(entry), ipv6_sip0,
@@ -823,7 +858,7 @@
*((u32 *)h_dest) = swab32(entry->ipv6_5t_route.dmac_hi);
*((u16 *)&h_dest[4]) =
swab16(entry->ipv6_5t_route.dmac_lo);
- PRINT_COUNT(m, acount);
+ PRINT_COUNT(m, acct);
seq_printf(m,
"addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x->DIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
entry, ppe_id, ei(entry, end),
@@ -852,7 +887,7 @@
*((u32 *)h_dest) = swab32(entry->ipv6_5t_route.dmac_hi);
*((u16 *)&h_dest[4]) =
swab16(entry->ipv6_5t_route.dmac_lo);
- PRINT_COUNT(m, acount);
+ PRINT_COUNT(m, acct);
seq_printf(m,
"addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%08x:%08x:%08x:%08x(sp=%d)->DIP=%08x:%08x:%08x:%08x(dp=%d)|TSIP=%pI4->TDIP=%pI4|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
entry, ppe_id, ei(entry, end),
@@ -883,7 +918,7 @@
*((u32 *)h_dest) = swab32(entry->ipv4_dslite.dmac_hi);
*((u16 *)&h_dest[4]) =
swab16(entry->ipv4_dslite.dmac_lo);
- PRINT_COUNT(m, acount);
+ PRINT_COUNT(m, acct);
seq_printf(m,
"addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%pI4->DIP=%pI4|TSIP=%08x:%08x:%08x:%08x->TDIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
entry, ppe_id, ei(entry, end),
@@ -915,7 +950,7 @@
*((u32 *)h_dest) = swab32(entry->ipv4_dslite.dmac_hi);
*((u16 *)&h_dest[4]) =
swab16(entry->ipv4_dslite.dmac_lo);
- PRINT_COUNT(m, acount);
+ PRINT_COUNT(m, acct);
seq_printf(m,
"addr=0x%p|ppe=%d|index=%d|state=%s|type=%s|SIP=%pI4:%d->DIP=%pI4:%d|NSIP=%pI4:%d->NDIP=%pI4:%d|TSIP=%08x:%08x:%08x:%08x->TDIP=%08x:%08x:%08x:%08x|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x\n",
entry, ppe_id, ei(entry, end),
@@ -1377,6 +1412,7 @@
case 4:
case 5:
case 6:
+ case 7:
p_token = strsep(&p_buf, p_delimiter);
if (!p_token)
arg1 = 0;
@@ -1937,7 +1973,7 @@
int get_ppe_mib(int ppe_id, int index, u64 *pkt_cnt, u64 *byte_cnt)
{
struct mtk_hnat *h = hnat_priv;
- struct hnat_accounting *acount;
+ struct hnat_accounting *acct;
struct foe_entry *entry;
if (ppe_id >= CFG_PPE_NUM)
@@ -1948,17 +1984,17 @@
return -EINVAL;
}
- acount = hnat_get_count(h, ppe_id, index);
+ acct = hnat_get_count(h, ppe_id, index, NULL);
entry = hnat_priv->foe_table_cpu[ppe_id] + index;
- if (!acount)
+ if (!acct)
return -1;
if (entry->bfib1.state != BIND)
return -1;
- *pkt_cnt = acount->packets;
- *byte_cnt = acount->bytes;
+ *pkt_cnt = acct->packets;
+ *byte_cnt = acct->bytes;
return 0;
}
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index a904189..c76189d 100644
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -23,6 +23,8 @@
#include <net/ip.h>
#include <net/tcp.h>
#include <net/udp.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_acct.h>
#include "nf_hnat_mtk.h"
#include "hnat.h"
@@ -1858,6 +1860,28 @@
}
}
+static void mtk_hnat_nf_update(struct sk_buff *skb)
+{
+ struct nf_conn *ct;
+ struct nf_conn_acct *acct;
+ struct nf_conn_counter *counter;
+ enum ip_conntrack_info ctinfo;
+ struct hnat_accounting diff;
+
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct) {
+ if (!hnat_get_count(hnat_priv, skb_hnat_ppe(skb), skb_hnat_entry(skb), &diff))
+ return;
+
+ acct = nf_conn_acct_find(ct);
+ if (acct) {
+ counter = acct->counter;
+ atomic64_add(diff.packets, &counter[CTINFO2DIR(ctinfo)].packets);
+ atomic64_add(diff.bytes, &counter[CTINFO2DIR(ctinfo)].bytes);
+ }
+ }
+}
+
static unsigned int mtk_hnat_nf_post_routing(
struct sk_buff *skb, const struct net_device *out,
unsigned int (*fn)(struct sk_buff *, const struct net_device *,
@@ -1903,6 +1927,10 @@
skb_to_hnat_info(skb, out, entry, &hw_path);
break;
case HIT_BIND_KEEPALIVE_DUP_OLD_HDR:
+ /* update hnat count to nf_conntrack by keepalive */
+ if (hnat_priv->data->per_flow_accounting && hnat_priv->nf_stat_en)
+ mtk_hnat_nf_update(skb);
+
if (fn && !mtk_hnat_accel_type(skb))
break;